blob: e31caf253da755d71b629fe3fe20b9b7a2d2148c [file] [log] [blame]
Sauw Mingd8435e62010-02-04 18:29:16 +00001/* $Id$ */
2/*
3 * Copyright (C) 2008-2010 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "test.h"
21
22#if INCLUDE_HTTP_CLIENT_TEST
23
24#define THIS_FILE "test_http"
25//#define VERBOSE
26#define STR_PREC(s) (int)s.slen, s.ptr
27#define USE_LOCAL_SERVER
28
29#include <pjlib.h>
30#include <pjlib-util.h>
31
32#define ACTION_REPLY 0
33#define ACTION_IGNORE -1
34
35static struct server_t
36{
37 pj_sock_t sock;
38 pj_uint16_t port;
39 pj_thread_t *thread;
40
41 /* Action:
42 * 0: reply with the response in resp.
43 * -1: ignore query (to simulate timeout).
44 * other: reply with that error
45 */
46 int action;
47 pj_bool_t send_content_length;
48 unsigned data_size;
49 unsigned buf_size;
50} g_server;
51
52static pj_bool_t thread_quit;
53static pj_timer_heap_t *timer_heap;
54static pj_ioqueue_t *ioqueue;
55static pj_pool_t *pool;
56static pj_http_req *http_req;
57static pj_bool_t test_cancel = PJ_FALSE;
58static pj_size_t total_size;
59static pj_size_t send_size = 0;
60static pj_status_t sstatus;
61static pj_sockaddr_in addr;
62static int counter = 0;
63
64static int server_thread(void *p)
65{
66 struct server_t *srv = (struct server_t*)p;
67 pj_sock_t newsock;
68
69 while (!thread_quit) {
70 char *pkt = pj_pool_alloc(pool, srv->buf_size);
71 pj_ssize_t pkt_len;
72 int rc;
73 pj_fd_set_t rset;
74 pj_time_val timeout = {0, 100};
75
76 rc = pj_sock_accept(srv->sock, &newsock, NULL, NULL);
77 if (rc != 0)
78 continue;
79
80 PJ_FD_ZERO(&rset);
81 PJ_FD_SET(newsock, &rset);
82 rc = pj_sock_select(newsock+1, &rset, NULL, NULL, &timeout);
83 if (rc != 1)
84 continue;
85
86 pkt_len = srv->buf_size;
87 do {
88 rc = pj_sock_recv(newsock, pkt, &pkt_len, 0);
89 if (rc != 0) {
90 app_perror("Server error receiving packet", rc);
91 continue;
92 }
93 rc = pj_sock_select(newsock+1, &rset, NULL, NULL, &timeout);
94 if (rc < 1)
95 break;
96 } while(1);
97
98 /* Simulate network RTT */
99 pj_thread_sleep(50);
100
101 if (srv->action == ACTION_IGNORE) {
102 continue;
103 } else if (srv->action == ACTION_REPLY) {
104 unsigned send_size = 0, ctr = 0;
105 pj_ansi_sprintf(pkt, "HTTP/1.0 200 OK\r\n");
106 if (srv->send_content_length) {
107 pj_ansi_sprintf(pkt + pj_ansi_strlen(pkt),
108 "Content-Length: %d\r\n",
109 srv->data_size);
110 }
111 pj_ansi_sprintf(pkt + pj_ansi_strlen(pkt), "\r\n");
112 pkt_len = pj_ansi_strlen(pkt);
113 pj_sock_send(newsock, pkt, &pkt_len, 0);
114 while (send_size < srv->data_size) {
115 pkt_len = srv->data_size - send_size;
116 if (pkt_len > (signed)srv->buf_size)
117 pkt_len = srv->buf_size;
118 send_size += pkt_len;
119 pj_create_random_string(pkt, pkt_len);
120 pj_ansi_sprintf(pkt, "\nPacket: %d", ++ctr);
121 pkt[pj_ansi_strlen(pkt)] = '\n';
122 pj_sock_send(newsock, pkt, &pkt_len, 0);
123 }
124 pj_sock_close(newsock);
125 }
126 }
127
128 return 0;
129}
130
131static void on_data_read(pj_http_req *hreq, void *data, pj_size_t size)
132{
133 PJ_UNUSED_ARG(hreq);
134 PJ_UNUSED_ARG(data);
135
Sauw Ming63236bb2010-02-05 16:03:29 +0000136 PJ_LOG(5, (THIS_FILE, "\nData received: %d bytes", size));
Sauw Mingd8435e62010-02-04 18:29:16 +0000137 if (size > 0) {
138#ifdef VERBOSE
139 printf("%.*s\n", (int)size, (char *)data);
140#endif
141 }
142}
143
144static void on_send_data(pj_http_req *hreq,
145 void **data, pj_size_t *size)
146{
147 char *sdata;
148 pj_size_t sendsz = 8397;
149
150 PJ_UNUSED_ARG(hreq);
151
152 if (send_size + sendsz > total_size) {
153 sendsz = total_size - send_size;
154 }
155 send_size += sendsz;
156
157 sdata = pj_pool_alloc(pool, sendsz);
158 pj_create_random_string(sdata, sendsz);
159 pj_ansi_sprintf(sdata, "\nSegment #%d\n", ++counter);
160 *data = sdata;
161 *size = sendsz;
162
Sauw Ming63236bb2010-02-05 16:03:29 +0000163 PJ_LOG(5, (THIS_FILE, "\nSending data progress: %d out of %d bytes",
Sauw Mingd8435e62010-02-04 18:29:16 +0000164 send_size, total_size));
165}
166
167
168static void on_complete(pj_http_req *hreq, pj_status_t status,
169 const pj_http_resp *resp)
170{
171 PJ_UNUSED_ARG(hreq);
172
173 if (status == PJ_ECANCELLED) {
Sauw Ming63236bb2010-02-05 16:03:29 +0000174 PJ_LOG(5, (THIS_FILE, "Request cancelled"));
Sauw Mingd8435e62010-02-04 18:29:16 +0000175 return;
176 } else if (status == PJ_ETIMEDOUT) {
Sauw Ming63236bb2010-02-05 16:03:29 +0000177 PJ_LOG(5, (THIS_FILE, "Request timed out!"));
Sauw Mingd8435e62010-02-04 18:29:16 +0000178 return;
Sauw Ming63236bb2010-02-05 16:03:29 +0000179 } else if (status != PJ_SUCCESS) {
180 PJ_LOG(3, (THIS_FILE, "Error %d", status));
Sauw Mingd8435e62010-02-04 18:29:16 +0000181 return;
182 }
Sauw Ming63236bb2010-02-05 16:03:29 +0000183 PJ_LOG(5, (THIS_FILE, "\nData completed: %d bytes", resp->size));
Sauw Mingd8435e62010-02-04 18:29:16 +0000184 if (resp->size > 0 && resp->data) {
185#ifdef VERBOSE
186 printf("%.*s\n", (int)resp->size, (char *)resp->data);
187#endif
188 }
189}
190
191static void on_response(pj_http_req *hreq, const pj_http_resp *resp)
192{
193 pj_size_t i;
194
195 PJ_UNUSED_ARG(hreq);
196 PJ_UNUSED_ARG(resp);
197 PJ_UNUSED_ARG(i);
198
199#ifdef VERBOSE
Sauw Ming63236bb2010-02-05 16:03:29 +0000200 printf("%.*s, %d, %.*s\n", STR_PREC(resp->version),
201 resp->status_code, STR_PREC(resp->reason));
Sauw Mingd8435e62010-02-04 18:29:16 +0000202 for (i = 0; i < resp->headers.count; i++) {
203 printf("%.*s : %.*s\n",
204 STR_PREC(resp->headers.header[i].name),
205 STR_PREC(resp->headers.header[i].value));
206 }
207#endif
208
209 if (test_cancel) {
210 pj_http_req_cancel(hreq, PJ_TRUE);
211 test_cancel = PJ_FALSE;
212 }
213}
214
215
216pj_status_t parse_url(const char *url)
217{
218 pj_str_t surl;
219 pj_http_url hurl;
220 pj_status_t status;
221
222 pj_cstr(&surl, url);
223 status = pj_http_req_parse_url(&surl, &hurl);
224#ifdef VERBOSE
225 if (!status) {
226 printf("URL: %s\nProtocol: %.*s\nHost: %.*s\nPort: %d\nPath: %.*s\n\n",
227 url, STR_PREC(hurl.protocol), STR_PREC(hurl.host),
228 hurl.port, STR_PREC(hurl.path));
229 } else {
230 }
231#endif
232 return status;
233}
234
235int parse_url_test()
236{
237 /* Simple URL without '/' in the end */
238 if (parse_url("http://www.google.com.sg") != PJ_SUCCESS)
239 return -11;
240 /* Simple URL with port number but without '/' in the end */
241 if (parse_url("http://www.example.com:8080") != PJ_SUCCESS)
242 return -13;
243 /* URL with path */
244 if (parse_url("http://127.0.0.1:280/Joomla/index.php?option=com_content&task=view&id=5&Itemid=6")
245 != PJ_SUCCESS)
246 return -15;
247 /* URL with port and path */
248 if (parse_url("http://teluu.com:81/about-us/") != PJ_SUCCESS)
249 return -17;
250 /* unsupported protocol */
251 if (parse_url("ftp://www.teluu.com") != PJ_ENOTSUP)
252 return -19;
253 /* invalid format */
254 if (parse_url("http:/teluu.com/about-us/") != PJLIB_UTIL_EHTTPINURL)
255 return -21;
256 /* invalid port number */
257 if (parse_url("http://teluu.com:xyz/") != PJLIB_UTIL_EHTTPINPORT)
258 return -23;
259
260 return 0;
261}
262
263/*
264 * GET request scenario 1: using on_response() and on_data_read()
265 * Server replies with content-length. Application cancels the
266 * request upon receiving the response, then start it again.
267 */
268int http_client_test1()
269{
270 pj_str_t url;
271 pj_http_req_callback hcb;
272 pj_http_req_param param;
273
274 pj_bzero(&hcb, sizeof(hcb));
275 hcb.on_complete = &on_complete;
276 hcb.on_data_read = &on_data_read;
277 hcb.on_response = &on_response;
278 pj_http_req_param_default(&param);
279
280 /* Create pool, timer, and ioqueue */
281 pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
282 if (pj_timer_heap_create(pool, 16, &timer_heap))
283 return -31;
284 if (pj_ioqueue_create(pool, 16, &ioqueue))
285 return -32;
286
287#ifdef USE_LOCAL_SERVER
288
289 pj_cstr(&url, "http://127.0.0.1:8080/about-us/");
290 thread_quit = PJ_FALSE;
291 g_server.action = ACTION_REPLY;
292 g_server.send_content_length = PJ_TRUE;
293 g_server.data_size = 2970;
294 g_server.port = 8080;
295 g_server.buf_size = 1024;
296
297 sstatus = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0,
298 &g_server.sock);
299 if (sstatus != PJ_SUCCESS)
300 return -41;
301
302 pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)g_server.port);
303
304 sstatus = pj_sock_bind(g_server.sock, &addr, sizeof(addr));
305 if (sstatus != PJ_SUCCESS)
306 return -43;
307
308 sstatus = pj_sock_listen(g_server.sock, 8);
309 if (sstatus != PJ_SUCCESS)
310 return -45;
311
312 sstatus = pj_thread_create(pool, NULL, &server_thread, &g_server,
313 0, 0, &g_server.thread);
314 if (sstatus != PJ_SUCCESS)
315 return -47;
316
317#else
318 pj_cstr(&url, "http://www.teluu.com/about-us/");
319#endif
320
321 if (pj_http_req_create(pool, &url, timer_heap, ioqueue,
322 &param, &hcb, &http_req))
323 return -33;
324
325 test_cancel = PJ_TRUE;
326 if (pj_http_req_start(http_req))
327 return -35;
328
329 while (pj_http_req_is_running(http_req)) {
330 pj_time_val delay = {0, 50};
331 pj_ioqueue_poll(ioqueue, &delay);
332 pj_timer_heap_poll(timer_heap, NULL);
333 }
334
335 if (pj_http_req_start(http_req))
336 return -37;
337
338 while (pj_http_req_is_running(http_req)) {
339 pj_time_val delay = {0, 50};
340 pj_ioqueue_poll(ioqueue, &delay);
341 pj_timer_heap_poll(timer_heap, NULL);
342 }
343
344#ifdef USE_LOCAL_SERVER
345 thread_quit = PJ_TRUE;
346 pj_sock_close(g_server.sock);
347#endif
348
349 pj_http_req_destroy(http_req);
350 pj_ioqueue_destroy(ioqueue);
351 pj_timer_heap_destroy(timer_heap);
352 pj_pool_release(pool);
353
354 return PJ_SUCCESS;
355}
356
357/*
358 * GET request scenario 2: using on_complete() to get the
359 * complete data. Server does not reply with content-length.
360 * Request timed out, application sets a longer timeout, then
361 * then restart the request.
362 */
363int http_client_test2()
364{
365 pj_str_t url;
366 pj_http_req_callback hcb;
367 pj_http_req_param param;
368 pj_time_val timeout;
369
370 pj_bzero(&hcb, sizeof(hcb));
371 hcb.on_complete = &on_complete;
372 hcb.on_response = &on_response;
373 pj_http_req_param_default(&param);
374
375 /* Create pool, timer, and ioqueue */
376 pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
377 if (pj_timer_heap_create(pool, 16, &timer_heap))
378 return -41;
379 if (pj_ioqueue_create(pool, 16, &ioqueue))
380 return -42;
381
382#ifdef USE_LOCAL_SERVER
383
384 pj_cstr(&url, "http://127.0.0.1:380");
385 param.timeout.sec = 0;
386 param.timeout.msec = 2000;
387
388 thread_quit = PJ_FALSE;
389 g_server.action = ACTION_IGNORE;
390 g_server.send_content_length = PJ_FALSE;
391 g_server.data_size = 4173;
392 g_server.port = 380;
393 g_server.buf_size = 1024;
394
395 sstatus = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0,
396 &g_server.sock);
397 if (sstatus != PJ_SUCCESS)
398 return -41;
399
400 pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)g_server.port);
401
402 sstatus = pj_sock_bind(g_server.sock, &addr, sizeof(addr));
403 if (sstatus != PJ_SUCCESS)
404 return -43;
405
406 sstatus = pj_sock_listen(g_server.sock, 8);
407 if (sstatus != PJ_SUCCESS)
408 return -45;
409
410 sstatus = pj_thread_create(pool, NULL, &server_thread, &g_server,
411 0, 0, &g_server.thread);
412 if (sstatus != PJ_SUCCESS)
413 return -47;
414
415#else
416 pj_cstr(&url, "http://www.google.com.sg");
417 param.timeout.sec = 0;
418 param.timeout.msec = 50;
419#endif
420
421 pj_http_headers_add_elmt2(&param.headers, "Accept",
422 "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
423 pj_http_headers_add_elmt2(&param.headers, "Accept-Language", "en-sg");
424 pj_http_headers_add_elmt2(&param.headers, "User-Agent",
425 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506)");
426 if (pj_http_req_create(pool, &url, timer_heap, ioqueue,
427 &param, &hcb, &http_req))
428 return -43;
429
430 if (pj_http_req_start(http_req))
431 return -45;
432
433 while (pj_http_req_is_running(http_req)) {
434 pj_time_val delay = {0, 50};
435 pj_ioqueue_poll(ioqueue, &delay);
436 pj_timer_heap_poll(timer_heap, NULL);
437 }
438
439#ifdef USE_LOCAL_SERVER
440 g_server.action = ACTION_REPLY;
441#endif
442
443 timeout.sec = 0; timeout.msec = 10000;
444 pj_http_req_set_timeout(http_req, &timeout);
445 if (pj_http_req_start(http_req))
446 return -47;
447
448 while (pj_http_req_is_running(http_req)) {
449 pj_time_val delay = {0, 50};
450 pj_ioqueue_poll(ioqueue, &delay);
451 pj_timer_heap_poll(timer_heap, NULL);
452 }
453
454#ifdef USE_LOCAL_SERVER
455 thread_quit = PJ_TRUE;
456 pj_sock_close(g_server.sock);
457#endif
458
459 pj_http_req_destroy(http_req);
460 pj_ioqueue_destroy(ioqueue);
461 pj_timer_heap_destroy(timer_heap);
462 pj_pool_release(pool);
463
464 return PJ_SUCCESS;
465}
466
467/*
468 * PUT request scenario 1: sending the whole data at once
469 */
470int http_client_test_put1()
471{
472 pj_str_t url;
473 pj_http_req_callback hcb;
474 pj_http_req_param param;
475 char *data;
476 int length = 3875;
477
478 pj_bzero(&hcb, sizeof(hcb));
479 hcb.on_complete = &on_complete;
480 hcb.on_data_read = &on_data_read;
481 hcb.on_response = &on_response;
482
483 /* Create pool, timer, and ioqueue */
484 pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
485 if (pj_timer_heap_create(pool, 16, &timer_heap))
486 return -51;
487 if (pj_ioqueue_create(pool, 16, &ioqueue))
488 return -52;
489
490#ifdef USE_LOCAL_SERVER
491 pj_cstr(&url, "http://127.0.0.1:380/test/test.txt");
492 thread_quit = PJ_FALSE;
493 g_server.action = ACTION_REPLY;
494 g_server.send_content_length = PJ_TRUE;
495 g_server.data_size = 0;
496 g_server.port = 380;
497 g_server.buf_size = 4096;
498
499 sstatus = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0,
500 &g_server.sock);
501 if (sstatus != PJ_SUCCESS)
502 return -41;
503
504 pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)g_server.port);
505
506 sstatus = pj_sock_bind(g_server.sock, &addr, sizeof(addr));
507 if (sstatus != PJ_SUCCESS)
508 return -43;
509
510 sstatus = pj_sock_listen(g_server.sock, 8);
511 if (sstatus != PJ_SUCCESS)
512 return -45;
513
514 sstatus = pj_thread_create(pool, NULL, &server_thread, &g_server,
515 0, 0, &g_server.thread);
516 if (sstatus != PJ_SUCCESS)
517 return -47;
518
519#else
520 pj_cstr(&url, "http://127.0.0.1:280/test/test.txt");
521
522#endif
523
524 pj_http_req_param_default(&param);
525 pj_strset2(&param.method, "PUT");
526 data = pj_pool_alloc(pool, length);
527 pj_create_random_string(data, length);
528 pj_ansi_sprintf(data, "PUT test\n");
529 param.reqdata.data = data;
530 param.reqdata.size = length;
531 if (pj_http_req_create(pool, &url, timer_heap, ioqueue,
532 &param, &hcb, &http_req))
533 return -53;
534
535 if (pj_http_req_start(http_req))
536 return -55;
537
538 while (pj_http_req_is_running(http_req)) {
539 pj_time_val delay = {0, 50};
540 pj_ioqueue_poll(ioqueue, &delay);
541 pj_timer_heap_poll(timer_heap, NULL);
542 }
543
544#ifdef USE_LOCAL_SERVER
545 thread_quit = PJ_TRUE;
546 pj_sock_close(g_server.sock);
547#endif
548
549 pj_http_req_destroy(http_req);
550 pj_ioqueue_destroy(ioqueue);
551 pj_timer_heap_destroy(timer_heap);
552 pj_pool_release(pool);
553
554 return PJ_SUCCESS;
555}
556
557/*
558 * PUT request scenario 2: using on_send_data() callback to
559 * sending the data in chunks
560 */
561int http_client_test_put2()
562{
563 pj_str_t url;
564 pj_http_req_callback hcb;
565 pj_http_req_param param;
566
567 pj_bzero(&hcb, sizeof(hcb));
568 hcb.on_complete = &on_complete;
569 hcb.on_send_data = &on_send_data;
570 hcb.on_data_read = &on_data_read;
571 hcb.on_response = &on_response;
572
573 /* Create pool, timer, and ioqueue */
574 pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
575 if (pj_timer_heap_create(pool, 16, &timer_heap))
576 return -51;
577 if (pj_ioqueue_create(pool, 16, &ioqueue))
578 return -52;
579
580#ifdef USE_LOCAL_SERVER
581 pj_cstr(&url, "http://127.0.0.1:380/test/test2.txt");
582 thread_quit = PJ_FALSE;
583 g_server.action = ACTION_REPLY;
584 g_server.send_content_length = PJ_TRUE;
585 g_server.data_size = 0;
586 g_server.port = 380;
587 g_server.buf_size = 16384;
588
589 sstatus = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0,
590 &g_server.sock);
591 if (sstatus != PJ_SUCCESS)
592 return -41;
593
594 pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)g_server.port);
595
596 sstatus = pj_sock_bind(g_server.sock, &addr, sizeof(addr));
597 if (sstatus != PJ_SUCCESS)
598 return -43;
599
600 sstatus = pj_sock_listen(g_server.sock, 8);
601 if (sstatus != PJ_SUCCESS)
602 return -45;
603
604 sstatus = pj_thread_create(pool, NULL, &server_thread, &g_server,
605 0, 0, &g_server.thread);
606 if (sstatus != PJ_SUCCESS)
607 return -47;
608
609#else
610 pj_cstr(&url, "http://127.0.0.1:280/test/test2.txt");
611
612#endif
613
614 pj_http_req_param_default(&param);
615 pj_strset2(&param.method, "PUT");
616 total_size = 15383;
617 send_size = 0;
618 param.reqdata.total_size = total_size;
619 if (pj_http_req_create(pool, &url, timer_heap, ioqueue,
620 &param, &hcb, &http_req))
621 return -53;
622
623 if (pj_http_req_start(http_req))
624 return -55;
625
626 while (pj_http_req_is_running(http_req)) {
627 pj_time_val delay = {0, 50};
628 pj_ioqueue_poll(ioqueue, &delay);
629 pj_timer_heap_poll(timer_heap, NULL);
630 }
631
632#ifdef USE_LOCAL_SERVER
633 thread_quit = PJ_TRUE;
634 pj_sock_close(g_server.sock);
635#endif
636
637 pj_http_req_destroy(http_req);
638 pj_ioqueue_destroy(ioqueue);
639 pj_timer_heap_destroy(timer_heap);
640 pj_pool_release(pool);
641
642 return PJ_SUCCESS;
643}
644
645int http_client_test_delete()
646{
647 pj_str_t url;
648 pj_http_req_callback hcb;
649 pj_http_req_param param;
650
651 pj_bzero(&hcb, sizeof(hcb));
652 hcb.on_complete = &on_complete;
653 hcb.on_response = &on_response;
654
655 /* Create pool, timer, and ioqueue */
656 pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
657 if (pj_timer_heap_create(pool, 16, &timer_heap))
658 return -61;
659 if (pj_ioqueue_create(pool, 16, &ioqueue))
660 return -62;
661
662#ifdef USE_LOCAL_SERVER
663 pj_cstr(&url, "http://127.0.0.1:380/test/test2.txt");
664 thread_quit = PJ_FALSE;
665 g_server.action = ACTION_REPLY;
666 g_server.send_content_length = PJ_TRUE;
667 g_server.data_size = 0;
668 g_server.port = 380;
669 g_server.buf_size = 1024;
670
671 sstatus = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0,
672 &g_server.sock);
673 if (sstatus != PJ_SUCCESS)
674 return -41;
675
676 pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)g_server.port);
677
678 sstatus = pj_sock_bind(g_server.sock, &addr, sizeof(addr));
679 if (sstatus != PJ_SUCCESS)
680 return -43;
681
682 sstatus = pj_sock_listen(g_server.sock, 8);
683 if (sstatus != PJ_SUCCESS)
684 return -45;
685
686 sstatus = pj_thread_create(pool, NULL, &server_thread, &g_server,
687 0, 0, &g_server.thread);
688 if (sstatus != PJ_SUCCESS)
689 return -47;
690
691#else
692 pj_cstr(&url, "http://127.0.0.1:280/test/test2.txt");
693#endif
694
695 pj_http_req_param_default(&param);
696 pj_strset2(&param.method, "DELETE");
697 if (pj_http_req_create(pool, &url, timer_heap, ioqueue,
698 &param, &hcb, &http_req))
699 return -63;
700
701 if (pj_http_req_start(http_req))
702 return -65;
703
704 while (pj_http_req_is_running(http_req)) {
705 pj_time_val delay = {0, 50};
706 pj_ioqueue_poll(ioqueue, &delay);
707 pj_timer_heap_poll(timer_heap, NULL);
708 }
709
710#ifdef USE_LOCAL_SERVER
711 thread_quit = PJ_TRUE;
712 pj_sock_close(g_server.sock);
713#endif
714
715 pj_http_req_destroy(http_req);
716 pj_ioqueue_destroy(ioqueue);
717 pj_timer_heap_destroy(timer_heap);
718 pj_pool_release(pool);
719
720 return PJ_SUCCESS;
721}
722
723int http_client_test()
724{
725 int rc;
726
727 PJ_LOG(3, (THIS_FILE, "..Testing URL parsing"));
728 rc = parse_url_test();
729 if (rc)
730 return rc;
731
732 PJ_LOG(3, (THIS_FILE, "..Testing GET request scenario 1"));
733 rc = http_client_test1();
734 if (rc)
735 return rc;
736
737 PJ_LOG(3, (THIS_FILE, "..Testing GET request scenario 2"));
738 rc = http_client_test2();
739 if (rc)
740 return rc;
741
742 PJ_LOG(3, (THIS_FILE, "..Testing PUT request scenario 1"));
743 rc = http_client_test_put1();
744 if (rc)
745 return rc;
746
747 PJ_LOG(3, (THIS_FILE, "..Testing PUT request scenario 2"));
748 rc = http_client_test_put2();
749 if (rc)
750 return rc;
751
752 PJ_LOG(3, (THIS_FILE, "..Testing DELETE request"));
753 rc = http_client_test_delete();
754 if (rc)
755 return rc;
756
757 return PJ_SUCCESS;
758}
759
760#else
761/* To prevent warning about "translation unit is empty"
762 * when this test is disabled.
763 */
764int dummy_http_client_test;
765#endif /* INCLUDE_HTTP_CLIENT_TEST */