我有一个lighttpd 1.4.35的实例监听httpsstream量,并将其反向代理到后端服务器。 也就是说,
.----------. .----------. client ---https--> | lighttpd | ---http--> | back-end | <--https--- | | <--http--- | server | `----------' `----------'
当我通过https(通过https)对代理页面进行HTTP发布时,后端服务器正在使用http
而不是https
返回Location标头。
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" ), )
但是,我如何重写lighttpd 1.4.x中的Location
标题?
从1.4.35开始,mod_proxy不允许你修改响应头。 但是我真的需要将http响应头从http更改为https的简单function,所以我把它砍成了mod_proxy.c。
这里是补丁,以防其他人有用。 应用此修补程序,然后从源重build和安装后,可以将proxy.force_https_location = 1
添加到您的configuration文件以全局启用该function。
--- 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); } } }