diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/connections.c | 18 | ||||
-rwxr-xr-x | tests/LightyTest.pm | 32 | ||||
-rwxr-xr-x | tests/request.t | 10 |
4 files changed, 46 insertions, 15 deletions
@@ -18,6 +18,7 @@ NEWS * fixed counter overrun in ?auto in mod_status (#909) * fixed too aggresive caching of nested conditionals (#41) * fixed possible overflow in unix-socket path checks on BSD (#713) + * fixed extra Content-Length header on 1xx, 204 and 304 (#1002) * removed config-check if passwd files exist (#1188) diff --git a/src/connections.c b/src/connections.c index eb7f057f..62b4d5e1 100644 --- a/src/connections.c +++ b/src/connections.c @@ -505,6 +505,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) { case 206: /* write_queue is already prepared */ break; + case 204: case 205: /* class: header only */ case 304: default: @@ -524,10 +525,19 @@ static int connection_handle_write_prepare(server *srv, connection *con) { (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) { off_t qlen = chunkqueue_length(con->write_queue); - /* if we have no content for a GET/PORT request, send Content-Length: 0 - * if it is a HEAD request, don't generate a Content-Length as - * the backend might have already cut it off */ - if (qlen > 0 || con->request.http_method != HTTP_METHOD_HEAD) { + /** + * The Content-Length header only can be sent if we have content: + * - HEAD doesn't have a content-body (but have a content-length) + * - 1xx, 204 and 304 don't have a content-body (RFC 2616 Section 4.3) + * + * Otherwise generate a Content-Length header as chunked encoding is not + * available + */ + if ((con->http_status >= 100 && con->http_status < 200) || + con->http_status == 204 || + con->http_status == 304) { + /* no Content-Body, no Content-Length */ + } else if (qlen > 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)); diff --git a/tests/LightyTest.pm b/tests/LightyTest.pm index 0426d45e..33eca612 100755 --- a/tests/LightyTest.pm +++ b/tests/LightyTest.pm @@ -235,9 +235,7 @@ sub handle_http { diag(sprintf("body failed: expected '%s', got '%s'\n", $href->{'HTTP-Content'}, $resp_body)); return -1; } - } - - if (defined $href->{'-HTTP-Content'}) { + } elsif (defined $href->{'-HTTP-Content'}) { if (defined $resp_body && $resp_body ne '') { diag(sprintf("body failed: expected empty body, got '%s'\n", $resp_body)); return -1; @@ -245,6 +243,7 @@ sub handle_http { } foreach (keys %{ $href }) { + ## filter special keys next if $_ eq 'HTTP-Protocol'; next if $_ eq 'HTTP-Status'; next if $_ eq 'HTTP-Content'; @@ -252,20 +251,33 @@ sub handle_http { (my $k = $_) =~ tr/[A-Z]/[a-z]/; - my $no_val = 0; + my $verify_value = 1; + my $key_inverted = 0; if (substr($k, 0, 1) eq '+') { + ## the key has to exist, but the value is ignored $k = substr($k, 1); - $no_val = 1; - + $verify_value = 0; + } elsif (substr($k, 0, 1) eq '-') { + ## the key should NOT exist + $k = substr($k, 1); + $key_inverted = 1; + $verify_value = 0; ## skip the value check } - if (!defined $resp_hdr{$k}) { - diag(sprintf("required header '%s' is missing\n", $k)); - return -1; + if ($key_inverted) { + if (defined $resp_hdr{$k}) { + diag(sprintf("required header '%s' is missing\n", $k)); + return -1; + } + } else { + if (not defined $resp_hdr{$k}) { + diag(sprintf("required header '%s' is missing\n", $k)); + return -1; + } } - if ($no_val == 0) { + if ($verify_value) { if ($href->{$_} =~ /^\/(.+)\/$/) { if ($resp_hdr{$k} !~ /$1/) { diag(sprintf("response-header failed: expected '%s', got '%s', regex: %s\n", diff --git a/tests/request.t b/tests/request.t index cbc90e41..8ece7218 100755 --- a/tests/request.t +++ b/tests/request.t @@ -8,7 +8,7 @@ BEGIN { use strict; use IO::Socket; -use Test::More tests => 40; +use Test::More tests => 41; use LightyTest; my $tf = LightyTest->new(); @@ -381,5 +381,13 @@ EOF $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304, 'Content-Type' => 'text/html' } ]; ok($tf->handle_http($t) == 0, 'If-Modified-Since'); +$t->{REQUEST} = ( <<EOF +GET /index.html HTTP/1.0 +If-Modified-Since: Sun, 01 Jan 2100 00:00:02 GMT +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304, '-Content-Length' => '' } ]; +ok($tf->handle_http($t) == 0, 'Status 304 has no Content-Length (#1002)'); + ok($tf->stop_proc == 0, "Stopping lighttpd"); |