summaryrefslogtreecommitdiff
path: root/lib/httpserver/HTTPQueryDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/httpserver/HTTPQueryDecoder.cpp')
-rw-r--r--lib/httpserver/HTTPQueryDecoder.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/httpserver/HTTPQueryDecoder.cpp b/lib/httpserver/HTTPQueryDecoder.cpp
new file mode 100644
index 00000000..c49ac2ce
--- /dev/null
+++ b/lib/httpserver/HTTPQueryDecoder.cpp
@@ -0,0 +1,159 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: HTTPQueryDecoder.cpp
+// Purpose: Utility class to decode HTTP query strings
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <stdlib.h>
+
+#include "HTTPQueryDecoder.h"
+
+#include "MemLeakFindOn.h"
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: HTTPQueryDecoder::HTTPQueryDecoder(
+// HTTPRequest::Query_t &)
+// Purpose: Constructor. Pass in the query contents you want
+// to decode the query string into.
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+HTTPQueryDecoder::HTTPQueryDecoder(HTTPRequest::Query_t &rDecodeInto)
+ : mrDecodeInto(rDecodeInto),
+ mInKey(true),
+ mEscapedState(0)
+{
+ // Insert the terminator for escaped characters
+ mEscaped[2] = '\0';
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: HTTPQueryDecoder::~HTTPQueryDecoder()
+// Purpose: Destructor.
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+HTTPQueryDecoder::~HTTPQueryDecoder()
+{
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: HTTPQueryDecoder::Decode(const char *, int)
+// Purpose: Decode a chunk of query string -- call several times with
+// the bits as they are received, and then call Finish()
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+void HTTPQueryDecoder::DecodeChunk(const char *pQueryString, int QueryStringSize)
+{
+ for(int l = 0; l < QueryStringSize; ++l)
+ {
+ char c = pQueryString[l];
+
+ // BEFORE unescaping, check to see if we need to flip key / value
+ if(mEscapedState == 0)
+ {
+ if(mInKey && c == '=')
+ {
+ // Set to store characters in the value
+ mInKey = false;
+ continue;
+ }
+ else if(!mInKey && c == '&')
+ {
+ // Need to store the current key/value pair
+ mrDecodeInto.insert(HTTPRequest::QueryEn_t(mCurrentKey, mCurrentValue));
+ // Blank the strings
+ mCurrentKey.erase();
+ mCurrentValue.erase();
+
+ // Set to store characters in the key
+ mInKey = true;
+ continue;
+ }
+ }
+
+ // Decode an escaped value?
+ if(mEscapedState == 1)
+ {
+ // Waiting for char one of the escaped hex value
+ mEscaped[0] = c;
+ mEscapedState = 2;
+ continue;
+ }
+ else if(mEscapedState == 2)
+ {
+ // Escaped value, decode it
+ mEscaped[1] = c; // str terminated in constructor
+ mEscapedState = 0; // stop being in escaped mode
+ long ch = ::strtol(mEscaped, NULL, 16);
+ if(ch <= 0 || ch > 255)
+ {
+ // Bad character, just ignore
+ continue;
+ }
+
+ // Use this instead
+ c = (char)ch;
+ }
+ else if(c == '+')
+ {
+ c = ' ';
+ }
+ else if(c == '%')
+ {
+ mEscapedState = 1;
+ continue;
+ }
+
+ // Store decoded value into the appropriate string
+ if(mInKey)
+ {
+ mCurrentKey += c;
+ }
+ else
+ {
+ mCurrentValue += c;
+ }
+ }
+
+ // Don't do anything here with left over values, DecodeChunk might be called
+ // again. Let Finish() clean up.
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: HTTPQueryDecoder::Finish()
+// Purpose: Finish the decoding. Necessary to get the last item!
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+void HTTPQueryDecoder::Finish()
+{
+ // Insert any remaining value.
+ if(!mCurrentKey.empty())
+ {
+ mrDecodeInto.insert(HTTPRequest::QueryEn_t(mCurrentKey, mCurrentValue));
+ // Blank values, just in case
+ mCurrentKey.erase();
+ mCurrentValue.erase();
+ }
+}
+
+