1 #ifndef common_field_optimization
2 #define common_field_optimization
12 * A list of common HTTP headers we expect to receive.
13 * This allows us to avoid repeatedly creating identical string
14 * objects to be used with rb_hash_aset().
16 static struct common_field common_http_fields
[] = {
17 # define f(N) { (sizeof(N) - 1), N, Qnil }
26 f("CONTENT_ENCODING"),
35 f("IF_MODIFIED_SINCE"),
38 f("IF_UNMODIFIED_SINCE"),
39 f("KEEP_ALIVE"), /* Firefox sends this */
42 f("PROXY_AUTHORIZATION"),
47 f("TRANSFER_ENCODING"),
51 f("X_FORWARDED_FOR"), /* common for proxies */
52 f("X_FORWARDED_PROTO"), /* common for proxies */
53 f("X_REAL_IP"), /* common for proxies */
58 #define HTTP_PREFIX "HTTP_"
59 #define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
61 /* this function is not performance-critical, called only at load time */
62 static void init_common_fields(void)
65 struct common_field
*cf
= common_http_fields
;
67 memcpy(tmp
, HTTP_PREFIX
, HTTP_PREFIX_LEN
);
69 for(i
= 0; i
< ARRAY_SIZE(common_http_fields
); cf
++, i
++) {
70 /* Rack doesn't like certain headers prefixed with "HTTP_" */
71 if (!strcmp("CONTENT_LENGTH", cf
->name
) ||
72 !strcmp("CONTENT_TYPE", cf
->name
)) {
73 cf
->value
= rb_str_new(cf
->name
, cf
->len
);
75 memcpy(tmp
+ HTTP_PREFIX_LEN
, cf
->name
, cf
->len
+ 1);
76 cf
->value
= rb_str_new(tmp
, HTTP_PREFIX_LEN
+ cf
->len
);
78 cf
->value
= rb_obj_freeze(cf
->value
);
79 rb_global_variable(&cf
->value
);
83 /* this function is called for every header set */
84 static VALUE
find_common_field_value(const char *field
, size_t flen
)
87 struct common_field
*cf
= common_http_fields
;
89 for(i
= 0; i
< ARRAY_SIZE(common_http_fields
); i
++, cf
++) {
90 if (cf
->len
== flen
&& !memcmp(cf
->name
, field
, flen
))
96 #endif /* common_field_optimization_h */