diff options
author | Richard Walters <rwalters@digitalstirling.com> | 2019-03-28 00:00:15 -0700 |
---|---|---|
committer | Richard Walters <rwalters@digitalstirling.com> | 2019-03-28 00:00:15 -0700 |
commit | 7cc97d98213436350624bcf5c38203b3116ca651 (patch) | |
tree | 44b8b13d35e5ac712041c3952c1fb938925bbce3 | |
parent | 79d2e347dc32c4f491c4cd3476b4ffa1db3e4003 (diff) |
Percent-encode '+' in the query portion
-rw-r--r-- | src/Uri.cpp | 17 | ||||
-rw-r--r-- | test/src/UriTests.cpp | 13 |
2 files changed, 29 insertions, 1 deletions
diff --git a/src/Uri.cpp b/src/Uri.cpp index b6b82e1..fef7fb6 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -99,6 +99,21 @@ namespace { }; /** + * This is the character set almost corresponds to the "query" syntax + * specified in RFC 3986 (https://tools.ietf.org/html/rfc3986), + * leaving out "pct-encoded", except that '+' is also excluded, because + * for some web services (e.g. AWS S3) a '+' is treated as + * synonymous with a space (' ') and thus gets misinterpreted. + */ + const Uri::CharacterSet QUERY_NOT_PCT_ENCODED_WITHOUT_PLUS{ + UNRESERVED, + '!', '$', '&', '\'', '(', ')', + '*', ',', ';', '=', + ':', '@', + '/', '?' + }; + + /** * This is the character set corresponds to the "userinfo" syntax * specified in RFC 3986 (https://tools.ietf.org/html/rfc3986), * leaving out "pct-encoded". @@ -1450,7 +1465,7 @@ namespace Uri { ++i; } if (impl_->hasQuery) { - buffer << '?' << EncodeElement(impl_->query, QUERY_OR_FRAGMENT_NOT_PCT_ENCODED); + buffer << '?' << EncodeElement(impl_->query, QUERY_NOT_PCT_ENCODED_WITHOUT_PLUS); } if (impl_->hasFragment) { buffer << '#' << EncodeElement(impl_->fragment, QUERY_OR_FRAGMENT_NOT_PCT_ENCODED); diff --git a/test/src/UriTests.cpp b/test/src/UriTests.cpp index 637bfb7..e3737c2 100644 --- a/test/src/UriTests.cpp +++ b/test/src/UriTests.cpp @@ -906,3 +906,16 @@ TEST(UriTests, ClearQuery) { EXPECT_EQ("http://www.example.com/", uri.GenerateString()); EXPECT_FALSE(uri.HasQuery()); } + +TEST(UriTests, PercentEncodePlusInQueries) { + // Although RFC 3986 doesn't say anything about '+', some web services + // treat it the same as ' ' due to how HTML originally defined how + // to encode the query portion of a URL + // (see https://stackoverflow.com/questions/2678551/when-to-encode-space-to-plus-or-20). + // + // To avoid issues with these web services, make sure '+' is + // percent-encoded in a URI when the URI is encoded. + Uri::Uri uri; + uri.SetQuery("foo+bar"); + EXPECT_EQ("?foo%2Bbar", uri.GenerateString()); +} |