blob: 2df02d85ada8765c1a6100b570176eee0c584bc0 [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/**
21 * \page page_httpdemo_c Samples: HTTP Client demo
22 *
23 * This file is pjsip-apps/src/samples/httpdemo.c
24 *
25 * \includelineno httpdemo.c
26 */
27
28#include <pjlib.h>
29#include <pjlib-util.h>
30#include <pjlib-util/http_client.h>
31#include <pjsip.h>
32#include <pjmedia.h>
33#include <pjnath.h>
34#include <pjsip_simple.h>
35
36static pj_timer_heap_t *timer_heap;
37static pj_ioqueue_t *ioqueue;
38static pj_pool_t *pool;
39static pj_http_req *http_req;
40static pj_pool_factory *mem;
41static FILE *f = NULL;
42
43//#define VERBOSE
44#define THIS_FILE "http_demo"
45
Sauw Ming63236bb2010-02-05 16:03:29 +000046static void on_response(pj_http_req *http_req, const pj_http_resp *resp)
47{
Benny Prijono00f88272010-09-27 08:35:08 +000048 unsigned i;
49
50 PJ_UNUSED_ARG(http_req);
Sauw Ming63236bb2010-02-05 16:03:29 +000051 PJ_LOG(3,(THIS_FILE, "%.*s %d %.*s", (int)resp->version.slen, resp->version.ptr,
52 resp->status_code,
53 (int)resp->reason.slen, resp->reason.ptr));
Benny Prijono00f88272010-09-27 08:35:08 +000054
55 for (i=0; i<resp->headers.count; ++i) {
56 const pj_http_header_elmt *h = &resp->headers.header[i];
57
58 if (!pj_stricmp2(&h->name, "Content-Length") ||
59 !pj_stricmp2(&h->name, "Content-Type"))
60 {
61 PJ_LOG(3,(THIS_FILE, "%.*s: %.*s",
62 (int)h->name.slen, h->name.ptr,
63 (int)h->value.slen, h->value.ptr));
64 }
65 }
Sauw Ming63236bb2010-02-05 16:03:29 +000066}
67
68static void on_send_data(pj_http_req *http_req, void **data, pj_size_t *size)
69{
Benny Prijono08280552010-08-01 15:25:04 +000070 PJ_UNUSED_ARG(http_req);
71 PJ_UNUSED_ARG(size);
72 PJ_UNUSED_ARG(data);
Sauw Ming63236bb2010-02-05 16:03:29 +000073}
74
Sauw Mingd8435e62010-02-04 18:29:16 +000075static void on_data_read(pj_http_req *hreq, void *data, pj_size_t size)
76{
77 PJ_UNUSED_ARG(hreq);
78
79 if (size > 0) {
80 fwrite(data, 1, size, f);
81 fflush(f);
82#ifdef VERBOSE
Sauw Ming63236bb2010-02-05 16:03:29 +000083 PJ_LOG(3, (THIS_FILE, "Data received: %d bytes", size));
Sauw Mingd8435e62010-02-04 18:29:16 +000084 printf("%.*s\n", (int)size, (char *)data);
85#endif
86 }
87}
88
89static void on_complete(pj_http_req *hreq, pj_status_t status,
90 const pj_http_resp *resp)
91{
92 PJ_UNUSED_ARG(hreq);
93
Sauw Ming63236bb2010-02-05 16:03:29 +000094 if (status != PJ_SUCCESS) {
95 PJ_PERROR(1, (THIS_FILE, status, "HTTP request completed with error"));
Sauw Mingd8435e62010-02-04 18:29:16 +000096 return;
97 }
Sauw Ming63236bb2010-02-05 16:03:29 +000098 PJ_LOG(3, (THIS_FILE, "Data completed: %d bytes", resp->size));
Sauw Mingd8435e62010-02-04 18:29:16 +000099 if (resp->size > 0 && resp->data) {
100#ifdef VERBOSE
101 printf("%.*s\n", (int)resp->size, (char *)resp->data);
102#endif
103 }
104}
105
106pj_status_t getURL(const char *curl)
107{
108 pj_str_t url;
109 pj_http_req_callback hcb;
110 pj_status_t status;
111
112 pj_bzero(&hcb, sizeof(hcb));
113 hcb.on_complete = &on_complete;
114 hcb.on_data_read = &on_data_read;
Sauw Ming63236bb2010-02-05 16:03:29 +0000115 hcb.on_send_data = &on_send_data;
116 hcb.on_response = &on_response;
Sauw Mingd8435e62010-02-04 18:29:16 +0000117
118 /* Create pool, timer, and ioqueue */
119 pool = pj_pool_create(mem, NULL, 8192, 4096, NULL);
120 if (pj_timer_heap_create(pool, 16, &timer_heap))
121 return -31;
122 if (pj_ioqueue_create(pool, 16, &ioqueue))
123 return -32;
124
125 pj_strdup2(pool, &url, curl);
126
127 if ((status = pj_http_req_create(pool, &url, timer_heap, ioqueue,
128 NULL, &hcb, &http_req)) != PJ_SUCCESS)
129 return status;
130
131 if ((status = pj_http_req_start(http_req)) != PJ_SUCCESS)
132 return status;
133
134 while (pj_http_req_is_running(http_req)) {
135 pj_time_val delay = {0, 50};
136 pj_ioqueue_poll(ioqueue, &delay);
137 pj_timer_heap_poll(timer_heap, NULL);
138 }
139
140 pj_http_req_destroy(http_req);
141 pj_ioqueue_destroy(ioqueue);
142 pj_timer_heap_destroy(timer_heap);
143 pj_pool_release(pool);
144
145 return PJ_SUCCESS;
146}
147/*
148 * main()
149 */
150int main(int argc, char *argv[])
151{
152 pj_caching_pool cp;
153 pj_status_t status;
154
Sauw Ming63236bb2010-02-05 16:03:29 +0000155 if (argc < 2 || argc > 3) {
156 puts("Usage: httpdemo URL [output-filename]");
Sauw Mingd8435e62010-02-04 18:29:16 +0000157 return 1;
158 }
159
Sauw Ming63236bb2010-02-05 16:03:29 +0000160 pj_log_set_level(5);
Sauw Mingd8435e62010-02-04 18:29:16 +0000161
162 pj_init();
163 pj_caching_pool_init(&cp, NULL, 0);
164 mem = &cp.factory;
165 pjlib_util_init();
166
Sauw Ming63236bb2010-02-05 16:03:29 +0000167 if (argc > 2)
168 f = fopen(argv[2], "wb");
169 else
170 f = stdout;
171
Sauw Mingd8435e62010-02-04 18:29:16 +0000172 status = getURL(argv[1]);
173 if (status != PJ_SUCCESS) {
174 PJ_PERROR(1, (THIS_FILE, status, "Error"));
175 }
Sauw Mingd8435e62010-02-04 18:29:16 +0000176
Sauw Ming63236bb2010-02-05 16:03:29 +0000177 if (f != stdout)
178 fclose(f);
179
180 pj_caching_pool_destroy(&cp);
Sauw Mingd8435e62010-02-04 18:29:16 +0000181 pj_shutdown();
182 return 0;
183}