ext/kcar/kcar.c in kcar-0.1.1 vs ext/kcar/kcar.c in kcar-0.1.2

- old
+ new

@@ -42,10 +42,11 @@ #define UH_FL_INBODY 0x4 #define UH_FL_HASTRAILER 0x8 #define UH_FL_INTRAILER 0x10 #define UH_FL_INCHUNK 0x20 #define UH_FL_KEEPALIVE 0x40 +#define UH_FL_HASHEADER 0x80 struct http_parser { int cs; /* Ragel internal state */ unsigned int flags; size_t mark; @@ -178,10 +179,12 @@ const char *fptr = PTR_TO(start.field); long flen = hp->s.field_len; const char *vptr; long vlen; + HP_FL_SET(hp, HASHEADER); + /* Rack does not like Status headers, so we never send them */ if (CSTR_CASE_EQ(fptr, flen, "status")) { hp->cont = Qnil; return; } @@ -272,42 +275,42 @@ } /** Machine **/ -#line 337 "kcar.rl" +#line 340 "kcar.rl" /** Data **/ -#line 283 "kcar.c" +#line 286 "kcar.c" static const int http_parser_start = 1; static const int http_parser_first_final = 44; static const int http_parser_error = 0; static const int http_parser_en_ChunkedBody = 22; static const int http_parser_en_ChunkedBody_chunk_chunk_end = 27; static const int http_parser_en_Trailers = 36; static const int http_parser_en_main = 1; -#line 341 "kcar.rl" +#line 344 "kcar.rl" static void http_parser_init(struct http_parser *hp) { int cs = 0; memset(hp, 0, sizeof(struct http_parser)); hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */ hp->status = Qnil; hp->len.content = -1; -#line 304 "kcar.c" +#line 307 "kcar.c" { cs = http_parser_start; } -#line 350 "kcar.rl" +#line 353 "kcar.rl" hp->cs = cs; } /** exec **/ static void http_parser_execute(struct http_parser *hp, @@ -331,11 +334,11 @@ if (HP_FL_TEST(hp, INCHUNK)) { HP_FL_UNSET(hp, INCHUNK); goto skip_chunk_data_hack; } -#line 337 "kcar.c" +#line 340 "kcar.c" { if ( p == pe ) goto _test_eof; switch ( cs ) { @@ -345,18 +348,18 @@ goto st0; st0: cs = 0; goto _out; tr0: -#line 277 "kcar.rl" +#line 280 "kcar.rl" {MARK(mark, p); } goto st2; st2: if ( ++p == pe ) goto _test_eof2; case 2: -#line 358 "kcar.c" +#line 361 "kcar.c" if ( (*p) == 84 ) goto st3; goto st0; st3: if ( ++p == pe ) @@ -410,69 +413,69 @@ goto tr9; if ( 48 <= (*p) && (*p) <= 57 ) goto st9; goto st0; tr9: -#line 284 "kcar.rl" +#line 287 "kcar.rl" { http_version(hp, hdr, PTR_TO(mark), LEN(mark, p)); } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 423 "kcar.c" +#line 426 "kcar.c" if ( (*p) == 32 ) goto st10; if ( 48 <= (*p) && (*p) <= 57 ) goto tr11; goto st0; tr11: -#line 277 "kcar.rl" +#line 280 "kcar.rl" {MARK(mark, p); } goto st11; st11: if ( ++p == pe ) goto _test_eof11; case 11: -#line 437 "kcar.c" +#line 440 "kcar.c" switch( (*p) ) { case 10: goto tr12; case 13: goto tr13; case 32: goto st20; } if ( 48 <= (*p) && (*p) <= 57 ) goto st11; goto st0; tr12: -#line 285 "kcar.rl" +#line 288 "kcar.rl" { status_phrase(hp, hdr, PTR_TO(mark), LEN(mark, p)); } goto st12; tr22: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st12; tr25: -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st12; tr31: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st12; tr35: -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st12; st12: if ( ++p == pe ) goto _test_eof12; case 12: -#line 474 "kcar.c" +#line 477 "kcar.c" switch( (*p) ) { case 9: goto st13; case 10: goto tr17; case 13: goto st16; case 32: goto st13; @@ -497,73 +500,73 @@ goto tr19; } else goto tr19; goto st0; tr21: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st13; st13: if ( ++p == pe ) goto _test_eof13; case 13: -#line 510 "kcar.c" +#line 513 "kcar.c" switch( (*p) ) { case 9: goto tr21; case 10: goto tr22; case 13: goto tr23; case 32: goto tr21; } goto tr20; tr20: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st14; st14: if ( ++p == pe ) goto _test_eof14; case 14: -#line 526 "kcar.c" +#line 529 "kcar.c" switch( (*p) ) { case 10: goto tr25; case 13: goto tr26; } goto st14; tr13: -#line 285 "kcar.rl" +#line 288 "kcar.rl" { status_phrase(hp, hdr, PTR_TO(mark), LEN(mark, p)); } goto st15; tr23: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st15; tr26: -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st15; tr32: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st15; tr36: -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st15; st15: if ( ++p == pe ) goto _test_eof15; case 15: -#line 560 "kcar.c" +#line 563 "kcar.c" if ( (*p) == 10 ) goto st12; goto st0; tr17: -#line 292 "kcar.rl" +#line 295 "kcar.rl" { finalize_header(hp); cs = http_parser_first_final; if (HP_FL_TEST(hp, CHUNKED)) @@ -578,28 +581,28 @@ goto st44; st44: if ( ++p == pe ) goto _test_eof44; case 44: -#line 584 "kcar.c" +#line 587 "kcar.c" goto st0; st16: if ( ++p == pe ) goto _test_eof16; case 16: if ( (*p) == 10 ) goto tr17; goto st0; tr19: -#line 279 "kcar.rl" +#line 282 "kcar.rl" { MARK(start.field, p); } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 601 "kcar.c" +#line 604 "kcar.c" switch( (*p) ) { case 33: goto st17; case 58: goto tr29; case 124: goto st17; case 126: goto st17; @@ -621,37 +624,37 @@ goto st17; } else goto st17; goto st0; tr33: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st18; tr29: -#line 280 "kcar.rl" +#line 283 "kcar.rl" { hp->s.field_len = LEN(start.field, p); } goto st18; st18: if ( ++p == pe ) goto _test_eof18; case 18: -#line 638 "kcar.c" +#line 641 "kcar.c" switch( (*p) ) { case 10: goto tr31; case 13: goto tr32; case 32: goto tr33; } goto tr30; tr30: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st19; st19: if ( ++p == pe ) goto _test_eof19; case 19: -#line 653 "kcar.c" +#line 656 "kcar.c" switch( (*p) ) { case 10: goto tr35; case 13: goto tr36; } goto st19; @@ -685,22 +688,22 @@ goto tr39; } else goto tr39; goto st0; tr38: -#line 287 "kcar.rl" +#line 290 "kcar.rl" { hp->len.chunk = step_incr(hp->len.chunk, (*p), 16); if (hp->len.chunk < 0) rb_raise(eParserError, "invalid chunk size"); } goto st23; st23: if ( ++p == pe ) goto _test_eof23; case 23: -#line 702 "kcar.c" +#line 705 "kcar.c" switch( (*p) ) { case 10: goto tr40; case 13: goto st24; case 48: goto tr38; case 59: goto st33; @@ -713,11 +716,11 @@ goto tr39; } else goto tr39; goto st0; tr40: -#line 311 "kcar.rl" +#line 314 "kcar.rl" { HP_FL_SET(hp, INTRAILER); cs = http_parser_en_Trailers; ++p; assert(p <= pe && "buffer overflow after chunked body"); @@ -726,32 +729,32 @@ goto st45; st45: if ( ++p == pe ) goto _test_eof45; case 45: -#line 732 "kcar.c" +#line 735 "kcar.c" goto st0; st24: if ( ++p == pe ) goto _test_eof24; case 24: if ( (*p) == 10 ) goto tr40; goto st0; tr39: -#line 287 "kcar.rl" +#line 290 "kcar.rl" { hp->len.chunk = step_incr(hp->len.chunk, (*p), 16); if (hp->len.chunk < 0) rb_raise(eParserError, "invalid chunk size"); } goto st25; st25: if ( ++p == pe ) goto _test_eof25; case 25: -#line 753 "kcar.c" +#line 756 "kcar.c" switch( (*p) ) { case 10: goto st26; case 13: goto st29; case 59: goto st30; } @@ -768,11 +771,11 @@ if ( ++p == pe ) goto _test_eof26; case 26: goto tr46; tr46: -#line 319 "kcar.rl" +#line 322 "kcar.rl" { skip_chunk_data_hack: { size_t nr = MIN((size_t)hp->len.chunk, REMAINING); memcpy(RSTRING_PTR(hdr) + hp->s.dest_offset, p, nr); hp->s.dest_offset += nr; @@ -790,11 +793,11 @@ goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 796 "kcar.c" +#line 799 "kcar.c" switch( (*p) ) { case 10: goto st22; case 13: goto st28; } goto st0; @@ -997,34 +1000,34 @@ goto st35; } else goto st35; goto st0; tr59: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st36; tr62: -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st36; tr68: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st36; tr72: -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st36; st36: if ( ++p == pe ) goto _test_eof36; case 36: -#line 1026 "kcar.c" +#line 1029 "kcar.c" switch( (*p) ) { case 9: goto st37; case 10: goto tr54; case 13: goto st40; case 32: goto st37; @@ -1049,96 +1052,96 @@ goto tr56; } else goto tr56; goto st0; tr58: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st37; st37: if ( ++p == pe ) goto _test_eof37; case 37: -#line 1062 "kcar.c" +#line 1065 "kcar.c" switch( (*p) ) { case 9: goto tr58; case 10: goto tr59; case 13: goto tr60; case 32: goto tr58; } goto tr57; tr57: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st38; st38: if ( ++p == pe ) goto _test_eof38; case 38: -#line 1078 "kcar.c" +#line 1081 "kcar.c" switch( (*p) ) { case 10: goto tr62; case 13: goto tr63; } goto st38; tr60: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st39; tr63: -#line 283 "kcar.rl" +#line 286 "kcar.rl" { write_cont_value(hp, buffer, p); } goto st39; tr69: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st39; tr73: -#line 282 "kcar.rl" +#line 285 "kcar.rl" { write_value(hdr, hp, buffer, p); } goto st39; st39: if ( ++p == pe ) goto _test_eof39; case 39: -#line 1108 "kcar.c" +#line 1111 "kcar.c" if ( (*p) == 10 ) goto st36; goto st0; tr54: -#line 306 "kcar.rl" +#line 309 "kcar.rl" { cs = http_parser_first_final; goto post_exec; } goto st46; st46: if ( ++p == pe ) goto _test_eof46; case 46: -#line 1123 "kcar.c" +#line 1126 "kcar.c" goto st0; st40: if ( ++p == pe ) goto _test_eof40; case 40: if ( (*p) == 10 ) goto tr54; goto st0; tr56: -#line 279 "kcar.rl" +#line 282 "kcar.rl" { MARK(start.field, p); } goto st41; st41: if ( ++p == pe ) goto _test_eof41; case 41: -#line 1140 "kcar.c" +#line 1143 "kcar.c" switch( (*p) ) { case 33: goto st41; case 58: goto tr66; case 124: goto st41; case 126: goto st41; @@ -1160,37 +1163,37 @@ goto st41; } else goto st41; goto st0; tr70: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st42; tr66: -#line 280 "kcar.rl" +#line 283 "kcar.rl" { hp->s.field_len = LEN(start.field, p); } goto st42; st42: if ( ++p == pe ) goto _test_eof42; case 42: -#line 1177 "kcar.c" +#line 1180 "kcar.c" switch( (*p) ) { case 10: goto tr68; case 13: goto tr69; case 32: goto tr70; } goto tr67; tr67: -#line 281 "kcar.rl" +#line 284 "kcar.rl" { MARK(mark, p); } goto st43; st43: if ( ++p == pe ) goto _test_eof43; case 43: -#line 1192 "kcar.c" +#line 1195 "kcar.c" switch( (*p) ) { case 10: goto tr72; case 13: goto tr73; } goto st43; @@ -1243,11 +1246,11 @@ _test_eof: {} _out: {} } -#line 377 "kcar.rl" +#line 380 "kcar.rl" post_exec: /* "_out:" also goes here */ if (hp->cs != http_parser_error) hp->cs = cs; hp->offset = p - buffer; @@ -1404,10 +1407,13 @@ */ static VALUE body_eof(VALUE self) { struct http_parser *hp = data_get(self); + if (!HP_FL_TEST(hp, HASHEADER) && HP_FL_ALL(hp, KEEPALIVE)) + return Qtrue; + if (HP_FL_TEST(hp, CHUNKED)) return chunked_eof(hp) ? Qtrue : Qfalse; if (! HP_FL_TEST(hp, HASBODY)) return Qtrue; @@ -1430,10 +1436,10 @@ static VALUE keepalive(VALUE self) { struct http_parser *hp = data_get(self); if (HP_FL_ALL(hp, KEEPALIVE)) { - if ( HP_FL_TEST(hp, HASBODY) ) { + if (HP_FL_TEST(hp, HASHEADER) && HP_FL_TEST(hp, HASBODY) ) { if (HP_FL_TEST(hp, CHUNKED) || (hp->len.content >= 0)) return Qtrue; /* unknown Content-Length and not chunked, we must assume close */ return Qfalse;