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

« back to all changes in this revision

Viewing changes to src/lib-http/test-http-transfer.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 "strfuncs.h"
 
7
#include "str-sanitize.h"
 
8
#include "istream.h"
 
9
#include "ostream.h"
 
10
#include "test-common.h"
 
11
#include "http-transfer.h"
 
12
 
 
13
#include <time.h>
 
14
 
 
15
struct http_transfer_chunked_input_test {
 
16
        const char *in;
 
17
        const char *out;
 
18
};
 
19
 
 
20
/* Valid transfer_chunked input tests */
 
21
static struct http_transfer_chunked_input_test
 
22
valid_transfer_chunked_input_tests[] = {
 
23
        {       .in = "1E\r\n"
 
24
                        "This is a simple test payload."
 
25
                        "\r\n"
 
26
                        "0\r\n"
 
27
                        "\r\n",
 
28
                .out =
 
29
                        "This is a simple test payload."
 
30
        },
 
31
        {       .in = "20\r\n"
 
32
                        "This is a longer test payload..."
 
33
                        "\r\n"
 
34
                        "23\r\n"
 
35
                        "...spread over two separate chunks."
 
36
                        "\r\n"
 
37
                        "0\r\n"
 
38
                        "\r\n",
 
39
                .out =
 
40
                        "This is a longer test payload..."
 
41
                        "...spread over two separate chunks."
 
42
        },
 
43
        {       .in = "26\r\n"
 
44
                        "This is an even longer test payload..."
 
45
                        "\r\n"
 
46
                        "27\r\n"
 
47
                        "...spread over three separate chunks..."
 
48
                        "\r\n"
 
49
                        "1F\r\n"
 
50
                        "...and also includes a trailer."
 
51
                        "\r\n"
 
52
                        "0\r\n"
 
53
                        "Checksum: adgfef3fdaf3daf3dfaf3ff3fdag\r\n"
 
54
                        "X-Dovecot: Whatever\r\n"
 
55
                        "\r\n",
 
56
                .out =
 
57
                        "This is an even longer test payload..."
 
58
                        "...spread over three separate chunks..."
 
59
                        "...and also includes a trailer."
 
60
        },
 
61
        {       .in = "26\n"
 
62
                        "This is an even longer test payload..."
 
63
                        "\n"
 
64
                        "27\n"
 
65
                        "...spread over three separate chunks..."
 
66
                        "\n"
 
67
                        "1F\n"
 
68
                        "...and also includes a trailer."
 
69
                        "\n"
 
70
                        "0\n"
 
71
                        "Checksum: adgfef3fdaf3daf3dfaf3ff3fdag\n"
 
72
                        "X-Dovecot: Whatever\n"
 
73
                        "\n",
 
74
                .out =
 
75
                        "This is an even longer test payload..."
 
76
                        "...spread over three separate chunks..."
 
77
                        "...and also includes a trailer."
 
78
        }
 
79
};
 
80
 
 
81
static unsigned int valid_transfer_chunked_input_test_count =
 
82
        N_ELEMENTS(valid_transfer_chunked_input_tests);
 
83
 
 
84
static void test_http_transfer_chunked_input_valid(void)
 
85
{
 
86
        struct istream *input, *chunked;
 
87
        struct ostream *output;
 
88
        buffer_t *payload_buffer;
 
89
        unsigned int i;
 
90
 
 
91
        payload_buffer = buffer_create_dynamic(default_pool, 1024);
 
92
 
 
93
        for (i = 0; i < valid_transfer_chunked_input_test_count; i++) T_BEGIN {
 
94
                const char *in, *out, *stream_out;
 
95
 
 
96
                in = valid_transfer_chunked_input_tests[i].in;
 
97
                out = valid_transfer_chunked_input_tests[i].out;
 
98
 
 
99
                test_begin(t_strdup_printf("http transfer_chunked input valid [%d]", i));
 
100
 
 
101
                input = i_stream_create_from_data(in, strlen(in));
 
102
                chunked = http_transfer_chunked_istream_create(input, 0);
 
103
 
 
104
                buffer_set_used_size(payload_buffer, 0);
 
105
                output = o_stream_create_buffer(payload_buffer);
 
106
                test_out("payload read", o_stream_send_istream(output, chunked) > 0
 
107
                        && chunked->stream_errno == 0);
 
108
                o_stream_destroy(&output);
 
109
                stream_out = str_c(payload_buffer);
 
110
 
 
111
                test_out(t_strdup_printf("response->payload = %s",
 
112
                        str_sanitize(stream_out, 80)),
 
113
                        strcmp(stream_out, out) == 0);
 
114
                test_end();
 
115
        } T_END;
 
116
 
 
117
        buffer_free(&payload_buffer);
 
118
}
 
119
 
 
120
/* Invalid transfer_chunked input tests */
 
121
static const char *
 
122
invalid_transfer_chunked_input_tests[] = {
 
123
        // invalid size
 
124
        "1X\r\n"
 
125
        "This is a simple test payload."
 
126
        "\r\n"
 
127
        "0\r\n"
 
128
        "\r\n",
 
129
        // invalid end
 
130
        "1E\r\n"
 
131
        "This is a simple test payload."
 
132
        "\r\n"
 
133
        "0\r\n"
 
134
        "ah\r\n",
 
135
        // invalid size
 
136
        "20\r\n"
 
137
        "This is a longer test payload..."
 
138
        "\r\n"
 
139
        "2q\r\n"
 
140
        "...spread over two separate chunks."
 
141
        "\r\n"
 
142
        "0\r\n"
 
143
        "\r\n",
 
144
        // invalid end
 
145
        "20\r\n"
 
146
        "This is a longer test payload..."
 
147
        "\r\n"
 
148
        "23\r\n"
 
149
        "...spread over two separate chunks."
 
150
        "\r\n"
 
151
        "0\r\n",
 
152
        // invalid last chunk
 
153
        "20\r\n"
 
154
        "This is a longer test payload..."
 
155
        "\r\n"
 
156
        "23\r\n"
 
157
        "...spread over two separate chunks."
 
158
        "\r\n"
 
159
        "4\r\n"
 
160
        "\r\n",
 
161
        // invalid trailer
 
162
        "26\r\n"
 
163
        "This is an even longer test payload..."
 
164
        "\r\n"
 
165
        "27\r\n"
 
166
        "...spread over three separate chunks..."
 
167
        "\r\n"
 
168
        "1F\r\n"
 
169
        "...and also includes a trailer."
 
170
        "\r\n"
 
171
        "0\r\n"
 
172
        "Checksum adgfef3fdaf3daf3dfaf3ff3fdag\r\n"
 
173
        "\r\n"
 
174
};
 
175
 
 
176
static unsigned int invalid_transfer_chunked_input_test_count =
 
177
        N_ELEMENTS(invalid_transfer_chunked_input_tests);
 
178
 
 
179
static void test_http_transfer_chunked_input_invalid(void)
 
180
{
 
181
        struct istream *input, *chunked;
 
182
        struct ostream *output;
 
183
        buffer_t *payload_buffer;
 
184
        unsigned int i;
 
185
 
 
186
        payload_buffer = buffer_create_dynamic(default_pool, 1024);
 
187
 
 
188
        for (i = 0; i < invalid_transfer_chunked_input_test_count; i++) T_BEGIN {
 
189
                const char *in;
 
190
 
 
191
                in = invalid_transfer_chunked_input_tests[i];
 
192
 
 
193
                test_begin(t_strdup_printf("http transfer_chunked input invalid [%d]", i));
 
194
 
 
195
                input = i_stream_create_from_data(in, strlen(in));
 
196
                chunked = http_transfer_chunked_istream_create(input, 0);
 
197
 
 
198
                buffer_set_used_size(payload_buffer, 0);
 
199
                output = o_stream_create_buffer(payload_buffer);
 
200
                (void)o_stream_send_istream(output, chunked);
 
201
                test_out("payload read failure", chunked->stream_errno != 0);
 
202
                o_stream_destroy(&output);
 
203
 
 
204
                test_end();
 
205
        } T_END;
 
206
 
 
207
        buffer_free(&payload_buffer);
 
208
}
 
209
 
 
210
/* Valid transfer_chunked output tests */
 
211
static const char *valid_transfer_chunked_output_tests[] = {
 
212
        /* The maximum chunk size is set to 16. These tests are tuned to some border
 
213
           cases 
 
214
        */
 
215
        "A small payload",  // 15 bytes
 
216
        "A longer payload", // 16 bytes
 
217
        "A lengthy payload", // 17 bytes
 
218
        /* Others */
 
219
        "This is a test payload with lots of nonsense.",
 
220
        "Yet another payload.",
 
221
        "This a very long repetitive payload. This a very long repetitive payload. "
 
222
        "This a very long repetitive payload. This a very long repetitive payload. "
 
223
        "This a very long repetitive payload. This a very long repetitive payload. "
 
224
        "This a very long repetitive payload. This a very long repetitive payload. "
 
225
        "This a very long repetitive payload. This a very long repetitive payload. "
 
226
        "This a very long repetitive payload. This a very long repetitive payload. "
 
227
        "This a very long repetitive payload. This a very long repetitive payload. "
 
228
        "This a very long repetitive payload. This a very long repetitive payload. "
 
229
        "This a very long repetitive payload. This a very long repetitive payload. "
 
230
        "This a very long repetitive payload. This a very long repetitive payload. "
 
231
        "This a very long repetitive payload. This a very long repetitive payload. "
 
232
        "This a very long repetitive payload. This a very long repetitive payload. "
 
233
        "This a very long repetitive payload. This a very long repetitive payload. "
 
234
        "This a very long repetitive payload. This a very long repetitive payload. "
 
235
        "This a very long repetitive payload. This a very long repetitive payload. "
 
236
        "This a very long repetitive payload. This a very long repetitive payload. "
 
237
        "This a very long repetitive payload. This a very long repetitive payload. "
 
238
        "This a very long repetitive payload. This a very long repetitive payload. "
 
239
        "This a very long repetitive payload. This a very long repetitive payload. "
 
240
}; 
 
241
 
 
242
static unsigned int valid_transfer_chunked_output_test_count =
 
243
        N_ELEMENTS(valid_transfer_chunked_output_tests);
 
244
 
 
245
static void test_http_transfer_chunked_output_valid(void)
 
246
{
 
247
        struct istream *input, *ichunked;
 
248
        struct ostream *output, *ochunked;
 
249
        buffer_t *chunked_buffer, *plain_buffer;
 
250
        unsigned int i;
 
251
 
 
252
        chunked_buffer = buffer_create_dynamic(default_pool, 1024);
 
253
        plain_buffer = buffer_create_dynamic(default_pool, 1024);
 
254
 
 
255
        for (i = 0; i < valid_transfer_chunked_output_test_count; i++) T_BEGIN {
 
256
                const char *data, *stream_out;
 
257
                const unsigned char *rdata;
 
258
                size_t rsize;
 
259
                ssize_t ret;
 
260
 
 
261
                data = valid_transfer_chunked_output_tests[i];
 
262
 
 
263
                test_begin(t_strdup_printf("http transfer_chunked output valid [%d]", i));
 
264
 
 
265
                /* create input stream */
 
266
                input = i_stream_create_from_data(data, strlen(data));
 
267
 
 
268
                /* create buffer output stream */
 
269
                buffer_set_used_size(chunked_buffer, 0);
 
270
                output = o_stream_create_buffer(chunked_buffer);
 
271
 
 
272
                /* create chunked output stream */
 
273
                ochunked = http_transfer_chunked_ostream_create(output);
 
274
 
 
275
                /* send input through chunked stream; chunk size is limited */
 
276
                for (;;) {
 
277
                        ret = i_stream_read_data(input, &rdata, &rsize, 0);
 
278
                        if (ret < 0) {
 
279
                                if (input->eof)
 
280
                                        ret = 1;
 
281
                                break;
 
282
                        }
 
283
                        if (rsize == 0) 
 
284
                                break;
 
285
                        if (rsize > 16)
 
286
                                rsize = 16;
 
287
 
 
288
                        ret = o_stream_send(ochunked, rdata, rsize);
 
289
                        if (ret < 0)
 
290
                                break;
 
291
 
 
292
                        if ((size_t)ret != rsize) {
 
293
                                ret = -1;
 
294
                                break;
 
295
                        }
 
296
 
 
297
                        i_stream_skip(input, ret);
 
298
                }
 
299
 
 
300
                /* cleanup streams */
 
301
                test_out("payload chunk", ret > 0);
 
302
                o_stream_destroy(&ochunked);
 
303
                o_stream_destroy(&output);
 
304
                i_stream_destroy(&input);
 
305
                
 
306
                /* create chunked input stream */
 
307
                input = i_stream_create_from_data
 
308
                        (chunked_buffer->data, chunked_buffer->used);
 
309
                ichunked = http_transfer_chunked_istream_create(input, 0);
 
310
 
 
311
                /* read back chunk */
 
312
                buffer_set_used_size(plain_buffer, 0);
 
313
                output = o_stream_create_buffer(plain_buffer);
 
314
                ret = o_stream_send_istream(output, ichunked);
 
315
                test_out("payload unchunk", ret >= 0
 
316
                        && ichunked->stream_errno == 0);
 
317
                o_stream_destroy(&output);
 
318
                i_stream_destroy(&ichunked);
 
319
                i_stream_destroy(&input);
 
320
 
 
321
                /* test output */
 
322
                stream_out = str_c(plain_buffer);
 
323
                test_out(t_strdup_printf("response->payload = %s",
 
324
                        str_sanitize(stream_out, 80)),
 
325
                        strcmp(stream_out, data) == 0);
 
326
                test_end();
 
327
        } T_END;
 
328
 
 
329
        buffer_free(&chunked_buffer);
 
330
        buffer_free(&plain_buffer);
 
331
}
 
332
 
 
333
int main(void)
 
334
{
 
335
        static void (*test_functions[])(void) = {
 
336
                test_http_transfer_chunked_input_valid,
 
337
                test_http_transfer_chunked_input_invalid,
 
338
                test_http_transfer_chunked_output_valid,
 
339
                NULL
 
340
        };
 
341
        return test_run(test_functions);
 
342
}