1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
5
#include "test-common.h"
6
#include "http-header-parser.h"
10
struct http_header_parse_result {
15
struct http_header_parse_test {
17
const struct http_header_parse_result *fields;
20
/* Valid header tests */
22
static struct http_header_parse_result valid_header_parse_result1[] = {
23
{ "Date", "Sat, 06 Oct 2012 16:01:44 GMT" },
24
{ "Server", "Apache/2.2.16 (Debian)" },
25
{ "Last-Modified", "Mon, 30 Jul 2012 11:09:28 GMT" },
26
{ "Etag", "\"3d24677-3261-4c60a1863aa00\"" },
27
{ "Accept-Ranges", "bytes" },
28
{ "Vary", "Accept-Encoding" },
29
{ "Content-Encoding", "gzip" },
30
{ "Content-Length", "4092" },
31
{ "Keep-Alive", "timeout=15, max=100" },
32
{ "Connection", "Keep-Alive" },
33
{ "Content-Type", "text/html" },
37
static struct http_header_parse_result valid_header_parse_result2[] = {
38
{ "Host", "p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com" },
39
{ "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)" },
40
{ "Accept", "image/png,image/*;q=0.8,*/*;q=0.5" },
41
{ "Accept-Language", "en-us,en;q=0.5" },
42
{ "Accept-Encoding", "gzip, deflate" },
44
{ "Connection", "keep-alive" },
45
{ "Referer", "http://www.example.nl/" },
49
static struct http_header_parse_result valid_header_parse_result3[] = {
50
{ "Date", "Sat, 06 Oct 2012 17:12:37 GMT" },
51
{ "Server", "Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with"
52
" Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6"
53
" mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1" },
54
{ "WWW-Authenticate", "Basic realm=\"Munin\"" },
55
{ "Vary", "Accept-Encoding" },
56
{ "Content-Encoding", "gzip" },
57
{ "Content-Length", "445" },
58
{ "Keep-Alive", "timeout=15, max=98" },
59
{ "Connection", "Keep-Alive" },
60
{ "Content-Type", "text/html; charset=iso-8859-1" },
64
static struct http_header_parse_result valid_header_parse_result4[] = {
66
{ "Date", "Sun, 04 Aug 2013 09:33:09 GMT" },
67
{ "Expires", "Sun, 04 Aug 2013 09:34:08 GMT" },
68
{ "Cache-Control", "max-age=60" },
69
{ "Content-Length", "17336" },
70
{ "Connection", "Keep-Alive" },
71
{ "Via", "NS-CACHE-9.3" },
72
{ "Server", "Apache" },
74
{ "Last-Modified", "Sun, 04 Aug 2013 09:33:07 GMT" },
75
{ "Content-Type", "text/html; charset=utf-8" },
76
{ "Content-Encoding", "gzip" },
80
static struct http_header_parse_result valid_header_parse_result5[] = {
84
static const struct http_header_parse_test valid_header_parse_tests[] = {
86
"Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n"
87
"Server: Apache/2.2.16 (Debian)\r\n"
88
"Last-Modified: Mon, 30 Jul 2012 11:09:28 GMT\r\n"
89
"Etag: \"3d24677-3261-4c60a1863aa00\"\r\n"
90
"Accept-Ranges: bytes\r\n"
91
"Vary: Accept-Encoding\r\n"
92
"Content-Encoding: gzip\r\n"
93
"Content-Length: 4092\r\n"
94
"Keep-Alive: timeout=15, max=100\r\n"
95
"Connection: Keep-Alive\r\n"
96
"Content-Type: text/html\r\n"
98
.fields = valid_header_parse_result1
101
"Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n"
102
"User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n"
103
"Accept:\t\timage/png,image/*;q=0.8,*/*;q=0.5\n"
104
"Accept-Language:\ten-us,en;q=0.5\n"
105
"Accept-Encoding: \t\tgzip, deflate\n"
107
"Connection: \t\tkeep-alive\n"
108
"Referer: http://www.example.nl/\n"
110
.fields = valid_header_parse_result2
113
"Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
114
"Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n"
115
" Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n"
116
" mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1\r\n"
117
"WWW-Authenticate: Basic realm=\"Munin\"\r\n"
118
"Vary: Accept-Encoding\r\n"
119
"Content-Encoding: gzip\r\n"
120
"Content-Length: 445\r\n"
121
"Keep-Alive: timeout=15, max=98\r\n"
122
"Connection: Keep-Alive\r\n"
123
"Content-Type: text/html; charset=iso-8859-1\r\n"
125
.fields = valid_header_parse_result3
129
"Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
130
"Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
131
"Cache-Control: max-age=60 \r\n"
132
"Content-Length: 17336 \r\n"
133
"Connection: Keep-Alive\r\n"
134
"Via: NS-CACHE-9.3\r\n"
137
"Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
138
"Content-Type: text/html; charset=utf-8\r\n"
139
"Content-Encoding: gzip\r\n"
141
.fields = valid_header_parse_result4
145
.fields = valid_header_parse_result5
149
unsigned int valid_header_parse_test_count = N_ELEMENTS(valid_header_parse_tests);
151
static void test_http_header_parse_valid(void)
155
for (i = 0; i < valid_header_parse_test_count; i++) T_BEGIN {
156
struct istream *input;
157
struct http_header_parser *parser;
158
const char *header, *field_name, *error;
159
const unsigned char *field_data;
162
unsigned int j, pos, header_len;
164
header = valid_header_parse_tests[i].header;
165
header_len = strlen(header);
166
input = test_istream_create_data(header, header_len);
167
parser = http_header_parser_init(input);
169
test_begin(t_strdup_printf("http header valid [%d]", i));
171
j = 0; pos = 0; test_istream_set_size(input, 0);
172
while ((ret=http_header_parse_next_field
173
(parser, &field_name, &field_data, &field_size, &error)) >= 0) {
174
const struct http_header_parse_result *result;
175
const char *field_value;
178
if (pos == header_len)
180
test_istream_set_size(input, ++pos);
184
if (field_name == NULL) break;
186
result = &valid_header_parse_tests[i].fields[j];
187
field_value = t_strndup(field_data, field_size);
189
if (result->name == NULL) {
190
test_out_reason("valid", FALSE,
191
t_strdup_printf("%s: %s", field_name, field_value));
195
test_out_reason("valid",
196
strcmp(result->name, field_name) == 0 &&
197
strcmp(result->value, field_value) == 0,
198
t_strdup_printf("%s: %s", field_name, field_value));
202
test_out("parse success", ret > 0);
204
http_header_parser_deinit(&parser);
208
static const char *invalid_header_parse_tests[] = {
209
"Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n"
210
"Server : Apache/2.2.16 (Debian)\r\n"
211
"Last-Modified: Mon, 30 Jul 2012 11:09:28 GMT\r\n"
213
"Date: Sat, 06 Oct 2012 17:18:22 GMT\r\n"
214
"Server: Apache/2.2.3 (CentOS)\r\n"
215
"X Powered By: PHP/5.3.6\r\n"
217
"Host: www.example.com\n\r"
218
"Accept: image/png,image/*;q=0.8,*/*;q=0.5\n\r"
219
"Accept-Language: en-us,en;q=0.5\n\r"
220
"Accept-Encoding: gzip, deflate\n\r"
222
"Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n"
223
"User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n"
224
"Accept:\t\timage/png,image/*;q=0.8,*/\177;q=0.5\n"
226
"Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
227
"Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n"
228
"Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n"
229
"mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1\r\n"
233
unsigned int invalid_header_parse_test_count = N_ELEMENTS(invalid_header_parse_tests);
235
static void test_http_header_parse_invalid(void)
239
for (i = 0; i < invalid_header_parse_test_count; i++) T_BEGIN {
240
struct istream *input;
241
struct http_header_parser *parser;
242
const char *header, *field_name, *error;
243
const unsigned char *field_data;
247
header = invalid_header_parse_tests[i];
248
input = i_stream_create_from_data(header, strlen(header));
249
parser = http_header_parser_init(input);
251
test_begin(t_strdup_printf("http header invalid [%d]", i));
253
while ((ret=http_header_parse_next_field
254
(parser, &field_name, &field_data, &field_size, &error)) > 0) {
255
if (field_name == NULL) break;
258
test_out("parse failure", ret < 0);
260
http_header_parser_deinit(&parser);
266
static void (*test_functions[])(void) = {
267
test_http_header_parse_valid,
268
test_http_header_parse_invalid,
271
return test_run(test_functions);