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