added SSL support to mod_http_cache

This commit is contained in:
Christopher Rienzo 2012-04-25 00:18:56 +00:00
parent 2a25c4f2e7
commit d79982e72c
3 changed files with 3422 additions and 9 deletions

View File

@ -3,6 +3,9 @@
<param name="max-urls" value="10000"/> <param name="max-urls" value="10000"/>
<param name="location" value="$${base_dir}/http_cache"/> <param name="location" value="$${base_dir}/http_cache"/>
<param name="default-max-age" value="86400"/> <param name="default-max-age" value="86400"/>
<param name="ssl-cacert" value="$${base_dir}/conf/cacert.pem"/>
<param name="ssl-verifyhost" value="true"/>
<param name="ssl-verifypeer" value="true"/>
</settings> </settings>
</configuration> </configuration>

File diff suppressed because it is too large Load Diff

View File

@ -96,12 +96,12 @@ struct http_get_data {
}; };
typedef struct http_get_data http_get_data_t; typedef struct http_get_data http_get_data_t;
static switch_status_t http_get(cached_url_t *url, switch_core_session_t *session); static switch_status_t http_get(url_cache_t *cache, cached_url_t *url, switch_core_session_t *session);
static size_t get_file_callback(void *ptr, size_t size, size_t nmemb, void *get); static size_t get_file_callback(void *ptr, size_t size, size_t nmemb, void *get);
static size_t get_header_callback(void *ptr, size_t size, size_t nmemb, void *url); static size_t get_header_callback(void *ptr, size_t size, size_t nmemb, void *url);
static void process_cache_control_header(cached_url_t *url, char *data); static void process_cache_control_header(cached_url_t *url, char *data);
static switch_status_t http_put(switch_core_session_t *session, const char *url, const char *filename); static switch_status_t http_put(url_cache_t *cache, switch_core_session_t *session, const char *url, const char *filename);
/** /**
* Queue used for clock cache replacement algorithm. This * Queue used for clock cache replacement algorithm. This
@ -159,6 +159,12 @@ struct url_cache {
int shutdown; int shutdown;
/** Synchronizes shutdown of cache */ /** Synchronizes shutdown of cache */
switch_thread_rwlock_t *shutdown_lock; switch_thread_rwlock_t *shutdown_lock;
/** SSL cert filename */
char *ssl_cacert;
/** Verify certificate */
int ssl_verifypeer;
/** Verify that hostname matches certificate */
int ssl_verifyhost;
}; };
static url_cache_t gcache; static url_cache_t gcache;
@ -173,12 +179,13 @@ static void url_cache_clear(url_cache_t *cache, switch_core_session_t *session);
/** /**
* Put a file to the URL * Put a file to the URL
* @param cache the cache
* @param session the (optional) session uploading the file * @param session the (optional) session uploading the file
* @param url The URL * @param url The URL
* @param filename The file to upload * @param filename The file to upload
* @return SWITCH_STATUS_SUCCESS if successful * @return SWITCH_STATUS_SUCCESS if successful
*/ */
static switch_status_t http_put(switch_core_session_t *session, const char *url, const char *filename) static switch_status_t http_put(url_cache_t *cache, switch_core_session_t *session, const char *url, const char *filename)
{ {
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
CURL *curl_handle = NULL; CURL *curl_handle = NULL;
@ -223,6 +230,18 @@ static switch_status_t http_put(switch_core_session_t *session, const char *url,
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10); switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0"); switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
if (!cache->ssl_verifypeer) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
} else {
/* this is the file with all the trusted certificate authorities */
if (!zstr(cache->ssl_cacert)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, cache->ssl_cacert);
}
/* verify that the host name matches the cert */
if (!cache->ssl_verifyhost) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
}
}
switch_curl_easy_perform(curl_handle); switch_curl_easy_perform(curl_handle);
switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
switch_curl_easy_cleanup(curl_handle); switch_curl_easy_cleanup(curl_handle);
@ -485,7 +504,7 @@ static char *url_cache_get(url_cache_t *cache, switch_core_session_t *session, c
/* download the file */ /* download the file */
url_cache_unlock(cache, session); url_cache_unlock(cache, session);
if (http_get(u, session) == SWITCH_STATUS_SUCCESS) { if (http_get(cache, u, session) == SWITCH_STATUS_SUCCESS) {
/* Got the file, let the waiters know it is available */ /* Got the file, let the waiters know it is available */
url_cache_lock(cache, session); url_cache_lock(cache, session);
u->status = CACHED_URL_AVAILABLE; u->status = CACHED_URL_AVAILABLE;
@ -708,11 +727,12 @@ static void cached_url_destroy(cached_url_t *url, switch_memory_pool_t *pool)
/** /**
* Fetch a file via HTTP * Fetch a file via HTTP
* @param cache the cache
* @param url The cached URL entry * @param url The cached URL entry
* @param session the (optional) session * @param session the (optional) session
* @return SWITCH_STATUS_SUCCESS if successful * @return SWITCH_STATUS_SUCCESS if successful
*/ */
static switch_status_t http_get(cached_url_t *url, switch_core_session_t *session) static switch_status_t http_get(url_cache_t *cache, cached_url_t *url, switch_core_session_t *session)
{ {
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_CURL *curl_handle = NULL; switch_CURL *curl_handle = NULL;
@ -734,7 +754,19 @@ static switch_status_t http_get(cached_url_t *url, switch_core_session_t *sessio
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &get_data); switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &get_data);
switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, get_header_callback); switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, get_header_callback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *) url); switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *) url);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0"); switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
if (!cache->ssl_verifypeer) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
} else {
/* this is the file with all the trusted certificate authorities */
if (!zstr(cache->ssl_cacert)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, cache->ssl_cacert);
}
/* verify that the host name matches the cert */
if (!cache->ssl_verifyhost) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
}
}
switch_curl_easy_perform(curl_handle); switch_curl_easy_perform(curl_handle);
switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
switch_curl_easy_cleanup(curl_handle); switch_curl_easy_cleanup(curl_handle);
@ -791,7 +823,7 @@ static void setup_dir(url_cache_t *cache)
static int isUrl(const char *filename) static int isUrl(const char *filename)
{ {
return !zstr(filename) && !strncmp("http://", filename, strlen("http://")); return !zstr(filename) && (!strncmp("http://", filename, strlen("http://")) || !strncmp("https://", filename, strlen("https://")));
} }
#define HTTP_PREFETCH_SYNTAX "<url>" #define HTTP_PREFETCH_SYNTAX "<url>"
@ -910,7 +942,7 @@ SWITCH_STANDARD_API(http_cache_put)
char *argv[10] = { 0 }; char *argv[10] = { 0 };
int argc = 0; int argc = 0;
if (zstr(cmd) || strncmp("http://", cmd, strlen("http://"))) { if (zstr(cmd) || (strncmp("http://", cmd, strlen("http://")) && strncmp("https://", cmd, strlen("https://")))) {
stream->write_function(stream, "USAGE: %s\n", HTTP_PUT_SYNTAX); stream->write_function(stream, "USAGE: %s\n", HTTP_PUT_SYNTAX);
status = SWITCH_STATUS_SUCCESS; status = SWITCH_STATUS_SUCCESS;
goto done; goto done;
@ -924,7 +956,7 @@ SWITCH_STANDARD_API(http_cache_put)
goto done; goto done;
} }
status = http_put(session, argv[0], argv[1]); status = http_put(&gcache, session, argv[0], argv[1]);
if (status == SWITCH_STATUS_SUCCESS) { if (status == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK\n"); stream->write_function(stream, "+OK\n");
} else { } else {
@ -1013,6 +1045,9 @@ static switch_status_t do_config(url_cache_t *cache)
cache->location = SWITCH_PREFIX_DIR "/http_cache"; cache->location = SWITCH_PREFIX_DIR "/http_cache";
cache->prefetch_queue_size = 100; cache->prefetch_queue_size = 100;
cache->prefetch_thread_count = 8; cache->prefetch_thread_count = 8;
cache->ssl_cacert = SWITCH_PREFIX_DIR "/conf/cacert.pem";
cache->ssl_verifyhost = 1;
cache->ssl_verifypeer = 1;
/* get params */ /* get params */
settings = switch_xml_child(cfg, "settings"); settings = switch_xml_child(cfg, "settings");
@ -1035,6 +1070,15 @@ static switch_status_t do_config(url_cache_t *cache)
} else if (!strcasecmp(var, "prefetch-thread-count")) { } else if (!strcasecmp(var, "prefetch-thread-count")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting prefetch-thread-count to %s\n", val); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting prefetch-thread-count to %s\n", val);
cache->prefetch_thread_count = atoi(val); cache->prefetch_thread_count = atoi(val);
} else if (!strcasecmp(var, "ssl-cacert")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-cacert to %s\n", val);
cache->ssl_cacert = switch_core_strdup(cache->pool, val);
} else if (!strcasecmp(var, "ssl-verifyhost")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-verifyhost to %s\n", val);
cache->ssl_verifyhost = !switch_false(val); /* only disable if explicitly set to false */
} else if (!strcasecmp(var, "ssl-verifypeer")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-verifypeer to %s\n", val);
cache->ssl_verifypeer = !switch_false(val); /* only disable if explicitly set to false */
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var);
} }