A partir de 1.4.35, o mod_proxy não permite modificar cabeçalhos de resposta. Mas eu realmente precisava da funcionalidade simples de alterar Location
cabeçalhos de resposta de http para https, então eu o criei no mod_proxy.c.
Aqui está o patch, caso seja útil para qualquer outra pessoa. Depois de aplicar esse patch e, em seguida, recriar e instalar a partir do código-fonte, você pode adicionar proxy.force_https_location = 1
ao seu arquivo de configuração para ativar o recurso globalmente.
--- 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] = '--- 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] = '%pre%';
ns[1] = '%pre%';
+ 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);
}
}
}
';
ns[1] = '%pre%';
+ 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);
}
}
}