dovecot-2.2: lib-http: Added more tests for the http_request_par...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 12 11:14:58 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/74bc909ba6a0
changeset: 16847:74bc909ba6a0
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sat Oct 12 10:52:35 2013 +0300
description:
lib-http: Added more tests for the http_request_parser.

diffstat:

 src/lib-http/test-http-request-parser.c |  249 ++++++++++++++++++++++++++-----
 1 files changed, 209 insertions(+), 40 deletions(-)

diffs (truncated from 365 to 300 lines):

diff -r a677a70e420c -r 74bc909ba6a0 src/lib-http/test-http-request-parser.c
--- a/src/lib-http/test-http-request-parser.c	Fri Oct 11 21:36:21 2013 +0300
+++ b/src/lib-http/test-http-request-parser.c	Sat Oct 12 10:52:35 2013 +0300
@@ -12,20 +12,27 @@
 
 #include <time.h>
 
-struct http_request_parse_test {
+/*
+ * Test: valid requests
+ */
+
+struct http_request_valid_parse_test {
 	const char *request;
 	const char *method;
 	const char *target_raw;
-	struct http_request_target target;
+	struct {
+		enum http_request_target_format format;
+		struct http_url url;
+	} target;
 	unsigned char version_major;
 	unsigned char version_minor;
 	uoff_t content_length;
 	const char *payload;
+	bool connection_close;
+	bool expect_100_continue;
 };
 
-/* Valid header tests */
-
-static const struct http_request_parse_test
+static const struct http_request_valid_parse_test
 valid_request_parse_tests[] = {
 	{ .request =
 			"GET / HTTP/1.1\r\n"
@@ -34,17 +41,20 @@
 		.method = "GET",
 		.target_raw = "/",
 		.target = {
-			.format = HTTP_REQUEST_TARGET_FORMAT_ORIGIN
+			.format = HTTP_REQUEST_TARGET_FORMAT_ORIGIN,
+			.url = { .host_name = "example.com" }
 		},
 		.version_major = 1, .version_minor = 1,
 	},{ .request =
 			"OPTIONS * HTTP/1.0\r\n"
 			"Host: example.com\r\n"
+			"Connection: Keep-Alive\r\n"
 			"\r\n",
 		.method = "OPTIONS",
 		.target_raw = "*",
 		.target = {
-			.format = HTTP_REQUEST_TARGET_FORMAT_ASTERISK
+			.format = HTTP_REQUEST_TARGET_FORMAT_ASTERISK,
+			.url = { .host_name = "example.com" }
 		},
 		.version_major = 1, .version_minor = 0,
 	},{ .request =
@@ -54,7 +64,8 @@
 		.method = "CONNECT",
 		.target_raw = "example.com:443",
 		.target = {
-			.format = HTTP_REQUEST_TARGET_FORMAT_AUTHORITY
+			.format = HTTP_REQUEST_TARGET_FORMAT_AUTHORITY,
+			.url = { .host_name = "example.com", .have_port = TRUE, .port = 443 }
 		},
 		.version_major = 1, .version_minor = 2,
 	},{ .request =
@@ -64,7 +75,12 @@
 		.method = "GET",
 		.target_raw = "https://www.example.com:443",
 		.target = {
-			.format = HTTP_REQUEST_TARGET_FORMAT_ABSOLUTE
+			.format = HTTP_REQUEST_TARGET_FORMAT_ABSOLUTE,
+			.url = {
+				.host_name = "www.example.com",
+				.have_port = TRUE, .port = 443,
+				.have_ssl = TRUE
+			}
 		},
 		.version_major = 1, .version_minor = 1,
 	},{ .request =
@@ -77,9 +93,48 @@
 		.target_raw = "http://api.example.com:8080/commit?user=dirk",
 		.target = {
 			.format = HTTP_REQUEST_TARGET_FORMAT_ABSOLUTE,
+			.url = { .host_name = "api.example.com", .have_port = TRUE, .port = 8080 }
 		},
 		.version_major = 1, .version_minor = 1,
 		.payload = "Content!\r\n"
+	},{ .request =
+			"GET http://www.example.com/index.php?seq=1 HTTP/1.1\r\n"
+			"Host: www.example.com\r\n"
+			"Connection: close\r\n"
+			"\r\n",
+		.method = "GET",
+		.target_raw = "http://www.example.com/index.php?seq=1",
+		.target = {
+			.format = HTTP_REQUEST_TARGET_FORMAT_ABSOLUTE,
+			.url = { .host_name = "www.example.com" }
+		},
+		.version_major = 1, .version_minor = 1,
+		.connection_close = TRUE
+	},{ .request =
+			"GET http://www.example.com/index.html HTTP/1.0\r\n"
+			"Host: www.example.com\r\n"
+			"\r\n",
+		.method = "GET",
+		.target_raw = "http://www.example.com/index.html",
+		.target = {
+			.format = HTTP_REQUEST_TARGET_FORMAT_ABSOLUTE,
+			.url = { .host_name = "www.example.com" }
+		},
+		.version_major = 1, .version_minor = 0,
+		.connection_close = TRUE
+	},{ .request =
+			"GET http://www.example.com/index.html HTTP/1.1\r\n"
+			"Host: www.example.com\r\n"
+			"Expect: 100-continue\r\n"
+			"\r\n",
+		.method = "GET",
+		.target_raw = "http://www.example.com/index.html",
+		.target = {
+			.format = HTTP_REQUEST_TARGET_FORMAT_ABSOLUTE,
+			.url = { .host_name = "www.example.com" }
+		},
+		.version_major = 1, .version_minor = 1,
+		.expect_100_continue = TRUE
 	}
 };
 
@@ -110,7 +165,7 @@
 	for (i = 0; i < valid_request_parse_test_count; i++) T_BEGIN {
 		struct istream *input;
 		struct ostream *output;
-		const struct http_request_parse_test *test;
+		const struct http_request_valid_parse_test *test;
 		struct http_request_parser *parser;
 		struct http_request request;
 		enum http_request_parse_error error_code;
@@ -153,26 +208,65 @@
 		if (ret == 0) {
 			/* verify last request only */
 			if (request.method == NULL || test->method == NULL) {
-				test_out(t_strdup_printf("request->method = %s", test->method),
+				test_out(t_strdup_printf("request->method = %s", request.method),
 					request.method == test->method);
 			} else {
-				test_out(t_strdup_printf("request->method = %s", test->method),
+				test_out(t_strdup_printf("request->method = %s", request.method),
 					strcmp(request.method, test->method) == 0);
 			}
+
 			if (request.target_raw == NULL || test->target_raw == NULL) {
-				test_out(t_strdup_printf("request->target = %s", test->target_raw),
+				test_out(t_strdup_printf
+						("request->target_raw = %s", request.target_raw),
 					request.target_raw == test->target_raw);
 			} else {
-				test_out(t_strdup_printf("request->target = %s", test->target_raw),
+				test_out(t_strdup_printf
+						("request->target_raw = %s", request.target_raw),
 					strcmp(request.target_raw, test->target_raw) == 0);
 			}
+			if (request.target.url == NULL) {
+				test_out("request->target.url = (null)",
+					test->target.url.host_name == NULL && !test->target.url.have_port);
+			} else {
+				if (request.target.url->host_name == NULL ||
+					test->target.url.host_name == NULL) {
+					test_out(t_strdup_printf("request->target.url->host_name = %s",
+							request.target.url->host_name),
+						request.target.url->host_name == test->target.url.host_name);
+				} else {
+					test_out(t_strdup_printf("request->target.url->host_name = %s",
+							request.target.url->host_name),
+						strcmp(request.target.url->host_name,
+							test->target.url.host_name) == 0);
+				}
+				if (!request.target.url->have_port) {
+					test_out("request->target.url->port = (unspecified)",
+						request.target.url->have_port == test->target.url.have_port);
+				} else {
+					test_out(t_strdup_printf
+						("request->target.url->port = %u", request.target.url->port),
+						request.target.url->have_port == test->target.url.have_port &&
+						request.target.url->port == test->target.url.port);
+				}
+				test_out(t_strdup_printf("request->target.url->have_ssl = %s",
+					(request.target.url->have_ssl ? "yes" : "no")),
+					request.target.url->have_ssl == test->target.url.have_ssl);
+			}
 			test_out(t_strdup_printf("request->target_format = %s",
-					_request_target_format(test->target.format)),
+					_request_target_format(request.target.format)),
 					request.target.format == test->target.format);
-			test_out(t_strdup_printf("request->version = %d.%d",
-					test->version_major, test->version_minor),
+
+			test_out(t_strdup_printf("request->version = %u.%u",
+					request.version_major, request.version_minor),
 					request.version_major == test->version_major &&
 					request.version_minor == test->version_minor);
+			test_out(t_strdup_printf("request->connection_close = %s",
+					(request.connection_close ? "yes" : "no")),
+					request.connection_close == test->connection_close);
+			test_out(t_strdup_printf("request->expect_100_continue = %s",
+					(request.expect_100_continue ? "yes" : "no")),
+					request.expect_100_continue == test->expect_100_continue);
+		
 			if (payload == NULL || test->payload == NULL) {
 				test_out(t_strdup_printf("request->payload = %s",
 					str_sanitize(payload, 80)),
@@ -190,25 +284,71 @@
 	buffer_free(&payload_buffer);
 }
 
-static const char *invalid_request_parse_tests[] = {
-	"GET: / HTTP/1.1\r\n"
-	"Host: example.com\r\n"
-	"\r\n",
-	"GET % HTTP/1.1\r\n"
-	"Host: example.com\r\n"
-	"\r\n",
-	"GET /frop\" HTTP/1.1\r\n"
-	"Host: example.com\r\n"
-	"\r\n",
-	"GET / HTCPCP/1.0\r\n"
-	"Host: example.com\r\n"
-	"\r\n",
-	"GET / HTTP/1.0.1\r\n"
-	"Host: example.com\r\n"
-	"\r\n",
-	"GET / HTTP/1.1\r\n"
-	"Host: \"example.com\r\n"
-	"\r\n",
+/*
+ * Test: invalid requests
+ */
+
+struct http_request_invalid_parse_test {
+	const char *request;
+	enum http_request_parse_error error_code;
+};
+
+static struct http_request_invalid_parse_test
+invalid_request_parse_tests[] = {
+	{ .request =
+			"GET: / HTTP/1.1\r\n"
+			"Host: example.com\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BROKEN_REQUEST
+	},{ .request =
+			"GET % HTTP/1.1\r\n"
+			"Host: example.com\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST
+	},{ .request =
+			"GET /frop\" HTTP/1.1\r\n"
+			"Host: example.com\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST
+	},{ .request =
+			"GET / HTCPCP/1.0\r\n"
+			"Host: example.com\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BROKEN_REQUEST
+	},{ .request =
+			"GET / HTTP/1.0.1\r\n"
+			"Host: example.com\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BROKEN_REQUEST
+	},{ .request =
+			"GET / HTTP/1.1\r\n"
+			"Host: \"example.com\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST
+	},{ .request =
+			"GET / HTTP/1.1\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST
+	},{ .request =
+			"GET / HTTP/1.1\r\n"
+			"Host: www.example.com\r\n"
+			"Transfer-Encoding: gzip\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_BROKEN_REQUEST
+	},{ .request =
+			"GET / HTTP/1.1\r\n"
+			"Host: www.example.com\r\n"
+			"Expect: payment\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED
+	},{ .request =
+			"GET / HTTP/1.1\r\n"
+			"Host: www.example.com\r\n"
+			"Transfer-Encoding: cuneiform, chunked\r\n"
+			"\r\n",
+		.error_code = HTTP_REQUEST_PARSE_ERROR_NOT_IMPLEMENTED


More information about the dovecot-cvs mailing list