From 9134ddd02c5ce2e92aec7ddc5c97debb10fa5c44 Mon Sep 17 00:00:00 2001 From: jakepruitt Date: Fri, 26 Aug 2016 14:31:21 -0700 Subject: [PATCH] Keep query strings in source URLs Carries over any query strings from mapbox://-prefixed styles urls, source urls and tile urls to the api.mapbox.com requests. --- src/mbgl/util/mapbox.cpp | 30 ++++++++++++++++++++++++------ test/util/mapbox.cpp | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/mbgl/util/mapbox.cpp b/src/mbgl/util/mapbox.cpp index 70f2ba92307..059b7ea3be1 100644 --- a/src/mbgl/util/mapbox.cpp +++ b/src/mbgl/util/mapbox.cpp @@ -11,14 +11,15 @@ namespace util { namespace mapbox { const std::string protocol = "mapbox://"; - +const std::size_t protocolLength = protocol.length(); + bool isMapboxURL(const std::string& url) { return std::equal(protocol.begin(), protocol.end(), url.begin()); } -std::vector getMapboxURLPathname(const std::string& url) { +static std::vector getMapboxURLPathname(const std::string& url) { std::vector pathname; - auto startIndex = protocol.length(); + auto startIndex = protocolLength; auto end = url.find_first_of("?#"); if (end == std::string::npos) { end = url.length(); @@ -34,6 +35,20 @@ std::vector getMapboxURLPathname(const std::string& url) { return pathname; } +static std::pair normalizeQuery(const std::string& url) { + std::string query; + + auto queryIdx = url.find("?"); + if (queryIdx != std::string::npos) { + query = url.substr(queryIdx + 1, url.length() - queryIdx + 1); + if (!query.empty()) { + query = "&" + query; + } + } + + return std::make_pair(query, queryIdx); +} + std::string normalizeSourceURL(const std::string& baseURL, const std::string& url, const std::string& accessToken) { if (!isMapboxURL(url)) { return url; @@ -42,7 +57,9 @@ std::string normalizeSourceURL(const std::string& baseURL, const std::string& ur if (accessToken.empty()) { throw std::runtime_error("You must provide a Mapbox API access token for Mapbox tile sources"); } - return baseURL + "/v4/" + url.substr(protocol.length()) + ".json?access_token=" + accessToken + "&secure"; + + auto query = normalizeQuery(url); + return baseURL + "/v4/" + url.substr(protocolLength, query.second - protocolLength) + ".json?access_token=" + accessToken + "&secure" + query.first; } std::string normalizeStyleURL(const std::string& baseURL, const std::string& url, const std::string& accessToken) { @@ -59,7 +76,7 @@ std::string normalizeStyleURL(const std::string& baseURL, const std::string& url const auto& user = pathname[1]; const auto& id = pathname[2]; const bool isDraft = pathname.size() > 3; - return baseURL + "/styles/v1/" + user + "/" + id + (isDraft ? "/draft" : "") + "?access_token=" + accessToken; + return baseURL + "/styles/v1/" + user + "/" + id + (isDraft ? "/draft" : "") + "?access_token=" + accessToken + normalizeQuery(url).first; } std::string normalizeSpriteURL(const std::string& baseURL, const std::string& url, const std::string& accessToken) { @@ -119,7 +136,8 @@ std::string normalizeTileURL(const std::string& baseURL, const std::string& url, return url; } - return baseURL + "/v4/" + url.substr(sizeof("mapbox://tiles/") - 1) + "?access_token=" + accessToken; + auto query = normalizeQuery(url); + return baseURL + "/v4/" + url.substr(sizeof("mapbox://tiles/") - 1, query.second - sizeof("mapbox://tiles/") + 1) + "?access_token=" + accessToken + normalizeQuery(url).first; } std::string canonicalizeTileURL(const std::string& url, SourceType type, uint16_t tileSize) { diff --git a/test/util/mapbox.cpp b/test/util/mapbox.cpp index f3fb42c59dd..b559c3a9476 100644 --- a/test/util/mapbox.cpp +++ b/test/util/mapbox.cpp @@ -15,6 +15,12 @@ TEST(Mapbox, SourceURL) { EXPECT_EQ( "https://api.example.com/v4/user.map.json?access_token=key&secure", mbgl::util::mapbox::normalizeSourceURL("https://api.example.com", "mapbox://user.map", "key")); + EXPECT_EQ( + "https://api.mapbox.com/v4/user.map.json?access_token=key&secure&style=mapbox://styles/mapbox/streets-v9@0", + mbgl::util::mapbox::normalizeSourceURL(util::API_BASE_URL, "mapbox://user.map?style=mapbox://styles/mapbox/streets-v9@0", "key")); + EXPECT_EQ( + "https://api.mapbox.com/v4/user.map.json?access_token=key&secure", + mbgl::util::mapbox::normalizeSourceURL(util::API_BASE_URL, "mapbox://user.map?", "key")); EXPECT_EQ( "http://path", mbgl::util::mapbox::normalizeSourceURL(util::API_BASE_URL, "http://path", "key")); @@ -54,6 +60,12 @@ TEST(Mapbox, StyleURL) { EXPECT_EQ( "https://api.mapbox.com/styles/v1/user/style/draft?access_token=key", mbgl::util::mapbox::normalizeStyleURL(util::API_BASE_URL, "mapbox://styles/user/style/draft", "key")); + EXPECT_EQ( + "https://api.mapbox.com/styles/v1/user/style?access_token=key&shave=true", + mbgl::util::mapbox::normalizeStyleURL(util::API_BASE_URL, "mapbox://styles/user/style?shave=true", "key")); + EXPECT_EQ( + "https://api.mapbox.com/styles/v1/user/style?access_token=key", + mbgl::util::mapbox::normalizeStyleURL(util::API_BASE_URL, "mapbox://styles/user/style?", "key")); EXPECT_EQ( "http://path", mbgl::util::mapbox::normalizeStyleURL(util::API_BASE_URL, "http://path", "key")); @@ -90,6 +102,12 @@ TEST(Mapbox, TileURL) { EXPECT_EQ( "https://api.mapbox.com/v4/a.b/0/0/0.pbf?access_token=key", mbgl::util::mapbox::normalizeTileURL(util::API_BASE_URL, "mapbox://tiles/a.b/0/0/0.pbf", "key")); + EXPECT_EQ( + "https://api.mapbox.com/v4/a.b/0/0/0.pbf?access_token=key&style=mapbox://styles/mapbox/streets-v9@0", + mbgl::util::mapbox::normalizeTileURL(util::API_BASE_URL, "mapbox://tiles/a.b/0/0/0.pbf?style=mapbox://styles/mapbox/streets-v9@0", "key")); + EXPECT_EQ( + "https://api.mapbox.com/v4/a.b/0/0/0.pbf?access_token=key", + mbgl::util::mapbox::normalizeTileURL(util::API_BASE_URL, "mapbox://tiles/a.b/0/0/0.pbf?", "key")); EXPECT_EQ( "https://api.mapbox.com/v4/a.b/0/0/0.png?access_token=key", mbgl::util::mapbox::normalizeTileURL(util::API_BASE_URL, "mapbox://tiles/a.b/0/0/0.png", "key"));