about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-08-02 13:58:34 -0700
committerEric Wong <normalperson@yhbt.net>2009-08-09 01:24:56 -0700
commitabb47b5a6cae1a814f56893df1f2572203fd8faa (patch)
tree007826593aee09e7c39b96ebea71297bfeca4139
parent4dc2a9e95d115547b7c2680f198293d6e25658b3 (diff)
downloadunicorn-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.
-rw-r--r--ext/unicorn_http/common_field_optimization.h13
-rw-r--r--ext/unicorn_http/unicorn_http.rl22
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;
   }