80#define MAX_HEADER_LENGTH 1023
82#ifdef CURL_AT_LEAST_VERSION
83#if CURL_AT_LEAST_VERSION(7, 85, 0)
84#define AST_CURL_HAS_PROTOCOLS_STR 1
125 .item_offset = offsetof(
struct conf, general),
126 .category =
"general",
135 struct conf *cfg = obj;
165 .
filename =
"res_http_media_cache.conf",
181#ifndef AST_CURL_HAS_PROTOCOLS_STR
185 ast_log(
AST_LOG_ERROR,
"'protocols' not supported by linked CURL library. Please recompile against newer CURL.\n");
190 ast_log(
AST_LOG_ERROR,
"'redirect_protocols' not supported by linked CURL library. Please recompile against newer CURL.\n");
217 realsize = size * nitems;
227 memcpy(
header, buffer, realsize);
236 if (strcasecmp(
header,
"ETag")
237 && strcasecmp(
header,
"Cache-Control")
238 && strcasecmp(
header,
"Last-Modified")
239 && strcasecmp(
header,
"Content-Type")
240 && strcasecmp(
header,
"Expires")) {
260 realsize = fwrite(ptr, size, nitems, cb_data->
out_file);
272 struct timeval actual_expires =
ast_tvnow();
278 str_max_age = strstr(metadata->
value,
"s-maxage");
280 str_max_age = strstr(metadata->
value,
"max-age");
284 unsigned int max_age;
285 char *equal = strchr(str_max_age,
'=');
286 if (equal && (sscanf(equal + 1,
"%30u", &max_age) == 1)) {
287 actual_expires.tv_sec += max_age;
294 struct tm expires_time;
296 strptime(metadata->
value,
"%a, %d %b %Y %T %z", &expires_time);
297 expires_time.tm_isdst = -1;
298 actual_expires.tv_sec = mktime(&expires_time);
306 snprintf(time_buf,
sizeof(time_buf),
"%30s", secs);
317 ast_debug(3,
"Found extension '%s' at end of string\n",
ext);
335 char *params = strchr(content_type,
';');
339 while (params > content_type && (*params ==
' ' || *params ==
'\t')) {
381 ast_debug(3,
"Derived extension '%s' from MIME type %s\n",
444 if (strstr(metadata->value,
"no-cache")
445 || strstr(metadata->value,
"must-revalidate")) {
460 struct timeval current_time =
ast_tvnow();
461 struct timeval expires = { .tv_sec = 0, .tv_usec = 0 };
471 return ast_tvcmp(current_time, expires) == -1 ? 0 : 1;
483 curl = curl_easy_init();
488 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
491 curl_easy_setopt(curl, CURLOPT_HEADERDATA, cb_data);
493 curl_easy_setopt(curl, CURLOPT_TIMEOUT, cfg->general->curl_timeout);
494 curl_easy_setopt(curl, CURLOPT_USERAGENT, cfg->general->curl_useragent);
495 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, cfg->general->curl_followlocation ? 1 : 0);
496 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, cfg->general->curl_maxredirs);
499 curl_easy_setopt(curl, CURLOPT_PROXY, cfg->general->curl_proxy);
503#ifdef AST_CURL_HAS_PROTOCOLS_STR
504 CURLcode rc = curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, cfg->general->curl_protocols);
505 if (rc != CURLE_OK) {
506 ast_log(
AST_LOG_ERROR,
"Setting protocols to '%s' failed: %d\n", cfg->general->curl_protocols, rc);
507 curl_easy_cleanup(curl);
513#ifdef AST_CURL_HAS_PROTOCOLS_STR
514 CURLcode rc = curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, cfg->general->curl_redir_protocols);
515 if (rc != CURLE_OK) {
516 ast_log(
AST_LOG_ERROR,
"Setting redirect_protocols to '%s' failed: %d\n", cfg->general->curl_redir_protocols, rc);
517 curl_easy_cleanup(curl);
523 rc = curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, cfg->general->curl_dns_cache_timeout);
524 if (rc != CURLE_OK) {
525 ast_log(
AST_LOG_ERROR,
"Setting dns_cache_timeout to '%d' failed: %d\n", cfg->general->curl_dns_cache_timeout, rc);
526 curl_easy_cleanup(curl);
538 char curl_errbuf[CURL_ERROR_SIZE + 1];
541 curl_errbuf[CURL_ERROR_SIZE] =
'\0';
542 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
544 if (curl_easy_perform(curl)) {
549 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
551 curl_easy_cleanup(curl);
581 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void*)&cb_data);
587 if (http_code / 100 == 2) {
624 snprintf(etag_buf,
sizeof(etag_buf),
"If-None-Match: %s", metadata->
value);
626 curl_easy_setopt(curl, CURLOPT_HTTPHEADER,
header_list);
627 curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
634 if (http_code == 304) {
651 void *data,
const char *
type,
const char *
id)
655 if (strcmp(
type,
"file")) {
692 unlink(bucket_file->
path);
780 ast_log(
LOG_NOTICE,
"Could not load res_http_media_cache config; using defaults\n");
788 ast_log(
LOG_ERROR,
"Failed to initialize res_http_media_cache defaults.\n");
800 ast_log(
LOG_ERROR,
"Failed to register Bucket HTTP wizard scheme implementation\n");
806 ast_log(
LOG_ERROR,
"Failed to register Bucket HTTPS wizard scheme implementation\n");
817 .
requires =
"res_curl",
Asterisk main include file. File version handling, generic pbx functions.
#define AST_CURL_USER_AGENT
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
#define ao2_alloc(data_size, destructor_fn)
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.
struct ast_bucket_file * ast_bucket_file_alloc(const char *uri)
Allocate a new bucket file.
#define ast_bucket_scheme_register(name, bucket, file, create_cb, destroy_cb)
Register support for a specific scheme.
int ast_bucket_file_temporary_create(struct ast_bucket_file *file)
Common file snapshot creation callback for creating a temporary file.
struct ast_bucket_metadata * ast_bucket_file_metadata_get(struct ast_bucket_file *file, const char *name)
Retrieve a metadata attribute from a file.
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_INT_T
Type for default option handler for signed integers.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
Generic File Format Support. Should be included by clients of the file handling routines....
struct ast_format * ast_get_format_for_file_ext(const char *file_ext)
Get the ast_format associated with the given file extension.
int ast_get_extension_for_mime_type(const char *mime_type, char *buffer, size_t capacity)
Get a suitable filename extension for the given MIME type.
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
static struct ast_sorcery * sorcery
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
The representation of a single configuration file to be processed.
Type information about a category-level configurable object.
Bucket file structure, contains reference to file and information about it.
char path[PATH_MAX]
Local path to this file.
Interface for a sorcery wizard.
const char * name
Name of the wizard.
Full structure for sorcery.
Stores parsed uri information.
General configuration options for http media cache.
const ast_string_field curl_useragent
int curl_dns_cache_timeout
Life-time of CURL DNS cache entries.
const ast_string_field curl_protocols
const ast_string_field curl_proxy
int curl_maxredirs
Number of redirects to follow for one request.
int curl_followlocation
Follow 3xx redirects automatically.
int curl_timeout
Request timeout to use.
const ast_string_field curl_redir_protocols
All configuration options for http media cache.
struct conf_general_options * general
Data passed to cURL callbacks.
struct ast_bucket_file * bucket_file
Definitions to aid in the use of thread local storage.
int ast_time_t_to_string(time_t time, char *buf, size_t length)
Converts to a string representation of a time_t as decimal seconds since the epoch....
time_t ast_string_to_time_t(const char *str)
Returns a time_t from a string containing seconds since the epoch.
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
const char * ast_uri_path(const struct ast_uri *uri)
Retrieve the uri path.
struct ast_uri * ast_uri_parse(const char *uri)
Parse the given uri into a structure.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.