Asterisk - The Open Source Telephony Project  21.4.1
Functions

Functions

long curl_download_to_file (const char *url, char *filename)
 Really simple document retrieval to file. More...
 
long curl_download_to_memory (const char *url, size_t *returned_length, char **returned_data, struct ast_variable **headers)
 Really simple document retrieval to memory. More...
 
long curler (const char *url, int request_timeout, struct curl_write_data *write_data, struct curl_header_data *header_data, struct curl_open_socket_data *open_socket_data)
 Perform a curl request. More...
 

Detailed Description

Function Documentation

long curl_download_to_file ( const char *  url,
char *  filename 
)

Really simple document retrieval to file.

Parameters
urlThe URL to retrieve.
filenameThe filename to save it to.
Return values
AnHTTP response code.
-1for internal error.

Definition at line 321 of file curl_utils.c.

References ast_strdup, curler(), curl_write_data::debug_info, and curl_write_data::output.

322 {
323  FILE *fp = NULL;
324  long rc = 0;
325  struct curl_write_data data = {
326  .debug_info = ast_strdup(url),
327  };
328 
329  if (ast_strlen_zero(url) || ast_strlen_zero(filename)) {
330  ast_log(LOG_ERROR,"url or filename was NULL\n");
331  return -1;
332  }
333  data.output = fopen(filename, "w");
334  if (!fp) {
335  ast_log(LOG_ERROR,"Unable to open file '%s': %s\n", filename,
336  strerror(errno));
337  return -1;
338  }
339  rc = curler(url, 0, &data, NULL, NULL);
340  fclose(data.output);
341  ast_free(data.debug_info);
342  return rc;
343 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Context structure passed to ast_curl_write_default_cb.
Definition: curl_utils.h:245
long curler(const char *url, int request_timeout, struct curl_write_data *write_data, struct curl_header_data *header_data, struct curl_open_socket_data *open_socket_data)
Perform a curl request.
Definition: curl_utils.c:232
char * debug_info
Definition: curl_utils.h:260
long curl_download_to_memory ( const char *  url,
size_t *  returned_length,
char **  returned_data,
struct ast_variable **  headers 
)

Really simple document retrieval to memory.

Parameters
urlThe URL to retrieve
returned_lengthPointer to a size_t to hold document length.
returned_dataPointer to a buffer which will be updated to point to the data. Must be freed with ast_std_free() after use.
headersPointer to an ast_variable * that will contain the response headers. Must be freed with ast_variables_destroy() Set to NULL if you don't need the headers.
Return values
AnHTTP response code.
-1for internal error.

Definition at line 300 of file curl_utils.c.

References ast_strdupa, curler(), curl_header_data::debug_info, curl_write_data::debug_info, curl_header_data::headers, curl_write_data::stream_buffer, and curl_write_data::stream_bytes_downloaded.

302 {
303  struct curl_write_data data = {
304  .debug_info = ast_strdupa(url),
305  };
306  struct curl_header_data hdata = {
307  .debug_info = ast_strdupa(url),
308  };
309 
310  long rc = curler(url, 0, &data, headers ? &hdata : NULL, NULL);
311 
312  *returned_length = data.stream_bytes_downloaded;
313  *returned_data = data.stream_buffer;
314  if (headers) {
315  *headers = hdata.headers;
316  }
317 
318  return rc;
319 }
char * stream_buffer
Definition: curl_utils.h:276
Context structure passed to ast_curl_write_default_cb.
Definition: curl_utils.h:245
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
Context structure passed to ast_curl_header_default_cb.
Definition: curl_utils.h:163
long curler(const char *url, int request_timeout, struct curl_write_data *write_data, struct curl_header_data *header_data, struct curl_open_socket_data *open_socket_data)
Perform a curl request.
Definition: curl_utils.c:232
char * debug_info
Definition: curl_utils.h:260
struct ast_variable * headers
Definition: curl_utils.h:182
size_t stream_bytes_downloaded
Definition: curl_utils.h:281
long curler ( const char *  url,
int  request_timeout,
struct curl_write_data write_data,
struct curl_header_data header_data,
struct curl_open_socket_data open_socket_data 
)

Perform a curl request.

Parameters
urlThe URL to request.
request_timeoutIf > 0, timeout after this number of seconds.
curl_write_dataA pointer to a curl_write_data structure. If curl_write_data.output is NULL, open_memstream will be called to provide one and the resulting data will be available in curl_write_data.stream_buffer with the number of bytes retrieved in curl_write_data.stream_bytes_downloaded. You must free curl_write_data.stream_buffer yourself with ast_std_free() when you no longer need it.
curl_header_dataA pointer to a ast_curl_header_data structure. The headers read will be in the curl_header_data.headers ast_variable list which you must free with ast_variables_destroy() when you're done with them.
curl_open_socket_dataA pointer to an curl_open_socket_data structure or NULL if you don't need it.
Return values
AnHTTP response code.
-1for internal error.

Definition at line 232 of file curl_utils.c.

References ast_strdupa, curl_header_cb(), curl_open_socket_cb(), curl_write_cb(), curl_write_data::output, and RAII_VAR.

Referenced by curl_download_to_file(), and curl_download_to_memory().

236 {
237  RAII_VAR(CURL *, curl, NULL, curl_easy_cleanup);
238  long http_code = 0;
239  CURLcode rc;
240 
241  SCOPE_ENTER(1, "'%s': Retrieving\n", url);
242 
243  if (ast_strlen_zero(url)) {
244  SCOPE_EXIT_LOG_RTN_VALUE(500, LOG_ERROR, "'missing': url is missing\n");
245  }
246 
247  if (!write_data) {
248  SCOPE_EXIT_LOG_RTN_VALUE(500, LOG_ERROR, "'%s': Either wite_cb and write_data are missing\n", url);
249  }
250 
251  curl = curl_easy_init();
252  if (!curl) {
253  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "'%s': Failed to set up CURL instance\n", url);
254  }
255 
256  curl_easy_setopt(curl, CURLOPT_URL, url);
257  if (request_timeout) {
258  curl_easy_setopt(curl, CURLOPT_TIMEOUT, request_timeout);
259  }
260  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
261  curl_easy_setopt(curl, CURLOPT_WRITEDATA, write_data);
262 
263  if (header_data) {
264  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_header_cb);
265  curl_easy_setopt(curl, CURLOPT_HEADERDATA, header_data);
266  }
267 
268  curl_easy_setopt(curl, CURLOPT_USERAGENT, AST_CURL_USER_AGENT);
269 
270  if (open_socket_data) {
271  curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, curl_open_socket_cb);
272  curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, open_socket_data);
273  }
274 
275  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
276  /*
277  * ATIS-1000074 specifically says to NOT follow redirections.
278  */
279  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0);
280 
281  rc = curl_easy_perform(curl);
282  if (rc != CURLE_OK) {
283  char *err = ast_strdupa(curl_easy_strerror(rc));
284  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "'%s': %s\n", url, err);
285  }
286 
287  fflush(write_data->output);
288  if (write_data->_internal_memstream) {
289  fclose(write_data->output);
290  write_data->output = NULL;
291  }
292 
293  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
294  curl_easy_cleanup(curl);
295  curl = NULL;
296 
297  SCOPE_EXIT_RTN_VALUE(http_code, "'%s': Done: %ld\n", url, http_code);
298 }
size_t curl_write_cb(char *data, size_t size, size_t nmemb, void *client_data)
A default implementation of a write data callback.
Definition: curl_utils.c:150
size_t curl_header_cb(char *data, size_t size, size_t nitems, void *client_data)
A default implementation of a header callback.
Definition: curl_utils.c:39
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
curl_socket_t curl_open_socket_cb(void *client_data, curlsocktype purpose, struct curl_sockaddr *address)
A default implementation of an open socket callback.
Definition: curl_utils.c:205
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941