/* $Id$ */ /* * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * \page page_httpdemo_c Samples: HTTP Client demo * * This file is pjsip-apps/src/samples/httpdemo.c * * \includelineno httpdemo.c */ #include #include #include #include #include #include #include static pj_timer_heap_t *timer_heap; static pj_ioqueue_t *ioqueue; static pj_pool_t *pool; static pj_http_req *http_req; static pj_pool_factory *mem; static FILE *f = NULL; //#define VERBOSE #define THIS_FILE "http_demo" static void on_response(pj_http_req *http_req, const pj_http_resp *resp) { unsigned i; PJ_UNUSED_ARG(http_req); PJ_LOG(3,(THIS_FILE, "%.*s %d %.*s", (int)resp->version.slen, resp->version.ptr, resp->status_code, (int)resp->reason.slen, resp->reason.ptr)); for (i=0; iheaders.count; ++i) { const pj_http_header_elmt *h = &resp->headers.header[i]; if (!pj_stricmp2(&h->name, "Content-Length") || !pj_stricmp2(&h->name, "Content-Type")) { PJ_LOG(3,(THIS_FILE, "%.*s: %.*s", (int)h->name.slen, h->name.ptr, (int)h->value.slen, h->value.ptr)); } } } static void on_send_data(pj_http_req *http_req, void **data, pj_size_t *size) { PJ_UNUSED_ARG(http_req); PJ_UNUSED_ARG(size); PJ_UNUSED_ARG(data); } static void on_data_read(pj_http_req *hreq, void *data, pj_size_t size) { PJ_UNUSED_ARG(hreq); if (size > 0) { fwrite(data, 1, size, f); fflush(f); #ifdef VERBOSE PJ_LOG(3, (THIS_FILE, "Data received: %d bytes", size)); printf("%.*s\n", (int)size, (char *)data); #endif } } static void on_complete(pj_http_req *hreq, pj_status_t status, const pj_http_resp *resp) { PJ_UNUSED_ARG(hreq); if (status != PJ_SUCCESS) { PJ_PERROR(1, (THIS_FILE, status, "HTTP request completed with error")); return; } PJ_LOG(3, (THIS_FILE, "Data completed: %d bytes", resp->size)); if (resp->size > 0 && resp->data) { #ifdef VERBOSE printf("%.*s\n", (int)resp->size, (char *)resp->data); #endif } } pj_status_t getURL(const char *curl) { pj_str_t url; pj_http_req_callback hcb; pj_status_t status; pj_bzero(&hcb, sizeof(hcb)); hcb.on_complete = &on_complete; hcb.on_data_read = &on_data_read; hcb.on_send_data = &on_send_data; hcb.on_response = &on_response; /* Create pool, timer, and ioqueue */ pool = pj_pool_create(mem, NULL, 8192, 4096, NULL); if (pj_timer_heap_create(pool, 16, &timer_heap)) return -31; if (pj_ioqueue_create(pool, 16, &ioqueue)) return -32; pj_strdup2(pool, &url, curl); if ((status = pj_http_req_create(pool, &url, timer_heap, ioqueue, NULL, &hcb, &http_req)) != PJ_SUCCESS) return status; if ((status = pj_http_req_start(http_req)) != PJ_SUCCESS) return status; while (pj_http_req_is_running(http_req)) { pj_time_val delay = {0, 50}; pj_ioqueue_poll(ioqueue, &delay); pj_timer_heap_poll(timer_heap, NULL); } pj_http_req_destroy(http_req); pj_ioqueue_destroy(ioqueue); pj_timer_heap_destroy(timer_heap); pj_pool_release(pool); return PJ_SUCCESS; } /* * main() */ int main(int argc, char *argv[]) { pj_caching_pool cp; pj_status_t status; if (argc < 2 || argc > 3) { puts("Usage: httpdemo URL [output-filename]"); return 1; } pj_log_set_level(5); pj_init(); pj_caching_pool_init(&cp, NULL, 0); mem = &cp.factory; pjlib_util_init(); if (argc > 2) f = fopen(argv[2], "wb"); else f = stdout; status = getURL(argv[1]); if (status != PJ_SUCCESS) { PJ_PERROR(1, (THIS_FILE, status, "Error")); } if (f != stdout) fclose(f); pj_caching_pool_destroy(&cp); pj_shutdown(); return 0; }