From f0ec893f43ac769d8b11e52ac73af34bfe46abe4 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 12 Aug 2014 16:07:56 -0400 Subject: [PATCH] mod_http_cache: fixed S3 URL parser to allow mybucketsubdomain.com.s3.amazonaws.com --- src/mod/applications/mod_http_cache/aws.c | 50 ++++++++++++++++--- .../mod_http_cache/test_aws/main.c | 4 ++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_http_cache/aws.c b/src/mod/applications/mod_http_cache/aws.c index 4d446d5857..58c4b4d917 100644 --- a/src/mod/applications/mod_http_cache/aws.c +++ b/src/mod/applications/mod_http_cache/aws.c @@ -105,6 +105,39 @@ char *aws_s3_signature(char *signature, int signature_length, const char *string return signature; } +/** + * Reverse string substring search + */ +static char *my_strrstr(const char *haystack, const char *needle) +{ + char *s; + size_t needle_len; + size_t haystack_len; + + if (zstr(haystack)) { + return NULL; + } + + if (zstr(needle)) { + return (char *)haystack; + } + + needle_len = strlen(needle); + haystack_len = strlen(haystack); + if (needle_len > haystack_len) { + return NULL; + } + + s = (char *)(haystack + haystack_len - needle_len); + do { + if (!strncmp(s, needle, needle_len)) { + return s; + } + } while (s-- != haystack); + + return NULL; +} + /** * Parse bucket and object from URL * @param url to parse. This value is modified. @@ -113,7 +146,7 @@ char *aws_s3_signature(char *signature, int signature_length, const char *string */ void aws_s3_parse_url(char *url, char **bucket, char **object) { - char *bucket_start; + char *bucket_start = NULL; char *bucket_end; char *object_start; @@ -124,15 +157,18 @@ void aws_s3_parse_url(char *url, char **bucket, char **object) return; } - /* expect: http(s)://bucket.s3.amazonaws.com/object */ - bucket_start = strstr(url, "://"); - if (!bucket_start) { + /* expect: http(s)://bucket.foo-bar.s3.amazonaws.com/object */ + if (!strncasecmp(url, "https://", 8)) { + bucket_start = url + 8; + } else if (!strncasecmp(url, "http://", 7)) { + bucket_start = url + 7; + } + if (zstr(bucket_start)) { /* invalid URL */ return; } - bucket_start += 3; - - bucket_end = strchr(bucket_start, '.'); + + bucket_end = my_strrstr(bucket_start, ".s3"); if (!bucket_end) { /* invalid URL */ return; diff --git a/src/mod/applications/mod_http_cache/test_aws/main.c b/src/mod/applications/mod_http_cache/test_aws/main.c index c29f1364ec..f661c5954f 100644 --- a/src/mod/applications/mod_http_cache/test_aws/main.c +++ b/src/mod/applications/mod_http_cache/test_aws/main.c @@ -111,6 +111,10 @@ static void test_parse_url(void) aws_s3_parse_url(strdup("https://my-bucket-with-dash.s3-us-west-2.amazonaws.com/greeting/file/1002/Lumino.mp3"), &bucket, &object); ASSERT_STRING_EQUALS("my-bucket-with-dash", bucket); 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); + ASSERT_STRING_EQUALS("quotes.s3.foo.bar", bucket); + ASSERT_STRING_EQUALS("greeting/file/1002/Lumino.mp3", object); } /**