|
@@ -46,24 +46,30 @@
|
|
/*
|
|
/*
|
|
* curl write function that saves received data as zero terminated
|
|
* curl write function that saves received data as zero terminated
|
|
* to stream. Returns the amount of data taken care of.
|
|
* to stream. Returns the amount of data taken care of.
|
|
|
|
+ *
|
|
|
|
+ * This function may be called multiple times for larger responses,
|
|
|
|
+ * so it reallocs + concatenates the buffer as needed.
|
|
*/
|
|
*/
|
|
-size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream)
|
|
|
|
|
|
+size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr)
|
|
{
|
|
{
|
|
- /* Allocate memory and copy */
|
|
|
|
- char* data;
|
|
|
|
|
|
+ http_res_stream_t *stream = (http_res_stream_t *) stream_ptr;
|
|
|
|
+
|
|
|
|
+ stream->buf = (char *) pkg_realloc(stream->buf, stream->curr_size +
|
|
|
|
+ (size * nmemb) + 1);
|
|
|
|
|
|
- data = (char*)pkg_malloc((size* nmemb) + 1);
|
|
|
|
- if (data == NULL) {
|
|
|
|
|
|
+ if (stream->buf == NULL) {
|
|
LM_ERR("cannot allocate memory for stream\n");
|
|
LM_ERR("cannot allocate memory for stream\n");
|
|
return CURLE_WRITE_ERROR;
|
|
return CURLE_WRITE_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
- memcpy(data, (char*)ptr, size* nmemb);
|
|
|
|
- data[nmemb] = '\0';
|
|
|
|
-
|
|
|
|
- *((char**) stream) = data;
|
|
|
|
-
|
|
|
|
- return size* nmemb;
|
|
|
|
|
|
+ memcpy(&stream->buf[stream->pos], (char *) ptr, (size * nmemb));
|
|
|
|
+
|
|
|
|
+ stream->curr_size += ((size * nmemb) + 1);
|
|
|
|
+ stream->pos += (size * nmemb);
|
|
|
|
+
|
|
|
|
+ stream->buf[stream->pos + 1] = '\0';
|
|
|
|
+
|
|
|
|
+ return size * nmemb;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -77,12 +83,14 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
|
|
CURLcode res;
|
|
CURLcode res;
|
|
str value, post_value;
|
|
str value, post_value;
|
|
char *url, *at, *post;
|
|
char *url, *at, *post;
|
|
- char* stream;
|
|
|
|
|
|
+ http_res_stream_t stream;
|
|
long stat;
|
|
long stat;
|
|
pv_spec_t *dst;
|
|
pv_spec_t *dst;
|
|
pv_value_t val;
|
|
pv_value_t val;
|
|
double download_size;
|
|
double download_size;
|
|
|
|
|
|
|
|
+ memset(&stream, 0, sizeof(http_res_stream_t));
|
|
|
|
+
|
|
if (fixup_get_svalue(_m, (gparam_p)_url, &value) != 0) {
|
|
if (fixup_get_svalue(_m, (gparam_p)_url, &value) != 0) {
|
|
LM_ERR("cannot get page value\n");
|
|
LM_ERR("cannot get page value\n");
|
|
return -1;
|
|
return -1;
|
|
@@ -129,7 +137,6 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
|
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1);
|
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1);
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)http_query_timeout);
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)http_query_timeout);
|
|
|
|
|
|
- stream = NULL;
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
|
|
|
|
|
|
@@ -150,8 +157,8 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
|
|
}
|
|
}
|
|
|
|
|
|
curl_easy_cleanup(curl);
|
|
curl_easy_cleanup(curl);
|
|
- if(stream)
|
|
|
|
- pkg_free(stream);
|
|
|
|
|
|
+ if(stream.buf)
|
|
|
|
+ pkg_free(stream.buf);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -159,14 +166,15 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
|
|
if ((stat >= 200) && (stat < 500)) {
|
|
if ((stat >= 200) && (stat < 500)) {
|
|
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
|
|
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
|
|
LM_DBG("http_query download size: %u\n", (unsigned int)download_size);
|
|
LM_DBG("http_query download size: %u\n", (unsigned int)download_size);
|
|
|
|
+
|
|
/* search for line feed */
|
|
/* search for line feed */
|
|
- at = memchr(stream, (char)10, download_size);
|
|
|
|
|
|
+ at = memchr(stream.buf, (char)10, download_size);
|
|
if (at == NULL) {
|
|
if (at == NULL) {
|
|
/* not found: use whole stream */
|
|
/* not found: use whole stream */
|
|
- at = stream + (unsigned int)download_size;
|
|
|
|
|
|
+ at = stream.buf + (unsigned int)download_size;
|
|
}
|
|
}
|
|
- val.rs.s = stream;
|
|
|
|
- val.rs.len = at - stream;
|
|
|
|
|
|
+ val.rs.s = stream.buf;
|
|
|
|
+ val.rs.len = at - stream.buf;
|
|
LM_DBG("http_query result: %.*s\n", val.rs.len, val.rs.s);
|
|
LM_DBG("http_query result: %.*s\n", val.rs.len, val.rs.s);
|
|
val.flags = PV_VAL_STR;
|
|
val.flags = PV_VAL_STR;
|
|
dst = (pv_spec_t *)_dst;
|
|
dst = (pv_spec_t *)_dst;
|
|
@@ -174,6 +182,6 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
|
|
}
|
|
}
|
|
|
|
|
|
curl_easy_cleanup(curl);
|
|
curl_easy_cleanup(curl);
|
|
- pkg_free(stream);
|
|
|
|
|
|
+ pkg_free(stream.buf);
|
|
return stat;
|
|
return stat;
|
|
}
|
|
}
|