src/server/daemon/httpparser.c

changeset 662
70fdf948b642
parent 415
d938228c382e
child 663
bd116bd44926
equal deleted inserted replaced
661:a4e1ba59b733 662:70fdf948b642
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;
152 } 181 }
153 } else { 182 } else {
154 parser->value.ptr = ""; 183 parser->value.ptr = "";
155 } 184 }
156 // add header 185 // add header
157 header_add( 186 header_array_add(
158 parser->request->headers, 187 parser->headers,
159 parser->name, 188 parser->name,
160 parser->value); 189 parser->value);
161 } else { 190 } else {
162 // error: no value 191 // error: no value
163 return 2; 192 return 2;
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

mercurial