diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-08-02 13:58:34 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-08-09 01:24:56 -0700 |
commit | abb47b5a6cae1a814f56893df1f2572203fd8faa (patch) | |
tree | 007826593aee09e7c39b96ebea71297bfeca4139 /ext/unicorn_http | |
parent | 4dc2a9e95d115547b7c2680f198293d6e25658b3 (diff) | |
download | unicorn-abb47b5a6cae1a814f56893df1f2572203fd8faa.tar.gz |
There's also no point in validating field hits if our field is a common field; so only do the validation for field length if we need to allocate memory for a new field.
Diffstat (limited to 'ext/unicorn_http')
-rw-r--r-- | ext/unicorn_http/common_field_optimization.h | 13 | ||||
-rw-r--r-- | ext/unicorn_http/unicorn_http.rl | 22 |
2 files changed, 16 insertions, 19 deletions
diff --git a/ext/unicorn_http/common_field_optimization.h b/ext/unicorn_http/common_field_optimization.h index adebe2c..97640c6 100644 --- a/ext/unicorn_http/common_field_optimization.h +++ b/ext/unicorn_http/common_field_optimization.h @@ -93,4 +93,17 @@ static VALUE find_common_field(const char *field, size_t flen) return Qnil; } +/* + * We got a strange header that we don't have a memoized value for. + * Fallback to creating a new string to use as a hash key. + */ +static VALUE uncommon_field(const char *field, size_t flen) +{ + VALUE f = rb_str_new(NULL, HTTP_PREFIX_LEN + flen); + memcpy(RSTRING_PTR(f), HTTP_PREFIX, HTTP_PREFIX_LEN); + memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen); + assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0'); /* paranoia */ + return f; +} + #endif /* common_field_optimization_h */ diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl index 706c77c..7a525e4 100644 --- a/ext/unicorn_http/unicorn_http.rl +++ b/ext/unicorn_http/unicorn_http.rl @@ -143,29 +143,13 @@ static struct http_parser *data_get(VALUE self) static void http_field(VALUE req, const char *field, size_t flen, const char *value, size_t vlen) { - VALUE f = Qnil; + VALUE f = find_common_field(field, flen); - VALIDATE_MAX_LENGTH(flen, FIELD_NAME); VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE); - f = find_common_field(field, flen); - if (f == Qnil) { - /* - * We got a strange header that we don't have a memoized value for. - * Fallback to creating a new string to use as a hash key. - * - * using rb_str_new(NULL, len) here is faster than rb_str_buf_new(len) - * in my testing, because: there's no minimum allocation length (and - * no check for it, either), RSTRING_LEN(f) does not need to be - * written twice, and and RSTRING_PTR(f) will already be - * null-terminated for us. - */ - f = rb_str_new(NULL, HTTP_PREFIX_LEN + flen); - memcpy(RSTRING_PTR(f), HTTP_PREFIX, HTTP_PREFIX_LEN); - memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen); - assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0'); /* paranoia */ - /* fprintf(stderr, "UNKNOWN HEADER <%s>\n", RSTRING_PTR(f)); */ + VALIDATE_MAX_LENGTH(flen, FIELD_NAME); + f = uncommon_field(field, flen); } else if (f == g_http_host && rb_hash_aref(req, f) != Qnil) { return; } |