Tristan Matthews | 0a329cc | 2013-07-17 13:20:14 -0400 | [diff] [blame] | 1 | /* $Id: httpdemo.c 3553 2011-05-05 06:14:19Z nanang $ */ |
| 2 | /* |
| 3 | * Copyright (C) 2008-2011 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 | |
| 36 | static pj_timer_heap_t *timer_heap; |
| 37 | static pj_ioqueue_t *ioqueue; |
| 38 | static pj_pool_t *pool; |
| 39 | static pj_http_req *http_req; |
| 40 | static pj_pool_factory *mem; |
| 41 | static FILE *f = NULL; |
| 42 | |
| 43 | //#define VERBOSE |
| 44 | #define THIS_FILE "http_demo" |
| 45 | |
| 46 | static void on_response(pj_http_req *http_req, const pj_http_resp *resp) |
| 47 | { |
| 48 | unsigned i; |
| 49 | |
| 50 | PJ_UNUSED_ARG(http_req); |
| 51 | 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)); |
| 54 | |
| 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 | } |
| 66 | } |
| 67 | |
| 68 | static void on_send_data(pj_http_req *http_req, void **data, pj_size_t *size) |
| 69 | { |
| 70 | PJ_UNUSED_ARG(http_req); |
| 71 | PJ_UNUSED_ARG(size); |
| 72 | PJ_UNUSED_ARG(data); |
| 73 | } |
| 74 | |
| 75 | static 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 |
| 83 | PJ_LOG(3, (THIS_FILE, "Data received: %d bytes", size)); |
| 84 | printf("%.*s\n", (int)size, (char *)data); |
| 85 | #endif |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | static void on_complete(pj_http_req *hreq, pj_status_t status, |
| 90 | const pj_http_resp *resp) |
| 91 | { |
| 92 | PJ_UNUSED_ARG(hreq); |
| 93 | |
| 94 | if (status != PJ_SUCCESS) { |
| 95 | PJ_PERROR(1, (THIS_FILE, status, "HTTP request completed with error")); |
| 96 | return; |
| 97 | } |
| 98 | PJ_LOG(3, (THIS_FILE, "Data completed: %d bytes", resp->size)); |
| 99 | if (resp->size > 0 && resp->data) { |
| 100 | #ifdef VERBOSE |
| 101 | printf("%.*s\n", (int)resp->size, (char *)resp->data); |
| 102 | #endif |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | pj_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; |
| 115 | hcb.on_send_data = &on_send_data; |
| 116 | hcb.on_response = &on_response; |
| 117 | |
| 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 | */ |
| 150 | int main(int argc, char *argv[]) |
| 151 | { |
| 152 | pj_caching_pool cp; |
| 153 | pj_status_t status; |
| 154 | |
| 155 | if (argc < 2 || argc > 3) { |
| 156 | puts("Usage: httpdemo URL [output-filename]"); |
| 157 | return 1; |
| 158 | } |
| 159 | |
| 160 | pj_log_set_level(5); |
| 161 | |
| 162 | pj_init(); |
| 163 | pj_caching_pool_init(&cp, NULL, 0); |
| 164 | mem = &cp.factory; |
| 165 | pjlib_util_init(); |
| 166 | |
| 167 | if (argc > 2) |
| 168 | f = fopen(argv[2], "wb"); |
| 169 | else |
| 170 | f = stdout; |
| 171 | |
| 172 | status = getURL(argv[1]); |
| 173 | if (status != PJ_SUCCESS) { |
| 174 | PJ_PERROR(1, (THIS_FILE, status, "Error")); |
| 175 | } |
| 176 | |
| 177 | if (f != stdout) |
| 178 | fclose(f); |
| 179 | |
| 180 | pj_caching_pool_destroy(&cp); |
| 181 | pj_shutdown(); |
| 182 | return 0; |
| 183 | } |