summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--src/connections.c8
-rw-r--r--src/request.c47
-rwxr-xr-xtests/request.t40
4 files changed, 83 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index fdb14636..acee2091 100644
--- a/NEWS
+++ b/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
diff --git a/src/connections.c b/src/connections.c
index 4322a020..cdb8c942 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -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;
diff --git a/src/request.c b/src/request.c
index 09357258..5d561ee0 100644
--- a/src/request.c
+++ b/src/request.c
@@ -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;
diff --git a/tests/request.t b/tests/request.t
index 40490131..be1f5d8f 100755
--- a/tests/request.t
+++ b/tests/request.t
@@ -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");