From fb7f6739c5bc041a28ae45fea80f840459523f8e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 31 Jul 2009 23:46:21 -0700 Subject: unicorn_http: small cleanups and size reduction Use Data_Make_Struct instead of Data_Wrap_Struct to avoid extra steps/code in object allocation. The GC will also free() implicitly if no free callback is passed to Data_Make_Struct, and we don't need an extra method here... Since we're more comfortable with object management nowadays, just make the data_get() fail with an assertion failure if it somehow (very unlikely) ends up getting a NULL parser object. Unicorn itself has no way of recovering other than throwing errors to clients anyways and we have bigger problems if there's a GC bug causing this. Then, finally, reduce the size of our http_parser struct even more (we'll add an int back later) since we know it's safe to do so... --- ext/unicorn_http/unicorn_http.h | 304 ++++++++++++++++++---------------------- 1 file changed, 137 insertions(+), 167 deletions(-) (limited to 'ext/unicorn_http/unicorn_http.h') diff --git a/ext/unicorn_http/unicorn_http.h b/ext/unicorn_http/unicorn_http.h index d39a22b..c651ed3 100644 --- a/ext/unicorn_http/unicorn_http.h +++ b/ext/unicorn_http/unicorn_http.h @@ -7,30 +7,32 @@ #ifndef unicorn_http_h #define unicorn_http_h +#include "ruby.h" +#include "ext_help.h" #include -static void http_field(void *data, const char *field, +static void http_field(VALUE req, const char *field, size_t flen, const char *value, size_t vlen); -static void request_method(void *data, const char *at, size_t length); -static void scheme(void *data, const char *at, size_t length); -static void host(void *data, const char *at, size_t length); -static void request_uri(void *data, const char *at, size_t length); -static void fragment(void *data, const char *at, size_t length); -static void request_path(void *data, const char *at, size_t length); -static void query_string(void *data, const char *at, size_t length); -static void http_version(void *data, const char *at, size_t length); -static void header_done(void *data, const char *at, size_t length); +static void request_method(VALUE req, const char *at, size_t length); +static void scheme(VALUE req, const char *at, size_t length); +static void host(VALUE req, const char *at, size_t length); +static void request_uri(VALUE req, const char *at, size_t length); +static void fragment(VALUE req, const char *at, size_t length); +static void request_path(VALUE req, const char *at, size_t length); +static void query_string(VALUE req, const char *at, size_t length); +static void http_version(VALUE req, const char *at, size_t length); +static void header_done(VALUE req, const char *at, size_t length); typedef struct http_parser { int cs; - size_t body_start; - size_t nread; + union { + size_t body; + size_t field; + size_t query; + size_t offset; + } start; size_t mark; - size_t field_start; size_t field_len; - size_t query_start; - - void *data; } http_parser; static int http_parser_has_error(http_parser *parser); @@ -61,12 +63,12 @@ static void downcase_char(char *c) /** Machine **/ -#line 109 "unicorn_http.rl" +#line 101 "unicorn_http.rl" /** Data **/ -#line 70 "unicorn_http.h" +#line 72 "unicorn_http.h" static const int http_parser_start = 1; static const int http_parser_first_final = 63; static const int http_parser_error = 0; @@ -74,28 +76,28 @@ static const int http_parser_error = 0; static const int http_parser_en_main = 1; -#line 113 "unicorn_http.rl" +#line 105 "unicorn_http.rl" static void http_parser_init(http_parser *parser) { int cs = 0; memset(parser, 0, sizeof(*parser)); -#line 84 "unicorn_http.h" +#line 86 "unicorn_http.h" { cs = http_parser_start; } -#line 118 "unicorn_http.rl" +#line 110 "unicorn_http.rl" parser->cs = cs; } /** exec **/ static void http_parser_execute( - http_parser *parser, const char *buffer, size_t len) + http_parser *parser, VALUE req, const char *buffer, size_t len) { const char *p, *pe; int cs = parser->cs; - size_t off = parser->nread; + size_t off = parser->start.offset; assert(off <= len && "offset past end of buffer"); @@ -106,7 +108,7 @@ static void http_parser_execute( assert(pe - p == len - off && "pointers aren't same distance"); -#line 110 "unicorn_http.h" +#line 112 "unicorn_http.h" { if ( p == pe ) goto _test_eof; @@ -130,14 +132,14 @@ st0: cs = 0; goto _out; tr0: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st2; st2: if ( ++p == pe ) goto _test_eof2; case 2: -#line 141 "unicorn_http.h" +#line 143 "unicorn_http.h" switch( (*p) ) { case 32: goto tr2; case 36: goto st44; @@ -153,10 +155,8 @@ case 2: goto st44; goto st0; tr2: -#line 77 "unicorn_http.rl" - { - request_method(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 80 "unicorn_http.rl" + { request_method(req, PTR_TO(mark), LEN(mark, p)); } goto st3; st3: if ( ++p == pe ) @@ -171,7 +171,7 @@ case 3: } goto st0; tr4: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st4; st4: @@ -185,74 +185,60 @@ case 4: } goto st0; tr7: -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st5; tr30: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } -#line 85 "unicorn_http.rl" - { - fragment(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 84 "unicorn_http.rl" + { fragment(req, PTR_TO(mark), LEN(mark, p)); } goto st5; tr33: -#line 85 "unicorn_http.rl" - { - fragment(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 84 "unicorn_http.rl" + { fragment(req, PTR_TO(mark), LEN(mark, p)); } goto st5; tr37: -#line 98 "unicorn_http.rl" - { - request_path(parser->data, PTR_TO(mark), LEN(mark,p)); - } -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 92 "unicorn_http.rl" + { request_path(req, PTR_TO(mark), LEN(mark,p)); } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st5; tr48: -#line 89 "unicorn_http.rl" - {MARK(query_start, p); } -#line 90 "unicorn_http.rl" +#line 86 "unicorn_http.rl" + {MARK(start.query, p); } +#line 87 "unicorn_http.rl" { - query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); - } -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); + query_string(req, PTR_TO(start.query), LEN(start.query, p)); } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st5; tr52: -#line 90 "unicorn_http.rl" +#line 87 "unicorn_http.rl" { - query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); - } -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); + query_string(req, PTR_TO(start.query), LEN(start.query, p)); } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: -#line 244 "unicorn_http.h" +#line 230 "unicorn_http.h" if ( (*p) == 72 ) goto tr9; goto st0; tr9: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st6; st6: if ( ++p == pe ) goto _test_eof6; case 6: -#line 256 "unicorn_http.h" +#line 242 "unicorn_http.h" if ( (*p) == 84 ) goto st7; goto st0; @@ -310,30 +296,30 @@ case 13: goto st13; goto st0; tr17: -#line 94 "unicorn_http.rl" - { - http_version(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 91 "unicorn_http.rl" + { http_version(req, PTR_TO(mark), LEN(mark, p)); } goto st14; tr25: -#line 73 "unicorn_http.rl" +#line 75 "unicorn_http.rl" { MARK(mark, p); } -#line 74 "unicorn_http.rl" +#line 76 "unicorn_http.rl" { - http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p)); + http_field(req, PTR_TO(start.field), parser->field_len, + PTR_TO(mark), LEN(mark, p)); } goto st14; tr28: -#line 74 "unicorn_http.rl" +#line 76 "unicorn_http.rl" { - http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p)); + http_field(req, PTR_TO(start.field), parser->field_len, + PTR_TO(mark), LEN(mark, p)); } goto st14; st14: if ( ++p == pe ) goto _test_eof14; case 14: -#line 337 "unicorn_http.h" +#line 323 "unicorn_http.h" if ( (*p) == 10 ) goto st15; goto st0; @@ -373,10 +359,10 @@ case 16: goto tr21; goto st0; tr21: -#line 102 "unicorn_http.rl" +#line 94 "unicorn_http.rl" { - parser->body_start = p - buffer + 1; - header_done(parser->data, p + 1, pe - p - 1); + parser->start.body = p - buffer + 1; + header_done(req, p + 1, pe - p - 1); {p++; cs = 63; goto _out;} } goto st63; @@ -384,23 +370,23 @@ st63: if ( ++p == pe ) goto _test_eof63; case 63: -#line 388 "unicorn_http.h" +#line 374 "unicorn_http.h" goto st0; tr20: -#line 66 "unicorn_http.rl" - { MARK(field_start, p); } -#line 67 "unicorn_http.rl" +#line 68 "unicorn_http.rl" + { MARK(start.field, p); } +#line 69 "unicorn_http.rl" { snake_upcase_char((char *)p); } goto st17; tr22: -#line 67 "unicorn_http.rl" +#line 69 "unicorn_http.rl" { snake_upcase_char((char *)p); } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 404 "unicorn_http.h" +#line 390 "unicorn_http.h" switch( (*p) ) { case 33: goto tr22; case 58: goto tr23; @@ -426,80 +412,70 @@ case 17: goto tr22; goto st0; tr23: -#line 69 "unicorn_http.rl" +#line 71 "unicorn_http.rl" { - parser->field_len = LEN(field_start, p); + parser->field_len = LEN(start.field, p); } goto st18; tr26: -#line 73 "unicorn_http.rl" +#line 75 "unicorn_http.rl" { MARK(mark, p); } goto st18; st18: if ( ++p == pe ) goto _test_eof18; case 18: -#line 443 "unicorn_http.h" +#line 429 "unicorn_http.h" switch( (*p) ) { case 13: goto tr25; case 32: goto tr26; } goto tr24; tr24: -#line 73 "unicorn_http.rl" +#line 75 "unicorn_http.rl" { MARK(mark, p); } goto st19; st19: if ( ++p == pe ) goto _test_eof19; case 19: -#line 457 "unicorn_http.h" +#line 443 "unicorn_http.h" if ( (*p) == 13 ) goto tr28; goto st19; tr8: -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st20; tr38: -#line 98 "unicorn_http.rl" - { - request_path(parser->data, PTR_TO(mark), LEN(mark,p)); - } -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); - } +#line 92 "unicorn_http.rl" + { request_path(req, PTR_TO(mark), LEN(mark,p)); } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st20; tr49: -#line 89 "unicorn_http.rl" - {MARK(query_start, p); } -#line 90 "unicorn_http.rl" +#line 86 "unicorn_http.rl" + {MARK(start.query, p); } +#line 87 "unicorn_http.rl" { - query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); - } -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); + query_string(req, PTR_TO(start.query), LEN(start.query, p)); } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st20; tr53: -#line 90 "unicorn_http.rl" +#line 87 "unicorn_http.rl" { - query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); - } -#line 82 "unicorn_http.rl" - { - request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); + query_string(req, PTR_TO(start.query), LEN(start.query, p)); } +#line 83 "unicorn_http.rl" + { request_uri(req, PTR_TO(mark), LEN(mark, p)); } goto st20; st20: if ( ++p == pe ) goto _test_eof20; case 20: -#line 503 "unicorn_http.h" +#line 479 "unicorn_http.h" switch( (*p) ) { case 32: goto tr30; case 35: goto st0; @@ -510,14 +486,14 @@ case 20: goto st0; goto tr29; tr29: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st21; st21: if ( ++p == pe ) goto _test_eof21; case 21: -#line 521 "unicorn_http.h" +#line 497 "unicorn_http.h" switch( (*p) ) { case 32: goto tr33; case 35: goto st0; @@ -528,14 +504,14 @@ case 21: goto st0; goto st21; tr31: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st22; st22: if ( ++p == pe ) goto _test_eof22; case 22: -#line 539 "unicorn_http.h" +#line 515 "unicorn_http.h" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st23; @@ -559,20 +535,20 @@ case 23: goto st21; goto st0; tr5: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st24; tr65: -#line 81 "unicorn_http.rl" - { host(parser->data, PTR_TO(mark), LEN(mark, p)); } -#line 64 "unicorn_http.rl" +#line 82 "unicorn_http.rl" + { host(req, PTR_TO(mark), LEN(mark, p)); } +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st24; st24: if ( ++p == pe ) goto _test_eof24; case 24: -#line 576 "unicorn_http.h" +#line 552 "unicorn_http.h" switch( (*p) ) { case 32: goto tr37; case 35: goto tr38; @@ -611,16 +587,14 @@ case 26: goto st24; goto st0; tr40: -#line 98 "unicorn_http.rl" - { - request_path(parser->data, PTR_TO(mark), LEN(mark,p)); - } +#line 92 "unicorn_http.rl" + { request_path(req, PTR_TO(mark), LEN(mark,p)); } goto st27; st27: if ( ++p == pe ) goto _test_eof27; case 27: -#line 624 "unicorn_http.h" +#line 598 "unicorn_http.h" switch( (*p) ) { case 32: goto tr7; case 35: goto tr8; @@ -658,16 +632,14 @@ case 29: goto st27; goto st0; tr41: -#line 98 "unicorn_http.rl" - { - request_path(parser->data, PTR_TO(mark), LEN(mark,p)); - } +#line 92 "unicorn_http.rl" + { request_path(req, PTR_TO(mark), LEN(mark,p)); } goto st30; st30: if ( ++p == pe ) goto _test_eof30; case 30: -#line 671 "unicorn_http.h" +#line 643 "unicorn_http.h" switch( (*p) ) { case 32: goto tr48; case 35: goto tr49; @@ -678,14 +650,14 @@ case 30: goto st0; goto tr47; tr47: -#line 89 "unicorn_http.rl" - {MARK(query_start, p); } +#line 86 "unicorn_http.rl" + {MARK(start.query, p); } goto st31; st31: if ( ++p == pe ) goto _test_eof31; case 31: -#line 689 "unicorn_http.h" +#line 661 "unicorn_http.h" switch( (*p) ) { case 32: goto tr52; case 35: goto tr53; @@ -696,14 +668,14 @@ case 31: goto st0; goto st31; tr50: -#line 89 "unicorn_http.rl" - {MARK(query_start, p); } +#line 86 "unicorn_http.rl" + {MARK(start.query, p); } goto st32; st32: if ( ++p == pe ) goto _test_eof32; case 32: -#line 707 "unicorn_http.h" +#line 679 "unicorn_http.h" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st33; @@ -727,58 +699,58 @@ case 33: goto st31; goto st0; tr6: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } -#line 68 "unicorn_http.rl" +#line 70 "unicorn_http.rl" { downcase_char((char *)p); } goto st34; st34: if ( ++p == pe ) goto _test_eof34; case 34: -#line 740 "unicorn_http.h" +#line 712 "unicorn_http.h" switch( (*p) ) { case 84: goto tr56; case 116: goto tr56; } goto st0; tr56: -#line 68 "unicorn_http.rl" +#line 70 "unicorn_http.rl" { downcase_char((char *)p); } goto st35; st35: if ( ++p == pe ) goto _test_eof35; case 35: -#line 754 "unicorn_http.h" +#line 726 "unicorn_http.h" switch( (*p) ) { case 84: goto tr57; case 116: goto tr57; } goto st0; tr57: -#line 68 "unicorn_http.rl" +#line 70 "unicorn_http.rl" { downcase_char((char *)p); } goto st36; st36: if ( ++p == pe ) goto _test_eof36; case 36: -#line 768 "unicorn_http.h" +#line 740 "unicorn_http.h" switch( (*p) ) { case 80: goto tr58; case 112: goto tr58; } goto st0; tr58: -#line 68 "unicorn_http.rl" +#line 70 "unicorn_http.rl" { downcase_char((char *)p); } goto st37; st37: if ( ++p == pe ) goto _test_eof37; case 37: -#line 782 "unicorn_http.h" +#line 754 "unicorn_http.h" switch( (*p) ) { case 58: goto tr59; case 83: goto tr60; @@ -786,14 +758,14 @@ case 37: } goto st0; tr59: -#line 80 "unicorn_http.rl" - { scheme(parser->data, PTR_TO(mark), LEN(mark, p)); } +#line 81 "unicorn_http.rl" + { scheme(req, PTR_TO(mark), LEN(mark, p)); } goto st38; st38: if ( ++p == pe ) goto _test_eof38; case 38: -#line 797 "unicorn_http.h" +#line 769 "unicorn_http.h" if ( (*p) == 47 ) goto st39; goto st0; @@ -823,14 +795,14 @@ case 40: goto tr63; goto st0; tr63: -#line 64 "unicorn_http.rl" +#line 66 "unicorn_http.rl" {MARK(mark, p); } goto st41; st41: if ( ++p == pe ) goto _test_eof41; case 41: -#line 834 "unicorn_http.h" +#line 806 "unicorn_http.h" switch( (*p) ) { case 47: goto tr65; case 58: goto st42; @@ -855,14 +827,14 @@ case 42: goto st42; goto st0; tr60: -#line 68 "unicorn_http.rl" +#line 70 "unicorn_http.rl" { downcase_char((char *)p); } goto st43; st43: if ( ++p == pe ) goto _test_eof43; case 43: -#line 866 "unicorn_http.h" +#line 838 "unicorn_http.h" if ( (*p) == 58 ) goto tr59; goto st0; @@ -1265,18 +1237,16 @@ case 62: _out: {} } -#line 138 "unicorn_http.rl" +#line 130 "unicorn_http.rl" if (!http_parser_has_error(parser)) parser->cs = cs; - parser->nread += p - (buffer + off); + parser->start.offset = p - buffer; assert(p <= pe && "buffer overflow after parsing execute"); - assert(parser->nread <= len && "nread longer than length"); - assert(parser->body_start <= len && "body starts after buffer end"); + assert(parser->start.offset <= len && "start.offset longer than length"); assert(parser->mark < len && "mark is after buffer end"); assert(parser->field_len <= len && "field has length longer than whole buffer"); - assert(parser->field_start < len && "field starts after buffer end"); } static int http_parser_has_error(http_parser *parser) { -- cgit v1.2.3-24-ge0c7