1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
6
#include "write-full.h"
8
#include "http-client.h"
10
struct http_test_request {
12
struct istream *payload;
16
static void payload_input(struct http_test_request *req)
18
const unsigned char *data;
23
while ((ret=i_stream_read_data(req->payload, &data, &size, 0)) > 0) {
24
i_info("DEBUG: got data (size=%d)", (int)size);
25
if (req->write_output)
26
write_full(1, data, size);
27
i_stream_skip(req->payload, size);
31
i_info("DEBUG: REQUEST: NEED MORE DATA");
32
/* we will be called again for this request */
34
if (req->payload->stream_errno != 0)
35
i_error("REQUEST PAYLOAD READ ERROR: %m");
37
i_info("DEBUG: REQUEST: Finished");
39
i_stream_unref(&req->payload);
45
got_request_response(const struct http_response *response,
46
struct http_test_request *req)
48
if (response->status / 100 != 2) {
49
i_error("HTTP Request failed: %s", response->reason);
51
/* payload (if any) is skipped implicitly */
55
i_info("DEBUG: REQUEST SUCCEEDED: %s", response->reason);
57
if (response->payload == NULL) {
62
i_info("DEBUG: REQUEST: Got payload");
63
i_stream_ref(response->payload);
64
req->payload = response->payload;
65
req->io = io_add(i_stream_get_fd(response->payload), IO_READ,
70
static const char *test_query1 = "data=Frop&submit=Submit";
71
static const char *test_query2 = "data=This%20is%20a%20test&submit=Submit";
72
static const char *test_query3 = "foo=bar";
74
static void run_tests(struct http_client *http_client)
76
struct http_client_request *http_req;
77
struct http_test_request *test_req;
78
struct istream *post_payload;
80
// JigSAW is useful for testing: http://jigsaw.w3.org/HTTP/
82
test_req = i_new(struct http_test_request, 1);
83
http_req = http_client_request(http_client,
84
"GET", "pigeonhole.dovecot.org", "/",
85
got_request_response, test_req);
86
http_client_request_submit(http_req);
88
test_req = i_new(struct http_test_request, 1);
89
http_req = http_client_request(http_client,
90
"GET", "pigeonhole.dovecot.org", "/download.html",
91
got_request_response, test_req);
92
http_client_request_submit(http_req);
94
test_req = i_new(struct http_test_request, 1);
95
http_req = http_client_request(http_client,
96
"GET", "jigsaw.w3.org", "/HTTP/300/301.html",
97
got_request_response, test_req);
98
http_client_request_submit(http_req);
100
test_req = i_new(struct http_test_request, 1);
101
http_req = http_client_request(http_client,
102
"GET", "pigeonhole.dovecot.org", "/frop.html",
103
got_request_response, test_req);
104
http_client_request_submit(http_req);
106
test_req = i_new(struct http_test_request, 1);
107
http_req = http_client_request(http_client,
108
"GET", "jigsaw.w3.org", "/HTTP/300/307.html",
109
got_request_response, test_req);
110
http_client_request_submit(http_req);
112
test_req = i_new(struct http_test_request, 1);
113
http_req = http_client_request(http_client,
114
"GET", "pigeonhole.dovecot.org", "/documentation.html",
115
got_request_response, test_req);
116
http_client_request_set_urgent(http_req);
117
http_client_request_submit(http_req);
119
test_req = i_new(struct http_test_request, 1);
120
http_req = http_client_request(http_client,
121
"GET", "jigsaw.w3.org", "/HTTP/300/302.html",
122
got_request_response, test_req);
123
http_client_request_submit(http_req);
125
test_req = i_new(struct http_test_request, 1);
126
http_req = http_client_request(http_client,
127
"POST", "test.dovecot.org", "/http/post/index.php",
128
got_request_response, test_req);
129
post_payload = i_stream_create_from_data
130
((unsigned char *)test_query1, strlen(test_query1));
131
http_client_request_set_payload(http_req, post_payload, FALSE);
132
i_stream_unref(&post_payload);
133
http_client_request_add_header(http_req,
134
"Content-Type", "application/x-www-form-urlencoded");
135
http_client_request_submit(http_req);
137
test_req = i_new(struct http_test_request, 1);
138
http_req = http_client_request(http_client,
139
"POST", "test.dovecot.org", "/http/post/index.php",
140
got_request_response, test_req);
141
post_payload = i_stream_create_from_data
142
((unsigned char *)test_query2, strlen(test_query2));
143
http_client_request_set_payload(http_req, post_payload, TRUE);
144
i_stream_unref(&post_payload);
145
http_client_request_add_header(http_req,
146
"Content-Type", "application/x-www-form-urlencoded");
147
http_client_request_submit(http_req);
149
test_req = i_new(struct http_test_request, 1);
150
http_req = http_client_request(http_client,
151
"GET", "pigeonhole.dovecot.org", "/",
152
got_request_response, test_req);
153
http_client_request_set_port(http_req, 81);
154
http_client_request_submit(http_req);
156
test_req = i_new(struct http_test_request, 1);
157
http_req = http_client_request(http_client,
158
"HEAD", "pigeonhole.dovecot.org", "/download.html",
159
got_request_response, test_req);
160
http_client_request_submit(http_req);
162
test_req = i_new(struct http_test_request, 1);
163
http_req = http_client_request(http_client,
164
"GET", "pigeonhole.dovecot.org", "/",
165
got_request_response, test_req);
166
http_client_request_set_ssl(http_req, TRUE);
167
http_client_request_submit(http_req);
169
test_req = i_new(struct http_test_request, 1);
170
http_req = http_client_request(http_client,
171
"GET", "pigeonhole.dovecot.org", "/download.html",
172
got_request_response, test_req);
173
http_client_request_set_ssl(http_req, TRUE);
174
http_client_request_submit(http_req);
176
test_req = i_new(struct http_test_request, 1);
177
http_req = http_client_request(http_client,
178
"GET", "pigeonhole.dovecot.org", "/documentation.html",
179
got_request_response, test_req);
180
http_client_request_set_ssl(http_req, TRUE);
181
http_client_request_submit(http_req);
182
http_client_request_abort(&http_req);
185
test_req = i_new(struct http_test_request, 1);
186
http_req = http_client_request(http_client,
187
"POST", "posttestserver.com", "/post.php",
188
got_request_response, test_req);
189
post_payload = i_stream_create_from_data
190
((unsigned char *)test_query1, strlen(test_query1));
191
http_client_request_set_payload(http_req, post_payload, TRUE);
192
i_stream_unref(&post_payload);
193
http_client_request_set_ssl(http_req, TRUE);
194
http_client_request_submit(http_req);
196
test_req = i_new(struct http_test_request, 1);
197
http_req = http_client_request(http_client,
198
"POST", "posttestserver.com", "/post.php",
199
got_request_response, test_req);
200
post_payload = i_stream_create_from_data
201
((unsigned char *)test_query1, strlen(test_query1));
202
http_client_request_set_payload(http_req, post_payload, TRUE);
203
i_stream_unref(&post_payload);
204
http_client_request_set_ssl(http_req, TRUE);
205
http_client_request_submit(http_req);
207
test_req = i_new(struct http_test_request, 1);
208
http_req = http_client_request(http_client,
209
"POST", "posttestserver.com", "/post.php",
210
got_request_response, test_req);
211
post_payload = i_stream_create_from_data
212
((unsigned char *)test_query1, strlen(test_query1));
213
http_client_request_set_payload(http_req, post_payload, TRUE);
214
i_stream_unref(&post_payload);
215
http_client_request_set_ssl(http_req, TRUE);
216
http_client_request_submit(http_req);
218
test_req = i_new(struct http_test_request, 1);
219
http_req = http_client_request(http_client,
220
"GET", "wiki2.dovecot.org", "/Pigeonhole",
221
got_request_response, test_req);
222
http_client_request_submit(http_req);
224
test_req = i_new(struct http_test_request, 1);
225
http_req = http_client_request(http_client,
226
"GET", "jigsaw.w3.org", "/HTTP/ChunkedScript",
227
got_request_response, test_req);
228
http_client_request_submit(http_req);
230
test_req = i_new(struct http_test_request, 1);
231
http_req = http_client_request(http_client,
232
"POST", "jigsaw.w3.org", "/HTTP/300/Go_307",
233
got_request_response, test_req);
234
post_payload = i_stream_create_from_data
235
((unsigned char *)test_query3, strlen(test_query3));
236
http_client_request_set_payload(http_req, post_payload, FALSE);
237
i_stream_unref(&post_payload);
238
http_client_request_submit(http_req);
240
test_req = i_new(struct http_test_request, 1);
241
http_req = http_client_request(http_client,
242
"POST", "jigsaw.w3.org", "/HTTP/300/Go_307",
243
got_request_response, test_req);
244
post_payload = i_stream_create_from_data
245
((unsigned char *)test_query3, strlen(test_query3));
246
http_client_request_set_payload(http_req, post_payload, FALSE);
247
i_stream_unref(&post_payload);
248
http_client_request_submit(http_req);
250
test_req = i_new(struct http_test_request, 1);
251
http_req = http_client_request(http_client,
252
"POST", "jigsaw.w3.org", "/HTTP/300/Go_307",
253
got_request_response, test_req);
254
post_payload = i_stream_create_from_data
255
((unsigned char *)test_query3, strlen(test_query3));
256
http_client_request_set_payload(http_req, post_payload, FALSE);
257
i_stream_unref(&post_payload);
258
http_client_request_submit(http_req);
260
test_req = i_new(struct http_test_request, 1);
261
http_req = http_client_request(http_client,
262
"PUT", "test.dovecot.org", "/http/put/put.php",
263
got_request_response, test_req);
264
post_payload = i_stream_create_file("Makefile.am", 10);
265
http_client_request_set_payload(http_req, post_payload, TRUE);
266
i_stream_unref(&post_payload);
267
http_client_request_submit(http_req);
271
test_http_request_init(struct http_client *http_client,
272
const char *method, const char *url_str,
273
struct http_client_request **http_req_r,
274
struct http_test_request **test_req_r)
276
struct http_client_request *http_req;
277
struct http_test_request *test_req;
278
struct http_url *url;
281
if (http_url_parse(url_str, NULL, 0, pool_datastack_create(),
283
i_fatal("Invalid URL %s: %s", url_str, error);
285
test_req = i_new(struct http_test_request, 1);
286
test_req->write_output = TRUE;
287
http_req = http_client_request(http_client,
288
method, url->host_name,
289
t_strconcat("/", url->path, url->enc_query, NULL),
290
got_request_response, test_req);
292
http_client_request_set_port(http_req, url->port);
294
http_client_request_set_ssl(http_req, TRUE);
296
*http_req_r = http_req;
297
*test_req_r = test_req;
300
static void run_http_get(struct http_client *http_client, const char *url_str)
302
struct http_client_request *http_req;
303
struct http_test_request *test_req;
305
test_http_request_init(http_client, "GET", url_str, &http_req, &test_req);
306
http_client_request_submit(http_req);
309
static void run_http_post(struct http_client *http_client, const char *url_str,
312
struct http_client_request *http_req;
313
struct http_test_request *test_req;
314
struct istream *input;
316
test_http_request_init(http_client, "POST", url_str, &http_req, &test_req);
317
input = i_stream_create_file(path, IO_BLOCK_SIZE);
318
http_client_request_set_payload(http_req, input, FALSE);
319
i_stream_unref(&input);
320
http_client_request_submit(http_req);
323
int main(int argc, char *argv[])
325
struct http_client_settings http_set;
326
struct http_client *http_client;
327
struct ioloop *ioloop;
329
memset(&http_set, 0, sizeof(http_set));
330
http_set.dns_client_socket_path = "/var/run/dovecot/dns-client";
331
http_set.ssl_allow_invalid_cert = TRUE;
332
http_set.ssl_ca_dir = "/etc/ssl/certs"; /* debian */
333
http_set.ssl_ca_file = "/etc/pki/tls/cert.pem"; /* redhat */
334
http_set.max_idle_time_msecs = 5*1000;
335
http_set.max_parallel_connections = 4;
336
http_set.max_pipelined_requests = 4;
337
http_set.max_redirects = 2;
338
http_set.max_attempts = 1;
339
http_set.debug = TRUE;
340
http_set.rawlog_dir = "/tmp/http-test";
344
ioloop = io_loop_create();
345
io_loop_set_running(ioloop);
347
http_client = http_client_init(&http_set);
351
run_tests(http_client);
354
run_http_get(http_client, argv[1]);
357
run_http_post(http_client, argv[1], argv[2]);
360
i_fatal("Too many parameters");
363
http_client_wait(http_client);
364
http_client_deinit(&http_client);
366
io_loop_destroy(&ioloop);