fixed #25 by setting all duplicates to 400
git-svn-id: svn://svn.lighttpd.net/lighttpd/trunk@60 152afb58-edef-0310-8abb-c4023f1b3aa9svn/tags/release-1.3.12
parent
a6dfdad19f
commit
0f779ce2f9
|
@ -380,6 +380,7 @@ AC_CONFIG_FILES([Makefile debian/Makefile src/Makefile doc/Makefile tests/Makefi
|
|||
tests/docroot/www/Makefile \
|
||||
tests/docroot/www/go/Makefile \
|
||||
tests/docroot/www/indexfile/Makefile \
|
||||
tests/docroot/www/expire/Makefile \
|
||||
lighttpd.spec distribute.sh cygwin/Makefile cygwin/lighttpd.README
|
||||
openwrt/Makefile openwrt/control openwrt/lighttpd.mk])
|
||||
AC_OUTPUT
|
||||
|
|
112
src/request.c
112
src/request.c
|
@ -732,6 +732,20 @@ int http_request_parse(server *srv, connection *con) {
|
|||
unsigned long int r;
|
||||
size_t j;
|
||||
|
||||
if (con_length_set) {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"duplicate Content-Length-header -> 400");
|
||||
if (srv->srvconf.log_request_header_on_error) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "Sb",
|
||||
"request-header:\n",
|
||||
con->request.request);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ds->value->used == 0) SEGFAULT();
|
||||
|
||||
for (j = 0; j < ds->value->used - 1; j++) {
|
||||
|
@ -764,7 +778,22 @@ 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("Content-Type")))) {
|
||||
con->request.http_content_type = ds->value->ptr;
|
||||
/* if dup, only the first one will survive */
|
||||
if (!con->request.http_content_type) {
|
||||
con->request.http_content_type = ds->value->ptr;
|
||||
} else {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"duplicate Content-Type-header -> 400");
|
||||
if (srv->srvconf.log_request_header_on_error) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "Sb",
|
||||
"request-header:\n",
|
||||
con->request.request);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
|
||||
/* HTTP 2616 8.2.3
|
||||
* Expect: 100-continue
|
||||
|
@ -781,18 +810,77 @@ int http_request_parse(server *srv, connection *con) {
|
|||
array_insert_unique(con->request.headers, (data_unset *)ds);
|
||||
return 0;
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
|
||||
con->request.http_host = ds->value;
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
|
||||
con->request.http_if_modified_since = ds->value->ptr;
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
|
||||
con->request.http_if_none_match = ds->value->ptr;
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
|
||||
/* bytes=.*-.* */
|
||||
|
||||
if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) &&
|
||||
NULL != strchr(ds->value->ptr+6, '-')) {
|
||||
if (!con->request.http_host) {
|
||||
con->request.http_host = ds->value;
|
||||
} else {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
||||
con->request.http_range = ds->value->ptr + 6;
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"duplicate Host-header -> 400");
|
||||
if (srv->srvconf.log_request_header_on_error) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "Sb",
|
||||
"request-header:\n",
|
||||
con->request.request);
|
||||
}
|
||||
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 */
|
||||
if (!con->request.http_if_modified_since) {
|
||||
con->request.http_if_modified_since = ds->value->ptr;
|
||||
} else {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"duplicate If-Modified-Since header -> 400");
|
||||
if (srv->srvconf.log_request_header_on_error) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "Sb",
|
||||
"request-header:\n",
|
||||
con->request.request);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
|
||||
/* if dup, only the first one will survive */
|
||||
if (!con->request.http_if_none_match) {
|
||||
con->request.http_if_none_match = ds->value->ptr;
|
||||
} else {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"duplicate If-None-Match-header -> 400");
|
||||
if (srv->srvconf.log_request_header_on_error) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "Sb",
|
||||
"request-header:\n",
|
||||
con->request.request);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
|
||||
if (!con->request.http_range) {
|
||||
/* bytes=.*-.* */
|
||||
|
||||
if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) &&
|
||||
NULL != strchr(ds->value->ptr+6, '-')) {
|
||||
|
||||
/* if dup, only the first one will survive */
|
||||
con->request.http_range = ds->value->ptr + 6;
|
||||
}
|
||||
} else {
|
||||
con->http_status = 400;
|
||||
con->keep_alive = 0;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"duplicate Host-header -> 400");
|
||||
if (srv->srvconf.log_request_header_on_error) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "Sb",
|
||||
"request-header:\n",
|
||||
con->request.request);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use Test::More tests => 114;
|
||||
use Test::More tests => 120;
|
||||
|
||||
|
||||
my $testname;
|
||||
|
@ -510,6 +510,12 @@ EOF
|
|||
ok(handle_http == 0, 'Host missing');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print "\nLow-Level Response-Header Parsing - Content-Length:\n";
|
||||
@request = ( <<EOF
|
||||
GET /12345.html HTTP/1.0
|
||||
|
@ -528,6 +534,14 @@ EOF
|
|||
ok(handle_http == 0, 'Content-Length for text/plain');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print "\nLow-Level Response-Header Parsing - Location:\n";
|
||||
@request = ( <<EOF
|
||||
GET /dummydir HTTP/1.0
|
||||
|
@ -544,6 +558,16 @@ EOF
|
|||
ok(handle_http == 0, 'internal redirect in directory + querystring');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print "\nBasic Request-Handling\n";
|
||||
@request = ( <<EOF
|
||||
GET /foobar HTTP/1.0
|
||||
|
@ -764,6 +788,62 @@ EOF
|
|||
ok(handle_http == 0, 'larger headers');
|
||||
|
||||
|
||||
@request = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Host: www.example.org
|
||||
Host: 123.example.org
|
||||
EOF
|
||||
);
|
||||
@response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } );
|
||||
ok(handle_http == 0, 'Duplicate Host headers, Bug #25');
|
||||
|
||||
|
||||
@request = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Content-Length: 5
|
||||
Content-Length: 4
|
||||
EOF
|
||||
);
|
||||
@response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } );
|
||||
ok(handle_http == 0, 'Duplicate Content-Length headers');
|
||||
|
||||
@request = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Content-Type: 5
|
||||
Content-Type: 4
|
||||
EOF
|
||||
);
|
||||
@response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } );
|
||||
ok(handle_http == 0, 'Duplicate Content-Type headers');
|
||||
|
||||
@request = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
Range: bytes=5-6
|
||||
Range: bytes=5-9
|
||||
EOF
|
||||
);
|
||||
@response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } );
|
||||
ok(handle_http == 0, 'Duplicate Range headers');
|
||||
|
||||
@request = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
If-None-Match: 5
|
||||
If-None-Match: 4
|
||||
EOF
|
||||
);
|
||||
@response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } );
|
||||
ok(handle_http == 0, 'Duplicate If-None-Match headers');
|
||||
|
||||
@request = ( <<EOF
|
||||
GET / HTTP/1.0
|
||||
If-Modified-Since: 5
|
||||
If-Modified-Since: 4
|
||||
EOF
|
||||
);
|
||||
@response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } );
|
||||
ok(handle_http == 0, 'Duplicate If-Modified-Since headers');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue