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;