/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "test-lib.h"
#include "buffer.h"
#include "str.h"
#include "str-sanitize.h"
#include "istream.h"
#include "ostream.h"
#include "test-common.h"
#include "http-response-parser.h"
#include <time.h>
struct valid_parse_test_response {
unsigned char version_major;
unsigned char version_minor;
unsigned int status;
const char *payload;
};
struct valid_parse_test {
const char *input;
unsigned int responses_count;
};
/* Valid response tests */
{
.status = 200,
.payload = "This is a piece of stupid text.\r\n"
}
};
{
.status = 200,
.payload = "This is a piece of stupid text.\r\n"
},{
.status = 200,
.payload = "This is a piece of even more stupid text.\r\n"
}
};
{
.status = 401,
.payload = "Frop!"
}
};
{
.status = 200,
.payload = "Invalid date header"
}
};
{
.status = 200,
.payload = "Duplicate headers"
}
};
static const struct valid_parse_test
{ .input =
"HTTP/1.1 200 OK\r\n"
"Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n"
"Server: Apache/2.2.16 (Debian)\r\n"
"Last-Modified: Tue, 18 Sep 2012 19:31:41 GMT\r\n"
"Etag: \"2a8400c-10751f-4c9fef0858140\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 33\r\n"
"Keep-Alive: timeout=15, max=100\r\n"
"Connection: Keep-Alive\r\n"
"\r\n"
"This is a piece of stupid text.\r\n",
},{
.input =
"HTTP/1.1 200 OK\r\n"
"Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n"
"Server: Apache/2.2.16 (Debian)\r\n"
"Last-Modified: Tue, 18 Sep 2012 19:31:41 GMT\r\n"
"Etag: \"2a8400c-10751f-4c9fef0858140\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 33\r\n"
"Keep-Alive: timeout=15, max=100\r\n"
"Connection: Keep-Alive\r\n"
"\r\n"
"This is a piece of stupid text.\r\n"
"HTTP/1.1 200 OK\r\n"
"Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n"
"Server: Apache/2.2.16 (Debian)\r\n"
"Last-Modified: Tue, 18 Sep 2012 19:31:41 GMT\r\n"
"Etag: \"2a8400c-10751f-4c9fef0858140\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 43\r\n"
"Keep-Alive: timeout=15, max=100\r\n"
"Connection: Keep-Alive\r\n"
"\r\n"
"This is a piece of even more stupid text.\r\n",
},{
.input =
"HTTP/1.1 401 Authorization Required\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"
"WWW-Authenticate: Basic realm=\"Munin\"\r\n"
"Vary: Accept-Encoding\r\n"
"Content-Encoding: gzip\r\n"
"Content-Length: 5\r\n"
"Keep-Alive: timeout=15, max=99\r\n"
"Connection: Keep-Alive\r\n"
"\r\n"
"Frop!",
},{
.input =
"HTTP/1.1 200 OK\r\n"
"Date: Sun, 07 Ocu 2012 19:52:03 GMT\r\n"
"Content-Length: 19\r\n"
"Keep-Alive: timeout=15, max=99\r\n"
"Connection: Keep-Alive\r\n"
"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
"\r\n"
"Invalid date header",
},{
.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"
"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
"\r\n"
"Duplicate headers",
}
};
static const unsigned int valid_response_parse_test_count =
static void test_http_response_parse_valid(void)
{
unsigned int i;
for (i = 0; i < valid_response_parse_test_count; i++) T_BEGIN {
int ret = 0;
test = &valid_response_parse_tests[i];
}
j = 0;
while (ret > 0) {
test_out("payload receive",
} else {
}
if (j >= test->responses_count)
break;
/* verify last response only */
} else {
}
if (++j == test->responses_count)
else
}
test_assert(ret == 0);
test_end();
} T_END;
}
/*
* Invalid response tests
*/
struct invalid_parse_test {
const char *input;
};
{
.input =
"XMPP/1.0 302 Found\r\n"
"Location: http://www.example.nl/\r\n"
"Cache-Control: private\r\n"
},{
.input =
"HTTP/1.1 302 Found\r\n"
"Location: http://www.example.nl/\r\n"
"Cache-Control: private\r\n"
},{
.input =
"HTTP/1.1 ABC Found\r\n"
"Location: http://www.example.nl/\r\n"
"Cache-Control: private\r\n"
},{
.input =
"HTTP/1.1 302 \177\r\n"
"Location: http://www.example.nl/\r\n"
"Cache-Control: private\r\n"
},{
.input =
"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 Ocu 2012 19:52:03 GMT\r\n"
"Content-Length: 19\r\n"
"Keep-Alive: timeout=15, max=99\r\n"
"Connection: Keep-Alive\r\n"
"\r\n"
"Invalid date header",
},{
.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"
"Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n"
"\r\n"
"Duplicate headers",
}
};
static const unsigned int invalid_response_parse_test_count =
static void test_http_response_parse_invalid(void)
{
int ret;
unsigned int i;
for (i = 0; i < invalid_response_parse_test_count; i++) T_BEGIN {
const char *test;
while ((ret=http_response_parse_next(parser, HTTP_RESPONSE_PAYLOAD_TYPE_ALLOWED, &response, &error)) > 0);
test_end();
} T_END;
}
/*
* Bad response tests
*/
static const unsigned char bad_response_with_nuls[] =
"HTTP/1.1 200 OK\r\n"
"Server: text\0server\r\n"
"\r\n";
static void test_http_response_parse_bad(void)
{
int ret;
/* parse failure guarantees http_response_header.size equals
strlen(http_response_header.value) */
test_begin("http response with NULs (strict)");
sizeof(bad_response_with_nuls)-1);
test_assert(ret < 0);
test_end();
/* even when lenient, bad characters like NUL must not be returned */
test_begin("http response with NULs (lenient)");
sizeof(bad_response_with_nuls)-1);
}
test_end();
}
int main(void)
{
static void (*const test_functions[])(void) = {
};
return test_run(test_functions);
}