OSDN Git Service

httpd
[iptd/iPTd.git] / src / net / HTTPRequest.cpp
diff --git a/src/net/HTTPRequest.cpp b/src/net/HTTPRequest.cpp
new file mode 100644 (file)
index 0000000..3463bc9
--- /dev/null
@@ -0,0 +1,260 @@
+//\r
+// HTTPRequest.cpp\r
+//\r
+\r
+#define DBG_LEVEL 0\r
+#include <Raym/Log.h>\r
+#include "net/HTTPRequest.h"\r
+\r
+using namespace Raym;\r
+\r
+namespace NET\r
+{\r
+\r
+const char *HTTPRequest::KEY_CGI    = "CGI";\r
+const char *HTTPRequest::KEY_PARAMS = "PARAMS";\r
+\r
+HTTPRequest::HTTPRequest()\r
+{\r
+    _method  = NULL;\r
+    _uri     = NULL;\r
+    _version = NULL;\r
+    _message = NULL;\r
+}\r
+\r
+HTTPRequest::~HTTPRequest()\r
+{\r
+    RELEASE(_method);\r
+    RELEASE(_uri);\r
+    RELEASE(_version);\r
+    RELEASE(_message);\r
+}\r
+\r
+HTTPRequest *HTTPRequest::requestWithSocket(SOCKET sock)\r
+{\r
+    DebugLog2("%s\n", __FUNCTION__);\r
+\r
+    char buf[16384];\r
+    int offset = 0;\r
+    while (offset < sizeof(buf) - 1)\r
+    {\r
+        int len = recv(sock, &buf[offset], 1, 0);\r
+        if (len == 0)\r
+        {\r
+            break;\r
+        }\r
+        if (offset > 0)\r
+        {\r
+            if ((buf[offset - 1] == '\r') && (buf[offset] == '\n'))\r
+            {\r
+                ++offset;\r
+                break;\r
+            }\r
+        }\r
+        ++offset;\r
+    }\r
+    buf[offset] = '\0';\r
+\r
+    HTTPRequest *result = NULL;\r
+\r
+    String *method  = NULL;\r
+    String *uri     = NULL;\r
+    String *version = NULL;\r
+    if (strchr(buf, ' ') != NULL)\r
+    {\r
+        char *p = strchr(buf, ' ');\r
+        *p++ = '\0';\r
+        if ((buf[strlen(buf) - 2] == '\r') && (buf[strlen(buf) - 1] == '\n'))\r
+        {\r
+            buf[strlen(buf) - 2] = '\0';\r
+        }\r
+        method = String::alloc()->initWithUTF8String(&buf[0]);\r
+        while (*p == ' ')\r
+        {\r
+            ++p;\r
+        }\r
+        if (strchr(p, ' ') != NULL)\r
+        {\r
+            char *p2 = strchr(p, ' ');\r
+            *p2++ = '\0';\r
+            if ((p[strlen(p) - 2] == '\r') && (p[strlen(p) - 1] == '\n'))\r
+            {\r
+                p[strlen(p) - 2] = '\0';\r
+            }\r
+            uri = String::alloc()->initWithUTF8String(p);\r
+            while (*p2 == ' ')\r
+            {\r
+                ++p2;\r
+            }\r
+            if (strchr(p2, ' ') == NULL)\r
+            {\r
+                if ((p2[strlen(p2) - 2] == '\r') && (p2[strlen(p2) - 1] == '\n'))\r
+                {\r
+                    p2[strlen(p2) - 2] = '\0';\r
+                }\r
+                version = String::alloc()->initWithUTF8String(p2);\r
+            }\r
+        }\r
+    }\r
+\r
+    if (version != NULL)\r
+    {\r
+        if (version->isEqualToString(String::stringWithUTF8String("HTTP/1.0")) || version->isEqualToString(String::stringWithUTF8String("HTTP/1.1")))\r
+        {\r
+            InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->initWithSocket(sock);\r
+            if (header != NULL)\r
+            {\r
+                InternetTextMessageBody *body = NULL;\r
+                /*\r
+                if (header->fieldBodyForName("Transfer-Encoding") != NULL)\r
+                {\r
+                    DebugLog3("has Transfer-Encoding\n");\r
+                    abort();\r
+                }\r
+                else if (header->fieldBodyForName("Content-Length") != NULL)\r
+                {\r
+                    DebugLog3("has Content-Length\n");\r
+                    abort();\r
+                }\r
+                else if (header->fieldBodyForName("Content-Type") != NULL)\r
+                {\r
+                    DebugLog3("has Content-Type\n");\r
+                    abort();\r
+                }\r
+                */\r
+\r
+                InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);\r
+                RELEASE(header);\r
+                RELEASE(body);\r
+\r
+                result = new HTTPRequest();\r
+                result->setMethod(method);\r
+                result->setURI(uri);\r
+                result->setVersion(version);\r
+                result->setMessage(message);\r
+                result->autorelease();\r
+\r
+                RELEASE(message);\r
+            }\r
+            else\r
+            {\r
+                DebugLog3("error: InternetTextMessageHeader::headerWithSocket()\n");\r
+            }\r
+        }\r
+    }\r
+\r
+    RELEASE(method);\r
+    RELEASE(uri);\r
+    RELEASE(version);\r
+\r
+    return result;\r
+}\r
+\r
+void HTTPRequest::setMethod(String *method)\r
+{\r
+    SET_METHOD(_method, method);\r
+}\r
+\r
+String *HTTPRequest::method()\r
+{\r
+    return _method;\r
+}\r
+\r
+void HTTPRequest::setURI(String *uri)\r
+{\r
+    SET_METHOD(_uri, uri);\r
+}\r
+\r
+String *HTTPRequest::URI()\r
+{\r
+    return _uri;\r
+}\r
+\r
+void HTTPRequest::setVersion(String *version)\r
+{\r
+    SET_METHOD(_version, version);\r
+}\r
+\r
+String *HTTPRequest::version()\r
+{\r
+    return _version;\r
+}\r
+\r
+void HTTPRequest::setMessage(InternetTextMessage *message)\r
+{\r
+    SET_METHOD(_message, message);\r
+}\r
+\r
+InternetTextMessage *HTTPRequest::message()\r
+{\r
+    return _message;\r
+}\r
+\r
+Dictionary *HTTPRequest::parseAsCGI()\r
+{\r
+    DebugLog2("HTTPRequest::parseAsCGI()");\r
+\r
+    Dictionary *result = NULL;\r
+    if (_uri != NULL)\r
+    {\r
+        DebugLog3("_uri != NULL");\r
+        char *tmpstr = _strdup(_uri->cString());\r
+        if (tmpstr != NULL)\r
+        {\r
+            DebugLog3("tmpstr != NULL");\r
+            char *p1 = strchr(tmpstr, '?');\r
+            if (p1 != NULL)\r
+            {\r
+                DebugLog3("p1 != NULL");\r
+                *p1 = '\0';\r
+                DebugLog2("cgi: %s", tmpstr);\r
+                result = Dictionary::dictionaryWithCapacity(0);\r
+                result->setObject(String::stringWithUTF8String(tmpstr), KEY_CGI);\r
+\r
+                Array *params = Array::arrayWithCapacity(0);\r
+                result->setObject(params, KEY_PARAMS);\r
+\r
+                ++p1;\r
+                while (true)\r
+                {\r
+                    char *p2 = strchr(p1, '&');\r
+                    if (p2 != NULL)\r
+                    {\r
+                        *p2 = '\0';\r
+                    }\r
+                    char *p3 = strchr(p1, '=');\r
+                    if (p3 != NULL)\r
+                    {\r
+                        *p3 = '\0';\r
+                        String *para_name = String::stringWithUTF8String(p1);\r
+                        ++p3;\r
+                        String *para_val = String::stringWithUTF8String(p3);\r
+                        DebugLog3("para_name: %s, para_val: %s", p1, p3);\r
+                        Dictionary *para = Dictionary::dictionaryWithCapacity(0);\r
+                        para->setObject(para_val, para_name);\r
+                        params->addObject(para);\r
+                    }\r
+\r
+                    // 終端判定\r
+                    if (p2 == NULL)\r
+                    {\r
+                        break;\r
+                    }\r
+\r
+                    // 次パラメータに設定\r
+                    p1 = p2 + 1;\r
+                }\r
+            }\r
+\r
+            free(tmpstr);\r
+        }\r
+    }\r
+    return result;\r
+}\r
+\r
+const char *HTTPRequest::className()\r
+{\r
+    return "HTTPRequest";\r
+}\r
+\r
+} // NET\r