Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] add custom URL scheme support
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaefer committed Dec 20, 2016
1 parent 5a544b6 commit 30d0f67
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 19 deletions.
3 changes: 3 additions & 0 deletions include/mbgl/storage/default_file_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class DefaultFileSource : public FileSource {
void setAccessToken(const std::string&);
std::string getAccessToken() const;

void setURLSchemeTemplate(const std::string& scheme, const std::string& tpl);
std::string getURLSchemeTemplate(const std::string& scheme) const;

std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;

/*
Expand Down
6 changes: 6 additions & 0 deletions include/mbgl/storage/online_file_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/constants.hpp>

#include <map>

namespace mbgl {

class OnlineFileSource : public FileSource {
Expand All @@ -16,6 +18,9 @@ class OnlineFileSource : public FileSource {
void setAccessToken(const std::string& t) { accessToken = t; }
std::string getAccessToken() const { return accessToken; }

void setURLSchemeTemplate(const std::string& scheme, const std::string& tpl);
std::string getURLSchemeTemplate(const std::string& scheme) const;

std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;

private:
Expand All @@ -25,6 +30,7 @@ class OnlineFileSource : public FileSource {
const std::unique_ptr<Impl> impl;
std::string accessToken;
std::string apiBaseURL = mbgl::util::API_BASE_URL;
std::map<std::string, std::string> urlSchemeTemplates;
};

} // namespace mbgl
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,34 @@ public void run() {
}
}

/**
* <p>Sets a URL template for the given scheme.</p>
* <p>Any URLs encountered in styles and subsequently loaded sources will be fed through a URL
* replacement mechanism that e.g. transforms {@code mapbox://} URLs into regular
* {@code https://} URLs. You can provide URL replacement patterns for your own scheme, e.g.
* {@code example://}.</p>
* <p>Any query string will be preserved from the original URL and merged with a query string of
* the template URL, if any.</p>
*
* @param scheme scheme The scheme that this template should be used for. Specify the scheme
* without trailing {@code ://}, e.g. just {@code example}. You may use arbitrary alphanumeric
* schemes, with the exception of the protected scheme {@code mapbox}.
* @param tpl A templated URL. it may contain these brace-enclosed replacement tokens, e.g. for
* {@code &quot;http://example.com/foo/bar/baz.png&quot;}, valid tokens are:
* <ul>
* <li>{@code {scheme}}: {@code &quot;http&quot;}</li>
* <li>{@code {domain}}: {@code &quot;example.com&quot;}</li>
* <li>{@code {path}}: {@code &quot;foo/bar/baz.png&quot;} (without leading {@code /})</li>
* <li>{@code {directory}}: {@code &quot;foo/bar/&quot;} (with trailing {@code /})</li>
* <li>{@code {filename}}: {@code &quot;baz&quot;} (without file extension)</li>
* <li>{@code {extension}}: {@code &quot;.png&quot;} (optionally with a preceding {@code @2x}
* ratio specifier)</li>
* </ul>
*/
public void setURLSchemeTemplate(String scheme, String tpl) {
nativeMapView.setURLSchemeTemplate(scheme, tpl);
}

/**
* <p>
* Loads a new map style from the specified URL.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ public String getAccessToken() {
return nativeGetAccessToken(nativeMapViewPtr);
}

public void setURLSchemeTemplate(String scheme, String tpl) {
nativeSetURLTemplate(nativeMapViewPtr, scheme, tpl);
}

public String getURLSchemeTemplate(String scheme) {
return nativeGetURLTemplate(nativeMapViewPtr, scheme);
}

public void cancelTransitions() {
nativeCancelTransitions(nativeMapViewPtr);
}
Expand Down Expand Up @@ -667,6 +675,10 @@ private native void nativeSetClasses(long nativeMapViewPtr,

private native String nativeGetAccessToken(long nativeMapViewPtr);

private native void nativeSetURLTemplate(long nativeMapViewPtr, String scheme, String tpl);

private native String nativeGetURLTemplate(long nativeMapViewPtr, String scheme);

private native void nativeCancelTransitions(long nativeMapViewPtr);

private native void nativeSetGestureInProgress(long nativeMapViewPtr, boolean inProgress);
Expand Down
14 changes: 14 additions & 0 deletions platform/android/src/jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,18 @@ jni::jstring* nativeGetAccessToken(JNIEnv *env, jni::jobject* obj, jlong nativeM
return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken());
}

void nativeSetURLTemplate(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* scheme, jni::jstring* tpl) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getFileSource().setURLSchemeTemplate(std_string_from_jstring(env, scheme), std_string_from_jstring(env, tpl));
}

jni::jstring* nativeGetURLTemplate(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* scheme) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return std_string_to_jstring(env, nativeMapView->getFileSource().getURLSchemeTemplate(std_string_from_jstring(env, scheme)));
}

void nativeCancelTransitions(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
Expand Down Expand Up @@ -1827,6 +1839,8 @@ void registerNatives(JavaVM *vm) {
MAKE_NATIVE_METHOD(nativeGetStyleJson, "(J)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeSetAccessToken, "(JLjava/lang/String;)V"),
MAKE_NATIVE_METHOD(nativeGetAccessToken, "(J)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeSetURLTemplate, "(JLjava/lang/String;Ljava/lang/String;)V"),
MAKE_NATIVE_METHOD(nativeGetURLTemplate, "(JLjava/lang/String;)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeCancelTransitions, "(J)V"),
MAKE_NATIVE_METHOD(nativeSetGestureInProgress, "(JZ)V"),
MAKE_NATIVE_METHOD(nativeMoveBy, "(JDDJ)V"),
Expand Down
25 changes: 25 additions & 0 deletions platform/darwin/src/MGLOfflineStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,31 @@ typedef void (^MGLOfflinePackRemovalCompletionHandler)(NSError * _Nullable error
*/
@property (nonatomic, readonly) unsigned long long countOfBytesCompleted;

/**
Sets a URL template for the given scheme.
Any URLs encountered in styles and subsequently loaded sources will be fed through
a URL replacement mechanism that e.g. transforms `mapbox://` URLs into regular
`https://` URLs. You can provide URL replacement patterns for your own scheme,
e.g. `example://`.
Any query string will be preserved from the original URL and merged with a
query string of the template URL, if any.
@param tpl A templated URL. it may contain these brace-enclosed replacement
tokens, e.g. for `"http://example.com/foo/bar/baz.png"`, valid tokens are:
* `{scheme}`: `"http"`
* `{domain}`: `"example.com"`
* `{path}`: `"foo/bar/baz.png"` (without leading `/`)
* `{directory}`: `"foo/bar/"` (with trailing `/`)
* `{filename}`: `"baz"` (without file extension)
* `{extension}`: `".png"` (optionally with a preceding `@2x` ratio specifier)
@param scheme The scheme that this template should be used for. Specify the
scheme without trailing `://`, e.g. just `example`. You may use arbitrary
alphanumeric schemes, with the exception of the protected scheme `mapbox`.
*/
- (void)setURLSchemeTemplate:(nullable NSString *)tpl forScheme:(NSString *)scheme;

@end

NS_ASSUME_NONNULL_END
4 changes: 4 additions & 0 deletions platform/darwin/src/MGLOfflineStorage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ - (unsigned long long)countOfBytesCompleted {
return attributes.fileSize;
}

- (void)setURLSchemeTemplate:(nullable NSString *)tpl forScheme:(NSString *)scheme {
self.mbglFileSource->setURLSchemeTemplate(scheme.UTF8String, tpl.UTF8String);
}

#pragma mark MGLOfflinePackDelegate methods

- (void)offlinePack:(MGLOfflinePack *)pack progressDidChange:(__unused MGLOfflinePackProgress)progress {
Expand Down
16 changes: 16 additions & 0 deletions platform/default/default_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ class DefaultFileSource::Impl {
return onlineFileSource.getAccessToken();
}

void setURLSchemeTemplate(const std::string& scheme, const std::string& tpl) {
onlineFileSource.setURLSchemeTemplate(scheme, tpl);
}

std::string getURLSchemeTemplate(const std::string& scheme) const {
return onlineFileSource.getURLSchemeTemplate(scheme);
}

void listRegions(std::function<void (std::exception_ptr, optional<std::vector<OfflineRegion>>)> callback) {
try {
callback({}, offlineDatabase.listRegions());
Expand Down Expand Up @@ -187,6 +195,14 @@ std::string DefaultFileSource::getAccessToken() const {
return thread->invokeSync(&Impl::getAccessToken);
}

void DefaultFileSource::setURLSchemeTemplate(const std::string& scheme, const std::string& tpl) {
thread->invokeSync(&Impl::setURLSchemeTemplate, scheme, tpl);
}

std::string DefaultFileSource::getURLSchemeTemplate(const std::string& scheme) const {
return thread->invokeSync(&Impl::getURLSchemeTemplate, scheme);
}

std::unique_ptr<AsyncRequest> DefaultFileSource::request(const Resource& resource, Callback callback) {
class DefaultFileRequest : public AsyncRequest {
public:
Expand Down
69 changes: 50 additions & 19 deletions platform/default/online_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/timer.hpp>
#include <mbgl/util/url.hpp>
#include <mbgl/util/http_timeout.hpp>

#include <algorithm>
Expand Down Expand Up @@ -164,33 +165,63 @@ OnlineFileSource::OnlineFileSource()

OnlineFileSource::~OnlineFileSource() = default;

void OnlineFileSource::setURLSchemeTemplate(const std::string& scheme, const std::string& tpl) {
if (scheme == "mapbox") {
throw std::runtime_error("Cannot override mapbox:// URL scheme");
}
auto it = urlSchemeTemplates.find(scheme);
if (tpl.empty()) {
urlSchemeTemplates.erase(it);
} else {
if (it != urlSchemeTemplates.end()) {
it->second = tpl;
} else {
urlSchemeTemplates.emplace(scheme, tpl);
}
}
}

std::string OnlineFileSource::getURLSchemeTemplate(const std::string& scheme) const {
auto it = urlSchemeTemplates.find(scheme);
return it != urlSchemeTemplates.end() ? it->second : "";
}

std::unique_ptr<AsyncRequest> OnlineFileSource::request(const Resource& resource, Callback callback) {
Resource res = resource;

switch (resource.kind) {
case Resource::Kind::Unknown:
break;
const util::URL url(resource.url);

if (resource.url.compare(url.scheme.first, url.scheme.second, "mapbox") == 0) {
switch (resource.kind) {
case Resource::Kind::Style:
res.url = mbgl::util::mapbox::normalizeStyleURL(apiBaseURL, resource.url, accessToken);
break;

case Resource::Kind::Style:
res.url = mbgl::util::mapbox::normalizeStyleURL(apiBaseURL, resource.url, accessToken);
break;
case Resource::Kind::Source:
res.url = util::mapbox::normalizeSourceURL(apiBaseURL, resource.url, accessToken);
break;

case Resource::Kind::Source:
res.url = util::mapbox::normalizeSourceURL(apiBaseURL, resource.url, accessToken);
break;
case Resource::Kind::Glyphs:
res.url = util::mapbox::normalizeGlyphsURL(apiBaseURL, resource.url, accessToken);
break;

case Resource::Kind::Glyphs:
res.url = util::mapbox::normalizeGlyphsURL(apiBaseURL, resource.url, accessToken);
break;
case Resource::Kind::SpriteImage:
case Resource::Kind::SpriteJSON:
res.url = util::mapbox::normalizeSpriteURL(apiBaseURL, resource.url, accessToken);
break;

case Resource::Kind::SpriteImage:
case Resource::Kind::SpriteJSON:
res.url = util::mapbox::normalizeSpriteURL(apiBaseURL, resource.url, accessToken);
break;
case Resource::Kind::Tile:
res.url = util::mapbox::normalizeTileURL(apiBaseURL, resource.url, accessToken);
break;

case Resource::Kind::Tile:
res.url = util::mapbox::normalizeTileURL(apiBaseURL, resource.url, accessToken);
break;
default:
break;
}
} else {
auto it = urlSchemeTemplates.find(resource.url.substr(url.scheme.first, url.scheme.second));
if (it != urlSchemeTemplates.end() && !it->second.empty()) {
res.url = util::transformURL(it->second, res.url, url);
}
}

return std::make_unique<OnlineFileRequest>(std::move(res), std::move(callback), *impl);
Expand Down
1 change: 1 addition & 0 deletions src/mbgl/util/mapbox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <string>
#include <mbgl/style/types.hpp>
#include <mbgl/storage/resource.hpp>

namespace mbgl {
namespace util {
Expand Down

0 comments on commit 30d0f67

Please sign in to comment.