mod_http_cache: add support for http/https formats if enable-file-formats is set to true in http_cache.conf. Don't load mod_httapi if you use this option

This commit is contained in:
Chris Rienzo 2013-03-18 17:58:51 -04:00
parent f05b493367
commit f45fa08e15
3 changed files with 161 additions and 21 deletions

View File

@ -1,10 +1,17 @@
<configuration name="http_cache.conf" description="HTTP GET cache">
<settings>
<!-- set to true if you want to enable http:// and https:// formats. Do not use if mod_httapi is also loaded -->
<param name="enable-file-formats" value="false"/>
<param name="max-urls" value="10000"/>
<param name="location" value="$${base_dir}/http_cache"/>
<param name="default-max-age" value="86400"/>
<param name="prefetch-thread-count" value="8"/>
<param name="prefetch-queue-size" value="100"/>
<!-- absolute path to CA bundle file -->
<param name="ssl-cacert" value="$${base_dir}/conf/cacert.pem"/>
<!-- verify certificates -->
<param name="ssl-verifypeer" value="true"/>
<!-- verify host name matches certificate -->
<param name="ssl-verifyhost" value="true"/>
</settings>
</configuration>

View File

@ -1,5 +1,7 @@
<configuration name="http_cache.conf" description="HTTP GET cache">
<settings>
<!-- set to true if you want to enable http:// and https:// formats. Do not use if mod_httapi is also loaded -->
<param name="enable-file-formats" value="false"/>
<param name="max-urls" value="10000"/>
<param name="location" value="$${base_dir}/http_cache"/>
<param name="default-max-age" value="86400"/>
@ -8,4 +10,3 @@
<param name="ssl-verifypeer" value="true"/>
</settings>
</configuration>

View File

@ -168,6 +168,8 @@ struct url_cache {
int ssl_verifypeer;
/** Verify that hostname matches certificate */
int ssl_verifyhost;
/** True if http/https file formats should be loaded */
int enable_file_formats;
};
static url_cache_t gcache;
@ -1082,6 +1084,7 @@ static switch_status_t do_config(url_cache_t *cache)
cache->ssl_cacert = SWITCH_PREFIX_DIR "/conf/cacert.pem";
cache->ssl_verifyhost = 1;
cache->ssl_verifypeer = 1;
cache->enable_file_formats = 0;
/* get params */
settings = switch_xml_child(cfg, "settings");
@ -1089,7 +1092,12 @@ static switch_status_t do_config(url_cache_t *cache)
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "max-urls")) {
if (!strcasecmp(var, "enable-file-formats")) {
cache->enable_file_formats = switch_true(val);
if (cache->enable_file_formats) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabling http:// and https:// formats. This is unstable if mod_httapi is also loaded\n");
}
} else if (!strcasecmp(var, "max-urls")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting max-urls to %s\n", val);
max_urls = atoi(val);
} else if (!strcasecmp(var, "location")) {
@ -1154,6 +1162,114 @@ done:
return status;
}
/**
* HTTP file playback state
*/
struct http_context {
switch_file_handle_t fh;
};
/**
* Open URL
* @param handle
* @param prefix URL prefix
* @param path the URL
* @return SWITCH_STATUS_SUCCESS if opened
*/
static switch_status_t file_open(switch_file_handle_t *handle, const char *prefix, const char *path)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
struct http_context *context = switch_core_alloc(handle->memory_pool, sizeof(*context));
const char *url = switch_core_sprintf(handle->memory_pool, "%s%s", prefix, path);
const char *local_path;
if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
/* WRITE not supported */
return SWITCH_STATUS_FALSE;
}
local_path = url_cache_get(&gcache, NULL, url, 1, handle->memory_pool);
if (!local_path) {
return SWITCH_STATUS_FALSE;
}
if ((status = switch_core_file_open(&context->fh,
local_path,
handle->channels,
handle->samplerate,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open HTTP cache file: %s, %s\n", local_path, url);
return status;
}
handle->private_info = context;
handle->samples = context->fh.samples;
handle->format = context->fh.format;
handle->sections = context->fh.sections;
handle->seekable = context->fh.seekable;
handle->speed = context->fh.speed;
handle->interval = context->fh.interval;
handle->channels = context->fh.channels;
handle->flags |= SWITCH_FILE_NOMUX;
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
}
return status;
}
/**
* Open HTTP URL
* @param handle
* @param path the URL
* @return SWITCH_STATUS_SUCCESS if opened
*/
static switch_status_t http_file_open(switch_file_handle_t *handle, const char *path)
{
return file_open(handle, "http://", path);
}
/**
* Open HTTPS URL
* @param handle
* @param path the URL
* @return SWITCH_STATUS_SUCCESS if opened
*/
static switch_status_t https_file_open(switch_file_handle_t *handle, const char *path)
{
return file_open(handle, "https://", path);
}
/**
* Read from HTTP file
* @param handle
* @param data
* @param len
* @return
*/
static switch_status_t http_file_read(switch_file_handle_t *handle, void *data, size_t *len)
{
struct http_context *context = (struct http_context *)handle->private_info;
return switch_core_file_read(&context->fh, data, len);
}
/**
* Close HTTP file
* @param handle
* @return SWITCH_STATUS_SUCCESS
*/
static switch_status_t http_file_close(switch_file_handle_t *handle)
{
struct http_context *context = (struct http_context *)handle->private_info;
return switch_core_file_close(&context->fh);
}
static char *http_supported_formats[] = { "http", NULL };
static char *https_supported_formats[] = { "https", NULL };
/**
* Called when FreeSWITCH loads the module
*/
@ -1177,6 +1293,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load)
return SWITCH_STATUS_TERM;
}
if (gcache.enable_file_formats) {
switch_file_interface_t *file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface->interface_name = modname;
file_interface->extens = http_supported_formats;
file_interface->file_open = http_file_open;
file_interface->file_close = http_file_close;
file_interface->file_read = http_file_read;
file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface->interface_name = modname;
file_interface->extens = https_supported_formats;
file_interface->file_open = https_file_open;
file_interface->file_close = http_file_close;
file_interface->file_read = http_file_read;
}
switch_core_hash_init(&gcache.map, gcache.pool);
switch_mutex_init(&gcache.mutex, SWITCH_MUTEX_UNNESTED, gcache.pool);
switch_thread_rwlock_create(&gcache.shutdown_lock, gcache.pool);