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

« back to all changes in this revision

Viewing changes to src/lib-http/test-http-response-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 "buffer.h"
 
5
#include "str.h"
 
6
#include "str-sanitize.h"
 
7
#include "istream.h"
 
8
#include "ostream.h"
 
9
#include "test-common.h"
 
10
#include "http-response-parser.h"
 
11
 
 
12
#include <time.h>
 
13
 
 
14
struct http_response_parse_test {
 
15
        const char *response;
 
16
        unsigned char version_major;
 
17
        unsigned char version_minor;
 
18
        unsigned int status;
 
19
        uoff_t content_length;
 
20
        const char *payload;
 
21
};
 
22
 
 
23
/* Valid header tests */
 
24
 
 
25
static const struct http_response_parse_test
 
26
valid_response_parse_tests[] = {
 
27
        { .response =
 
28
                        "HTTP/1.1 200 OK\r\n"
 
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"
 
38
                        "\r\n"
 
39
                        "This is a piece of stupid text.\r\n",
 
40
                .status = 200,
 
41
                .payload = "This is a piece of stupid text.\r\n"
 
42
        },{ 
 
43
                .response =
 
44
                        "HTTP/1.1 200 OK\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"
 
54
                        "\r\n"
 
55
                        "This is a piece of stupid text.\r\n"
 
56
                        "HTTP/1.1 200 OK\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"
 
66
                        "\r\n"
 
67
                        "This is a piece of even more stupid text.\r\n",
 
68
                .status = 200,
 
69
                .payload = "This is a piece of even more stupid text.\r\n"
 
70
        },{
 
71
                .response =
 
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"
 
82
                        "\r\n"
 
83
                        "Frop!",
 
84
                .status = 401,
 
85
                .payload = "Frop!"
 
86
        }
 
87
};
 
88
 
 
89
unsigned int valid_response_parse_test_count =
 
90
        N_ELEMENTS(valid_response_parse_tests);
 
91
 
 
92
static void test_http_response_parse_valid(void)
 
93
{
 
94
        unsigned int i;
 
95
        buffer_t *payload_buffer = buffer_create_dynamic(default_pool, 1024);
 
96
 
 
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;
 
105
                int ret = 0;
 
106
 
 
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);
 
113
 
 
114
                test_begin(t_strdup_printf("http response valid [%d]", i));
 
115
 
 
116
                payload = NULL;
 
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);
 
120
                }
 
121
                test_istream_set_size(input, response_text_len);
 
122
                while (ret > 0) {
 
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);
 
130
                        } else {
 
131
                                payload = NULL;
 
132
                        }
 
133
                        ret = http_response_parse_next(parser, FALSE, &response, &error);
 
134
                }
 
135
 
 
136
                test_out("parse success", ret == 0);
 
137
                
 
138
                if (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);
 
146
                        } else {
 
147
                                test_out(t_strdup_printf("response->payload = %s",
 
148
                                        str_sanitize(payload, 80)),
 
149
                                        strcmp(payload, test->payload) == 0);
 
150
                        }
 
151
                }
 
152
                test_end();
 
153
                http_response_parser_deinit(&parser);
 
154
        } T_END;
 
155
 
 
156
        buffer_free(&payload_buffer);
 
157
}
 
158
 
 
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"
 
175
};
 
176
 
 
177
static unsigned char invalid_response_with_nuls[] =
 
178
        "HTTP/1.1 200 OK\r\n"
 
179
        "Server: text\0server\r\n"
 
180
        "\r\n";
 
181
 
 
182
unsigned int invalid_response_parse_test_count =
 
183
        N_ELEMENTS(invalid_response_parse_tests);
 
184
 
 
185
static void test_http_response_parse_invalid(void)
 
186
{
 
187
        struct http_response_parser *parser;
 
188
        struct http_response response;
 
189
        const char *response_text, *error;
 
190
        struct istream *input;
 
191
        int ret;
 
192
        unsigned int i;
 
193
 
 
194
        for (i = 0; i < invalid_response_parse_test_count; i++) T_BEGIN {
 
195
                const char *test;
 
196
 
 
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);
 
201
 
 
202
                test_begin(t_strdup_printf("http response invalid [%d]", i));
 
203
 
 
204
                while ((ret=http_response_parse_next(parser, FALSE, &response, &error)) > 0);
 
205
 
 
206
                test_assert(ret < 0);
 
207
                test_end();
 
208
                http_response_parser_deinit(&parser);
 
209
        } T_END;
 
210
 
 
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);
 
219
        test_end();
 
220
}
 
221
 
 
222
int main(void)
 
223
{
 
224
        static void (*test_functions[])(void) = {
 
225
                test_http_response_parse_valid,
 
226
                test_http_response_parse_invalid,
 
227
                NULL
 
228
        };
 
229
        return test_run(test_functions);
 
230
}