54 hd->alloc = 16; |
54 hd->alloc = 16; |
55 |
55 |
56 req->headers = hd; |
56 req->headers = hd; |
57 } |
57 } |
58 |
58 |
|
59 void http_request_cleanup(HTTPRequest *req) { |
|
60 // TODO: implement |
|
61 } |
|
62 |
|
63 sstr_t http_request_get_abspath(HTTPRequest *req) { |
|
64 sstr_t uri = req->uri; |
|
65 |
|
66 int i = 0; |
|
67 if(uri.ptr[0] == '/') { |
|
68 return uri; |
|
69 } else if(sstrprefix(uri, S("http://"))) { |
|
70 i = 7; |
|
71 } else if(sstrprefix(uri, S("https://"))) { |
|
72 i = 8; |
|
73 } else if(!sstrcmp(uri, S("*"))) { |
|
74 return uri; |
|
75 } |
|
76 |
|
77 for(;i<uri.length;i++) { |
|
78 if(uri.ptr[i] == '/') { |
|
79 return sstrsubs(uri, i); |
|
80 } |
|
81 } |
|
82 |
|
83 return S("/"); |
|
84 } |
|
85 |
59 int handle_request(HTTPRequest *request, threadpool_t *thrpool) { |
86 int handle_request(HTTPRequest *request, threadpool_t *thrpool) { |
60 // handle nsapi request |
87 // handle nsapi request |
61 |
88 |
62 // create pool |
89 // create pool |
63 pool_handle_t *pool = pool_create(); |
90 pool_handle_t *pool = pool_create(); |
135 pblock_kvinsert( |
162 pblock_kvinsert( |
136 pb_key_protocol, |
163 pb_key_protocol, |
137 request->httpv.ptr, |
164 request->httpv.ptr, |
138 request->httpv.length, |
165 request->httpv.length, |
139 rq->rq.reqpb); |
166 rq->rq.reqpb); |
140 // TODO: protocol num |
167 |
|
168 if(!sstrcmp(request->httpv, S("HTTP/1.1"))) { |
|
169 rq->rq.protv_num = PROTOCOL_VERSION_HTTP11; |
|
170 } else if(!sstrcmp(request->httpv, S("HTTP/1.0"))) { |
|
171 rq->rq.protv_num = PROTOCOL_VERSION_HTTP10; |
|
172 } else { |
|
173 // TODO: invalid protocol version - abort |
|
174 } |
141 |
175 |
142 /* |
176 /* |
143 * get absolute path and query of the request uri |
177 * get absolute path and query of the request uri |
144 */ |
178 */ |
145 // TODO: check for '#' |
179 // TODO: check for '#' |
146 sstr_t absPath = request->uri; |
180 sstr_t absPath = http_request_get_abspath(request); |
|
181 if(!absPath.ptr) { |
|
182 // TODO: error msg |
|
183 return 1; |
|
184 } else if(absPath.ptr[0] == '*') { |
|
185 // TODO: implement global OPTIONS |
|
186 return 1; |
|
187 } |
|
188 |
147 sstr_t query; |
189 sstr_t query; |
148 query.length = 0; |
190 query.length = 0; |
149 |
191 |
150 for(int i=0;i<request->uri.length;i++) { |
192 for(int i=0;i<request->uri.length;i++) { |
151 if(request->uri.ptr[i] == '?') { |
193 if(request->uri.ptr[i] == '?') { |
198 break; |
240 break; |
199 } |
241 } |
200 i = 0; |
242 i = 0; |
201 hlen = ha->len; |
243 hlen = ha->len; |
202 } |
244 } |
203 |
245 |
204 if(ha->headers[i].name[0] < 90) { |
246 Header header = ha->headers[i]; |
205 ha->headers[i].name[0] += 32; |
247 |
|
248 if(header.name.ptr[0] < 90) { |
|
249 header.name.ptr[0] += 32; |
206 } |
250 } |
207 |
251 |
208 // change to lower case |
252 // change to lower case |
209 char *header_name = ha->headers[i].name; |
253 for(int i=0;i<header.name.length;i++) { |
210 for(int i=0;header_name[i]!=0;i++) { |
254 if(header.name.ptr[i] > 64 && header.name.ptr[i] < 97) { |
211 if(header_name[i] > 64 && header_name[i] < 97) { |
255 header.name.ptr[i] += 32; |
212 header_name[i] += 32; |
256 } |
213 } |
257 } |
214 } |
258 |
215 |
259 pblock_nvlinsert( |
216 pblock_nvinsert( |
260 header.name.ptr, |
217 ha->headers[i].name, |
261 header.name.length, |
218 ha->headers[i].value, |
262 header.value.ptr, |
|
263 header.value.length, |
219 rq->rq.headers); |
264 rq->rq.headers); |
|
265 } |
|
266 |
|
267 // parse connection header |
|
268 rq->rq.rq_attr.keep_alive = (rq->rq.protv_num >= PROTOCOL_VERSION_HTTP11); |
|
269 char *conn_str = pblock_findkeyval(pb_key_connection, rq->rq.headers); |
|
270 if(conn_str) { |
|
271 if(!strcasecmp(conn_str, "keep-alive")) { |
|
272 rq->rq.rq_attr.keep_alive = 1; |
|
273 } else if(!strcasecmp(conn_str, "close")) { |
|
274 rq->rq.rq_attr.keep_alive = 0; |
|
275 } |
220 } |
276 } |
221 |
277 |
222 // check for request body and prepare input buffer |
278 // check for request body and prepare input buffer |
223 char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); |
279 char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); |
224 if(ctlen_str) { |
280 if(ctlen_str) { |
282 return 0; |
338 return 0; |
283 } |
339 } |
284 |
340 |
285 |
341 |
286 |
342 |
287 void header_add(HeaderArray *hd, char *name, char *value) { |
343 void header_add(HeaderArray *hd, sstr_t name, sstr_t value) { |
288 while(hd->len >= hd->alloc) { |
344 while(hd->len >= hd->alloc) { |
289 if(hd->next == NULL) { |
345 if(hd->next == NULL) { |
290 HeaderArray *block = malloc(sizeof(HeaderArray)); |
346 HeaderArray *block = malloc(sizeof(HeaderArray)); |
291 block->next = NULL; |
347 block->next = NULL; |
292 block->len = 0; |
348 block->len = 0; |