The last instance of the date header is used.
/* 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;
/* 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
},
.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,
}
};
"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
};
}
};
+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 =
"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)
}
};
"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
}
};