Rewrite

在 lighttpd 中重寫位置響應標頭

  • August 14, 2015

我有一個 lighttpd 1.4.35 實例偵聽 https 流量並將其反向代理到後端伺服器。IE,

                  .----------.            .----------.
client ---https--> | lighttpd | ---http--> | back-end |
      <--https--- |          | <--http--- | server   |
                  `----------'            `----------'

當我向代理頁面(通過 https)進行 HTTP 發佈時,後端伺服器返回 Location 標頭,http而不是https.

Location:  http://lighttpd_url/some_page.htm

有沒有辦法 lighttpd 可以重寫位置標頭中的 URL?我在 lighttpd 1.5.x 中看到,proxy-core 有一個rewrite-response指令,我想這就是它的樣子:

proxy-core.rewrite-response = (
     "Location" => ( "^http://xyz/(.*)" => "https://xyz/$1" ),
   )

但是如何Location在 lighttpd 1.4.x 中重寫標題?

從 1.4.35 開始,mod_proxy 不允許您修改響應標頭。但我確實需要將Location響應標頭從 http 更改為 https 的簡單功能,因此我將其破解為 mod_proxy.c。

這是更新檔,以防它對其他人有用。應用此更新檔,然後從原始碼重建和安裝後,您可以添加proxy.force_https_location = 1到配置文件以全域啟用該功能。

--- src/mod_proxy.c-orig    2014-06-26 14:33:50.000000000 -0700
+++ src/mod_proxy.c 2014-06-26 16:08:11.000000000 -0700
@@ -64,6 +64,7 @@
typedef struct {
   array *extensions;
   unsigned short debug;
+   unsigned short force_https_location;

   proxy_balance_t balance;
} plugin_config;
@@ -191,6 +192,7 @@
       { "proxy.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
       { "proxy.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
       { "proxy.balance",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 2 */
+       { "proxy.force_https_location", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },      /* 3 */
       { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
   };

@@ -203,10 +205,12 @@
       s = malloc(sizeof(plugin_config));
       s->extensions    = array_init();
       s->debug         = 0;
+       s->force_https_location = 0;

       cv[0].destination = s->extensions;
       cv[1].destination = &(s->debug);
       cv[2].destination = p->balance_buf;
+       cv[3].destination = &(s->force_https_location);

       buffer_reset(p->balance_buf);

@@ -568,10 +572,13 @@
       int key_len;
       data_string *ds;
       int copy_header;
+       int is_location_header;

       ns[0] = '\0';
       ns[1] = '\0';

+       is_location_header = 0;
+
       if (-1 == http_response_status) {
           /* The first line of a Response message is the Status-Line */

@@ -614,6 +621,7 @@
           if (0 == strncasecmp(key, "Location", key_len)) {
               con->parsed_response |= HTTP_LOCATION;
           }
+           is_location_header = 1;
           break;
       case 10:
           if (0 == strncasecmp(key, "Connection", key_len)) {
@@ -635,7 +643,26 @@
               ds = data_response_init();
           }
           buffer_copy_string_len(ds->key, key, key_len);
-           buffer_copy_string(ds->value, value);
+
+           if (is_location_header && p->conf.force_https_location) {
+               const unsigned int http_prefix_len = 7; /* strlen("http://") */
+
+               if (0 == strncasecmp(value, "http://", http_prefix_len)) {
+                   buffer_copy_string(ds->value, "https://");
+                   buffer_append_string(ds->value, value + http_prefix_len);
+
+                   if (p->conf.debug) {
+                       log_error_write(srv, __FILE__, __LINE__, "sb", "forced Location to https: ", ds->value);
+                   }
+               }
+               else {
+                   buffer_copy_string(ds->value, value);
+               }
+           }
+           else
+           {
+               buffer_copy_string(ds->value, value);
+           }

           array_insert_unique(con->response.headers, (data_unset *)ds);
       }
@@ -873,6 +897,7 @@
   PATCH(extensions);
   PATCH(debug);
   PATCH(balance);
+   PATCH(force_https_location);

   /* skip the first, the global context */
   for (i = 1; i < srv->config_context->used; i++) {
@@ -892,6 +917,8 @@
               PATCH(debug);
           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) {
               PATCH(balance);
+           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.force_https_location"))) {
+               PATCH(force_https_location);
           }
       }
   }

引用自:https://serverfault.com/questions/608257