forbid Content-Length for GET, HEAD or OPTIONS requests
allow duplicate If-Modified-Since headers if they are equal git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@907 152afb58-edef-0310-8abb-c4023f1b3aa9
This commit is contained in:
parent
f3e3fc8007
commit
580823f791
5
NEWS
5
NEWS
|
@ -7,10 +7,15 @@ NEWS
|
|||
|
||||
* added server.core-files option (sandy <sandy@meebo.com>)
|
||||
* added docs for mod_status
|
||||
* added mod_evasive to limit the number of connections by IP (<w1zzard@techpowerup.com>)
|
||||
* added the power-magnet to mod_cml
|
||||
* added framework for internal statistics
|
||||
* fixed 100% cpu loops in mod_cgi ("sandy" <sjen@cs.stanford.edu>)
|
||||
* fixed handling for secure-download.timeout (jamis@37signals.com)
|
||||
* fixed IE bug in content-charset in the output of mod_dirlisting (sniper@php.net)
|
||||
* fixed typos and language in the docs (ryan-2005@ryandesign.com)
|
||||
* fixed assertion in mod_cgi on HEAD request is Content-Length (<sandy@meebo.com>)
|
||||
* fixed handling if equal but duplicate If-Modified-Since request headers
|
||||
|
||||
- 1.4.8 - 2005-11-23
|
||||
|
||||
|
|
|
@ -352,7 +352,13 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
|
|||
case HTTP_METHOD_PROPPATCH:
|
||||
break;
|
||||
case HTTP_METHOD_OPTIONS:
|
||||
if (con->uri.path->ptr[0] != '*') {
|
||||
/*
|
||||
* 400 is coming from the request-parser BEFORE uri.path is set
|
||||
* 403 is from the response handler when noone else catched it
|
||||
*
|
||||
* */
|
||||
if (con->uri.path->used &&
|
||||
con->uri.path->ptr[0] != '*') {
|
||||
response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
|
||||
|
||||
con->http_status = 200;
|
||||
|
|
|
@ -815,9 +815,14 @@ 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("If-Modified-Since")))) {
|
||||
/* if dup, only the first one will survive */
|
||||
/* Proxies sometimes send dup headers
|
||||
* if they are the same we ignore the second
|
||||
* if not, we raise an error */
|
||||
if (!con->request.http_if_modified_since) {
|
||||
con->request.http_if_modified_since = ds->value->ptr;
|
||||
} else if (0 == strcasecmp(con->request.http_if_modified_since,
|
||||
ds->value->ptr)) {
|
||||
/* ignore it if they are the same */
|
||||
} else {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
@ -963,22 +968,25 @@ int http_request_parse(server *srv, connection *con) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if we have read post data */
|
||||
if (con->request.http_method == HTTP_METHOD_POST
|
||||
|| (con->request.http_method != HTTP_METHOD_GET
|
||||
&& con->request.http_method != HTTP_METHOD_HEAD
|
||||
&& con->request.http_method != HTTP_METHOD_OPTIONS
|
||||
&& con_length_set)) {
|
||||
|
||||
#if 0
|
||||
if (con->request.http_content_type == NULL) {
|
||||
switch(con->request.http_method) {
|
||||
case HTTP_METHOD_GET:
|
||||
case HTTP_METHOD_HEAD:
|
||||
case HTTP_METHOD_OPTIONS:
|
||||
/* content-length is forbidden for those */
|
||||
if (con_length_set) {
|
||||
/* content-length is missing */
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"Content-Length request, but content-type not set");
|
||||
"GET/HEAD/OPTIONS with content-length -> 400");
|
||||
con->keep_alive = 0;
|
||||
|
||||
con->http_status = 400;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (con_length_set == 0) {
|
||||
break;
|
||||
case HTTP_METHOD_POST:
|
||||
/* content-length is required for them */
|
||||
if (!con_length_set) {
|
||||
/* content-length is missing */
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"POST-request, but content-length missing -> 411");
|
||||
|
@ -986,8 +994,17 @@ int http_request_parse(server *srv, connection *con) {
|
|||
|
||||
con->http_status = 411;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/* the may have a content-length */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* check if we have read post data */
|
||||
if (con_length_set) {
|
||||
/* don't handle more the SSIZE_MAX bytes in content-length */
|
||||
if (con->request.content_length > SSIZE_MAX) {
|
||||
con->http_status = 413;
|
||||
|
|
|
@ -8,7 +8,7 @@ BEGIN {
|
|||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use Test::More tests => 29;
|
||||
use Test::More tests => 33;
|
||||
use LightyTest;
|
||||
|
||||
my $tf = LightyTest->new();
|
||||
|
@ -300,7 +300,45 @@ EOF
|
|||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'GET, Range with range-requests-disabled');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Content-Length: 4
|
||||
|
||||
1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'GET with Content-Length');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
OPTIONS / HTTP/1.0
|
||||
Content-Length: 4
|
||||
|
||||
1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'OPTIONS with Content-Length');
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
HEAD / HTTP/1.0
|
||||
Content-Length: 4
|
||||
|
||||
1234
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
|
||||
ok($tf->handle_http($t) == 0, 'HEAD with Content-Length');
|
||||
|
||||
|
||||
$t->{REQUEST} = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
If-Modified-Since: Sun, 1970 Jan 01 00:00:01 GMT
|
||||
If-Modified-Since: Sun, 1970 Jan 01 00:00:01 GMT
|
||||
EOF
|
||||
);
|
||||
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
|
||||
ok($tf->handle_http($t) == 0, 'Duplicate If-Mod-Since, with equal timestamps');
|
||||
|
||||
ok($tf->stop_proc == 0, "Stopping lighttpd");
|
||||
|
||||
|
|
Loading…
Reference in New Issue