2 #line 1 "http11_parser.rl"
4 * Copyright (c) 2005 Zed A. Shaw
5 * You can redistribute it and/or modify it under the same terms as Ruby.
7 #ifndef http11_parser_h
8 #define http11_parser_h
10 #include <sys/types.h>
12 static void http_field(void *data
, const char *field
,
13 size_t flen
, const char *value
, size_t vlen
);
14 static void request_method(void *data
, const char *at
, size_t length
);
15 static void request_uri(void *data
, const char *at
, size_t length
);
16 static void fragment(void *data
, const char *at
, size_t length
);
17 static void request_path(void *data
, const char *at
, size_t length
);
18 static void query_string(void *data
, const char *at
, size_t length
);
19 static void http_version(void *data
, const char *at
, size_t length
);
20 static void header_done(void *data
, const char *at
, size_t length
);
22 typedef struct http_parser
{
34 static int http_parser_has_error(http_parser
*parser
);
35 static int http_parser_is_finished(http_parser
*parser
);
38 * capitalizes all lower-case ASCII characters,
39 * converts dashes to underscores.
41 static void snake_upcase_char(char *c
)
43 if (*c
>= 'a' && *c
<= 'z')
49 static void downcase_char(char *c
)
51 if (*c
>= 'A' && *c
<= 'Z')
55 #define LEN(AT, FPC) (FPC - buffer - parser->AT)
56 #define MARK(M,FPC) (parser->M = (FPC) - buffer)
57 #define PTR_TO(F) (buffer + parser->F)
62 #line 105 "http11_parser.rl"
67 #line 68 "http11_parser.h"
68 static const int http_parser_start
= 1;
69 static const int http_parser_first_final
= 63;
70 static const int http_parser_error
= 0;
72 static const int http_parser_en_main
= 1;
75 #line 109 "http11_parser.rl"
77 static void http_parser_init(http_parser
*parser
) {
79 memset(parser
, 0, sizeof(*parser
));
81 #line 82 "http11_parser.h"
83 cs
= http_parser_start
;
86 #line 114 "http11_parser.rl"
91 static void http_parser_execute(
92 http_parser
*parser
, const char *buffer
, size_t len
)
96 size_t off
= parser
->nread
;
98 assert(off
<= len
&& "offset past end of buffer");
103 assert(*pe
== '\0' && "pointer does not end on NUL");
104 assert(pe
- p
== len
- off
&& "pointers aren't same distance");
107 #line 108 "http11_parser.h"
119 if ( 45 <= (*p
) && (*p
) <= 46 )
121 } else if ( (*p
) > 57 ) {
122 if ( 65 <= (*p
) && (*p
) <= 90 )
131 #line 62 "http11_parser.rl"
138 #line 139 "http11_parser.h"
145 if ( 45 <= (*p
) && (*p
) <= 46 )
147 } else if ( (*p
) > 57 ) {
148 if ( 65 <= (*p
) && (*p
) <= 90 )
154 #line 75 "http11_parser.rl"
156 request_method(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
163 #line 164 "http11_parser.h"
172 #line 62 "http11_parser.rl"
179 #line 180 "http11_parser.h"
186 #line 78 "http11_parser.rl"
188 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
192 #line 62 "http11_parser.rl"
194 #line 81 "http11_parser.rl"
196 fragment(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
200 #line 81 "http11_parser.rl"
202 fragment(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
206 #line 94 "http11_parser.rl"
208 request_path(parser
->data
, PTR_TO(mark
), LEN(mark
,p
));
210 #line 78 "http11_parser.rl"
212 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
216 #line 85 "http11_parser.rl"
217 {MARK(query_start
, p
); }
218 #line 86 "http11_parser.rl"
220 query_string(parser
->data
, PTR_TO(query_start
), LEN(query_start
, p
));
222 #line 78 "http11_parser.rl"
224 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
228 #line 86 "http11_parser.rl"
230 query_string(parser
->data
, PTR_TO(query_start
), LEN(query_start
, p
));
232 #line 78 "http11_parser.rl"
234 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
241 #line 242 "http11_parser.h"
246 #line 62 "http11_parser.rl"
253 #line 254 "http11_parser.h"
282 if ( 48 <= (*p
) && (*p
) <= 57 )
291 if ( 48 <= (*p
) && (*p
) <= 57 )
298 if ( 48 <= (*p
) && (*p
) <= 57 )
307 if ( 48 <= (*p
) && (*p
) <= 57 )
311 #line 90 "http11_parser.rl"
313 http_version(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
317 #line 71 "http11_parser.rl"
319 #line 72 "http11_parser.rl"
321 http_field(parser
->data
, PTR_TO(field_start
), parser
->field_len
, PTR_TO(mark
), LEN(mark
, p
));
325 #line 72 "http11_parser.rl"
327 http_field(parser
->data
, PTR_TO(field_start
), parser
->field_len
, PTR_TO(mark
), LEN(mark
, p
));
334 #line 335 "http11_parser.h"
350 if ( 42 <= (*p
) && (*p
) <= 43 )
352 } else if ( (*p
) >= 35 )
354 } else if ( (*p
) > 46 ) {
356 if ( 48 <= (*p
) && (*p
) <= 57 )
358 } else if ( (*p
) > 90 ) {
359 if ( 94 <= (*p
) && (*p
) <= 122 )
374 #line 98 "http11_parser.rl"
376 parser
->body_start
= p
- buffer
+ 1;
377 header_done(parser
->data
, p
+ 1, pe
- p
- 1);
378 {p
++; cs
= 63; goto _out
;}
385 #line 386 "http11_parser.h"
388 #line 64 "http11_parser.rl"
389 { MARK(field_start
, p
); }
390 #line 65 "http11_parser.rl"
391 { snake_upcase_char((char *)p
); }
394 #line 65 "http11_parser.rl"
395 { snake_upcase_char((char *)p
); }
401 #line 402 "http11_parser.h"
410 if ( 42 <= (*p
) && (*p
) <= 43 )
412 } else if ( (*p
) >= 35 )
414 } else if ( (*p
) > 46 ) {
416 if ( 48 <= (*p
) && (*p
) <= 57 )
418 } else if ( (*p
) > 90 ) {
419 if ( 94 <= (*p
) && (*p
) <= 122 )
427 #line 67 "http11_parser.rl"
429 parser
->field_len
= LEN(field_start
, p
);
433 #line 71 "http11_parser.rl"
440 #line 441 "http11_parser.h"
447 #line 71 "http11_parser.rl"
454 #line 455 "http11_parser.h"
459 #line 78 "http11_parser.rl"
461 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
465 #line 94 "http11_parser.rl"
467 request_path(parser
->data
, PTR_TO(mark
), LEN(mark
,p
));
469 #line 78 "http11_parser.rl"
471 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
475 #line 85 "http11_parser.rl"
476 {MARK(query_start
, p
); }
477 #line 86 "http11_parser.rl"
479 query_string(parser
->data
, PTR_TO(query_start
), LEN(query_start
, p
));
481 #line 78 "http11_parser.rl"
483 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
487 #line 86 "http11_parser.rl"
489 query_string(parser
->data
, PTR_TO(query_start
), LEN(query_start
, p
));
491 #line 78 "http11_parser.rl"
493 request_uri(parser
->data
, PTR_TO(mark
), LEN(mark
, p
));
500 #line 501 "http11_parser.h"
507 if ( 0 <= (*p
) && (*p
) <= 31 )
511 #line 62 "http11_parser.rl"
518 #line 519 "http11_parser.h"
525 if ( 0 <= (*p
) && (*p
) <= 31 )
529 #line 62 "http11_parser.rl"
536 #line 537 "http11_parser.h"
538 if ( 48 <= (*p
) && (*p
) <= 57 )
540 } else if ( (*p
) > 70 ) {
541 if ( 97 <= (*p
) && (*p
) <= 102 )
551 if ( 48 <= (*p
) && (*p
) <= 57 )
553 } else if ( (*p
) > 70 ) {
554 if ( 97 <= (*p
) && (*p
) <= 102 )
560 #line 62 "http11_parser.rl"
567 #line 568 "http11_parser.h"
576 if ( 0 <= (*p
) && (*p
) <= 31 )
584 if ( 48 <= (*p
) && (*p
) <= 57 )
586 } else if ( (*p
) > 70 ) {
587 if ( 97 <= (*p
) && (*p
) <= 102 )
597 if ( 48 <= (*p
) && (*p
) <= 57 )
599 } else if ( (*p
) > 70 ) {
600 if ( 97 <= (*p
) && (*p
) <= 102 )
606 #line 94 "http11_parser.rl"
608 request_path(parser
->data
, PTR_TO(mark
), LEN(mark
,p
));
615 #line 616 "http11_parser.h"
623 if ( 0 <= (*p
) && (*p
) <= 31 )
631 if ( 48 <= (*p
) && (*p
) <= 57 )
633 } else if ( (*p
) > 70 ) {
634 if ( 97 <= (*p
) && (*p
) <= 102 )
644 if ( 48 <= (*p
) && (*p
) <= 57 )
646 } else if ( (*p
) > 70 ) {
647 if ( 97 <= (*p
) && (*p
) <= 102 )
653 #line 94 "http11_parser.rl"
655 request_path(parser
->data
, PTR_TO(mark
), LEN(mark
,p
));
662 #line 663 "http11_parser.h"
669 if ( 0 <= (*p
) && (*p
) <= 31 )
673 #line 85 "http11_parser.rl"
674 {MARK(query_start
, p
); }
680 #line 681 "http11_parser.h"
687 if ( 0 <= (*p
) && (*p
) <= 31 )
691 #line 85 "http11_parser.rl"
692 {MARK(query_start
, p
); }
698 #line 699 "http11_parser.h"
700 if ( 48 <= (*p
) && (*p
) <= 57 )
702 } else if ( (*p
) > 70 ) {
703 if ( 97 <= (*p
) && (*p
) <= 102 )
713 if ( 48 <= (*p
) && (*p
) <= 57 )
715 } else if ( (*p
) > 70 ) {
716 if ( 97 <= (*p
) && (*p
) <= 102 )
722 #line 66 "http11_parser.rl"
723 { downcase_char((char *)p
); }
729 #line 730 "http11_parser.h"
736 #line 66 "http11_parser.rl"
737 { downcase_char((char *)p
); }
743 #line 744 "http11_parser.h"
750 #line 66 "http11_parser.rl"
751 { downcase_char((char *)p
); }
757 #line 758 "http11_parser.h"
764 #line 66 "http11_parser.rl"
765 { downcase_char((char *)p
); }
771 #line 772 "http11_parser.h"
797 if ( 45 <= (*p
) && (*p
) <= 46 )
799 } else if ( (*p
) > 57 ) {
801 if ( 97 <= (*p
) && (*p
) <= 122 )
803 } else if ( (*p
) >= 65 )
817 if ( 45 <= (*p
) && (*p
) <= 57 )
819 } else if ( (*p
) > 90 ) {
820 if ( 97 <= (*p
) && (*p
) <= 122 )
831 if ( 48 <= (*p
) && (*p
) <= 57 )
835 #line 66 "http11_parser.rl"
836 { downcase_char((char *)p
); }
842 #line 843 "http11_parser.h"
856 if ( 45 <= (*p
) && (*p
) <= 46 )
858 } else if ( (*p
) > 57 ) {
859 if ( 65 <= (*p
) && (*p
) <= 90 )
874 if ( 45 <= (*p
) && (*p
) <= 46 )
876 } else if ( (*p
) > 57 ) {
877 if ( 65 <= (*p
) && (*p
) <= 90 )
892 if ( 45 <= (*p
) && (*p
) <= 46 )
894 } else if ( (*p
) > 57 ) {
895 if ( 65 <= (*p
) && (*p
) <= 90 )
910 if ( 45 <= (*p
) && (*p
) <= 46 )
912 } else if ( (*p
) > 57 ) {
913 if ( 65 <= (*p
) && (*p
) <= 90 )
928 if ( 45 <= (*p
) && (*p
) <= 46 )
930 } else if ( (*p
) > 57 ) {
931 if ( 65 <= (*p
) && (*p
) <= 90 )
946 if ( 45 <= (*p
) && (*p
) <= 46 )
948 } else if ( (*p
) > 57 ) {
949 if ( 65 <= (*p
) && (*p
) <= 90 )
964 if ( 45 <= (*p
) && (*p
) <= 46 )
966 } else if ( (*p
) > 57 ) {
967 if ( 65 <= (*p
) && (*p
) <= 90 )
982 if ( 45 <= (*p
) && (*p
) <= 46 )
984 } else if ( (*p
) > 57 ) {
985 if ( 65 <= (*p
) && (*p
) <= 90 )
1000 if ( 45 <= (*p
) && (*p
) <= 46 )
1002 } else if ( (*p
) > 57 ) {
1003 if ( 65 <= (*p
) && (*p
) <= 90 )
1018 if ( 45 <= (*p
) && (*p
) <= 46 )
1020 } else if ( (*p
) > 57 ) {
1021 if ( 65 <= (*p
) && (*p
) <= 90 )
1036 if ( 45 <= (*p
) && (*p
) <= 46 )
1038 } else if ( (*p
) > 57 ) {
1039 if ( 65 <= (*p
) && (*p
) <= 90 )
1054 if ( 45 <= (*p
) && (*p
) <= 46 )
1056 } else if ( (*p
) > 57 ) {
1057 if ( 65 <= (*p
) && (*p
) <= 90 )
1072 if ( 45 <= (*p
) && (*p
) <= 46 )
1074 } else if ( (*p
) > 57 ) {
1075 if ( 65 <= (*p
) && (*p
) <= 90 )
1090 if ( 45 <= (*p
) && (*p
) <= 46 )
1092 } else if ( (*p
) > 57 ) {
1093 if ( 65 <= (*p
) && (*p
) <= 90 )
1108 if ( 45 <= (*p
) && (*p
) <= 46 )
1110 } else if ( (*p
) > 57 ) {
1111 if ( 65 <= (*p
) && (*p
) <= 90 )
1126 if ( 45 <= (*p
) && (*p
) <= 46 )
1128 } else if ( (*p
) > 57 ) {
1129 if ( 65 <= (*p
) && (*p
) <= 90 )
1144 if ( 45 <= (*p
) && (*p
) <= 46 )
1146 } else if ( (*p
) > 57 ) {
1147 if ( 65 <= (*p
) && (*p
) <= 90 )
1162 if ( 45 <= (*p
) && (*p
) <= 46 )
1164 } else if ( (*p
) > 57 ) {
1165 if ( 65 <= (*p
) && (*p
) <= 90 )
1178 _test_eof2
: cs
= 2; goto _test_eof
;
1179 _test_eof3
: cs
= 3; goto _test_eof
;
1180 _test_eof4
: cs
= 4; goto _test_eof
;
1181 _test_eof5
: cs
= 5; goto _test_eof
;
1182 _test_eof6
: cs
= 6; goto _test_eof
;
1183 _test_eof7
: cs
= 7; goto _test_eof
;
1184 _test_eof8
: cs
= 8; goto _test_eof
;
1185 _test_eof9
: cs
= 9; goto _test_eof
;
1186 _test_eof10
: cs
= 10; goto _test_eof
;
1187 _test_eof11
: cs
= 11; goto _test_eof
;
1188 _test_eof12
: cs
= 12; goto _test_eof
;
1189 _test_eof13
: cs
= 13; goto _test_eof
;
1190 _test_eof14
: cs
= 14; goto _test_eof
;
1191 _test_eof15
: cs
= 15; goto _test_eof
;
1192 _test_eof16
: cs
= 16; goto _test_eof
;
1193 _test_eof63
: cs
= 63; goto _test_eof
;
1194 _test_eof17
: cs
= 17; goto _test_eof
;
1195 _test_eof18
: cs
= 18; goto _test_eof
;
1196 _test_eof19
: cs
= 19; goto _test_eof
;
1197 _test_eof20
: cs
= 20; goto _test_eof
;
1198 _test_eof21
: cs
= 21; goto _test_eof
;
1199 _test_eof22
: cs
= 22; goto _test_eof
;
1200 _test_eof23
: cs
= 23; goto _test_eof
;
1201 _test_eof24
: cs
= 24; goto _test_eof
;
1202 _test_eof25
: cs
= 25; goto _test_eof
;
1203 _test_eof26
: cs
= 26; goto _test_eof
;
1204 _test_eof27
: cs
= 27; goto _test_eof
;
1205 _test_eof28
: cs
= 28; goto _test_eof
;
1206 _test_eof29
: cs
= 29; goto _test_eof
;
1207 _test_eof30
: cs
= 30; goto _test_eof
;
1208 _test_eof31
: cs
= 31; goto _test_eof
;
1209 _test_eof32
: cs
= 32; goto _test_eof
;
1210 _test_eof33
: cs
= 33; goto _test_eof
;
1211 _test_eof34
: cs
= 34; goto _test_eof
;
1212 _test_eof35
: cs
= 35; goto _test_eof
;
1213 _test_eof36
: cs
= 36; goto _test_eof
;
1214 _test_eof37
: cs
= 37; goto _test_eof
;
1215 _test_eof38
: cs
= 38; goto _test_eof
;
1216 _test_eof39
: cs
= 39; goto _test_eof
;
1217 _test_eof40
: cs
= 40; goto _test_eof
;
1218 _test_eof41
: cs
= 41; goto _test_eof
;
1219 _test_eof42
: cs
= 42; goto _test_eof
;
1220 _test_eof43
: cs
= 43; goto _test_eof
;
1221 _test_eof44
: cs
= 44; goto _test_eof
;
1222 _test_eof45
: cs
= 45; goto _test_eof
;
1223 _test_eof46
: cs
= 46; goto _test_eof
;
1224 _test_eof47
: cs
= 47; goto _test_eof
;
1225 _test_eof48
: cs
= 48; goto _test_eof
;
1226 _test_eof49
: cs
= 49; goto _test_eof
;
1227 _test_eof50
: cs
= 50; goto _test_eof
;
1228 _test_eof51
: cs
= 51; goto _test_eof
;
1229 _test_eof52
: cs
= 52; goto _test_eof
;
1230 _test_eof53
: cs
= 53; goto _test_eof
;
1231 _test_eof54
: cs
= 54; goto _test_eof
;
1232 _test_eof55
: cs
= 55; goto _test_eof
;
1233 _test_eof56
: cs
= 56; goto _test_eof
;
1234 _test_eof57
: cs
= 57; goto _test_eof
;
1235 _test_eof58
: cs
= 58; goto _test_eof
;
1236 _test_eof59
: cs
= 59; goto _test_eof
;
1237 _test_eof60
: cs
= 60; goto _test_eof
;
1238 _test_eof61
: cs
= 61; goto _test_eof
;
1239 _test_eof62
: cs
= 62; goto _test_eof
;
1245 #line 134 "http11_parser.rl"
1247 if (!http_parser_has_error(parser
))
1249 parser
->nread
+= p
- (buffer
+ off
);
1251 assert(p
<= pe
&& "buffer overflow after parsing execute");
1252 assert(parser
->nread
<= len
&& "nread longer than length");
1253 assert(parser
->body_start
<= len
&& "body starts after buffer end");
1254 assert(parser
->mark
< len
&& "mark is after buffer end");
1255 assert(parser
->field_len
<= len
&& "field has length longer than whole buffer");
1256 assert(parser
->field_start
< len
&& "field starts after buffer end");
1259 static int http_parser_has_error(http_parser
*parser
) {
1260 return parser
->cs
== http_parser_error
;
1263 static int http_parser_is_finished(http_parser
*parser
) {
1264 return parser
->cs
== http_parser_first_final
;
1266 #endif /* http11_parser_h */