36 #include <curl/curl.h> 43 #define GLOBAL_USERAGENT "asterisk-libcurl-agent/1.0" 45 #define MAX_HEADER_LENGTH 1023 65 realsize = size * nitems;
75 memcpy(header, buffer, realsize);
76 header[realsize] =
'\0';
77 value = strchr(header,
':');
84 if (strcasecmp(header,
"ETag")
85 && strcasecmp(header,
"Cache-Control")
86 && strcasecmp(header,
"Last-Modified")
87 && strcasecmp(header,
"Content-Type")
88 && strcasecmp(header,
"Expires")) {
108 realsize = fwrite(ptr, size, nitems, cb_data->
out_file);
120 struct timeval actual_expires =
ast_tvnow();
126 str_max_age = strstr(metadata->
value,
"s-maxage");
128 str_max_age = strstr(metadata->
value,
"max-age");
132 unsigned int max_age;
133 char *equal = strchr(str_max_age,
'=');
134 if (equal && (sscanf(equal + 1,
"%30u", &max_age) == 1)) {
135 actual_expires.tv_sec += max_age;
142 struct tm expires_time;
144 strptime(metadata->
value,
"%a, %d %b %Y %T %z", &expires_time);
145 expires_time.tm_isdst = -1;
146 actual_expires.tv_sec = mktime(&expires_time);
153 snprintf(time_buf,
sizeof(time_buf),
"%30lu", actual_expires.tv_sec);
171 if (strstr(metadata->value,
"no-cache")
172 || strstr(metadata->value,
"must-revalidate")) {
187 struct timeval current_time =
ast_tvnow();
188 struct timeval expires = { .tv_sec = 0, .tv_usec = 0 };
194 if (sscanf(metadata->value,
"%lu", &expires.tv_sec) != 1) {
198 return ast_tvcmp(current_time, expires) == -1 ? 0 : 1;
208 curl = curl_easy_init();
213 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
214 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180);
217 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
218 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 8);
220 curl_easy_setopt(curl, CURLOPT_HEADERDATA, cb_data);
230 char curl_errbuf[CURL_ERROR_SIZE + 1];
233 curl_errbuf[CURL_ERROR_SIZE] =
'\0';
234 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
236 if (curl_easy_perform(curl)) {
241 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
243 curl_easy_cleanup(curl);
273 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void*)&cb_data);
277 fclose(cb_data.out_file);
279 if (http_code / 100 == 2) {
315 snprintf(etag_buf,
sizeof(etag_buf),
"If-None-Match: %s", metadata->
value);
316 header_list = curl_slist_append(header_list, etag_buf);
317 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
318 curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
323 curl_slist_free_all(header_list);
325 if (http_code == 304) {
342 void *data,
const char *
type,
const char *
id)
346 if (strcmp(type,
"file")) {
383 unlink(bucket_file->
path);
429 ast_log(
LOG_ERROR,
"Failed to register Bucket HTTP wizard scheme implementation\n");
435 ast_log(
LOG_ERROR,
"Failed to register Bucket HTTPS wizard scheme implementation\n");
446 .requires =
"res_curl",
struct ast_bucket_metadata * ast_bucket_file_metadata_get(struct ast_bucket_file *file, const char *name)
Retrieve a metadata attribute from a file.
Asterisk main include file. File version handling, generic pbx functions.
struct ast_bucket_file * bucket_file
int ast_bucket_file_metadata_set(struct ast_bucket_file *file, const char *name, const char *value)
Set a metadata attribute on a file to a specific value.
Full structure for sorcery.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct ast_bucket_file * ast_bucket_file_alloc(const char *uri)
Allocate a new bucket file.
Definitions to aid in the use of thread local storage.
const char * name
Name of the wizard.
#define ast_strlen_zero(foo)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ao2_ref(o, delta)
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Bucket file structure, contains reference to file and information about it.
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
Data passed to cURL callbacks.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Module has failed to load, may be in an inconsistent state.
int ast_bucket_file_temporary_create(struct ast_bucket_file *file)
Common file snapshot creation callback for creating a temporary file.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
Interface for a sorcery wizard.
static struct ast_sorcery * sorcery
#define ast_bucket_scheme_register(name, bucket, file, create_cb, destroy_cb)
Register support for a specific scheme.
void(* load)(void *data, const struct ast_sorcery *sorcery, const char *type)
Optional callback for loading persistent objects.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
char path[PATH_MAX]
Local path to this file.
Sorcery Data Access Layer API.