~ubuntu-branches/ubuntu/utopic/dovecot/utopic-proposed

« back to all changes in this revision

Viewing changes to src/lib-http/test-http-header-parser.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (4.1.35 sid)
  • Revision ID: package-import@ubuntu.com-20140108093549-i72o93pux8p0dlaf
Tags: 1:2.2.9-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
 
2
 
 
3
#include "test-lib.h"
 
4
#include "istream.h"
 
5
#include "test-common.h"
 
6
#include "http-response.h"
 
7
#include "http-header-parser.h"
 
8
 
 
9
#include <time.h>
 
10
 
 
11
struct http_header_parse_result {
 
12
        const char *name;
 
13
        const char *value;
 
14
};
 
15
 
 
16
struct http_header_parse_test {
 
17
        const char *header;
 
18
        struct http_header_limits limits;
 
19
        const struct http_header_parse_result *fields;
 
20
};
 
21
 
 
22
/* Valid header tests */
 
23
 
 
24
static struct http_header_parse_result valid_header_parse_result1[] = {
 
25
        { "Date", "Sat, 06 Oct 2012 16:01:44 GMT" },
 
26
        { "Server", "Apache/2.2.16 (Debian)" },
 
27
        { "Last-Modified", "Mon, 30 Jul 2012 11:09:28 GMT" },
 
28
        { "Etag", "\"3d24677-3261-4c60a1863aa00\"" },
 
29
        { "Accept-Ranges", "bytes" },
 
30
        { "Vary", "Accept-Encoding" },
 
31
        { "Content-Encoding", "gzip" },
 
32
        { "Content-Length", "4092" },
 
33
        { "Keep-Alive", "timeout=15, max=100" },
 
34
        { "Connection", "Keep-Alive" },
 
35
        { "Content-Type", "text/html" },
 
36
        { NULL, NULL }
 
37
};
 
38
 
 
39
static struct http_header_parse_result valid_header_parse_result2[] = {
 
40
        { "Host", "p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com" },
 
41
        { "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)" },
 
42
        { "Accept", "image/png,image/*;q=0.8,*/*;q=0.5" },
 
43
        { "Accept-Language", "en-us,en;q=0.5" },
 
44
        { "Accept-Encoding", "gzip, deflate" },
 
45
        { "DNT", "1" },
 
46
        { "Connection", "keep-alive" },
 
47
        { "Referer", "http://www.example.nl/" },
 
48
        { NULL, NULL }
 
49
};
 
50
 
 
51
static struct http_header_parse_result valid_header_parse_result3[] = {
 
52
        { "Date", "Sat, 06 Oct 2012 17:12:37 GMT" },
 
53
        { "Server", "Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with"
 
54
                " Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6"
 
55
                " mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1" },
 
56
        { "WWW-Authenticate", "Basic realm=\"Munin\"" },
 
57
        { "Vary", "Accept-Encoding" },
 
58
        { "Content-Encoding", "gzip" },
 
59
        { "Content-Length", "445" },
 
60
        { "Keep-Alive", "timeout=15, max=98" },
 
61
        { "Connection", "Keep-Alive" },
 
62
        { "Content-Type", "text/html; charset=iso-8859-1" },
 
63
        { NULL, NULL }
 
64
};
 
65
 
 
66
static struct http_header_parse_result valid_header_parse_result4[] = {
 
67
        { "Age", "58" },
 
68
        { "Date", "Sun, 04 Aug 2013 09:33:09 GMT" },
 
69
        { "Expires", "Sun, 04 Aug 2013 09:34:08 GMT" },
 
70
        { "Cache-Control", "max-age=60" },
 
71
        { "Content-Length", "17336" },
 
72
        { "Connection", "Keep-Alive" },
 
73
        { "Via", "NS-CACHE-9.3" },
 
74
        { "Server", "Apache" },
 
75
        { "Vary", "Host" },
 
76
        { "Last-Modified", "Sun, 04 Aug 2013 09:33:07 GMT" },
 
77
        { "Content-Type", "text/html; charset=utf-8" },
 
78
        { "Content-Encoding", "gzip" },
 
79
        { NULL, NULL }
 
80
};
 
81
 
 
82
static struct http_header_parse_result valid_header_parse_result5[] = {
 
83
        { NULL, NULL }
 
84
};
 
85
 
 
86
static const struct http_header_parse_test valid_header_parse_tests[] = {
 
87
        { .header = 
 
88
                        "Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n"
 
89
                        "Server: Apache/2.2.16 (Debian)\r\n"
 
90
                        "Last-Modified: Mon, 30 Jul 2012 11:09:28 GMT\r\n"
 
91
                        "Etag: \"3d24677-3261-4c60a1863aa00\"\r\n"
 
92
                        "Accept-Ranges: bytes\r\n"
 
93
                        "Vary: Accept-Encoding\r\n"
 
94
                        "Content-Encoding: gzip\r\n"
 
95
                        "Content-Length: 4092\r\n"
 
96
                        "Keep-Alive: timeout=15, max=100\r\n"
 
97
                        "Connection: Keep-Alive\r\n"
 
98
                        "Content-Type: text/html\r\n"
 
99
                        "\r\n",
 
100
                .fields = valid_header_parse_result1
 
101
        },{
 
102
                .header =
 
103
                        "Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n"
 
104
                        "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n"
 
105
                        "Accept:\t\timage/png,image/*;q=0.8,*/*;q=0.5\n"
 
106
                        "Accept-Language:\ten-us,en;q=0.5\n"
 
107
                        "Accept-Encoding: \t\tgzip, deflate\n"
 
108
                        "DNT:   1\n"
 
109
                        "Connection: \t\tkeep-alive\n"
 
110
                        "Referer:   http://www.example.nl/\n"
 
111
                        "\n",
 
112
                .fields = valid_header_parse_result2
 
113
        },{
 
114
                .header =
 
115
                        "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
 
116
                        "Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n"
 
117
                        " Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n"
 
118
                        " mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1\r\n"
 
119
                        "WWW-Authenticate: Basic realm=\"Munin\"\r\n"
 
120
                        "Vary: Accept-Encoding\r\n"
 
121
                        "Content-Encoding: gzip\r\n"
 
122
                        "Content-Length: 445\r\n"
 
123
                        "Keep-Alive: timeout=15, max=98\r\n"
 
124
                        "Connection: Keep-Alive\r\n"
 
125
                        "Content-Type: text/html; charset=iso-8859-1\r\n"
 
126
                        "\r\n",
 
127
                .fields = valid_header_parse_result3
 
128
        },{
 
129
                .header = 
 
130
                        "Age: 58        \r\n"
 
131
                        "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
 
132
                        "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
 
133
                        "Cache-Control: max-age=60        \r\n"
 
134
                        "Content-Length: 17336     \r\n"
 
135
                        "Connection: Keep-Alive\r\n"
 
136
                        "Via: NS-CACHE-9.3\r\n"
 
137
                        "Server: Apache\r\n"
 
138
                        "Vary: Host\r\n"
 
139
                        "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
 
140
                        "Content-Type: text/html; charset=utf-8\r\n"
 
141
                        "Content-Encoding: gzip\r\n"
 
142
                        "\r\n",
 
143
                .fields = valid_header_parse_result4,
 
144
                .limits = {
 
145
                        .max_size = 340,
 
146
                        .max_field_size = 46,
 
147
                        .max_fields = 12
 
148
                }
 
149
        },{
 
150
                .header =
 
151
                        "\r\n",
 
152
                .fields = valid_header_parse_result5
 
153
        }
 
154
};
 
155
 
 
156
unsigned int valid_header_parse_test_count = N_ELEMENTS(valid_header_parse_tests);
 
157
 
 
158
static void test_http_header_parse_valid(void)
 
159
{
 
160
        unsigned int i;
 
161
 
 
162
        for (i = 0; i < valid_header_parse_test_count; i++) T_BEGIN {
 
163
                struct istream *input;
 
164
                struct http_header_parser *parser;
 
165
                const struct http_header_limits *limits;
 
166
                const char *header, *field_name, *error = NULL;
 
167
                const unsigned char *field_data;
 
168
                size_t field_size;
 
169
                int ret;
 
170
                unsigned int j, pos, header_len;
 
171
 
 
172
                header = valid_header_parse_tests[i].header;
 
173
                header_len = strlen(header);
 
174
                limits = &valid_header_parse_tests[i].limits;
 
175
                input = test_istream_create_data(header, header_len);
 
176
                parser = http_header_parser_init(input, limits);
 
177
 
 
178
                test_begin(t_strdup_printf("http header valid [%d]", i));
 
179
 
 
180
                j = 0; pos = 0; test_istream_set_size(input, 0);
 
181
                while ((ret=http_header_parse_next_field
 
182
                        (parser, &field_name, &field_data, &field_size, &error)) >= 0) {
 
183
                        const struct http_header_parse_result *result;
 
184
                        const char *field_value;
 
185
 
 
186
                        if (ret == 0) {
 
187
                                if (pos == header_len)
 
188
                                        break;
 
189
                                test_istream_set_size(input, ++pos);
 
190
                                continue;
 
191
                        }
 
192
 
 
193
                        if (field_name == NULL) break;
 
194
 
 
195
                        result = &valid_header_parse_tests[i].fields[j];
 
196
                        field_value = t_strndup(field_data, field_size);
 
197
 
 
198
                        if (result->name == NULL) {
 
199
                                test_out_reason("valid", FALSE,
 
200
                                        t_strdup_printf("%s: %s", field_name, field_value));
 
201
                                break;
 
202
                        }
 
203
 
 
204
                        test_out_reason("valid",
 
205
                                strcmp(result->name, field_name) == 0 &&
 
206
                                strcmp(result->value, field_value) == 0,
 
207
                                t_strdup_printf("%s: %s", field_name, field_value));
 
208
                        j++;
 
209
                }
 
210
 
 
211
                test_out_reason("parse success", ret > 0, error);
 
212
                test_end();
 
213
                http_header_parser_deinit(&parser);
 
214
        } T_END;
 
215
}
 
216
 
 
217
static const struct http_header_parse_test invalid_header_parse_tests[] = {
 
218
        {
 
219
                .header = 
 
220
                        "Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n"
 
221
                        "Server : Apache/2.2.16 (Debian)\r\n"
 
222
                        "Last-Modified: Mon, 30 Jul 2012 11:09:28 GMT\r\n"
 
223
                        "\r\n"
 
224
        },{
 
225
                .header = 
 
226
                        "Date: Sat, 06 Oct 2012 17:18:22 GMT\r\n"
 
227
                        "Server: Apache/2.2.3 (CentOS)\r\n"
 
228
                        "X Powered By: PHP/5.3.6\r\n"
 
229
                        "\r\n"
 
230
        },{
 
231
                .header = 
 
232
                        "Host: www.example.com\n\r"
 
233
                        "Accept: image/png,image/*;q=0.8,*/*;q=0.5\n\r"
 
234
                        "Accept-Language: en-us,en;q=0.5\n\r"
 
235
                        "Accept-Encoding: gzip, deflate\n\r"
 
236
                        "\n\r"
 
237
        },{
 
238
                .header = 
 
239
                        "Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n"
 
240
                        "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n"
 
241
                        "Accept:\t\timage/png,image/*;q=0.8,*/\177;q=0.5\n"
 
242
                        "\n"
 
243
        },{
 
244
                .header = 
 
245
                        "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
 
246
                        "Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n"
 
247
                        "Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n"
 
248
                        "mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1\r\n"
 
249
                        "\r\n"
 
250
        },{
 
251
                .header = 
 
252
                        "Age: 58        \r\n"
 
253
                        "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
 
254
                        "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
 
255
                        "Cache-Control: max-age=60        \r\n"
 
256
                        "Content-Length: 17336     \r\n"
 
257
                        "Connection: Keep-Alive\r\n"
 
258
                        "Via: NS-CACHE-9.3\r\n"
 
259
                        "Server: Apache\r\n"
 
260
                        "Vary: Host\r\n"
 
261
                        "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
 
262
                        "Content-Type: text/html; charset=utf-8\r\n"
 
263
                        "Content-Encoding: gzip\r\n"
 
264
                        "\r\n",
 
265
                .limits = { .max_size = 339 }
 
266
        },{
 
267
                .header = 
 
268
                        "Age: 58        \r\n"
 
269
                        "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
 
270
                        "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
 
271
                        "Cache-Control: max-age=60        \r\n"
 
272
                        "Content-Length: 17336     \r\n"
 
273
                        "Connection: Keep-Alive\r\n"
 
274
                        "Via: NS-CACHE-9.3\r\n"
 
275
                        "Server: Apache\r\n"
 
276
                        "Vary: Host\r\n"
 
277
                        "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
 
278
                        "Content-Type: text/html; charset=utf-8\r\n"
 
279
                        "Content-Encoding: gzip\r\n"
 
280
                        "\r\n",
 
281
                .fields = valid_header_parse_result4,
 
282
                .limits = { .max_field_size = 45 }
 
283
        },{
 
284
                .header = 
 
285
                        "Age: 58        \r\n"
 
286
                        "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
 
287
                        "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
 
288
                        "Cache-Control: max-age=60        \r\n"
 
289
                        "Content-Length: 17336     \r\n"
 
290
                        "Connection: Keep-Alive\r\n"
 
291
                        "Via: NS-CACHE-9.3\r\n"
 
292
                        "Server: Apache\r\n"
 
293
                        "Vary: Host\r\n"
 
294
                        "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
 
295
                        "Content-Type: text/html; charset=utf-8\r\n"
 
296
                        "Content-Encoding: gzip\r\n"
 
297
                        "\r\n",
 
298
                .fields = valid_header_parse_result4,
 
299
                .limits = { .max_fields = 11 }
 
300
        }
 
301
};
 
302
 
 
303
unsigned int invalid_header_parse_test_count = N_ELEMENTS(invalid_header_parse_tests);
 
304
 
 
305
static void test_http_header_parse_invalid(void)
 
306
{
 
307
        unsigned int i;
 
308
 
 
309
        for (i = 0; i < invalid_header_parse_test_count; i++) T_BEGIN {
 
310
                struct istream *input;
 
311
                struct http_header_parser *parser;
 
312
                const struct http_header_limits *limits;
 
313
                const char *header, *field_name, *error = NULL;
 
314
                const unsigned char *field_data;
 
315
                size_t field_size;
 
316
                int ret;
 
317
 
 
318
                header = invalid_header_parse_tests[i].header;
 
319
                limits = &invalid_header_parse_tests[i].limits;
 
320
                input = i_stream_create_from_data(header, strlen(header));
 
321
                parser = http_header_parser_init(input, limits);
 
322
 
 
323
                test_begin(t_strdup_printf("http header invalid [%d]", i));
 
324
 
 
325
                while ((ret=http_header_parse_next_field
 
326
                        (parser, &field_name, &field_data, &field_size, &error)) > 0) {
 
327
                        if (field_name == NULL) break;
 
328
                }
 
329
 
 
330
                test_out_reason("parse failure", ret < 0, error);
 
331
                test_end();
 
332
                http_header_parser_deinit(&parser);
 
333
        } T_END;
 
334
}
 
335
 
 
336
int main(void)
 
337
{
 
338
        static void (*test_functions[])(void) = {
 
339
                test_http_header_parse_valid,
 
340
                test_http_header_parse_invalid,
 
341
                NULL
 
342
        };
 
343
        return test_run(test_functions);
 
344
}