2 #line 1 "http11_parser.rl"
5 * Copyright (c) 2010, Zed A. Shaw and Mongrel2 Project Contributors.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * * Neither the name of the Mongrel2 Project, Zed A. Shaw, nor the names
20 * of its contributors may be used to endorse or promote products
21 * derived from this software without specific prior written
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include "http11_parser.h"
44 #define LEN(AT, FPC) (FPC - buffer - parser->AT)
45 #define MARK(M,FPC) (parser->M = (FPC) - buffer)
46 #define PTR_TO(F) (buffer + parser->F)
51 #line 165 "http11_parser.rl"
56 #line 57 "http11_parser.c"
57 static const int http_parser_start
= 1;
58 static const int http_parser_first_final
= 60;
59 static const int http_parser_error
= 0;
61 static const int http_parser_en_main
= 1;
64 #line 169 "http11_parser.rl"
66 static int apply_element(http_parser
*parser
, int type
, const char *begin
, const char *end
, int max_length
)
68 int len
= (int)(end
-begin
);
69 if(len
> max_length
) {
72 if(parser
->on_element
)
73 parser
->on_element(parser
->data
, type
, begin
, len
);
79 int http_parser_init(http_parser
*parser
) {
82 #line 83 "http11_parser.c"
84 cs
= http_parser_start
;
87 #line 186 "http11_parser.rl"
89 parser
->body_start
= 0;
90 parser
->content_len
= 0;
93 parser
->field_len
= 0;
94 parser
->field_start
= 0;
100 size_t http_parser_execute(http_parser
*parser
, const char *buffer
, size_t len
, size_t off
)
102 if(len
== 0) return 0;
107 assert(off
<= len
&& "offset past end of buffer");
112 assert(pe
- p
== (int)len
- (int)off
&& "pointers aren't same distance");
115 #line 116 "http11_parser.c"
127 if ( 45 <= (*p
) && (*p
) <= 46 )
129 } else if ( (*p
) > 57 ) {
130 if ( 65 <= (*p
) && (*p
) <= 90 )
139 #line 52 "http11_parser.rl"
146 #line 147 "http11_parser.c"
153 if ( 45 <= (*p
) && (*p
) <= 46 )
155 } else if ( (*p
) > 57 ) {
156 if ( 65 <= (*p
) && (*p
) <= 90 )
162 #line 94 "http11_parser.rl"
164 if(!apply_element(parser
, REQUEST_METHOD
, PTR_TO(mark
), p
, 1024))
165 {p
++; cs
= 3; goto _out
;}
172 #line 173 "http11_parser.c"
180 #line 52 "http11_parser.rl"
187 #line 188 "http11_parser.c"
194 #line 99 "http11_parser.rl"
196 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
197 {p
++; cs
= 5; goto _out
;}
201 #line 52 "http11_parser.rl"
203 #line 79 "http11_parser.rl"
205 if(!apply_element(parser
, FRAGMENT
, PTR_TO(mark
), p
, 10*1024))
206 {p
++; cs
= 5; goto _out
;}
210 #line 79 "http11_parser.rl"
212 if(!apply_element(parser
, FRAGMENT
, PTR_TO(mark
), p
, 10*1024))
213 {p
++; cs
= 5; goto _out
;}
217 #line 89 "http11_parser.rl"
219 if(!apply_element(parser
, REQUEST_PATH
, PTR_TO(mark
), p
, 1024))
220 {p
++; cs
= 5; goto _out
;}
222 #line 99 "http11_parser.rl"
224 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
225 {p
++; cs
= 5; goto _out
;}
229 #line 104 "http11_parser.rl"
230 {MARK(query_start
, p
); }
231 #line 106 "http11_parser.rl"
233 if(!apply_element(parser
, QUERY_STRING
, PTR_TO(query_start
), p
, 10*1024))
234 {p
++; cs
= 5; goto _out
;}
236 #line 99 "http11_parser.rl"
238 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
239 {p
++; cs
= 5; goto _out
;}
243 #line 106 "http11_parser.rl"
245 if(!apply_element(parser
, QUERY_STRING
, PTR_TO(query_start
), p
, 10*1024))
246 {p
++; cs
= 5; goto _out
;}
248 #line 99 "http11_parser.rl"
250 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
251 {p
++; cs
= 5; goto _out
;}
258 #line 259 "http11_parser.c"
263 #line 52 "http11_parser.rl"
270 #line 271 "http11_parser.c"
313 if ( 48 <= (*p
) && (*p
) <= 49 )
326 #line 84 "http11_parser.rl"
328 if(!apply_element(parser
, HTTP_VERSION
, PTR_TO(mark
), p
, 10))
329 {p
++; cs
= 14; goto _out
;}
333 #line 60 "http11_parser.rl"
335 #line 62 "http11_parser.rl"
337 if(parser
->http_field
!= NULL
) {
338 parser
->http_field(parser
->data
, PTR_TO(field_start
), parser
->field_len
, PTR_TO(mark
), LEN(mark
, p
));
343 #line 62 "http11_parser.rl"
345 if(parser
->http_field
!= NULL
) {
346 parser
->http_field(parser
->data
, PTR_TO(field_start
), parser
->field_len
, PTR_TO(mark
), LEN(mark
, p
));
354 #line 355 "http11_parser.c"
364 if ( 42 <= (*p
) && (*p
) <= 43 )
366 } else if ( (*p
) >= 35 )
368 } else if ( (*p
) > 46 ) {
370 if ( 48 <= (*p
) && (*p
) <= 57 )
372 } else if ( (*p
) > 90 ) {
373 if ( 94 <= (*p
) && (*p
) <= 122 )
381 #line 111 "http11_parser.rl"
383 parser
->body_start
= p
- buffer
+ 1;
384 {p
++; cs
= 60; goto _out
;}
391 #line 392 "http11_parser.c"
401 #line 55 "http11_parser.rl"
402 { MARK(field_start
, p
); }
408 #line 409 "http11_parser.c"
417 if ( 42 <= (*p
) && (*p
) <= 43 )
419 } else if ( (*p
) >= 35 )
421 } else if ( (*p
) > 46 ) {
423 if ( 48 <= (*p
) && (*p
) <= 57 )
425 } else if ( (*p
) > 90 ) {
426 if ( 94 <= (*p
) && (*p
) <= 122 )
434 #line 56 "http11_parser.rl"
436 parser
->field_len
= LEN(field_start
, p
);
440 #line 60 "http11_parser.rl"
447 #line 448 "http11_parser.c"
455 #line 60 "http11_parser.rl"
462 #line 463 "http11_parser.c"
469 #line 84 "http11_parser.rl"
471 if(!apply_element(parser
, HTTP_VERSION
, PTR_TO(mark
), p
, 10))
472 {p
++; cs
= 19; goto _out
;}
476 #line 60 "http11_parser.rl"
478 #line 62 "http11_parser.rl"
480 if(parser
->http_field
!= NULL
) {
481 parser
->http_field(parser
->data
, PTR_TO(field_start
), parser
->field_len
, PTR_TO(mark
), LEN(mark
, p
));
486 #line 62 "http11_parser.rl"
488 if(parser
->http_field
!= NULL
) {
489 parser
->http_field(parser
->data
, PTR_TO(field_start
), parser
->field_len
, PTR_TO(mark
), LEN(mark
, p
));
497 #line 498 "http11_parser.c"
502 #line 99 "http11_parser.rl"
504 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
505 {p
++; cs
= 20; goto _out
;}
509 #line 89 "http11_parser.rl"
511 if(!apply_element(parser
, REQUEST_PATH
, PTR_TO(mark
), p
, 1024))
512 {p
++; cs
= 20; goto _out
;}
514 #line 99 "http11_parser.rl"
516 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
517 {p
++; cs
= 20; goto _out
;}
521 #line 104 "http11_parser.rl"
522 {MARK(query_start
, p
); }
523 #line 106 "http11_parser.rl"
525 if(!apply_element(parser
, QUERY_STRING
, PTR_TO(query_start
), p
, 10*1024))
526 {p
++; cs
= 20; goto _out
;}
528 #line 99 "http11_parser.rl"
530 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
531 {p
++; cs
= 20; goto _out
;}
535 #line 106 "http11_parser.rl"
537 if(!apply_element(parser
, QUERY_STRING
, PTR_TO(query_start
), p
, 10*1024))
538 {p
++; cs
= 20; goto _out
;}
540 #line 99 "http11_parser.rl"
542 if(!apply_element(parser
, REQUEST_URI
, PTR_TO(mark
), p
, 12*1024))
543 {p
++; cs
= 20; goto _out
;}
550 #line 551 "http11_parser.c"
559 if ( 34 <= (*p
) && (*p
) <= 35 )
561 } else if ( (*p
) >= 0 )
565 #line 52 "http11_parser.rl"
572 #line 573 "http11_parser.c"
581 if ( 34 <= (*p
) && (*p
) <= 35 )
583 } else if ( (*p
) >= 0 )
587 #line 52 "http11_parser.rl"
594 #line 595 "http11_parser.c"
596 if ( 48 <= (*p
) && (*p
) <= 57 )
598 } else if ( (*p
) > 70 ) {
599 if ( 97 <= (*p
) && (*p
) <= 102 )
609 if ( 48 <= (*p
) && (*p
) <= 57 )
611 } else if ( (*p
) > 70 ) {
612 if ( 97 <= (*p
) && (*p
) <= 102 )
618 #line 52 "http11_parser.rl"
625 #line 626 "http11_parser.c"
637 if ( 0 <= (*p
) && (*p
) <= 31 )
645 if ( 48 <= (*p
) && (*p
) <= 57 )
647 } else if ( (*p
) > 70 ) {
648 if ( 97 <= (*p
) && (*p
) <= 102 )
658 if ( 48 <= (*p
) && (*p
) <= 57 )
660 } else if ( (*p
) > 70 ) {
661 if ( 97 <= (*p
) && (*p
) <= 102 )
667 #line 89 "http11_parser.rl"
669 if(!apply_element(parser
, REQUEST_PATH
, PTR_TO(mark
), p
, 1024))
670 {p
++; cs
= 27; goto _out
;}
677 #line 678 "http11_parser.c"
688 if ( 0 <= (*p
) && (*p
) <= 31 )
696 if ( 48 <= (*p
) && (*p
) <= 57 )
698 } else if ( (*p
) > 70 ) {
699 if ( 97 <= (*p
) && (*p
) <= 102 )
709 if ( 48 <= (*p
) && (*p
) <= 57 )
711 } else if ( (*p
) > 70 ) {
712 if ( 97 <= (*p
) && (*p
) <= 102 )
718 #line 89 "http11_parser.rl"
720 if(!apply_element(parser
, REQUEST_PATH
, PTR_TO(mark
), p
, 1024))
721 {p
++; cs
= 30; goto _out
;}
728 #line 729 "http11_parser.c"
738 if ( 0 <= (*p
) && (*p
) <= 31 )
742 #line 104 "http11_parser.rl"
743 {MARK(query_start
, p
); }
749 #line 750 "http11_parser.c"
759 if ( 0 <= (*p
) && (*p
) <= 31 )
763 #line 104 "http11_parser.rl"
764 {MARK(query_start
, p
); }
770 #line 771 "http11_parser.c"
772 if ( 48 <= (*p
) && (*p
) <= 57 )
774 } else if ( (*p
) > 70 ) {
775 if ( 97 <= (*p
) && (*p
) <= 102 )
785 if ( 48 <= (*p
) && (*p
) <= 57 )
787 } else if ( (*p
) > 70 ) {
788 if ( 97 <= (*p
) && (*p
) <= 102 )
794 #line 52 "http11_parser.rl"
801 #line 802 "http11_parser.c"
839 if ( 0 <= (*p
) && (*p
) <= 31 )
847 if ( 48 <= (*p
) && (*p
) <= 57 )
849 } else if ( (*p
) > 70 ) {
850 if ( 97 <= (*p
) && (*p
) <= 102 )
860 if ( 48 <= (*p
) && (*p
) <= 57 )
862 } else if ( (*p
) > 70 ) {
863 if ( 97 <= (*p
) && (*p
) <= 102 )
878 if ( 45 <= (*p
) && (*p
) <= 46 )
880 } else if ( (*p
) > 57 ) {
881 if ( 65 <= (*p
) && (*p
) <= 90 )
896 if ( 45 <= (*p
) && (*p
) <= 46 )
898 } else if ( (*p
) > 57 ) {
899 if ( 65 <= (*p
) && (*p
) <= 90 )
914 if ( 45 <= (*p
) && (*p
) <= 46 )
916 } else if ( (*p
) > 57 ) {
917 if ( 65 <= (*p
) && (*p
) <= 90 )
932 if ( 45 <= (*p
) && (*p
) <= 46 )
934 } else if ( (*p
) > 57 ) {
935 if ( 65 <= (*p
) && (*p
) <= 90 )
950 if ( 45 <= (*p
) && (*p
) <= 46 )
952 } else if ( (*p
) > 57 ) {
953 if ( 65 <= (*p
) && (*p
) <= 90 )
968 if ( 45 <= (*p
) && (*p
) <= 46 )
970 } else if ( (*p
) > 57 ) {
971 if ( 65 <= (*p
) && (*p
) <= 90 )
986 if ( 45 <= (*p
) && (*p
) <= 46 )
988 } else if ( (*p
) > 57 ) {
989 if ( 65 <= (*p
) && (*p
) <= 90 )
1004 if ( 45 <= (*p
) && (*p
) <= 46 )
1006 } else if ( (*p
) > 57 ) {
1007 if ( 65 <= (*p
) && (*p
) <= 90 )
1022 if ( 45 <= (*p
) && (*p
) <= 46 )
1024 } else if ( (*p
) > 57 ) {
1025 if ( 65 <= (*p
) && (*p
) <= 90 )
1040 if ( 45 <= (*p
) && (*p
) <= 46 )
1042 } else if ( (*p
) > 57 ) {
1043 if ( 65 <= (*p
) && (*p
) <= 90 )
1058 if ( 45 <= (*p
) && (*p
) <= 46 )
1060 } else if ( (*p
) > 57 ) {
1061 if ( 65 <= (*p
) && (*p
) <= 90 )
1076 if ( 45 <= (*p
) && (*p
) <= 46 )
1078 } else if ( (*p
) > 57 ) {
1079 if ( 65 <= (*p
) && (*p
) <= 90 )
1094 if ( 45 <= (*p
) && (*p
) <= 46 )
1096 } else if ( (*p
) > 57 ) {
1097 if ( 65 <= (*p
) && (*p
) <= 90 )
1112 if ( 45 <= (*p
) && (*p
) <= 46 )
1114 } else if ( (*p
) > 57 ) {
1115 if ( 65 <= (*p
) && (*p
) <= 90 )
1130 if ( 45 <= (*p
) && (*p
) <= 46 )
1132 } else if ( (*p
) > 57 ) {
1133 if ( 65 <= (*p
) && (*p
) <= 90 )
1148 if ( 45 <= (*p
) && (*p
) <= 46 )
1150 } else if ( (*p
) > 57 ) {
1151 if ( 65 <= (*p
) && (*p
) <= 90 )
1166 if ( 45 <= (*p
) && (*p
) <= 46 )
1168 } else if ( (*p
) > 57 ) {
1169 if ( 65 <= (*p
) && (*p
) <= 90 )
1184 if ( 45 <= (*p
) && (*p
) <= 46 )
1186 } else if ( (*p
) > 57 ) {
1187 if ( 65 <= (*p
) && (*p
) <= 90 )
1200 _test_eof2
: cs
= 2; goto _test_eof
;
1201 _test_eof3
: cs
= 3; goto _test_eof
;
1202 _test_eof4
: cs
= 4; goto _test_eof
;
1203 _test_eof5
: cs
= 5; goto _test_eof
;
1204 _test_eof6
: cs
= 6; goto _test_eof
;
1205 _test_eof7
: cs
= 7; goto _test_eof
;
1206 _test_eof8
: cs
= 8; goto _test_eof
;
1207 _test_eof9
: cs
= 9; goto _test_eof
;
1208 _test_eof10
: cs
= 10; goto _test_eof
;
1209 _test_eof11
: cs
= 11; goto _test_eof
;
1210 _test_eof12
: cs
= 12; goto _test_eof
;
1211 _test_eof13
: cs
= 13; goto _test_eof
;
1212 _test_eof14
: cs
= 14; goto _test_eof
;
1213 _test_eof60
: cs
= 60; goto _test_eof
;
1214 _test_eof15
: cs
= 15; goto _test_eof
;
1215 _test_eof16
: cs
= 16; goto _test_eof
;
1216 _test_eof17
: cs
= 17; goto _test_eof
;
1217 _test_eof18
: cs
= 18; goto _test_eof
;
1218 _test_eof19
: cs
= 19; goto _test_eof
;
1219 _test_eof20
: cs
= 20; goto _test_eof
;
1220 _test_eof21
: cs
= 21; goto _test_eof
;
1221 _test_eof22
: cs
= 22; goto _test_eof
;
1222 _test_eof23
: cs
= 23; goto _test_eof
;
1223 _test_eof24
: cs
= 24; goto _test_eof
;
1224 _test_eof25
: cs
= 25; goto _test_eof
;
1225 _test_eof26
: cs
= 26; goto _test_eof
;
1226 _test_eof27
: cs
= 27; goto _test_eof
;
1227 _test_eof28
: cs
= 28; goto _test_eof
;
1228 _test_eof29
: cs
= 29; goto _test_eof
;
1229 _test_eof30
: cs
= 30; goto _test_eof
;
1230 _test_eof31
: cs
= 31; goto _test_eof
;
1231 _test_eof32
: cs
= 32; goto _test_eof
;
1232 _test_eof33
: cs
= 33; goto _test_eof
;
1233 _test_eof34
: cs
= 34; goto _test_eof
;
1234 _test_eof35
: cs
= 35; goto _test_eof
;
1235 _test_eof36
: cs
= 36; goto _test_eof
;
1236 _test_eof37
: cs
= 37; goto _test_eof
;
1237 _test_eof38
: cs
= 38; goto _test_eof
;
1238 _test_eof39
: cs
= 39; goto _test_eof
;
1239 _test_eof40
: cs
= 40; goto _test_eof
;
1240 _test_eof41
: cs
= 41; goto _test_eof
;
1241 _test_eof42
: cs
= 42; goto _test_eof
;
1242 _test_eof43
: cs
= 43; goto _test_eof
;
1243 _test_eof44
: cs
= 44; goto _test_eof
;
1244 _test_eof45
: cs
= 45; goto _test_eof
;
1245 _test_eof46
: cs
= 46; goto _test_eof
;
1246 _test_eof47
: cs
= 47; goto _test_eof
;
1247 _test_eof48
: cs
= 48; goto _test_eof
;
1248 _test_eof49
: cs
= 49; goto _test_eof
;
1249 _test_eof50
: cs
= 50; goto _test_eof
;
1250 _test_eof51
: cs
= 51; goto _test_eof
;
1251 _test_eof52
: cs
= 52; goto _test_eof
;
1252 _test_eof53
: cs
= 53; goto _test_eof
;
1253 _test_eof54
: cs
= 54; goto _test_eof
;
1254 _test_eof55
: cs
= 55; goto _test_eof
;
1255 _test_eof56
: cs
= 56; goto _test_eof
;
1256 _test_eof57
: cs
= 57; goto _test_eof
;
1257 _test_eof58
: cs
= 58; goto _test_eof
;
1258 _test_eof59
: cs
= 59; goto _test_eof
;
1264 #line 213 "http11_parser.rl"
1266 assert(p
<= pe
&& "Buffer overflow after parsing.");
1268 if (!http_parser_has_error(parser
)) {
1272 parser
->nread
+= p
- (buffer
+ off
);
1274 assert(parser
->nread
<= len
&& "nread longer than length");
1275 assert(parser
->body_start
<= len
&& "body starts after buffer end");
1276 assert(parser
->mark
< len
&& "mark is after buffer end");
1277 assert(parser
->field_len
<= len
&& "field has length longer than whole buffer");
1278 assert(parser
->field_start
< len
&& "field starts after buffer end");
1280 return(parser
->nread
);
1283 int http_parser_finish(http_parser
*parser
)
1285 if (http_parser_has_error(parser
) ) {
1287 } else if (http_parser_is_finished(parser
) ) {
1294 int http_parser_has_error(http_parser
*parser
) {
1295 return parser
->cs
== http_parser_error
;
1298 int http_parser_is_finished(http_parser
*parser
) {
1299 return parser
->cs
>= http_parser_first_final
;