| 33 #include "../public/nsapi.h" |
33 #include "../public/nsapi.h" |
| 34 //include "request.h" |
34 //include "request.h" |
| 35 |
35 |
| 36 |
36 |
| 37 HttpParser* http_parser_new(HTTPRequest *request) { |
37 HttpParser* http_parser_new(HTTPRequest *request) { |
| |
38 return http_parser_new2(0, request->netbuf, request->headers); |
| |
39 } |
| |
40 |
| |
41 HttpParser* http_parser_new2(int type, netbuf *netbuf, HeaderArray *headers) { |
| 38 HttpParser *parser = calloc(1, sizeof(HttpParser)); |
42 HttpParser *parser = calloc(1, sizeof(HttpParser)); |
| 39 parser->request = request; |
43 parser->type = type; |
| |
44 parser->netbuf = netbuf; |
| |
45 parser->headers = headers; |
| 40 |
46 |
| 41 parser->state = 0; |
47 parser->state = 0; |
| 42 parser->start_line.ptr = (char*)request->netbuf->inbuf; |
48 parser->start_line.ptr = (char*)netbuf->inbuf; |
| 43 parser->start_line.length = 0; |
49 parser->start_line.length = 0; |
| 44 |
50 |
| 45 parser->offset = 0; |
51 parser->offset = 0; |
| 46 |
52 |
| 47 return parser; |
53 return parser; |
| 48 } |
54 } |
| 49 |
55 |
| 50 void http_parser_free(HttpParser *parser) { |
56 void http_parser_free(HttpParser *parser) { |
| 51 free(parser); |
57 free(parser); |
| |
58 } |
| |
59 |
| |
60 void http_parser_update_request(HttpParser *parser, HTTPRequest *request) { |
| |
61 request->method = parser->method; |
| |
62 request->uri = parser->uri; |
| |
63 request->httpv = parser->httpv; |
| 52 } |
64 } |
| 53 |
65 |
| 54 int http_parser_process(HttpParser *parser) { |
66 int http_parser_process(HttpParser *parser) { |
| 55 switch(parser->state) { |
67 switch(parser->state) { |
| 56 case 0: { |
68 case 0: { |
| 57 int r = get_start_line(parser); |
69 int r = get_start_line(parser); |
| 58 switch(r) { |
70 switch(r) { |
| 59 case 0: break; |
71 case 0: break; |
| 60 default: return r; |
72 default: return r; |
| 61 } |
73 } |
| 62 parse_request_line(parser); |
74 if(parser->type == 0) { |
| |
75 if(parse_request_line(parser)) { |
| |
76 return 2; |
| |
77 } |
| |
78 } else { |
| |
79 if(parse_response_line(parser)) { |
| |
80 return 2; |
| |
81 } |
| |
82 } |
| |
83 |
| 63 parser->state++; |
84 parser->state++; |
| 64 } |
85 } |
| 65 case 1: { |
86 case 1: { |
| 66 return http_parser_parse_header(parser); |
87 return http_parser_parse_header(parser); |
| 67 } |
88 } |
| 71 } |
92 } |
| 72 return -1; |
93 return -1; |
| 73 } |
94 } |
| 74 |
95 |
| 75 int http_parser_validate(HttpParser *parser) { |
96 int http_parser_validate(HttpParser *parser) { |
| 76 HTTPRequest *req = parser->request; |
97 if(parser->type == 0) { |
| 77 if( |
98 if (!parser->method.ptr || parser->method.length == 0 |
| 78 !req->method.ptr || req->method.length == 0 |
99 || !parser->uri.ptr || parser->uri.length == 0 |
| 79 || !req->uri.ptr || req->uri.length == 0 |
100 || !parser->httpv.ptr || parser->httpv.length == 0) |
| 80 || !req->httpv.ptr || req->httpv.length == 0) |
101 { |
| 81 { |
102 return 0; |
| 82 return 0; |
103 } |
| 83 } |
104 } else { |
| |
105 if (!parser->httpv.ptr || parser->httpv.length == 0 |
| |
106 || !parser->msg.ptr || parser->msg.length == 0 |
| |
107 || parser->status == 0) |
| |
108 { |
| |
109 return 0; |
| |
110 } |
| |
111 } |
| |
112 |
| 84 return 1; |
113 return 1; |
| 85 } |
114 } |
| 86 |
115 |
| 87 int get_start_line(HttpParser *parser) { |
116 int get_start_line(HttpParser *parser) { |
| 88 netbuf *buf = parser->request->netbuf; |
117 netbuf *buf = parser->netbuf; |
| 89 while(buf->pos < buf->cursize) { |
118 while(buf->pos < buf->cursize) { |
| 90 unsigned char c = buf->inbuf[buf->pos]; |
119 unsigned char c = buf->inbuf[buf->pos]; |
| 91 if(c == '\n') { |
120 if(c == '\n') { |
| 92 size_t lnlen = buf->pos - parser->offset + 1; |
121 size_t lnlen = buf->pos - parser->offset + 1; |
| 93 if(lnlen <= 2) { |
122 if(lnlen <= 2) { |
| 113 } |
142 } |
| 114 return 1; |
143 return 1; |
| 115 } |
144 } |
| 116 |
145 |
| 117 int http_parser_parse_header(HttpParser *parser) { |
146 int http_parser_parse_header(HttpParser *parser) { |
| 118 netbuf *buf = parser->request->netbuf; |
147 netbuf *buf = parser->netbuf; |
| 119 |
148 |
| 120 parser->offset = buf->pos; // line offset |
149 parser->offset = buf->pos; // line offset |
| 121 parser->name.ptr = NULL; |
150 parser->name.ptr = NULL; |
| 122 parser->name.length = 0; |
151 parser->name.length = 0; |
| 123 parser->value.ptr = NULL; |
152 parser->value.ptr = NULL; |
| 172 } |
201 } |
| 173 } |
202 } |
| 174 |
203 |
| 175 int parse_request_line(HttpParser *parser) { |
204 int parse_request_line(HttpParser *parser) { |
| 176 cxmutstr line = parser->start_line; |
205 cxmutstr line = parser->start_line; |
| 177 parser->request->request_line = line; |
206 |
| 178 |
207 // parse method, url and http version |
| 179 /* |
|
| 180 * parse method, url and http version |
|
| 181 */ |
|
| 182 |
208 |
| 183 int i = 0; |
209 int i = 0; |
| 184 int ns = 0; |
210 int ns = 0; |
| 185 |
211 |
| 186 parser->request->method.ptr = line.ptr; |
212 parser->method.ptr = line.ptr; |
| 187 for(;i<line.length;i++) { |
213 for(;i<line.length;i++) { |
| 188 if(!ns && line.ptr[i] == ' ') { |
214 if(!ns && line.ptr[i] == ' ') { |
| 189 ns = 1; |
215 ns = 1; |
| 190 parser->request->method.length = i; |
216 parser->method.length = i; |
| 191 } else if(ns) { |
217 } else if(ns) { |
| 192 if(line.ptr[i] != ' ') { |
218 if(line.ptr[i] != ' ') { |
| 193 break; |
219 break; |
| 194 } |
220 } |
| 195 } |
221 } |
| 196 } |
222 } |
| 197 |
223 if(i == line.length) { |
| 198 parser->request->uri.ptr = line.ptr + i; |
224 return 1; |
| |
225 } |
| |
226 |
| |
227 parser->uri.ptr = line.ptr + i; |
| 199 ns = 0; |
228 ns = 0; |
| 200 int s = i; |
229 int s = i; |
| 201 for(;i<line.length;i++) { |
230 for(;i<line.length;i++) { |
| 202 if(!ns && isspace(line.ptr[i])) { |
231 if(!ns && isspace(line.ptr[i])) { |
| 203 ns = 1; |
232 ns = 1; |
| 204 parser->request->uri.length = i - s; |
233 parser->uri.length = i - s; |
| 205 } else if(ns) { |
234 } else if(ns) { |
| 206 if(line.ptr[i] > 32) { |
235 if(line.ptr[i] > 32) { |
| 207 break; |
236 break; |
| 208 } |
237 } |
| 209 } |
238 } |
| 210 } |
239 } |
| 211 |
240 if(i == line.length) { |
| 212 parser->request->httpv.ptr = line.ptr + i; |
241 return 1; |
| |
242 } |
| |
243 |
| |
244 parser->httpv.ptr = line.ptr + i; |
| 213 ns = 0; |
245 ns = 0; |
| 214 s = i; |
246 s = i; |
| 215 for(;i<line.length;i++) { |
247 for(;i<line.length;i++) { |
| 216 if(!ns && isspace(line.ptr[i])) { |
248 if(!ns && isspace(line.ptr[i])) { |
| 217 ns = 1; |
249 ns = 1; |
| 218 parser->request->httpv.length = i - s; |
250 parser->httpv.length = i - s; |
| |
251 } else if(ns) { |
| |
252 if(line.ptr[i] > 32) { |
| |
253 return 1; // non-whitespace char after httpv |
| |
254 } |
| |
255 } |
| |
256 } |
| |
257 |
| |
258 return 0; |
| |
259 } |
| |
260 |
| |
261 int parse_response_line(HttpParser *parser) { |
| |
262 cxmutstr line = parser->start_line; |
| |
263 |
| |
264 // parse http version, status num, status message |
| |
265 |
| |
266 int i = 0; |
| |
267 int ns = 0; |
| |
268 |
| |
269 parser->httpv.ptr = line.ptr; |
| |
270 for(;i<line.length;i++) { |
| |
271 if(!ns && line.ptr[i] == ' ') { |
| |
272 ns = 1; |
| |
273 parser->httpv.length = i; |
| |
274 } else if(ns) { |
| |
275 if(line.ptr[i] != ' ') { |
| |
276 break; |
| |
277 } |
| |
278 } |
| |
279 } |
| |
280 |
| |
281 ns = 0; |
| |
282 int s = i; |
| |
283 cxmutstr num_str; |
| |
284 num_str.ptr = line.ptr + i; |
| |
285 num_str.length = 0; |
| |
286 for(;i<line.length;i++) { |
| |
287 if(!ns && isspace(line.ptr[i])) { |
| |
288 ns = 1; |
| |
289 num_str.length = i - s; |
| 219 } else if(ns) { |
290 } else if(ns) { |
| 220 if(line.ptr[i] > 32) { |
291 if(line.ptr[i] > 32) { |
| 221 break; |
292 break; |
| 222 } |
293 } |
| 223 } |
294 } |
| 224 } |
295 } |
| 225 |
296 |
| |
297 if(num_str.length != 3) { |
| |
298 return 1; |
| |
299 } |
| |
300 if(cx_strtoi(num_str, &parser->status, 10)) { |
| |
301 return 1; |
| |
302 } |
| |
303 |
| |
304 parser->msg.ptr = line.ptr + i; |
| |
305 ns = 1; |
| |
306 s = i; |
| |
307 for(;i<line.length;i++) { |
| |
308 char c = line.ptr[i]; |
| |
309 if(ns && c < 33) { |
| |
310 parser->msg.length = i - s; |
| |
311 ns = 0; |
| |
312 } else { |
| |
313 ns = 1; |
| |
314 } |
| |
315 } |
| |
316 |
| 226 return 0; |
317 return 0; |
| 227 } |
318 } |
| |
319 |