OSDN Git Service

initial files
[iptd/iPTd_R3.git] / src / net / HTTPRequest.cpp
1 //\r
2 // HTTPRequest.cpp\r
3 //\r
4 \r
5 #define DBG_LEVEL 0\r
6 #include <Raym/Log.h>\r
7 #include "net/HTTPRequest.h"\r
8 \r
9 using namespace Raym;\r
10 \r
11 namespace NET\r
12 {\r
13 \r
14 const char *HTTPRequest::KEY_CGI    = "CGI";\r
15 const char *HTTPRequest::KEY_PARAMS = "PARAMS";\r
16 \r
17 HTTPRequest::HTTPRequest()\r
18 {\r
19     _method  = NULL;\r
20     _uri     = NULL;\r
21     _version = NULL;\r
22     _message = NULL;\r
23 }\r
24 \r
25 HTTPRequest::~HTTPRequest()\r
26 {\r
27     RELEASE(_method);\r
28     RELEASE(_uri);\r
29     RELEASE(_version);\r
30     RELEASE(_message);\r
31 }\r
32 \r
33 HTTPRequest *HTTPRequest::requestWithSocket(SOCKET sock)\r
34 {\r
35     DebugLog2("%s", __FUNCTION__);\r
36 \r
37     char buf[16384];\r
38     int offset = 0;\r
39     while (offset < sizeof(buf) - 1)\r
40     {\r
41         int len = recv(sock, &buf[offset], 1, 0);\r
42         if (len == 0)\r
43         {\r
44             break;\r
45         }\r
46         if (offset > 0)\r
47         {\r
48             if ((buf[offset - 1] == '\r') && (buf[offset] == '\n'))\r
49             {\r
50                 ++offset;\r
51                 break;\r
52             }\r
53         }\r
54         ++offset;\r
55     }\r
56     buf[offset] = '\0';\r
57 \r
58     DebugLog2("%s 02", __FUNCTION__);\r
59 \r
60     HTTPRequest *result = NULL;\r
61 \r
62     String *method  = NULL;\r
63     String *uri     = NULL;\r
64     String *version = NULL;\r
65     if (strchr(buf, ' ') != NULL)\r
66     {\r
67         char *p = strchr(buf, ' ');\r
68         *p++ = '\0';\r
69         if ((buf[strlen(buf) - 2] == '\r') && (buf[strlen(buf) - 1] == '\n'))\r
70         {\r
71             buf[strlen(buf) - 2] = '\0';\r
72         }\r
73         method = String::alloc()->initWithUTF8String(&buf[0]);\r
74         while (*p == ' ')\r
75         {\r
76             ++p;\r
77         }\r
78         if (strchr(p, ' ') != NULL)\r
79         {\r
80             char *p2 = strchr(p, ' ');\r
81             *p2++ = '\0';\r
82             if ((p[strlen(p) - 2] == '\r') && (p[strlen(p) - 1] == '\n'))\r
83             {\r
84                 p[strlen(p) - 2] = '\0';\r
85             }\r
86             uri = String::alloc()->initWithUTF8String(p);\r
87             while (*p2 == ' ')\r
88             {\r
89                 ++p2;\r
90             }\r
91             if (strchr(p2, ' ') == NULL)\r
92             {\r
93                 if ((p2[strlen(p2) - 2] == '\r') && (p2[strlen(p2) - 1] == '\n'))\r
94                 {\r
95                     p2[strlen(p2) - 2] = '\0';\r
96                 }\r
97                 version = String::alloc()->initWithUTF8String(p2);\r
98             }\r
99         }\r
100     }\r
101 \r
102     if (version != NULL)\r
103     {\r
104         if (version->isEqualToString(String::stringWithUTF8String("HTTP/1.0")) || version->isEqualToString(String::stringWithUTF8String("HTTP/1.1")))\r
105         {\r
106             InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->initWithSocket(sock);\r
107             if (header != NULL)\r
108             {\r
109                 InternetTextMessageBody *body = NULL;\r
110                 /*\r
111                 if (header->fieldBodyForName("Transfer-Encoding") != NULL)\r
112                 {\r
113                     DebugLog3("has Transfer-Encoding\n");\r
114                     abort();\r
115                 }\r
116                 else if (header->fieldBodyForName("Content-Length") != NULL)\r
117                 {\r
118                     DebugLog3("has Content-Length\n");\r
119                     abort();\r
120                 }\r
121                 else if (header->fieldBodyForName("Content-Type") != NULL)\r
122                 {\r
123                     DebugLog3("has Content-Type\n");\r
124                     abort();\r
125                 }\r
126                 */\r
127 \r
128                 InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);\r
129                 RELEASE(header);\r
130                 RELEASE(body);\r
131 \r
132                 result = new HTTPRequest();\r
133                 result->setMethod(method);\r
134                 result->setURI(uri);\r
135                 result->setVersion(version);\r
136                 result->setMessage(message);\r
137                 result->autorelease();\r
138 \r
139                 RELEASE(message);\r
140             }\r
141             else\r
142             {\r
143                 DebugLog3("error: InternetTextMessageHeader::headerWithSocket()\n");\r
144             }\r
145         }\r
146     }\r
147 \r
148     RELEASE(method);\r
149     RELEASE(uri);\r
150     RELEASE(version);\r
151 \r
152     return result;\r
153 }\r
154 \r
155 void HTTPRequest::setMethod(String *method)\r
156 {\r
157     SET_METHOD(_method, method);\r
158 }\r
159 \r
160 String *HTTPRequest::method()\r
161 {\r
162     return _method;\r
163 }\r
164 \r
165 void HTTPRequest::setURI(String *uri)\r
166 {\r
167     SET_METHOD(_uri, uri);\r
168 }\r
169 \r
170 String *HTTPRequest::URI()\r
171 {\r
172     return _uri;\r
173 }\r
174 \r
175 void HTTPRequest::setVersion(String *version)\r
176 {\r
177     SET_METHOD(_version, version);\r
178 }\r
179 \r
180 String *HTTPRequest::version()\r
181 {\r
182     return _version;\r
183 }\r
184 \r
185 void HTTPRequest::setMessage(InternetTextMessage *message)\r
186 {\r
187     SET_METHOD(_message, message);\r
188 }\r
189 \r
190 InternetTextMessage *HTTPRequest::message()\r
191 {\r
192     return _message;\r
193 }\r
194 \r
195 Dictionary *HTTPRequest::parseAsCGI()\r
196 {\r
197     DebugLog2("HTTPRequest::parseAsCGI()");\r
198 \r
199     Dictionary *result = NULL;\r
200     if (_uri != NULL)\r
201     {\r
202         DebugLog3("_uri != NULL");\r
203         char *tmpstr = _strdup(_uri->cString());\r
204         if (tmpstr != NULL)\r
205         {\r
206             DebugLog3("tmpstr != NULL");\r
207             char *p1 = strchr(tmpstr, '?');\r
208             if (p1 != NULL)\r
209             {\r
210                 DebugLog3("p1 != NULL");\r
211                 *p1 = '\0';\r
212                 DebugLog2("cgi: %s", tmpstr);\r
213                 result = Dictionary::dictionaryWithCapacity(0);\r
214                 result->setObject(String::stringWithUTF8String(tmpstr), KEY_CGI);\r
215 \r
216                 Array *params = Array::arrayWithCapacity(0);\r
217                 result->setObject(params, KEY_PARAMS);\r
218 \r
219                 ++p1;\r
220                 while (true)\r
221                 {\r
222                     char *p2 = strchr(p1, '&');\r
223                     if (p2 != NULL)\r
224                     {\r
225                         *p2 = '\0';\r
226                     }\r
227                     char *p3 = strchr(p1, '=');\r
228                     if (p3 != NULL)\r
229                     {\r
230                         *p3 = '\0';\r
231                         String *para_name = String::stringWithUTF8String(p1);\r
232                         ++p3;\r
233                         String *para_val = String::stringWithUTF8String(p3);\r
234                         DebugLog3("para_name: %s, para_val: %s", p1, p3);\r
235                         Dictionary *para = Dictionary::dictionaryWithCapacity(0);\r
236                         para->setObject(para_val, para_name);\r
237                         params->addObject(para);\r
238                     }\r
239 \r
240                     // 終端判定\r
241                     if (p2 == NULL)\r
242                     {\r
243                         break;\r
244                     }\r
245 \r
246                     // 次パラメータに設定\r
247                     p1 = p2 + 1;\r
248                 }\r
249             }\r
250 \r
251             free(tmpstr);\r
252         }\r
253     }\r
254     return result;\r
255 }\r
256 \r
257 const char *HTTPRequest::className()\r
258 {\r
259     return "HTTPRequest";\r
260 }\r
261 \r
262 } // NET\r