在lighttpd中重写位置响应头

在lighttpd中重写位置响应头

我有一个 lighttpd 1.4.35 实例,用于监听 https 流量并将其反向代理到后端服务器。例如,

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

当我向代理页面(通过 https)执行 HTTP 发布时,后端服务器返回带有http而不是 的位置标头https

Location:  http://lighttpd_url/some_page.htm

lighttpd 有没有办法重写 location 标头中的 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

从 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);
            }
        }
    }

相关内容