Browse Source

- don't duplicate Server and Date Header

- strip Connection header from backend response if we are proxy
- trust Connection-Length if we are proxy


git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@862 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.8
Jan Kneschke 16 years ago
parent
commit
93693b11e0
  1. 3
      src/connections.c
  2. 64
      src/mod_proxy.c
  3. 52
      src/response.c

3
src/connections.c

@ -473,7 +473,8 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
if (con->file_finished) {
/* we have all the content and chunked encoding is not used, set a content-length */
if ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) {
if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) &&
(con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) {
buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->write_queue));
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));

64
src/mod_proxy.c

@ -396,12 +396,36 @@ static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
return 0;
}
void proxy_set_header(connection *con, const char *key, const char *value) {
data_string *ds_dst;
if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
ds_dst = data_string_init();
}
buffer_copy_string(ds_dst->key, key);
buffer_copy_string(ds_dst->value, value);
array_insert_unique(con->request.headers, (data_unset *)ds_dst);
}
void proxy_append_header(connection *con, const char *key, const char *value) {
data_string *ds_dst;
if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
ds_dst = data_string_init();
}
buffer_copy_string(ds_dst->key, key);
buffer_append_string(ds_dst->value, value);
array_insert_unique(con->request.headers, (data_unset *)ds_dst);
}
static int proxy_create_env(server *srv, handler_ctx *hctx) {
size_t i;
connection *con = hctx->remote_conn;
buffer *b;
data_string *ds_dst;
/* build header */
@ -414,15 +438,10 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
buffer_append_string_buffer(b, con->request.uri);
BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n");
if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
ds_dst = data_string_init();
}
BUFFER_COPY_STRING_CONST(ds_dst->key, "X-Forwarded-For");
buffer_append_string(ds_dst->value, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
array_insert_unique(con->request.headers, (data_unset *)ds_dst);
proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
proxy_set_header(con, "X-Host", con->request.http_host->ptr);
proxy_set_header(con, "X-Forwarded-Proto", con->conf.is_ssl ? "https" : "http");
/* request header */
for (i = 0; i < con->request.headers->used; i++) {
data_string *ds;
@ -430,7 +449,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
ds = (data_string *)con->request.headers->data[i];
if (ds->value->used && ds->key->used) {
if (0 == strcmp(ds->key->ptr, "Connection")) continue;
if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
buffer_append_string_buffer(b, ds->key);
BUFFER_APPEND_STRING_CONST(b, ": ");
@ -522,6 +541,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
char *key, *value;
int key_len;
data_string *ds;
int copy_header;
ns[0] = '\0';
ns[1] = '\0';
@ -556,14 +576,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
/* strip WS */
while (*value == ' ' || *value == '\t') value++;
if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
ds = data_response_init();
}
buffer_copy_string_len(ds->key, key, key_len);
buffer_copy_string(ds->value, value);
array_insert_unique(con->response.headers, (data_unset *)ds);
copy_header = 1;
switch(key_len) {
case 4:
@ -578,8 +591,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
break;
case 10:
if (0 == strncasecmp(key, "Connection", key_len)) {
con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
con->parsed_response |= HTTP_CONNECTION;
copy_header = 0;
}
break;
case 14:
@ -591,6 +603,16 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
default:
break;
}
if (copy_header) {
if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
ds = data_response_init();
}
buffer_copy_string_len(ds->key, key, key_len);
buffer_copy_string(ds->value, value);
array_insert_unique(con->response.headers, (data_unset *)ds);
}
}
return 0;

52
src/response.c

@ -28,6 +28,8 @@
int http_response_write_header(server *srv, connection *con) {
buffer *b;
size_t i;
int have_date = 0;
int have_server = 0;
b = chunkqueue_get_prepend_buffer(con->write_queue);
@ -49,22 +51,6 @@ int http_response_write_header(server *srv, connection *con) {
BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked");
}
/* HTTP/1.1 requires a Date: header */
BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
/* cache the generated timestamp */
if (srv->cur_ts != srv->last_generated_date_ts) {
buffer_prepare_copy(srv->ts_date_str, 255);
strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
"%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
srv->last_generated_date_ts = srv->cur_ts;
}
buffer_append_string_buffer(b, srv->ts_date_str);
/* add all headers */
for (i = 0; i < con->response.headers->used; i++) {
@ -74,6 +60,9 @@ int http_response_write_header(server *srv, connection *con) {
if (ds->value->used && ds->key->used &&
0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) {
if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1;
if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1;
BUFFER_APPEND_STRING_CONST(b, "\r\n");
buffer_append_string_buffer(b, ds->key);
BUFFER_APPEND_STRING_CONST(b, ": ");
@ -85,11 +74,32 @@ int http_response_write_header(server *srv, connection *con) {
}
}
if (buffer_is_empty(con->conf.server_tag)) {
BUFFER_APPEND_STRING_CONST(b, "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION);
} else {
BUFFER_APPEND_STRING_CONST(b, "\r\nServer: ");
buffer_append_string_buffer(b, con->conf.server_tag);
if (!have_date) {
/* HTTP/1.1 requires a Date: header */
BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
/* cache the generated timestamp */
if (srv->cur_ts != srv->last_generated_date_ts) {
buffer_prepare_copy(srv->ts_date_str, 255);
strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
"%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
srv->last_generated_date_ts = srv->cur_ts;
}
buffer_append_string_buffer(b, srv->ts_date_str);
}
if (!have_server) {
if (buffer_is_empty(con->conf.server_tag)) {
BUFFER_APPEND_STRING_CONST(b, "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION);
} else {
BUFFER_APPEND_STRING_CONST(b, "\r\nServer: ");
buffer_append_string_buffer(b, con->conf.server_tag);
}
}
BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n");

Loading…
Cancel
Save