summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/default/sqlite_cache.cpp60
-rw-r--r--src/mbgl/util/mapbox.cpp51
-rw-r--r--src/mbgl/util/mapbox.hpp6
-rw-r--r--test/miscellaneous/mapbox.cpp56
4 files changed, 120 insertions, 53 deletions
diff --git a/platform/default/sqlite_cache.cpp b/platform/default/sqlite_cache.cpp
index 8863c151e7..46df7ed2af 100644
--- a/platform/default/sqlite_cache.cpp
+++ b/platform/default/sqlite_cache.cpp
@@ -5,6 +5,7 @@
#include <mbgl/util/compression.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/thread.hpp>
+#include <mbgl/util/mapbox.hpp>
#include <mbgl/platform/log.hpp>
#include "sqlite3.hpp"
@@ -12,53 +13,6 @@
namespace mbgl {
-std::string removeAccessTokenFromURL(const std::string &url) {
- const size_t token_start = url.find("access_token=");
- // Ensure that token exists, isn't at the front and is preceded by either & or ?.
- if (token_start == std::string::npos || token_start == 0 || !(url[token_start - 1] == '&' || url[token_start - 1] == '?')) {
- return url;
- }
-
- const size_t token_end = url.find_first_of('&', token_start);
- if (token_end == std::string::npos) {
- // The token is the last query argument. We slice away the "&access_token=..." part
- return url.substr(0, token_start - 1);
- } else {
- // We slice away the "access_token=...&" part.
- return url.substr(0, token_start) + url.substr(token_end + 1);
- }
-}
-
-std::string convertMapboxDomainsToProtocol(const std::string &url) {
- const size_t protocol_separator = url.find("://");
- if (protocol_separator == std::string::npos) {
- return url;
- }
-
- const std::string protocol = url.substr(0, protocol_separator);
- if (!(protocol == "http" || protocol == "https")) {
- return url;
- }
-
- const size_t domain_begin = protocol_separator + 3;
- const size_t path_separator = url.find("/", domain_begin);
- if (path_separator == std::string::npos) {
- return url;
- }
-
- const std::string domain = url.substr(domain_begin, path_separator - domain_begin);
- if (domain.find(".tiles.mapbox.com") != std::string::npos) {
- return "mapbox://" + url.substr(path_separator + 1);
- } else {
- return url;
- }
-}
-
-std::string unifyMapboxURLs(const std::string &url) {
- return removeAccessTokenFromURL(convertMapboxDomainsToProtocol(url));
-}
-
-
using namespace mapbox::sqlite;
SQLiteCache::SQLiteCache(const std::string& path_)
@@ -154,8 +108,8 @@ void SQLiteCache::Impl::get(const Resource &resource, Callback callback) {
getStmt->reset();
}
- const std::string unifiedURL = unifyMapboxURLs(resource.url);
- getStmt->bind(1, unifiedURL.c_str());
+ const auto canonicalURL = util::mapbox::canonicalURL(resource.url);
+ getStmt->bind(1, canonicalURL.c_str());
if (getStmt->run()) {
// There is data.
auto response = std::make_unique<Response>();
@@ -208,8 +162,8 @@ void SQLiteCache::Impl::put(const Resource& resource, std::shared_ptr<const Resp
putStmt->reset();
}
- const std::string unifiedURL = unifyMapboxURLs(resource.url);
- putStmt->bind(1 /* url */, unifiedURL.c_str());
+ const auto canonicalURL = util::mapbox::canonicalURL(resource.url);
+ putStmt->bind(1 /* url */, canonicalURL.c_str());
putStmt->bind(2 /* status */, int(response->status));
putStmt->bind(3 /* kind */, int(resource.kind));
putStmt->bind(4 /* modified */, response->modified);
@@ -255,9 +209,9 @@ void SQLiteCache::Impl::refresh(const Resource& resource, int64_t expires) {
refreshStmt->reset();
}
- const std::string unifiedURL = unifyMapboxURLs(resource.url);
+ const auto canonicalURL = util::mapbox::canonicalURL(resource.url);
refreshStmt->bind(1, int64_t(expires));
- refreshStmt->bind(2, unifiedURL.c_str());
+ refreshStmt->bind(2, canonicalURL.c_str());
refreshStmt->run();
} catch (mapbox::sqlite::Exception& ex) {
Log::Error(Event::Database, ex.code, ex.what());
diff --git a/src/mbgl/util/mapbox.cpp b/src/mbgl/util/mapbox.cpp
index 70587ac5ad..9a97f281d9 100644
--- a/src/mbgl/util/mapbox.cpp
+++ b/src/mbgl/util/mapbox.cpp
@@ -118,6 +118,57 @@ std::string normalizeTileURL(const std::string& url, const std::string& sourceUR
return normalizedURL;
}
+
+std::string removeAccessTokenFromURL(const std::string &url) {
+ const size_t token_start = url.find("access_token=");
+ // Ensure that token exists, isn't at the front and is preceded by either & or ?.
+ if (token_start == std::string::npos || token_start == 0 || !(url[token_start - 1] == '&' || url[token_start - 1] == '?')) {
+ return url;
+ }
+
+ const size_t token_end = url.find_first_of('&', token_start);
+ if (token_end == std::string::npos) {
+ // The token is the last query argument. We slice away the "&access_token=..." part
+ return url.substr(0, token_start - 1);
+ } else {
+ // We slice away the "access_token=...&" part.
+ return url.substr(0, token_start) + url.substr(token_end + 1);
+ }
}
+
+namespace {
+
+std::string convertMapboxDomainsToProtocol(const std::string &url) {
+ const size_t protocol_separator = url.find("://");
+ if (protocol_separator == std::string::npos) {
+ return url;
+ }
+
+ const std::string protocol = url.substr(0, protocol_separator);
+ if (!(protocol == "http" || protocol == "https")) {
+ return url;
+ }
+
+ const size_t domain_begin = protocol_separator + 3;
+ const size_t path_separator = url.find("/", domain_begin);
+ if (path_separator == std::string::npos) {
+ return url;
+ }
+
+ const std::string domain = url.substr(domain_begin, path_separator - domain_begin);
+ if (domain == "api.mapbox.com" || domain.find(".tiles.mapbox.com") != std::string::npos) {
+ return std::string{ "mapbox://" } + url.substr(path_separator + 1);
+ } else {
+ return url;
+ }
}
+
+} // end namespace
+
+std::string canonicalURL(const std::string &url) {
+ return removeAccessTokenFromURL(convertMapboxDomainsToProtocol(url));
}
+
+} // end namespace mapbox
+} // end namespace util
+} // end namespace mbgl
diff --git a/src/mbgl/util/mapbox.hpp b/src/mbgl/util/mapbox.hpp
index 9c24dda0e6..57f87e7959 100644
--- a/src/mbgl/util/mapbox.hpp
+++ b/src/mbgl/util/mapbox.hpp
@@ -14,6 +14,12 @@ std::string normalizeSpriteURL(const std::string& url, const std::string& access
std::string normalizeGlyphsURL(const std::string& url, const std::string& accessToken);
std::string normalizeTileURL(const std::string& url, const std::string& sourceURL, SourceType sourceType);
+// Canonicalizes Mapbox URLs by removing [a-d] subdomain prefixes, access tokens, and protocol.
+// Note that this is close, but not exactly the reverse operation as above, as this retains certain
+// information, such as the API version. It is used to cache resources retrieved from the URL, that
+// sometimes have multiple valid URLs.
+std::string canonicalURL(const std::string &url);
+
}
}
}
diff --git a/test/miscellaneous/mapbox.cpp b/test/miscellaneous/mapbox.cpp
index a0f9208298..1ec48a4196 100644
--- a/test/miscellaneous/mapbox.cpp
+++ b/test/miscellaneous/mapbox.cpp
@@ -81,3 +81,59 @@ TEST(Mapbox, TileURL) {
throw e;
}
}
+
+TEST(Mapbox, CanonicalURL) {
+ using mbgl::util::mapbox::canonicalURL;
+ EXPECT_EQ(
+ canonicalURL("https://a.tiles.mapbox.com/v4/"
+ "mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/"
+ "10744.vector.pbf?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/10744.vector.pbf");
+
+ EXPECT_EQ(
+ canonicalURL("http://a.tiles.mapbox.com/v4/"
+ "mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/"
+ "10744.vector.pbf?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/10744.vector.pbf");
+
+ EXPECT_EQ(
+ canonicalURL("https://b.tiles.mapbox.com/v4/"
+ "mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/"
+ "10744.vector.pbf?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/10744.vector.pbf");
+
+ EXPECT_EQ(
+ canonicalURL("http://c.tiles.mapbox.com/v4/"
+ "mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/"
+ "10744.vector.pbf?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/10744.vector.pbf");
+
+ EXPECT_EQ(
+ canonicalURL("https://api.mapbox.com/v4/"
+ "mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/"
+ "10744.vector.pbf?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/10744.vector.pbf");
+
+ EXPECT_EQ(
+ canonicalURL("http://api.mapbox.com/v4/"
+ "mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/"
+ "10744.vector.pbf"),
+ "mapbox://v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v6/15/17599/10744.vector.pbf");
+
+ EXPECT_EQ(canonicalURL("https://api.mapbox.com/fonts/v1/mapbox/"
+ "DIN%20Offc%20Pro%20Italic%2cArial%20Unicode%20MS%20Regular/"
+ "0-255.pbf?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://fonts/v1/mapbox/DIN%20Offc%20Pro%20Italic%2cArial%20Unicode%20MS%20Regular/"
+ "0-255.pbf");
+
+ EXPECT_EQ(canonicalURL("https://api.mapbox.com/styles/v1/mapbox/streets-v8/"
+ "sprite.json?access_token=pk.kAeslEm93Sjf3mXk."
+ "vbiF02XnvkPkzlFhGSn2iIm6De3Cxsk5tmips2tvkG8sF"),
+ "mapbox://styles/v1/mapbox/streets-v8/sprite.json");
+}