utils/functions.c

Go to the documentation of this file.
00001 /*
00002  * script functions of utils module
00003  *
00004  * Copyright (C) 2008 Juha Heinanen
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00032 #include <curl/curl.h>
00033 
00034 #include "../../mod_fix.h"
00035 #include "../../pvar.h"
00036 #include "../../route_struct.h"
00037 #include "../../ut.h"
00038 #include "../../mem/mem.h"
00039 #include "../../parser/msg_parser.h"
00040 #include "../../lvalue.h"
00041 
00042 #include "utils.h"
00043 
00044 
00045 /* 
00046  * curl write function that saves received data as zero terminated
00047  * to stream. Returns the amount of data taken care of.
00048  */
00049 size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream)
00050 {
00051     /* Allocate memory and copy */
00052     char* data;
00053 
00054     data = (char*)malloc((size* nmemb) + 1);
00055     if (data == NULL) {
00056         LM_ERR("cannot allocate memory for stream\n");
00057         return CURLE_WRITE_ERROR;
00058     }
00059 
00060     memcpy(data, (char*)ptr, size* nmemb);
00061     data[nmemb] = '\0';
00062         
00063     *((char**) stream) = data;
00064     
00065     return size* nmemb;
00066  }
00067 
00068 
00069 /* 
00070  * Performs http_query and saves possible result (first body line of reply)
00071  * to pvar.
00072  */
00073 int http_query(struct sip_msg* _m, char* _url, char* _dst)
00074 {
00075     CURL *curl;
00076     CURLcode res;  
00077     str value;
00078     char *url, *at;
00079     char* stream;
00080     long stat;
00081     pv_spec_t *dst;
00082     pv_value_t val;
00083     double download_size;
00084 
00085     if (fixup_get_svalue(_m, (gparam_p)_url, &value) != 0) {
00086         LM_ERR("cannot get page value\n");
00087         return -1;
00088     }
00089 
00090     curl = curl_easy_init();
00091     if (curl == NULL) {
00092         LM_ERR("failed to initialize curl\n");
00093         return -1;
00094     }
00095 
00096     url = pkg_malloc(value.len + 1);
00097     if (url == NULL) {
00098         curl_easy_cleanup(curl);
00099         LM_ERR("cannot allocate pkg memory for url\n");
00100         return -1;
00101     }
00102     memcpy(url, value.s, value.len);
00103     *(url + value.len) = (char)0;
00104     curl_easy_setopt(curl, CURLOPT_URL, url);
00105 
00106     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1);
00107     curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)http_query_timeout);
00108 
00109     stream = NULL;
00110     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
00111     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
00112 
00113     res = curl_easy_perform(curl);  
00114     pkg_free(url);
00115     curl_easy_cleanup(curl);
00116 
00117     if (res != CURLE_OK) {
00118         LM_ERR("failed to perform curl\n");
00119         return -1;
00120     }
00121 
00122     curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &stat);
00123     if ((stat >= 200) && (stat < 400)) {
00124         curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
00125         LM_DBG("http_query download size: %u\n", (unsigned int)download_size);
00126         /* search for line feed */
00127         at = memchr(stream, (char)10, download_size);
00128         if (at == NULL) {
00129             /* not found: use whole stream */
00130             at = stream + (unsigned int)download_size;
00131         }
00132         val.rs.s = stream;
00133         val.rs.len = at - stream;
00134         LM_DBG("http)query result: %.*s\n", val.rs.len, val.rs.s);
00135         val.flags = PV_VAL_STR;
00136         dst = (pv_spec_t *)_dst;
00137         dst->setf(_m, &dst->pvp, (int)EQ_T, &val);
00138     }
00139         
00140     return stat;
00141 }