Rewrite
在 lighttpd 中重寫位置響應標頭
我有一個 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); } } }