about summary refs log tree commit homepage
path: root/ext
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-04-08 17:42:23 -0700
committerEric Wong <normalperson@yhbt.net>2009-04-08 17:42:23 -0700
commite26ebc985b882c38da50fb0104791a5f2c0f8522 (patch)
treeaed3ecdde023b3809c7ee9de6c8e8ed63fe1f8b0 /ext
parent9625ad39b73d3d1443ff097e9113d1ec9c9d5f00 (diff)
downloadunicorn-e26ebc985b882c38da50fb0104791a5f2c0f8522.tar.gz
Pass "https" to "rack.url_scheme" if the X-Forwarded-Proto
header matches "https".  X-Forwarded-Proto is a semi-standard
header that Ruby frameworks seem to respect; so we use that.

We won't support ENV['HTTPS'] since that can only be set at
start time and some app servers supporting https also support
http.

Currently, "rack.url_scheme" only allows "http" and "https",
so we won't set anything else to avoid breaking Rack::Lint.
Diffstat (limited to 'ext')
-rw-r--r--ext/unicorn/http11/http11.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/ext/unicorn/http11/http11.c b/ext/unicorn/http11/http11.c
index 995bf2a..a262d18 100644
--- a/ext/unicorn/http11/http11.c
+++ b/ext/unicorn/http11/http11.c
@@ -24,6 +24,7 @@ static VALUE sym_http_body;
 #define HTTP_PREFIX "HTTP_"
 #define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
 
+static VALUE global_rack_url_scheme;
 static VALUE global_request_method;
 static VALUE global_request_uri;
 static VALUE global_fragment;
@@ -37,6 +38,7 @@ static VALUE global_server_port;
 static VALUE global_server_protocol;
 static VALUE global_server_protocol_value;
 static VALUE global_http_host;
+static VALUE global_http_x_forwarded_proto;
 static VALUE global_port_80;
 static VALUE global_localhost;
 
@@ -106,6 +108,7 @@ static struct common_field common_http_fields[] = {
         f("USER_AGENT"),
         f("VIA"),
         f("X_FORWARDED_FOR"), /* common for proxies */
+        f("X_FORWARDED_PROTO"), /* common for proxies */
         f("X_REAL_IP"), /* common for proxies */
         f("WARNING")
 # undef f
@@ -248,6 +251,17 @@ static void header_done(void *data, const char *at, size_t length)
   VALUE temp = Qnil;
   char *colon = NULL;
 
+  /* set rack.url_scheme to "https" or "http" */
+  if ((temp = rb_hash_aref(req, global_http_x_forwarded_proto)) != Qnil) {
+    if (strcmp("https", RSTRING_PTR(temp)))
+      temp = rb_str_new("http", 4);
+    /* we leave temp alone if it's "https" */
+  } else {
+    temp = rb_str_new("http", 4);
+  }
+  rb_hash_aset(req, global_rack_url_scheme, temp);
+
+  /* set the SERVER_NAME and SERVER_PORT variables */
   if((temp = rb_hash_aref(req, global_http_host)) != Qnil) {
     colon = memchr(RSTRING_PTR(temp), ':', RSTRING_LEN(temp));
     if(colon != NULL) {
@@ -372,6 +386,7 @@ void Init_http11()
 
   mUnicorn = rb_define_module("Unicorn");
 
+  DEF_GLOBAL(rack_url_scheme, "rack.url_scheme");
   DEF_GLOBAL(request_method, "REQUEST_METHOD");
   DEF_GLOBAL(request_uri, "REQUEST_URI");
   DEF_GLOBAL(fragment, "FRAGMENT");
@@ -385,6 +400,7 @@ void Init_http11()
   DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
   DEF_GLOBAL(server_protocol_value, "HTTP/1.1");
   DEF_GLOBAL(http_host, "HTTP_HOST");
+  DEF_GLOBAL(http_x_forwarded_proto, "HTTP_X_FORWARDED_PROTO");
   DEF_GLOBAL(port_80, "80");
   DEF_GLOBAL(localhost, "localhost");