提交 dd612321 authored 作者: Chris Rienzo's avatar Chris Rienzo

FS-6979 #resolve #comment mod_http_cache: added base-domain config to s3…

FS-6979 #resolve #comment mod_http_cache: added base-domain config to s3 profiles so mod_http_cache can access self hosted s3 compatible service.

Example configuration:

  <profiles>
    <profile name="s3">
       <!-- Credentials for AWS account. -->
       <aws-s3>
          <!-- 20 character key identifier -->
          <access-key-id><![CDATA[AKIAIOSFODNN7EXAMPLE]]></access-key-id>
          <!-- 40 character secret -->
          <secret-access-key><![CDATA[wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY]]></secret-access-key>
          <base-domain><![CDATA[example.com]]></base-domain>
       </aws-s3>
       <!-- Domains that this profile applies to -->
       <domains>
          <domain name="bucket.example.com"/>
          <domain name="bucket2.example.com"/>
       </domains>
    </profile>
  </profiles>
上级 75473a70
/* /*
* aws.c for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * aws.c for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper * Copyright (C) 2013-2014, Grasshopper
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -41,8 +41,18 @@ ...@@ -41,8 +41,18 @@
* @param url to check * @param url to check
* @return true if this is an S3 url * @return true if this is an S3 url
*/ */
int aws_s3_is_s3_url(const char *url) int aws_s3_is_s3_url(const char *url, const char *base_domain)
{ {
if (!zstr(base_domain)) {
char *base_domain_escaped;
char regex[1024];
int result;
base_domain_escaped = switch_string_replace(base_domain, ".", "\\.");
switch_snprintf(regex, 1024, "^https?://\\w[-\\w.]{1,61}\\w\\.%s/.*$", base_domain_escaped);
result = !zstr(url) && switch_regex_match(url, regex) == SWITCH_STATUS_SUCCESS;
switch_safe_free(base_domain_escaped);
return result;
}
/* AWS bucket naming rules are complex... this match only supports virtual hosting of buckets */ /* AWS bucket naming rules are complex... this match only supports virtual hosting of buckets */
return !zstr(url) && switch_regex_match(url, "^https?://\\w[-\\w.]{1,61}\\w\\.s3([-\\w]+)?\\.amazonaws\\.com/.*$") == SWITCH_STATUS_SUCCESS; return !zstr(url) && switch_regex_match(url, "^https?://\\w[-\\w.]{1,61}\\w\\.s3([-\\w]+)?\\.amazonaws\\.com/.*$") == SWITCH_STATUS_SUCCESS;
} }
...@@ -141,10 +151,11 @@ static char *my_strrstr(const char *haystack, const char *needle) ...@@ -141,10 +151,11 @@ static char *my_strrstr(const char *haystack, const char *needle)
/** /**
* Parse bucket and object from URL * Parse bucket and object from URL
* @param url to parse. This value is modified. * @param url to parse. This value is modified.
* @param base_domain of URL (assumes s3.amazonaws.com if not specified)
* @param bucket to store result in * @param bucket to store result in
* @param bucket_length of result buffer * @param bucket_length of result buffer
*/ */
void aws_s3_parse_url(char *url, char **bucket, char **object) void aws_s3_parse_url(char *url, const char *base_domain, char **bucket, char **object)
{ {
char *bucket_start = NULL; char *bucket_start = NULL;
char *bucket_end; char *bucket_end;
...@@ -153,7 +164,7 @@ void aws_s3_parse_url(char *url, char **bucket, char **object) ...@@ -153,7 +164,7 @@ void aws_s3_parse_url(char *url, char **bucket, char **object)
*bucket = NULL; *bucket = NULL;
*object = NULL; *object = NULL;
if (!aws_s3_is_s3_url(url)) { if (!aws_s3_is_s3_url(url, base_domain)) {
return; return;
} }
...@@ -167,8 +178,15 @@ void aws_s3_parse_url(char *url, char **bucket, char **object) ...@@ -167,8 +178,15 @@ void aws_s3_parse_url(char *url, char **bucket, char **object)
/* invalid URL */ /* invalid URL */
return; return;
} }
bucket_end = my_strrstr(bucket_start, ".s3"); {
char base_domain_match[1024];
if (zstr(base_domain)) {
base_domain = "s3";
}
switch_snprintf(base_domain_match, 1024, ".%s", base_domain);
bucket_end = my_strrstr(bucket_start, base_domain_match);
}
if (!bucket_end) { if (!bucket_end) {
/* invalid URL */ /* invalid URL */
return; return;
...@@ -195,6 +213,7 @@ void aws_s3_parse_url(char *url, char **bucket, char **object) ...@@ -195,6 +213,7 @@ void aws_s3_parse_url(char *url, char **bucket, char **object)
* Create a pre-signed URL for AWS S3 * Create a pre-signed URL for AWS S3
* @param verb (PUT/GET) * @param verb (PUT/GET)
* @param url address (virtual-host-style) * @param url address (virtual-host-style)
* @param base_domain (optional - amazon aws assumed if not specified)
* @param content_type optional content type * @param content_type optional content type
* @param content_md5 optional content MD5 checksum * @param content_md5 optional content MD5 checksum
* @param aws_access_key_id secret access key identifier * @param aws_access_key_id secret access key identifier
...@@ -202,7 +221,7 @@ void aws_s3_parse_url(char *url, char **bucket, char **object) ...@@ -202,7 +221,7 @@ void aws_s3_parse_url(char *url, char **bucket, char **object)
* @param expires seconds since the epoch * @param expires seconds since the epoch
* @return presigned_url * @return presigned_url
*/ */
char *aws_s3_presigned_url_create(const char *verb, const char *url, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *expires) char *aws_s3_presigned_url_create(const char *verb, const char *url, const char *base_domain, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *expires)
{ {
char signature[S3_SIGNATURE_LENGTH_MAX]; char signature[S3_SIGNATURE_LENGTH_MAX];
char signature_url_encoded[S3_SIGNATURE_LENGTH_MAX]; char signature_url_encoded[S3_SIGNATURE_LENGTH_MAX];
...@@ -212,7 +231,7 @@ char *aws_s3_presigned_url_create(const char *verb, const char *url, const char ...@@ -212,7 +231,7 @@ char *aws_s3_presigned_url_create(const char *verb, const char *url, const char
char *object; char *object;
/* create URL encoded signature */ /* create URL encoded signature */
aws_s3_parse_url(url_dup, &bucket, &object); aws_s3_parse_url(url_dup, base_domain, &bucket, &object);
string_to_sign = aws_s3_string_to_sign(verb, bucket, object, content_type, content_md5, expires); string_to_sign = aws_s3_string_to_sign(verb, bucket, object, content_type, content_md5, expires);
signature[0] = '\0'; signature[0] = '\0';
aws_s3_signature(signature, S3_SIGNATURE_LENGTH_MAX, string_to_sign, aws_secret_access_key); aws_s3_signature(signature, S3_SIGNATURE_LENGTH_MAX, string_to_sign, aws_secret_access_key);
...@@ -230,6 +249,7 @@ char *aws_s3_presigned_url_create(const char *verb, const char *url, const char ...@@ -230,6 +249,7 @@ char *aws_s3_presigned_url_create(const char *verb, const char *url, const char
* @param authentication_length maximum result length * @param authentication_length maximum result length
* @param verb (PUT/GET) * @param verb (PUT/GET)
* @param url address (virtual-host-style) * @param url address (virtual-host-style)
* @param base_domain (optional - amazon aws assumed if not specified)
* @param content_type optional content type * @param content_type optional content type
* @param content_md5 optional content MD5 checksum * @param content_md5 optional content MD5 checksum
* @param aws_access_key_id secret access key identifier * @param aws_access_key_id secret access key identifier
...@@ -237,7 +257,7 @@ char *aws_s3_presigned_url_create(const char *verb, const char *url, const char ...@@ -237,7 +257,7 @@ char *aws_s3_presigned_url_create(const char *verb, const char *url, const char
* @param date header * @param date header
* @return signature for Authorization header * @return signature for Authorization header
*/ */
char *aws_s3_authentication_create(const char *verb, const char *url, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *date) char *aws_s3_authentication_create(const char *verb, const char *url, const char *base_domain, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *date)
{ {
char signature[S3_SIGNATURE_LENGTH_MAX]; char signature[S3_SIGNATURE_LENGTH_MAX];
char *string_to_sign; char *string_to_sign;
...@@ -246,7 +266,7 @@ char *aws_s3_authentication_create(const char *verb, const char *url, const char ...@@ -246,7 +266,7 @@ char *aws_s3_authentication_create(const char *verb, const char *url, const char
char *object; char *object;
/* create base64 encoded signature */ /* create base64 encoded signature */
aws_s3_parse_url(url_dup, &bucket, &object); aws_s3_parse_url(url_dup, base_domain, &bucket, &object);
string_to_sign = aws_s3_string_to_sign(verb, bucket, object, content_type, content_md5, date); string_to_sign = aws_s3_string_to_sign(verb, bucket, object, content_type, content_md5, date);
signature[0] = '\0'; signature[0] = '\0';
aws_s3_signature(signature, S3_SIGNATURE_LENGTH_MAX, string_to_sign, aws_secret_access_key); aws_s3_signature(signature, S3_SIGNATURE_LENGTH_MAX, string_to_sign, aws_secret_access_key);
......
/* /*
* aws.h for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * aws.h for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper * Copyright (C) 2013-2014, Grasshopper
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -34,12 +34,12 @@ ...@@ -34,12 +34,12 @@
/* (SHA1_LENGTH * 1.37 base64 bytes per byte * 3 url-encoded bytes per byte) */ /* (SHA1_LENGTH * 1.37 base64 bytes per byte * 3 url-encoded bytes per byte) */
#define S3_SIGNATURE_LENGTH_MAX 83 #define S3_SIGNATURE_LENGTH_MAX 83
int aws_s3_is_s3_url(const char *url); int aws_s3_is_s3_url(const char *url, const char *base_domain);
void aws_s3_parse_url(char *url, char **bucket, char **object); void aws_s3_parse_url(char *url, const char *base_domain, char **bucket, char **object);
char *aws_s3_string_to_sign(const char *verb, const char *bucket, const char *object, const char *content_type, const char *content_md5, const char *date); char *aws_s3_string_to_sign(const char *verb, const char *bucket, const char *object, const char *content_type, const char *content_md5, const char *date);
char *aws_s3_signature(char *signature, int signature_length, const char *string_to_sign, const char *aws_secret_access_key); char *aws_s3_signature(char *signature, int signature_length, const char *string_to_sign, const char *aws_secret_access_key);
char *aws_s3_presigned_url_create(const char *verb, const char *url, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *expires); char *aws_s3_presigned_url_create(const char *verb, const char *url, const char *base_domain, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *expires);
char *aws_s3_authentication_create(const char *verb, const char *url, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *date); char *aws_s3_authentication_create(const char *verb, const char *url, const char *base_domain, const char *content_type, const char *content_md5, const char *aws_access_key_id, const char *aws_secret_access_key, const char *date);
#endif #endif
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
<access-key-id><![CDATA[AKIAIOSFODNN7EXAMPLE]]></access-key-id> <access-key-id><![CDATA[AKIAIOSFODNN7EXAMPLE]]></access-key-id>
<!-- 40 character secret --> <!-- 40 character secret -->
<secret-access-key><![CDATA[wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY]]></secret-access-key> <secret-access-key><![CDATA[wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY]]></secret-access-key>
<!--base-url><![CDATA[s3.example.com]]></base-url-->
</aws-s3> </aws-s3>
<!-- Domains that this profile applies to --> <!-- Domains that this profile applies to -->
<domains> <domains>
......
/* /*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2013, Anthony Minessale II <anthm@freeswitch.org> * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -61,6 +61,7 @@ struct http_profile { ...@@ -61,6 +61,7 @@ struct http_profile {
const char *name; const char *name;
const char *aws_s3_access_key_id; const char *aws_s3_access_key_id;
const char *aws_s3_secret_access_key; const char *aws_s3_secret_access_key;
const char *aws_s3_base_domain;
}; };
typedef struct http_profile http_profile_t; typedef struct http_profile http_profile_t;
...@@ -201,7 +202,7 @@ static void url_cache_unlock(url_cache_t *cache, switch_core_session_t *session) ...@@ -201,7 +202,7 @@ static void url_cache_unlock(url_cache_t *cache, switch_core_session_t *session)
static void url_cache_clear(url_cache_t *cache, switch_core_session_t *session); static void url_cache_clear(url_cache_t *cache, switch_core_session_t *session);
static http_profile_t *url_cache_http_profile_find(url_cache_t *cache, const char *name); static http_profile_t *url_cache_http_profile_find(url_cache_t *cache, const char *name);
static http_profile_t *url_cache_http_profile_find_by_fqdn(url_cache_t *cache, const char *url); static http_profile_t *url_cache_http_profile_find_by_fqdn(url_cache_t *cache, const char *url);
static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char *name, const char *aws_s3_access_key_id, const char *aws_s3_secret_access_key); static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char *name, const char *aws_s3_access_key_id, const char *aws_s3_secret_access_key, const char *aws_s3_base_domain);
static switch_curl_slist_t *append_aws_s3_headers(switch_curl_slist_t *headers, http_profile_t *profile, const char *verb, const char *content_type, const char *url); static switch_curl_slist_t *append_aws_s3_headers(switch_curl_slist_t *headers, http_profile_t *profile, const char *verb, const char *content_type, const char *url);
...@@ -792,7 +793,7 @@ static http_profile_t *url_cache_http_profile_find_by_fqdn(url_cache_t *cache, c ...@@ -792,7 +793,7 @@ static http_profile_t *url_cache_http_profile_find_by_fqdn(url_cache_t *cache, c
/** /**
* Add a profile to the cache * Add a profile to the cache
*/ */
static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char *name, const char *aws_s3_access_key_id, const char *aws_s3_secret_access_key) static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char *name, const char *aws_s3_access_key_id, const char *aws_s3_secret_access_key, const char *aws_s3_base_domain)
{ {
http_profile_t *profile = switch_core_alloc(cache->pool, sizeof(*profile)); http_profile_t *profile = switch_core_alloc(cache->pool, sizeof(*profile));
profile->name = switch_core_strdup(cache->pool, name); profile->name = switch_core_strdup(cache->pool, name);
...@@ -802,6 +803,10 @@ static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char ...@@ -802,6 +803,10 @@ static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char
if (aws_s3_secret_access_key) { if (aws_s3_secret_access_key) {
profile->aws_s3_secret_access_key = switch_core_strdup(cache->pool, aws_s3_secret_access_key); profile->aws_s3_secret_access_key = switch_core_strdup(cache->pool, aws_s3_secret_access_key);
} }
if (aws_s3_base_domain) {
profile->aws_s3_base_domain = switch_core_strdup(cache->pool, aws_s3_base_domain);
}
switch_core_hash_insert(cache->profiles, profile->name, profile); switch_core_hash_insert(cache->profiles, profile->name, profile);
return profile; return profile;
} }
...@@ -919,7 +924,7 @@ static void cached_url_destroy(cached_url_t *url, switch_memory_pool_t *pool) ...@@ -919,7 +924,7 @@ static void cached_url_destroy(cached_url_t *url, switch_memory_pool_t *pool)
static switch_curl_slist_t *append_aws_s3_headers(switch_curl_slist_t *headers, http_profile_t *profile, const char *verb, const char *content_type, const char *url) static switch_curl_slist_t *append_aws_s3_headers(switch_curl_slist_t *headers, http_profile_t *profile, const char *verb, const char *content_type, const char *url)
{ {
/* check if Amazon headers are needed */ /* check if Amazon headers are needed */
if (profile && profile->aws_s3_access_key_id && aws_s3_is_s3_url(url)) { if (profile && profile->aws_s3_access_key_id && aws_s3_is_s3_url(url, profile->aws_s3_base_domain)) {
char date[256]; char date[256];
char header[1024]; char header[1024];
char *authenticate; char *authenticate;
...@@ -930,7 +935,7 @@ static switch_curl_slist_t *append_aws_s3_headers(switch_curl_slist_t *headers, ...@@ -930,7 +935,7 @@ static switch_curl_slist_t *append_aws_s3_headers(switch_curl_slist_t *headers,
headers = switch_curl_slist_append(headers, header); headers = switch_curl_slist_append(headers, header);
/* Authorization: */ /* Authorization: */
authenticate = aws_s3_authentication_create(verb, url, content_type, "", profile->aws_s3_access_key_id, profile->aws_s3_secret_access_key, date); authenticate = aws_s3_authentication_create(verb, url, profile->aws_s3_base_domain, content_type, "", profile->aws_s3_access_key_id, profile->aws_s3_secret_access_key, date);
snprintf(header, 1024, "Authorization: %s", authenticate); snprintf(header, 1024, "Authorization: %s", authenticate);
free(authenticate); free(authenticate);
headers = switch_curl_slist_append(headers, header); headers = switch_curl_slist_append(headers, header);
...@@ -1397,7 +1402,9 @@ static switch_status_t do_config(url_cache_t *cache) ...@@ -1397,7 +1402,9 @@ static switch_status_t do_config(url_cache_t *cache)
switch_xml_t s3 = switch_xml_child(profile, "aws-s3"); switch_xml_t s3 = switch_xml_child(profile, "aws-s3");
char *access_key_id = NULL; char *access_key_id = NULL;
char *secret_access_key = NULL; char *secret_access_key = NULL;
char *base_domain = NULL;
if (s3) { if (s3) {
switch_xml_t base_domain_xml = switch_xml_child(s3, "base-domain");
switch_xml_t id = switch_xml_child(s3, "access-key-id"); switch_xml_t id = switch_xml_child(s3, "access-key-id");
switch_xml_t secret = switch_xml_child(s3, "secret-access-key"); switch_xml_t secret = switch_xml_child(s3, "secret-access-key");
if (id && secret) { if (id && secret) {
...@@ -1412,12 +1419,21 @@ static switch_status_t do_config(url_cache_t *cache) ...@@ -1412,12 +1419,21 @@ static switch_status_t do_config(url_cache_t *cache)
} }
} else { } else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing key id or secret\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing key id or secret\n");
continue;
}
if (base_domain_xml) {
base_domain = switch_strip_whitespace(switch_xml_txt(base_domain_xml));
if (zstr(base_domain)) {
switch_safe_free(base_domain);
base_domain = NULL;
}
} }
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding profile \"%s\" to cache\n", name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding profile \"%s\" to cache\n", name);
profile_obj = url_cache_http_profile_add(cache, name, access_key_id, secret_access_key); profile_obj = url_cache_http_profile_add(cache, name, access_key_id, secret_access_key, base_domain);
switch_safe_free(access_key_id); switch_safe_free(access_key_id);
switch_safe_free(secret_access_key); switch_safe_free(secret_access_key);
switch_safe_free(base_domain);
domains = switch_xml_child(profile, "domains"); domains = switch_xml_child(profile, "domains");
if (domains) { if (domains) {
......
...@@ -41,24 +41,28 @@ static void test_signature(void) ...@@ -41,24 +41,28 @@ static void test_signature(void)
*/ */
static void test_check_url(void) static void test_check_url(void)
{ {
ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3-us-west-1.amazonaws.com/object.ext")); ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3-us-west-1.amazonaws.com/object.ext", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3-us-west-1.amazonaws.com/object.ext")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3-us-west-1.amazonaws.com/object.ext", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3.amazonaws.com/object.ext")); ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3.amazonaws.com/object.ext", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3.amazonaws.com/object.ext")); ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3.amazonaws.com/object.ext", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3.amazonaws.com/object")); ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.s3.amazonaws.com/object", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("http://red.bucket.s3.amazonaws.com/object.ext")); ASSERT_TRUE(aws_s3_is_s3_url("http://red.bucket.s3.amazonaws.com/object.ext", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/object.ext")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/object.ext", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/object")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/object", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/recordings/1240fwjf8we.mp3")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/recordings/1240fwjf8we.mp3", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/en/us/8000/1232345.mp3")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/en/us/8000/1232345.mp3", NULL));
ASSERT_TRUE(aws_s3_is_s3_url("https://bucket_with_underscore.s3.amazonaws.com/en/us/8000/1232345.mp3")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket_with_underscore.s3.amazonaws.com/en/us/8000/1232345.mp3", NULL));
ASSERT_FALSE(aws_s3_is_s3_url("bucket.s3.amazonaws.com/object.ext")); ASSERT_FALSE(aws_s3_is_s3_url("bucket.s3.amazonaws.com/object.ext", NULL));
ASSERT_FALSE(aws_s3_is_s3_url("https://s3.amazonaws.com/bucket/object")); ASSERT_FALSE(aws_s3_is_s3_url("https://s3.amazonaws.com/bucket/object", NULL));
ASSERT_FALSE(aws_s3_is_s3_url("http://s3.amazonaws.com/bucket/object")); ASSERT_FALSE(aws_s3_is_s3_url("http://s3.amazonaws.com/bucket/object", NULL));
ASSERT_FALSE(aws_s3_is_s3_url("http://google.com/")); ASSERT_FALSE(aws_s3_is_s3_url("http://google.com/", NULL));
ASSERT_FALSE(aws_s3_is_s3_url("http://phono.com/audio/troporocks.mp3")); ASSERT_FALSE(aws_s3_is_s3_url("http://phono.com/audio/troporocks.mp3", NULL));
ASSERT_FALSE(aws_s3_is_s3_url("")); ASSERT_FALSE(aws_s3_is_s3_url("", NULL));
ASSERT_FALSE(aws_s3_is_s3_url(NULL)); ASSERT_FALSE(aws_s3_is_s3_url(NULL, NULL));
ASSERT_FALSE(aws_s3_is_s3_url("https://example.com/bucket/object", "example.com"));
ASSERT_TRUE(aws_s3_is_s3_url("http://bucket.example.com/object", "example.com"));
ASSERT_FALSE(aws_s3_is_s3_url("", "example.com"));
ASSERT_FALSE(aws_s3_is_s3_url(NULL, "example.com"));
} }
/** /**
...@@ -68,51 +72,55 @@ static void test_parse_url(void) ...@@ -68,51 +72,55 @@ static void test_parse_url(void)
{ {
char *bucket; char *bucket;
char *object; char *object;
aws_s3_parse_url(strdup("http://quotes.s3.amazonaws.com/nelson"), &bucket, &object); aws_s3_parse_url(strdup("http://quotes.s3.amazonaws.com/nelson"), NULL, &bucket, &object);
ASSERT_STRING_EQUALS("quotes", bucket); ASSERT_STRING_EQUALS("quotes", bucket);
ASSERT_STRING_EQUALS("nelson", object); ASSERT_STRING_EQUALS("nelson", object);
aws_s3_parse_url(strdup("https://quotes.s3.amazonaws.com/nelson.mp3"), &bucket, &object); aws_s3_parse_url(strdup("https://quotes.s3.amazonaws.com/nelson.mp3"), NULL, &bucket, &object);
ASSERT_STRING_EQUALS("quotes", bucket); ASSERT_STRING_EQUALS("quotes", bucket);
ASSERT_STRING_EQUALS("nelson.mp3", object); ASSERT_STRING_EQUALS("nelson.mp3", object);
aws_s3_parse_url(strdup("http://s3.amazonaws.com/quotes/nelson"), &bucket, &object); aws_s3_parse_url(strdup("http://s3.amazonaws.com/quotes/nelson"), NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(strdup("http://quotes/quotes/nelson"), &bucket, &object); aws_s3_parse_url(strdup("http://quotes/quotes/nelson"), NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(strdup("http://quotes.s3.amazonaws.com/"), &bucket, &object); aws_s3_parse_url(strdup("http://quotes.s3.amazonaws.com/"), NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(strdup("http://quotes.s3.amazonaws.com"), &bucket, &object); aws_s3_parse_url(strdup("http://quotes.s3.amazonaws.com"), NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(strdup("http://quotes"), &bucket, &object); aws_s3_parse_url(strdup("http://quotes"), NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(strdup(""), &bucket, &object); aws_s3_parse_url(strdup(""), NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(NULL, &bucket, &object); aws_s3_parse_url(NULL, NULL, &bucket, &object);
ASSERT_NULL(bucket); ASSERT_NULL(bucket);
ASSERT_NULL(object); ASSERT_NULL(object);
aws_s3_parse_url(strdup("http://bucket.s3.amazonaws.com/voicemails/recording.wav"), &bucket, &object); aws_s3_parse_url(strdup("http://bucket.s3.amazonaws.com/voicemails/recording.wav"), NULL, &bucket, &object);
ASSERT_STRING_EQUALS("bucket", bucket); ASSERT_STRING_EQUALS("bucket", bucket);
ASSERT_STRING_EQUALS("voicemails/recording.wav", object); ASSERT_STRING_EQUALS("voicemails/recording.wav", object);
aws_s3_parse_url(strdup("https://my-bucket-with-dash.s3-us-west-2.amazonaws.com/greeting/file/1002/Lumino.mp3"), &bucket, &object); aws_s3_parse_url(strdup("https://my-bucket-with-dash.s3-us-west-2.amazonaws.com/greeting/file/1002/Lumino.mp3"), NULL, &bucket, &object);
ASSERT_STRING_EQUALS("my-bucket-with-dash", bucket); ASSERT_STRING_EQUALS("my-bucket-with-dash", bucket);
ASSERT_STRING_EQUALS("greeting/file/1002/Lumino.mp3", object); ASSERT_STRING_EQUALS("greeting/file/1002/Lumino.mp3", object);
aws_s3_parse_url(strdup("http://quotes.s3.foo.bar.s3.amazonaws.com/greeting/file/1002/Lumino.mp3"), &bucket, &object); aws_s3_parse_url(strdup("http://quotes.s3.foo.bar.s3.amazonaws.com/greeting/file/1002/Lumino.mp3"), NULL, &bucket, &object);
ASSERT_STRING_EQUALS("quotes.s3.foo.bar", bucket);
ASSERT_STRING_EQUALS("greeting/file/1002/Lumino.mp3", object);
aws_s3_parse_url(strdup("http://quotes.s3.foo.bar.example.com/greeting/file/1002/Lumino.mp3"), "example.com", &bucket, &object);
ASSERT_STRING_EQUALS("quotes.s3.foo.bar", bucket); ASSERT_STRING_EQUALS("quotes.s3.foo.bar", bucket);
ASSERT_STRING_EQUALS("greeting/file/1002/Lumino.mp3", object); ASSERT_STRING_EQUALS("greeting/file/1002/Lumino.mp3", object);
} }
...@@ -122,7 +130,9 @@ static void test_parse_url(void) ...@@ -122,7 +130,9 @@ static void test_parse_url(void)
*/ */
static void test_authorization_header(void) static void test_authorization_header(void)
{ {
ASSERT_STRING_EQUALS("AWS AKIAIOSFODNN7EXAMPLE:YJkomOaqUJlvEluDq4fpusID38Y=", aws_s3_authentication_create("GET", "https://vault.s3.amazonaws.com/awesome.mp3", "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890")); ASSERT_STRING_EQUALS("AWS AKIAIOSFODNN7EXAMPLE:YJkomOaqUJlvEluDq4fpusID38Y=", aws_s3_authentication_create("GET", "https://vault.s3.amazonaws.com/awesome.mp3", NULL, "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890"));
ASSERT_STRING_EQUALS("AWS AKIAIOSFODNN7EXAMPLE:YJkomOaqUJlvEluDq4fpusID38Y=", aws_s3_authentication_create("GET", "https://vault.s3.amazonaws.com/awesome.mp3", "s3.amazonaws.com", "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890"));
ASSERT_STRING_EQUALS("AWS AKIAIOSFODNN7EXAMPLE:YJkomOaqUJlvEluDq4fpusID38Y=", aws_s3_authentication_create("GET", "https://vault.example.com/awesome.mp3", "example.com", "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890"));
} }
/** /**
...@@ -130,7 +140,9 @@ static void test_authorization_header(void) ...@@ -130,7 +140,9 @@ static void test_authorization_header(void)
*/ */
static void test_presigned_url(void) static void test_presigned_url(void)
{ {
ASSERT_STRING_EQUALS("https://vault.s3.amazonaws.com/awesome.mp3?Signature=YJkomOaqUJlvEluDq4fpusID38Y%3D&Expires=1234567890&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE", aws_s3_presigned_url_create("GET", "https://vault.s3.amazonaws.com/awesome.mp3", "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890")); ASSERT_STRING_EQUALS("https://vault.s3.amazonaws.com/awesome.mp3?Signature=YJkomOaqUJlvEluDq4fpusID38Y%3D&Expires=1234567890&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE", aws_s3_presigned_url_create("GET", "https://vault.s3.amazonaws.com/awesome.mp3", NULL, "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890"));
ASSERT_STRING_EQUALS("https://vault.s3.amazonaws.com/awesome.mp3?Signature=YJkomOaqUJlvEluDq4fpusID38Y%3D&Expires=1234567890&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE", aws_s3_presigned_url_create("GET", "https://vault.s3.amazonaws.com/awesome.mp3", "s3.amazonaws.com", "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890"));
ASSERT_STRING_EQUALS("https://vault.example.com/awesome.mp3?Signature=YJkomOaqUJlvEluDq4fpusID38Y%3D&Expires=1234567890&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE", aws_s3_presigned_url_create("GET", "https://vault.example.com/awesome.mp3", "example.com", "audio/mpeg", "", "AKIAIOSFODNN7EXAMPLE", "0123456789012345678901234567890123456789", "1234567890"));
} }
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论