From 17d0c36eed57e7a3b1c1cbf3da7ae5dc158edbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sun, 11 Oct 2009 18:31:25 +0000 Subject: [PATCH] Read hostname from absolute uris in the request line (fixes #1937) git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2631 152afb58-edef-0310-8abb-c4023f1b3aa9 --- src/request.c | 30 ++++++++++++++++++++++++++++-- tests/mod-fastcgi.t | 12 ++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/request.c b/src/request.c index 2d080858..5879efef 100644 --- a/src/request.c +++ b/src/request.c @@ -282,6 +282,8 @@ int http_request_parse(server *srv, connection *con) { char *uri = NULL, *proto = NULL, *method = NULL, con_length_set; int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding; char *value = NULL, *key = NULL; + char *reqline_host = NULL; + int reqline_hostlen = 0; enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET; @@ -451,7 +453,14 @@ int http_request_parse(server *srv, connection *con) { if (0 == strncmp(uri, "http://", 7) && NULL != (nuri = strchr(uri + 7, '/'))) { - /* ignore the host-part */ + reqline_host = uri + 7; + reqline_hostlen = nuri - reqline_host; + + buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1); + } else if (0 == strncmp(uri, "https://", 8) && + NULL != (nuri = strchr(uri + 8, '/'))) { + reqline_host = uri + 8; + reqline_hostlen = nuri - reqline_host; buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1); } else { @@ -549,6 +558,19 @@ int http_request_parse(server *srv, connection *con) { return 0; } + if (reqline_host) { + /* Insert as host header */ + data_string *ds; + + if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { + ds = data_string_init(); + } + + buffer_copy_string_len(ds->key, CONST_STR_LEN("Host")); + buffer_copy_string_len(ds->value, reqline_host, reqline_hostlen); + array_insert_unique(con->request.headers, (data_unset *)ds); + con->request.http_host = ds->value; + } for (; i < con->parse_request->used && !done; i++) { char *cur = con->parse_request->ptr + i; @@ -909,7 +931,11 @@ int http_request_parse(server *srv, connection *con) { return 0; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) { - if (!con->request.http_host) { + if (reqline_host) { + /* ignore all host: headers as we got the host in the request line */ + ds->free((data_unset*) ds); + ds = NULL; + } else if (!con->request.http_host) { con->request.http_host = ds->value; } else { con->http_status = 400; diff --git a/tests/mod-fastcgi.t b/tests/mod-fastcgi.t index b5f74d64..880344f2 100755 --- a/tests/mod-fastcgi.t +++ b/tests/mod-fastcgi.t @@ -7,7 +7,7 @@ BEGIN { } use strict; -use Test::More tests => 53; +use Test::More tests => 54; use LightyTest; my $tf = LightyTest->new(); @@ -25,7 +25,7 @@ SKIP: { } SKIP: { - skip "no PHP running on port 1026", 30 unless $tf->listening_on(1026); + skip "no PHP running on port 1026", 31 unless $tf->listening_on(1026); ok($tf->start_proc == 0, "Starting lighttpd") or goto cleanup; @@ -188,6 +188,14 @@ EOF $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'zzz.example.org' } ]; ok($tf->handle_http($t) == 0, 'FastCGI + Host'); + $t->{REQUEST} = ( <{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'zzz.example.org' } ]; + ok($tf->handle_http($t) == 0, 'SERVER_NAME (absolute url in request line)'); + ok($tf->stop_proc == 0, "Stopping lighttpd"); $tf->{CONFIGFILE} = 'bug-06.conf';