changeset 22390:110cf7691bba

lib-http: message parser: Allow duplicate date header if HTTP_MESSAGE_PARSE_FLAG_STRICT is not set. The last instance of the date header is used.
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Tue, 11 Jul 2017 14:34:06 +0200
parents 36a38929734d
children e8bf64a8bb8f
files src/lib-http/http-message-parser.c src/lib-http/test-http-request-parser.c src/lib-http/test-http-response-parser.c
diffstat 3 files changed, 64 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-message-parser.c	Tue Jul 11 14:18:47 2017 +0200
+++ b/src/lib-http/http-message-parser.c	Tue Jul 11 14:34:06 2017 +0200
@@ -193,6 +193,8 @@
 		/* Content-Length: */
 		if (strcasecmp(name, "Content-Length") == 0) {
 			if (parser->msg.have_content_length) {
+				/* There is no acceptable way to allow duplicates for this
+				   header. */
 				parser->error = "Duplicate Content-Length header";
 				parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
 				return -1;
@@ -215,9 +217,12 @@
 		/* Date: */
 		if (strcasecmp(name, "Date") == 0) {
 			if (parser->msg.date != (time_t)-1) {
-				parser->error = "Duplicate Date header";
-				parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
-				return -1;
+				if ((parser->flags & HTTP_MESSAGE_PARSE_FLAG_STRICT) != 0) {
+					parser->error = "Duplicate Date header";
+					parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
+					return -1;
+				}
+				/* Allow the duplicate; last instance is used */
 			}
 
 			/* RFC 7231, Section 7.1.1.2: Date
--- a/src/lib-http/test-http-request-parser.c	Tue Jul 11 14:18:47 2017 +0200
+++ b/src/lib-http/test-http-request-parser.c	Tue Jul 11 14:34:06 2017 +0200
@@ -137,6 +137,19 @@
 		},
 		.version_major = 1, .version_minor = 1,
 		.expect_100_continue = TRUE
+	},{ .request =
+			"GET / HTTP/1.1\r\n"
+			"Date: Sun, 07 Oct 2012 19:52:03 GMT\r\n"
+			"Host: example.com\r\n"
+			"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
+			"\r\n",
+		.method = "GET",
+		.target_raw = "/",
+		.target = {
+			.format = HTTP_REQUEST_TARGET_FORMAT_ORIGIN,
+			.url = { .host_name = "example.com" }
+		},
+		.version_major = 1, .version_minor = 1,
 	}
 };
 
@@ -354,6 +367,15 @@
 			"Transfer-Encoding: cuneiform, chunked\r\n"
 			"\r\n",
 		.error_code = HTTP_REQUEST_PARSE_ERROR_NOT_IMPLEMENTED
+	},{
+		.request =
+			"GET / HTTP/1.1\r\n"
+			"Date: Sun, 07 Oct 2012 19:52:03 GMT\r\n"
+			"Host: example.com\r\n"
+			"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
+			"\r\n",
+		.flags = HTTP_REQUEST_PARSE_FLAG_STRICT,
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BROKEN_REQUEST
 	}
 	// FIXME: test request limits
 };
--- a/src/lib-http/test-http-response-parser.c	Tue Jul 11 14:18:47 2017 +0200
+++ b/src/lib-http/test-http-response-parser.c	Tue Jul 11 14:34:06 2017 +0200
@@ -53,6 +53,13 @@
 	}
 };
 
+static const struct valid_parse_test_response valid_responses4[] = {
+	{
+		.status = 200,
+		.payload = "Duplicate headers"
+	}
+};
+
 static const struct valid_parse_test
 valid_response_parse_tests[] = {
 	{ .input =
@@ -114,6 +121,20 @@
 			"Frop!",
 		.responses = valid_responses3,
 		.responses_count = N_ELEMENTS(valid_responses3)
+	},{
+		.input =
+			"HTTP/1.1 200 OK\r\n"
+			"Date: Sun, 07 Oct 2012 19:52:03 GMT\r\n"
+			"Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14\r\n"
+			"Content-Length: 17\r\n"
+			"Keep-Alive: timeout=15, max=99\r\n"
+			"Connection: Keep-Alive\r\n"
+			"Content-Type: text/html; charset=iso-8859-1\r\n"
+			"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
+			"\r\n"
+			"Duplicate headers",
+		.responses = valid_responses4,
+		.responses_count = N_ELEMENTS(valid_responses4)
 	}
 };
 
@@ -239,6 +260,19 @@
 			"HTTP/1.1 302 Found\n\r"
 			"Location: http://www.example.nl/\n\r"
 			"Cache-Control: private\n\r"
+	},{
+		.input =
+			"HTTP/1.1 200 OK\r\n"
+			"Date: Sun, 07 Oct 2012 19:52:03 GMT\r\n"
+			"Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14\r\n"
+			"Content-Length: 17\r\n"
+			"Keep-Alive: timeout=15, max=99\r\n"
+			"Connection: Keep-Alive\r\n"
+			"Content-Type: text/html; charset=iso-8859-1\r\n"
+			"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
+			"\r\n"
+			"Duplicate headers",
+		.flags = HTTP_RESPONSE_PARSE_FLAG_STRICT
 	}
 };