1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
6
#include "str-sanitize.h"
9
#include "test-common.h"
10
#include "http-response-parser.h"
14
struct http_response_parse_test {
16
unsigned char version_major;
17
unsigned char version_minor;
19
uoff_t content_length;
23
/* Valid header tests */
25
static const struct http_response_parse_test
26
valid_response_parse_tests[] = {
29
"Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n"
30
"Server: Apache/2.2.16 (Debian)\r\n"
31
"Last-Modified: Tue, 18 Sep 2012 19:31:41 GMT\r\n"
32
"Etag: \"2a8400c-10751f-4c9fef0858140\"\r\n"
33
"Accept-Ranges: bytes\r\n"
34
"Content-Length: 33\r\n"
35
"Keep-Alive: timeout=15, max=100\r\n"
36
"Connection: Keep-Alive\r\n"
37
"Content-Type: text/plain\r\n"
39
"This is a piece of stupid text.\r\n",
41
.payload = "This is a piece of stupid text.\r\n"
45
"Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n"
46
"Server: Apache/2.2.16 (Debian)\r\n"
47
"Last-Modified: Tue, 18 Sep 2012 19:31:41 GMT\r\n"
48
"Etag: \"2a8400c-10751f-4c9fef0858140\"\r\n"
49
"Accept-Ranges: bytes\r\n"
50
"Content-Length: 33\r\n"
51
"Keep-Alive: timeout=15, max=100\r\n"
52
"Connection: Keep-Alive\r\n"
53
"Content-Type: text/plain\r\n"
55
"This is a piece of stupid text.\r\n"
57
"Date: Sun, 07 Oct 2012 13:02:27 GMT\r\n"
58
"Server: Apache/2.2.16 (Debian)\r\n"
59
"Last-Modified: Tue, 18 Sep 2012 19:31:41 GMT\r\n"
60
"Etag: \"2a8400c-10751f-4c9fef0858140\"\r\n"
61
"Accept-Ranges: bytes\r\n"
62
"Content-Length: 43\r\n"
63
"Keep-Alive: timeout=15, max=100\r\n"
64
"Connection: Keep-Alive\r\n"
65
"Content-Type: text/plain\r\n"
67
"This is a piece of even more stupid text.\r\n",
69
.payload = "This is a piece of even more stupid text.\r\n"
72
"HTTP/1.1 401 Authorization Required\r\n"
73
"Date: Sun, 07 Oct 2012 19:52:03 GMT\r\n"
74
"Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14\r\n"
75
"WWW-Authenticate: Basic realm=\"Munin\"\r\n"
76
"Vary: Accept-Encoding\r\n"
77
"Content-Encoding: gzip\r\n"
78
"Content-Length: 5\r\n"
79
"Keep-Alive: timeout=15, max=99\r\n"
80
"Connection: Keep-Alive\r\n"
81
"Content-Type: text/html; charset=iso-8859-1\r\n"
89
unsigned int valid_response_parse_test_count =
90
N_ELEMENTS(valid_response_parse_tests);
92
static void test_http_response_parse_valid(void)
95
buffer_t *payload_buffer = buffer_create_dynamic(default_pool, 1024);
97
for (i = 0; i < valid_response_parse_test_count; i++) T_BEGIN {
98
struct istream *input;
99
struct ostream *output;
100
const struct http_response_parse_test *test;
101
struct http_response_parser *parser;
102
struct http_response response;
103
const char *response_text, *payload, *error;
104
unsigned int pos, response_text_len;
107
memset(&response, 0, sizeof(response));
108
test = &valid_response_parse_tests[i];
109
response_text = test->response;
110
response_text_len = strlen(response_text);
111
input = test_istream_create_data(response_text, response_text_len);
112
parser = http_response_parser_init(input, NULL);
114
test_begin(t_strdup_printf("http response valid [%d]", i));
117
for (pos = 0; pos < response_text_len && ret == 0; pos++) {
118
test_istream_set_size(input, pos);
119
ret = http_response_parse_next(parser, FALSE, &response, &error);
121
test_istream_set_size(input, response_text_len);
123
if (response.payload != NULL) {
124
buffer_set_used_size(payload_buffer, 0);
125
output = o_stream_create_buffer(payload_buffer);
126
test_out("payload receive",
127
o_stream_send_istream(output, response.payload));
128
o_stream_destroy(&output);
129
payload = str_c(payload_buffer);
133
ret = http_response_parse_next(parser, FALSE, &response, &error);
136
test_out("parse success", ret == 0);
139
/* verify last response only */
140
test_out(t_strdup_printf("response->status = %d",test->status),
141
response.status == test->status);
142
if (payload == NULL || test->payload == NULL) {
143
test_out(t_strdup_printf("response->payload = %s",
144
str_sanitize(payload, 80)),
145
payload == test->payload);
147
test_out(t_strdup_printf("response->payload = %s",
148
str_sanitize(payload, 80)),
149
strcmp(payload, test->payload) == 0);
153
http_response_parser_deinit(&parser);
156
buffer_free(&payload_buffer);
159
static const char *invalid_response_parse_tests[] = {
160
"XMPP/1.0 302 Found\r\n"
161
"Location: http://www.example.nl/\r\n"
162
"Cache-Control: private\r\n",
163
"HTTP/1.1 302 Found\r\n"
164
"Location: http://www.example.nl/\r\n"
165
"Cache-Control: private\r\n",
166
"HTTP/1.1 ABC Found\r\n"
167
"Location: http://www.example.nl/\r\n"
168
"Cache-Control: private\r\n",
169
"HTTP/1.1 302 \177\r\n"
170
"Location: http://www.example.nl/\r\n"
171
"Cache-Control: private\r\n",
172
"HTTP/1.1 302 Found\n\r"
173
"Location: http://www.example.nl/\n\r"
174
"Cache-Control: private\n\r"
177
static unsigned char invalid_response_with_nuls[] =
178
"HTTP/1.1 200 OK\r\n"
179
"Server: text\0server\r\n"
182
unsigned int invalid_response_parse_test_count =
183
N_ELEMENTS(invalid_response_parse_tests);
185
static void test_http_response_parse_invalid(void)
187
struct http_response_parser *parser;
188
struct http_response response;
189
const char *response_text, *error;
190
struct istream *input;
194
for (i = 0; i < invalid_response_parse_test_count; i++) T_BEGIN {
197
test = invalid_response_parse_tests[i];
198
response_text = test;
199
input = i_stream_create_from_data(response_text, strlen(response_text));
200
parser = http_response_parser_init(input, NULL);
202
test_begin(t_strdup_printf("http response invalid [%d]", i));
204
while ((ret=http_response_parse_next(parser, FALSE, &response, &error)) > 0);
206
test_assert(ret < 0);
208
http_response_parser_deinit(&parser);
211
/* parse failure guarantees http_response_header.size equals
212
strlen(http_response_header.value) */
213
test_begin("http response with NULs");
214
input = i_stream_create_from_data(invalid_response_with_nuls,
215
sizeof(invalid_response_with_nuls)-1);
216
parser = http_response_parser_init(input, 0);
217
while ((ret=http_response_parse_next(parser, FALSE, &response, &error)) > 0);
218
test_assert(ret < 0);
224
static void (*test_functions[])(void) = {
225
test_http_response_parse_valid,
226
test_http_response_parse_invalid,
229
return test_run(test_functions);