diff options
author | Mark Doffman <mark.doffman@codethink.co.uk> | 2014-04-01 20:02:03 +0000 |
---|---|---|
committer | Mark Doffman <mark.doffman@codethink.co.uk> | 2014-04-01 20:02:03 +0000 |
commit | ce764489e358bad6b49418f5c8bc7b25a4b1815e (patch) | |
tree | bdf7d009702adc91e63d261f7d924d9e5bf94cff /tests/header-parsing.c | |
parent | 0d45677b0a20270735e4d18e969a4991a4e67078 (diff) | |
parent | 6c14af04775a9de4dfa3fa0cc15a7ad0462ef3d9 (diff) | |
download | libsoup-ce764489e358bad6b49418f5c8bc7b25a4b1815e.tar.gz |
Merge tag '2.46.0' into baserock/morphbaserock/morph
2.46.0
Diffstat (limited to 'tests/header-parsing.c')
-rw-r--r-- | tests/header-parsing.c | 472 |
1 files changed, 154 insertions, 318 deletions
diff --git a/tests/header-parsing.c b/tests/header-parsing.c index e57d7d83..fdc7885d 100644 --- a/tests/header-parsing.c +++ b/tests/header-parsing.c @@ -8,6 +8,7 @@ typedef struct { static struct RequestTest { const char *description; + const char *bugref; const char *request; int length; guint status; @@ -19,14 +20,14 @@ static struct RequestTest { /*** VALID REQUESTS ***/ /**********************/ - { "HTTP 1.0 request with no headers", + { "HTTP 1.0 request with no headers", NULL, "GET / HTTP/1.0\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_0, { { NULL } } }, - { "Req w/ 1 header", + { "Req w/ 1 header", NULL, "GET / HTTP/1.1\r\nHost: example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -35,7 +36,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header, no leading whitespace", + { "Req w/ 1 header, no leading whitespace", NULL, "GET / HTTP/1.1\r\nHost:example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -44,7 +45,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header including trailing whitespace", + { "Req w/ 1 header including trailing whitespace", NULL, "GET / HTTP/1.1\r\nHost: example.com \r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -53,7 +54,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header, wrapped", + { "Req w/ 1 header, wrapped", NULL, "GET / HTTP/1.1\r\nFoo: bar\r\n baz\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -62,7 +63,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header, wrapped with additional whitespace", + { "Req w/ 1 header, wrapped with additional whitespace", NULL, "GET / HTTP/1.1\r\nFoo: bar \r\n baz\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -71,7 +72,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header, wrapped with tab", + { "Req w/ 1 header, wrapped with tab", NULL, "GET / HTTP/1.1\r\nFoo: bar\r\n\tbaz\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -80,7 +81,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header, wrapped before value", + { "Req w/ 1 header, wrapped before value", NULL, "GET / HTTP/1.1\r\nFoo:\r\n bar baz\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -89,7 +90,7 @@ static struct RequestTest { } }, - { "Req w/ 1 header with empty value", + { "Req w/ 1 header with empty value", NULL, "GET / HTTP/1.1\r\nHost:\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -98,7 +99,7 @@ static struct RequestTest { } }, - { "Req w/ 2 headers", + { "Req w/ 2 headers", NULL, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -108,7 +109,7 @@ static struct RequestTest { } }, - { "Req w/ 3 headers", + { "Req w/ 3 headers", NULL, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\nBlah: blah\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -119,7 +120,7 @@ static struct RequestTest { } }, - { "Req w/ 3 headers, 1st wrapped", + { "Req w/ 3 headers, 1st wrapped", NULL, "GET / HTTP/1.1\r\nFoo: bar\r\n baz\r\nConnection: close\r\nBlah: blah\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -130,7 +131,7 @@ static struct RequestTest { } }, - { "Req w/ 3 headers, 2nd wrapped", + { "Req w/ 3 headers, 2nd wrapped", NULL, "GET / HTTP/1.1\r\nConnection: close\r\nBlah: blah\r\nFoo: bar\r\n baz\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -141,7 +142,7 @@ static struct RequestTest { } }, - { "Req w/ 3 headers, 3rd wrapped", + { "Req w/ 3 headers, 3rd wrapped", NULL, "GET / HTTP/1.1\r\nConnection: close\r\nBlah: blah\r\nFoo: bar\r\n baz\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -152,7 +153,7 @@ static struct RequestTest { } }, - { "Req w/ same header multiple times", + { "Req w/ same header multiple times", NULL, "GET / HTTP/1.1\r\nFoo: bar\r\nFoo: baz\r\nFoo: quux\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -161,7 +162,7 @@ static struct RequestTest { } }, - { "Connection header on HTTP/1.0 message", + { "Connection header on HTTP/1.0 message", NULL, "GET / HTTP/1.0\r\nFoo: bar\r\nConnection: Bar, Quux\r\nBar: baz\r\nQuux: foo\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_0, @@ -171,14 +172,14 @@ static struct RequestTest { } }, - { "GET with full URI", + { "GET with full URI", "667637", "GET http://example.com HTTP/1.1\r\n", -1, SOUP_STATUS_OK, "GET", "http://example.com", SOUP_HTTP_1_1, { { NULL } } }, - { "GET with full URI in upper-case", + { "GET with full URI in upper-case", "667637", "GET HTTP://example.com HTTP/1.1\r\n", -1, SOUP_STATUS_OK, "GET", "HTTP://example.com", SOUP_HTTP_1_1, @@ -188,7 +189,7 @@ static struct RequestTest { /* It's better for this to be passed through: this means a SoupServer * could implement ftp-over-http proxying, for instance */ - { "GET with full URI of unrecognised scheme", + { "GET with full URI of unrecognised scheme", "667637", "GET AbOuT: HTTP/1.1\r\n", -1, SOUP_STATUS_OK, "GET", "AbOuT:", SOUP_HTTP_1_1, @@ -201,7 +202,7 @@ static struct RequestTest { /* RFC 2616 section 4.1 says we SHOULD accept this */ - { "Spurious leading CRLF", + { "Spurious leading CRLF", NULL, "\r\nGET / HTTP/1.1\r\nHost: example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -212,7 +213,7 @@ static struct RequestTest { /* RFC 2616 section 3.1 says we MUST accept this */ - { "HTTP/01.01 request", + { "HTTP/01.01 request", NULL, "GET / HTTP/01.01\r\nHost: example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -223,7 +224,7 @@ static struct RequestTest { /* RFC 2616 section 19.3 says we SHOULD accept these */ - { "LF instead of CRLF after header", + { "LF instead of CRLF after header", NULL, "GET / HTTP/1.1\r\nHost: example.com\nConnection: close\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -233,7 +234,7 @@ static struct RequestTest { } }, - { "LF instead of CRLF after Request-Line", + { "LF instead of CRLF after Request-Line", NULL, "GET / HTTP/1.1\nHost: example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -242,7 +243,7 @@ static struct RequestTest { } }, - { "Mixed CRLF/LF", + { "Mixed CRLF/LF", "666316", "GET / HTTP/1.1\r\na: b\r\nc: d\ne: f\r\ng: h\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -254,7 +255,7 @@ static struct RequestTest { } }, - { "Req w/ incorrect whitespace in Request-Line", + { "Req w/ incorrect whitespace in Request-Line", NULL, "GET /\tHTTP/1.1\r\nHost: example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -263,7 +264,7 @@ static struct RequestTest { } }, - { "Req w/ incorrect whitespace after Request-Line", + { "Req w/ incorrect whitespace after Request-Line", "475169", "GET / HTTP/1.1 \r\nHost: example.com\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -274,10 +275,9 @@ static struct RequestTest { /* If the request/status line is parseable, then we * just ignore any invalid-looking headers after that. - * (qv bug 579318). */ - { "Req w/ mangled header", + { "Req w/ mangled header", "579318", "GET / HTTP/1.1\r\nHost: example.com\r\nFoo one\r\nBar: two\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -287,7 +287,7 @@ static struct RequestTest { } }, - { "First header line is continuation", + { "First header line is continuation", "666316", "GET / HTTP/1.1\r\n b\r\nHost: example.com\r\nc: d\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -297,7 +297,7 @@ static struct RequestTest { } }, - { "Zero-length header name", + { "Zero-length header name", "666316", "GET / HTTP/1.1\r\na: b\r\n: example.com\r\nc: d\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -307,7 +307,7 @@ static struct RequestTest { } }, - { "CR in header name", + { "CR in header name", "666316", "GET / HTTP/1.1\r\na: b\r\na\rb: cd\r\nx\r: y\r\n\rz: w\r\nc: d\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -317,7 +317,7 @@ static struct RequestTest { } }, - { "CR in header value", + { "CR in header value", "666316", "GET / HTTP/1.1\r\na: b\r\nHost: example\rcom\r\np: \rq\r\ns: t\r\r\nc: d\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -330,7 +330,7 @@ static struct RequestTest { } }, - { "Tab in header name", + { "Tab in header name", "666316", "GET / HTTP/1.1\r\na: b\r\na\tb: cd\r\nx\t: y\r\np: q\r\n\tz: w\r\nc: d\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -345,7 +345,7 @@ static struct RequestTest { } }, - { "Tab in header value", + { "Tab in header value", "666316", "GET / HTTP/1.1\r\na: b\r\nab: c\td\r\nx: \ty\r\nz: w\t\r\nc: d\r\n", -1, SOUP_STATUS_OK, "GET", "/", SOUP_HTTP_1_1, @@ -362,84 +362,84 @@ static struct RequestTest { /*** INVALID REQUESTS ***/ /************************/ - { "HTTP 0.9 request; not supported", + { "HTTP 0.9 request; not supported", NULL, "GET /\r\n", -1, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "HTTP 1.2 request (no such thing)", + { "HTTP 1.2 request (no such thing)", NULL, "GET / HTTP/1.2\r\n", -1, SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED, NULL, NULL, -1, { { NULL } } }, - { "HTTP 2000 request (no such thing)", + { "HTTP 2000 request (no such thing)", NULL, "GET / HTTP/2000.0\r\n", -1, SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED, NULL, NULL, -1, { { NULL } } }, - { "Non-HTTP request", + { "Non-HTTP request", NULL, "GET / SOUP/1.1\r\nHost: example.com\r\n", -1, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "Junk after Request-Line", + { "Junk after Request-Line", NULL, "GET / HTTP/1.1 blah\r\nHost: example.com\r\n", -1, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "NUL in Method", + { "NUL in Method", NULL, "G\x00T / HTTP/1.1\r\nHost: example.com\r\n", 37, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "NUL at beginning of Method", + { "NUL at beginning of Method", "666316", "\x00 / HTTP/1.1\r\nHost: example.com\r\n", 35, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "NUL in Path", + { "NUL in Path", NULL, "GET /\x00 HTTP/1.1\r\nHost: example.com\r\n", 38, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "NUL in header name", + { "NUL in header name", "666316", "GET / HTTP/1.1\r\n\x00: silly\r\n", 37, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "NUL in header value", + { "NUL in header value", NULL, "GET / HTTP/1.1\r\nHost: example\x00com\r\n", 37, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "No terminating CRLF", + { "No terminating CRLF", NULL, "GET / HTTP/1.1\r\nHost: example.com", -1, SOUP_STATUS_BAD_REQUEST, NULL, NULL, -1, { { NULL } } }, - { "Unrecognized expectation", + { "Unrecognized expectation", NULL, "GET / HTTP/1.1\r\nHost: example.com\r\nExpect: the-impossible\r\n", -1, SOUP_STATUS_EXPECTATION_FAILED, NULL, NULL, -1, @@ -450,36 +450,37 @@ static const int num_reqtests = G_N_ELEMENTS (reqtests); static struct ResponseTest { const char *description; + const char *bugref; const char *response; int length; SoupHTTPVersion version; guint status_code; const char *reason_phrase; - Header headers[4]; + Header headers[10]; } resptests[] = { /***********************/ /*** VALID RESPONSES ***/ /***********************/ - { "HTTP 1.0 response w/ no headers", + { "HTTP 1.0 response w/ no headers", NULL, "HTTP/1.0 200 ok\r\n", -1, SOUP_HTTP_1_0, SOUP_STATUS_OK, "ok", { { NULL } } }, - { "HTTP 1.1 response w/ no headers", + { "HTTP 1.1 response w/ no headers", NULL, "HTTP/1.1 200 ok\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { NULL } } }, - { "Response w/ multi-word Reason-Phrase", + { "Response w/ multi-word Reason-Phrase", NULL, "HTTP/1.1 400 bad request\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_BAD_REQUEST, "bad request", { { NULL } } }, - { "Response w/ 1 header", + { "Response w/ 1 header", NULL, "HTTP/1.1 200 ok\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -487,7 +488,7 @@ static struct ResponseTest { } }, - { "Response w/ 2 headers", + { "Response w/ 2 headers", NULL, "HTTP/1.1 200 ok\r\nFoo: bar\r\nBaz: quux\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -496,7 +497,7 @@ static struct ResponseTest { } }, - { "Response w/ same header multiple times", + { "Response w/ same header multiple times", NULL, "HTTP/1.1 200 ok\r\nFoo: bar\r\nFoo: baz\r\nFoo: quux\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar, baz, quux" }, @@ -504,7 +505,7 @@ static struct ResponseTest { } }, - { "Response w/ no reason phrase", + { "Response w/ no reason phrase", NULL, "HTTP/1.1 200 \r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "", { { "Foo", "bar" }, @@ -512,7 +513,7 @@ static struct ResponseTest { } }, - { "Connection header on HTTP/1.0 message", + { "Connection header on HTTP/1.0 message", NULL, "HTTP/1.0 200 ok\r\nFoo: bar\r\nConnection: Bar\r\nBar: quux\r\n", -1, SOUP_HTTP_1_0, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -521,13 +522,26 @@ static struct ResponseTest { } }, + /* Tests from Cockpit */ + + { "Response w/ 3 headers, check case-insensitivity", "722341", + "HTTP/1.0 200 ok\r\nHeader1: value3\r\nHeader2: field\r\nHead3: Another \r\n", -1, + SOUP_HTTP_1_0, SOUP_STATUS_OK, "ok", + { { "header1", "value3" }, + { "Header2", "field" }, + { "hEAD3", "Another" }, + { "Something else", NULL }, + { NULL } + } + }, + /*****************************/ /*** RECOVERABLE RESPONSES ***/ /*****************************/ /* RFC 2616 section 3.1 says we MUST accept this */ - { "HTTP/01.01 response", + { "HTTP/01.01 response", NULL, "HTTP/01.01 200 ok\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -537,7 +551,7 @@ static struct ResponseTest { /* RFC 2616 section 19.3 says we SHOULD accept these */ - { "Response w/ LF instead of CRLF after Status-Line", + { "Response w/ LF instead of CRLF after Status-Line", NULL, "HTTP/1.1 200 ok\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -545,7 +559,7 @@ static struct ResponseTest { } }, - { "Response w/ incorrect spacing in Status-Line", + { "Response w/ incorrect spacing in Status-Line", NULL, "HTTP/1.1 200\tok\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -553,7 +567,7 @@ static struct ResponseTest { } }, - { "Response w/ no reason phrase or preceding SP", + { "Response w/ no reason phrase or preceding SP", NULL, "HTTP/1.1 200\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "", { { "Foo", "bar" }, @@ -561,7 +575,7 @@ static struct ResponseTest { } }, - { "Response w/ no whitespace after status code", + { "Response w/ no whitespace after status code", NULL, "HTTP/1.1 200ok\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -570,7 +584,7 @@ static struct ResponseTest { }, /* Shoutcast support */ - { "Shoutcast server not-quite-HTTP", + { "Shoutcast server not-quite-HTTP", "502325", "ICY 200 OK\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_0, SOUP_STATUS_OK, "OK", { { "Foo", "bar" }, @@ -578,8 +592,7 @@ static struct ResponseTest { } }, - /* qv bug 579318, do_bad_header_tests() below */ - { "Response w/ mangled header", + { "Response w/ mangled header", "579318", "HTTP/1.1 200 ok\r\nFoo: one\r\nBar two:2\r\nBaz: three\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "one" }, @@ -588,8 +601,7 @@ static struct ResponseTest { } }, - /* qv bug 602863 */ - { "HTTP 1.1 response with leading line break", + { "HTTP 1.1 response with leading line break", "602863", "\nHTTP/1.1 200 ok\r\nFoo: bar\r\n", -1, SOUP_HTTP_1_1, SOUP_STATUS_OK, "ok", { { "Foo", "bar" }, @@ -600,79 +612,79 @@ static struct ResponseTest { /*** INVALID RESPONSES ***/ /*************************/ - { "Invalid HTTP version", + { "Invalid HTTP version", NULL, "HTTP/1.2 200 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "Non-HTTP response", + { "Non-HTTP response", NULL, "SOUP/1.1 200 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "Non-numeric status code", + { "Non-numeric status code", NULL, "HTTP/1.1 XXX OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "No status code", + { "No status code", NULL, "HTTP/1.1 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "One-digit status code", + { "One-digit status code", NULL, "HTTP/1.1 2 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "Two-digit status code", + { "Two-digit status code", NULL, "HTTP/1.1 20 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "Four-digit status code", + { "Four-digit status code", NULL, "HTTP/1.1 2000 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "Status code < 100", + { "Status code < 100", NULL, "HTTP/1.1 001 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "Status code > 599", + { "Status code > 599", NULL, "HTTP/1.1 600 OK\r\nFoo: bar\r\n", -1, -1, 0, NULL, { { NULL } } }, - { "NUL at start", + { "NUL at start", "666316", "\x00HTTP/1.1 200 OK\r\nFoo: bar\r\n", 28, -1, 0, NULL, { { NULL } } }, - { "NUL in Reason Phrase", + { "NUL in Reason Phrase", NULL, "HTTP/1.1 200 O\x00K\r\nFoo: bar\r\n", 28, -1, 0, NULL, { { NULL } } }, - { "NUL in header name", + { "NUL in header name", NULL, "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28, -1, 0, NULL, { { NULL } } }, - { "NUL in header value", + { "NUL in header value", NULL, "HTTP/1.1 200 OK\r\nFoo: b\x00ar\r\n", 28, -1, 0, NULL, { { NULL } } @@ -704,18 +716,11 @@ static struct QValueTest { static const int num_qvaluetests = G_N_ELEMENTS (qvaluetests); static void -print_header (const char *name, const char *value, gpointer data) -{ - debug_printf (1, " '%s': '%s'\n", name, value); -} - -static gboolean check_headers (Header *headers, SoupMessageHeaders *hdrs) { GSList *header_names, *h; SoupMessageHeadersIter iter; const char *name, *value; - gboolean ok = TRUE; int i; header_names = NULL; @@ -727,36 +732,33 @@ check_headers (Header *headers, SoupMessageHeaders *hdrs) } for (i = 0, h = header_names; headers[i].name && h; i++, h = h->next) { - if (strcmp (h->data, headers[i].name) != 0) { - ok = FALSE; - break; - } + g_assert (g_ascii_strcasecmp (h->data, headers[i].name) == 0); + value = soup_message_headers_get_list (hdrs, headers[i].name); - if (strcmp (value, headers[i].value) != 0) { - ok = FALSE; - break; - } + g_assert_cmpstr (value, ==, headers[i].value); + } + /* If we have remaining fields to check, they should return NULL */ + for (; headers[i].name; i++) { + value = soup_message_headers_get_list (hdrs, headers[i].name); + g_assert_null (value); } - if (headers[i].name || h) - ok = FALSE; + g_assert_null (headers[i].name); + g_assert_null (h); + g_slist_free (header_names); - return ok; } static void do_request_tests (void) { - int i, len, h; + int i, len; char *method, *path; SoupHTTPVersion version; SoupMessageHeaders *headers; guint status; - debug_printf (1, "Request tests\n"); for (i = 0; i < num_reqtests; i++) { - gboolean ok = TRUE; - - debug_printf (1, "%2d. %s (%s): ", i + 1, reqtests[i].description, + debug_printf (1, "%2d. %s (%s)\n", i + 1, reqtests[i].description, soup_status_get_phrase (reqtests[i].status)); headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST); @@ -769,71 +771,32 @@ do_request_tests (void) status = soup_headers_parse_request (reqtests[i].request, len, headers, &method, &path, &version); + g_assert_cmpint (status, ==, reqtests[i].status); if (SOUP_STATUS_IS_SUCCESSFUL (status)) { - if ((reqtests[i].method && strcmp (reqtests[i].method, method) != 0) || !reqtests[i].method) - ok = FALSE; - if ((reqtests[i].path && strcmp (reqtests[i].path, path) != 0) || !reqtests[i].path) - ok = FALSE; - if (reqtests[i].version != version) - ok = FALSE; - - if (!check_headers (reqtests[i].headers, headers)) - ok = FALSE; - } else { - if (status != reqtests[i].status) - ok = FALSE; - } + g_assert_cmpstr (method, ==, reqtests[i].method); + g_assert_cmpstr (path, ==, reqtests[i].path); + g_assert_cmpint (version, ==, reqtests[i].version); - if (ok) - debug_printf (1, "OK!\n"); - else { - debug_printf (1, "BAD!\n"); - errors++; - if (reqtests[i].method) { - debug_printf (1, " expected: '%s' '%s' 'HTTP/1.%d'\n", - reqtests[i].method, - reqtests[i].path, - reqtests[i].version); - for (h = 0; reqtests[i].headers[h].name; h++) { - debug_printf (1, " '%s': '%s'\n", - reqtests[i].headers[h].name, - reqtests[i].headers[h].value); - } - } else { - debug_printf (1, " expected: %s\n", - soup_status_get_phrase (reqtests[i].status)); - } - if (method) { - debug_printf (1, " got: '%s' '%s' 'HTTP/1.%d'\n", - method, path, version); - soup_message_headers_foreach (headers, print_header, NULL); - } else { - debug_printf (1, " got: %s\n", - soup_status_get_phrase (status)); - } + check_headers (reqtests[i].headers, headers); } g_free (method); g_free (path); soup_message_headers_free (headers); } - debug_printf (1, "\n"); } static void do_response_tests (void) { - int i, len, h; + int i, len; guint status_code; char *reason_phrase; SoupHTTPVersion version; SoupMessageHeaders *headers; - debug_printf (1, "Response tests\n"); for (i = 0; i < num_resptests; i++) { - gboolean ok = TRUE; - - debug_printf (1, "%2d. %s (%s): ", i + 1, resptests[i].description, + debug_printf (1, "%2d. %s (%s)\n", i + 1, resptests[i].description, resptests[i].reason_phrase ? "should parse" : "should NOT parse"); headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE); @@ -846,49 +809,17 @@ do_response_tests (void) if (soup_headers_parse_response (resptests[i].response, len, headers, &version, &status_code, &reason_phrase)) { - if (resptests[i].version != version) - ok = FALSE; - if (resptests[i].status_code != status_code) - ok = FALSE; - if ((resptests[i].reason_phrase && strcmp (resptests[i].reason_phrase, reason_phrase) != 0) || !resptests[i].reason_phrase) - ok = FALSE; - - if (!check_headers (resptests[i].headers, headers)) - ok = FALSE; - } else { - if (resptests[i].reason_phrase) - ok = FALSE; - } + g_assert_cmpint (version, ==, resptests[i].version); + g_assert_cmpint (status_code, ==, resptests[i].status_code); + g_assert_cmpstr (reason_phrase, ==, resptests[i].reason_phrase); - if (ok) - debug_printf (1, "OK!\n"); - else { - debug_printf (1, "BAD!\n"); - errors++; - if (resptests[i].reason_phrase) { - debug_printf (1, " expected: 'HTTP/1.%d' '%03d' '%s'\n", - resptests[i].version, - resptests[i].status_code, - resptests[i].reason_phrase); - for (h = 0; resptests[i].headers[h].name; h++) { - debug_printf (1, " '%s': '%s'\n", - resptests[i].headers[h].name, - resptests[i].headers[h].value); - } - } else - debug_printf (1, " expected: parse error\n"); - if (reason_phrase) { - debug_printf (1, " got: 'HTTP/1.%d' '%03d' '%s'\n", - version, status_code, reason_phrase); - soup_message_headers_foreach (headers, print_header, NULL); - } else - debug_printf (1, " got: parse error\n"); - } + check_headers (resptests[i].headers, headers); + } else + g_assert_null (resptests[i].reason_phrase); g_free (reason_phrase); soup_message_headers_free (headers); } - debug_printf (1, "\n"); } static void @@ -896,9 +827,7 @@ do_qvalue_tests (void) { int i, j; GSList *acceptable, *unacceptable, *iter; - gboolean wrong; - debug_printf (1, "qvalue tests\n"); for (i = 0; i < num_qvaluetests; i++) { debug_printf (1, "%2d. %s:\n", i + 1, qvaluetests[i].header_value); @@ -907,48 +836,26 @@ do_qvalue_tests (void) &unacceptable); debug_printf (1, " acceptable: "); - wrong = FALSE; if (acceptable) { for (iter = acceptable, j = 0; iter; iter = iter->next, j++) { debug_printf (1, "%s ", (char *)iter->data); - if (!qvaluetests[i].acceptable[j] || - strcmp (iter->data, qvaluetests[i].acceptable[j]) != 0) - wrong = TRUE; + g_assert_cmpstr (iter->data, ==, qvaluetests[i].acceptable[j]); } debug_printf (1, "\n"); soup_header_free_list (acceptable); } else debug_printf (1, "(none)\n"); - if (wrong) { - debug_printf (1, " WRONG! expected: "); - for (j = 0; qvaluetests[i].acceptable[j]; j++) - debug_printf (1, "%s ", qvaluetests[i].acceptable[j]); - debug_printf (1, "\n"); - errors++; - } debug_printf (1, " unacceptable: "); - wrong = FALSE; if (unacceptable) { for (iter = unacceptable, j = 0; iter; iter = iter->next, j++) { debug_printf (1, "%s ", (char *)iter->data); - if (!qvaluetests[i].unacceptable[j] || - strcmp (iter->data, qvaluetests[i].unacceptable[j]) != 0) - wrong = TRUE; + g_assert_cmpstr (iter->data, ==, qvaluetests[i].unacceptable[j]); } debug_printf (1, "\n"); soup_header_free_list (unacceptable); } else debug_printf (1, "(none)\n"); - if (wrong) { - debug_printf (1, " WRONG! expected: "); - for (j = 0; qvaluetests[i].unacceptable[j]; j++) - debug_printf (1, "%s ", qvaluetests[i].unacceptable[j]); - debug_printf (1, "\n"); - errors++; - } - - debug_printf (1, "\n"); } } @@ -972,8 +879,6 @@ do_content_disposition_tests (void) SoupMultipart *multipart; SoupMessageBody *body; - debug_printf (1, "Content-Disposition tests\n"); - hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); params = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (params, "filename", RFC5987_TEST_FILENAME); @@ -981,13 +886,7 @@ do_content_disposition_tests (void) g_hash_table_destroy (params); header = soup_message_headers_get_one (hdrs, "Content-Disposition"); - if (!strcmp (header, RFC5987_TEST_HEADER_ENCODED)) - debug_printf (1, " encoded OK\n"); - else { - debug_printf (1, " encoding FAILED!\n expected: %s\n got: %s\n", - RFC5987_TEST_HEADER_ENCODED, header); - errors++; - } + g_assert_cmpstr (header, ==, RFC5987_TEST_HEADER_ENCODED); /* UTF-8 decoding */ soup_message_headers_clear (hdrs); @@ -996,22 +895,13 @@ do_content_disposition_tests (void) if (!soup_message_headers_get_content_disposition (hdrs, &disposition, ¶ms)) { - debug_printf (1, " UTF-8 decoding FAILED!\n could not parse\n"); - errors++; + soup_test_assert (FALSE, "UTF-8 decoding FAILED"); return; } g_free (disposition); filename = g_hash_table_lookup (params, "filename"); - if (!filename) { - debug_printf (1, " UTF-8 decoding FAILED!\n could not find filename\n"); - errors++; - } else if (strcmp (filename, RFC5987_TEST_FILENAME) != 0) { - debug_printf (1, " UTF-8 decoding FAILED!\n expected: %s\n got: %s\n", - RFC5987_TEST_FILENAME, filename); - errors++; - } else - debug_printf (1, " UTF-8 decoded OK\n"); + g_assert_cmpstr (filename, ==, RFC5987_TEST_FILENAME); g_hash_table_destroy (params); /* ISO-8859-1 decoding */ @@ -1021,22 +911,13 @@ do_content_disposition_tests (void) if (!soup_message_headers_get_content_disposition (hdrs, &disposition, ¶ms)) { - debug_printf (1, " iso-8859-1 decoding FAILED!\n could not parse\n"); - errors++; + soup_test_assert (FALSE, "iso-8859-1 decoding FAILED"); return; } g_free (disposition); filename = g_hash_table_lookup (params, "filename"); - if (!filename) { - debug_printf (1, " iso-8859-1 decoding FAILED!\n could not find filename\n"); - errors++; - } else if (strcmp (filename, RFC5987_TEST_FILENAME) != 0) { - debug_printf (1, " iso-8859-1 decoding FAILED!\n expected: %s\n got: %s\n", - RFC5987_TEST_FILENAME, filename); - errors++; - } else - debug_printf (1, " iso-8859-1 decoded OK\n"); + g_assert_cmpstr (filename, ==, RFC5987_TEST_FILENAME); g_hash_table_destroy (params); /* Fallback */ @@ -1046,27 +927,19 @@ do_content_disposition_tests (void) if (!soup_message_headers_get_content_disposition (hdrs, &disposition, ¶ms)) { - debug_printf (1, " fallback decoding FAILED!\n could not parse\n"); - errors++; + soup_test_assert (FALSE, "fallback decoding FAILED"); return; } g_free (disposition); filename = g_hash_table_lookup (params, "filename"); - if (!filename) { - debug_printf (1, " fallback decoding FAILED!\n could not find filename\n"); - errors++; - } else if (strcmp (filename, RFC5987_TEST_FALLBACK_FILENAME) != 0) { - debug_printf (1, " fallback decoding FAILED!\n expected: %s\n got: %s\n", - RFC5987_TEST_FALLBACK_FILENAME, filename); - errors++; - } else - debug_printf (1, " fallback decoded OK\n"); + g_assert_cmpstr (filename, ==, RFC5987_TEST_FALLBACK_FILENAME); g_hash_table_destroy (params); soup_message_headers_free (hdrs); - /* Ensure that soup-multipart always quotes filename (bug 641280) */ + /* Ensure that soup-multipart always quotes filename */ + g_test_bug ("641280"); multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART); buffer = soup_buffer_new (SOUP_MEMORY_STATIC, "foo", 3); soup_multipart_append_form_file (multipart, "test", "token", @@ -1082,15 +955,9 @@ do_content_disposition_tests (void) buffer = soup_message_body_flatten (body); soup_message_body_free (body); - if (strstr (buffer->data, "filename=\"token\"")) - debug_printf (1, " SoupMultipart encoded filename correctly\n"); - else { - debug_printf (1, " SoupMultipart encoded filename incorrectly!\n"); - errors++; - } - soup_buffer_free (buffer); + g_assert_true (strstr (buffer->data, "filename=\"token\"")); - debug_printf (1, "\n"); + soup_buffer_free (buffer); } #define CONTENT_TYPE_TEST_MIME_TYPE "text/plain" @@ -1107,7 +974,7 @@ do_content_type_tests (void) GHashTable *params; const char *header, *mime_type; - debug_printf (1, "Content-Type tests\n"); + g_test_bug ("576760"); hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); params = g_hash_table_new (g_str_hash, g_str_equal); @@ -1117,13 +984,7 @@ do_content_type_tests (void) g_hash_table_destroy (params); header = soup_message_headers_get_one (hdrs, "Content-Type"); - if (!strcmp (header, CONTENT_TYPE_TEST_HEADER)) - debug_printf (1, " encoded OK\n"); - else { - debug_printf (1, " encoding FAILED!\n expected: %s\n got: %s\n", - CONTENT_TYPE_TEST_HEADER, header); - errors++; - } + g_assert_cmpstr (header, ==, CONTENT_TYPE_TEST_HEADER); soup_message_headers_clear (hdrs); soup_message_headers_append (hdrs, "Content-Type", @@ -1133,38 +994,20 @@ do_content_type_tests (void) CONTENT_TYPE_TEST_MIME_TYPE); mime_type = soup_message_headers_get_content_type (hdrs, ¶ms); - if (!mime_type) { - debug_printf (1, " decoding FAILED!\n could not parse\n"); - errors++; - } - - if (mime_type && strcmp (mime_type, CONTENT_TYPE_TEST_MIME_TYPE) != 0) { - debug_printf (1, " decoding FAILED!\n bad returned MIME type: %s\n", - mime_type); - errors++; - } else if (params && g_hash_table_size (params) != 0) { - debug_printf (1, " decoding FAILED!\n params contained %d params (should be 0)\n", - g_hash_table_size (params)); - errors++; - } else - debug_printf (1, " decoded OK\n"); - + g_assert_cmpstr (mime_type, ==, CONTENT_TYPE_TEST_MIME_TYPE); + g_assert_cmpint (g_hash_table_size (params), ==, 0); if (params) g_hash_table_destroy (params); + g_test_bug ("577630"); + soup_message_headers_clear (hdrs); soup_message_headers_append (hdrs, "Content-Type", CONTENT_TYPE_BAD_HEADER); mime_type = soup_message_headers_get_content_type (hdrs, ¶ms); - if (mime_type) { - debug_printf (1, " Bad content rejection FAILED!\n"); - errors++; - } else - debug_printf (1, " Bad content rejection OK\n"); + g_assert_null (mime_type); soup_message_headers_free (hdrs); - - debug_printf (1, "\n"); } struct { @@ -1185,7 +1028,7 @@ do_append_param_tests (void) GString *params; int i; - debug_printf (1, "soup_header_g_string_append_param() tests\n"); + g_test_bug ("577728"); params = g_string_new (NULL); for (i = 0; i < G_N_ELEMENTS (test_params); i++) { @@ -1195,15 +1038,8 @@ do_append_param_tests (void) test_params[i].name, test_params[i].value); } - if (strcmp (params->str, TEST_PARAMS_RESULT) != 0) { - debug_printf (1, " FAILED!\n expected: %s\n got: %s\n", - TEST_PARAMS_RESULT, params->str); - errors++; - } else - debug_printf (1, " OK\n"); + g_assert_cmpstr (params->str, ==, TEST_PARAMS_RESULT); g_string_free (params, TRUE); - - debug_printf (1, "\n"); } static const struct { @@ -1226,19 +1062,15 @@ do_bad_header_tests (void) SoupMessageHeaders *hdrs; int i; - debug_printf (1, "bad header rejection tests\n"); - hdrs = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); for (i = 0; i < G_N_ELEMENTS (bad_headers); i++) { debug_printf (1, " %s\n", bad_headers[i].description); - expect_warning = TRUE; + + g_test_expect_message ("libsoup", G_LOG_LEVEL_CRITICAL, + "*soup_message_headers_append*assertion*failed*"); soup_message_headers_append (hdrs, bad_headers[i].name, bad_headers[i].value); - if (expect_warning) { - expect_warning = FALSE; - debug_printf (1, " FAILED: soup_message_headers_append() did not reject it\n"); - errors++; - } + g_test_assert_expected_messages (); } soup_message_headers_free (hdrs); } @@ -1246,16 +1078,20 @@ do_bad_header_tests (void) int main (int argc, char **argv) { + int ret; + test_init (argc, argv, NULL); - do_request_tests (); - do_response_tests (); - do_qvalue_tests (); - do_content_disposition_tests (); - do_content_type_tests (); - do_append_param_tests (); - do_bad_header_tests (); + g_test_add_func ("/header-parsing/request", do_request_tests); + g_test_add_func ("/header-parsing/response", do_response_tests); + g_test_add_func ("/header-parsing/qvalue", do_qvalue_tests); + g_test_add_func ("/header-parsing/content-disposition", do_content_disposition_tests); + g_test_add_func ("/header-parsing/content-type", do_content_type_tests); + g_test_add_func ("/header-parsing/append-param", do_append_param_tests); + g_test_add_func ("/header-parsing/bad", do_bad_header_tests); + + ret = g_test_run (); test_cleanup (); - return errors != 0; + return ret; } |