[core] add ability to transform URLs before they're requested from the Internet
This commit is contained in:
@@ -36,6 +36,8 @@ public:
|
||||
void setAccessToken(const std::string&);
|
||||
std::string getAccessToken() const;
|
||||
|
||||
void setResourceTransform(std::function<std::string(Resource::Kind, std::string&&)>);
|
||||
|
||||
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,6 +16,10 @@ public:
|
||||
void setAccessToken(const std::string& t) { accessToken = t; }
|
||||
std::string getAccessToken() const { return accessToken; }
|
||||
|
||||
using ResourceTransform =
|
||||
std::function<std::unique_ptr<AsyncRequest>(Resource::Kind, std::string&&, std::function<void(std::string&&)>)>;
|
||||
void setResourceTransform(ResourceTransform&& cb);
|
||||
|
||||
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -46,6 +46,10 @@ public:
|
||||
return onlineFileSource.getAccessToken();
|
||||
}
|
||||
|
||||
void setResourceTransform(OnlineFileSource::ResourceTransform&& transform) {
|
||||
onlineFileSource.setResourceTransform(std::move(transform));
|
||||
}
|
||||
|
||||
void listRegions(std::function<void (std::exception_ptr, optional<std::vector<OfflineRegion>>)> callback) {
|
||||
try {
|
||||
callback({}, offlineDatabase.listRegions());
|
||||
@@ -187,6 +191,15 @@ std::string DefaultFileSource::getAccessToken() const {
|
||||
return thread->invokeSync(&Impl::getAccessToken);
|
||||
}
|
||||
|
||||
void DefaultFileSource::setResourceTransform(std::function<std::string(Resource::Kind, std::string&&)> transform) {
|
||||
auto loop = util::RunLoop::Get();
|
||||
thread->invoke(&Impl::setResourceTransform, [loop, transform](Resource::Kind kind_, std::string&& url_, auto callback_) {
|
||||
return loop->invokeWithCallback([transform](Resource::Kind kind, std::string&& url, auto callback) {
|
||||
callback(transform(kind, std::move(url)));
|
||||
}, kind_, std::move(url_), callback_);
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_ptr<AsyncRequest> DefaultFileSource::request(const Resource& resource, Callback callback) {
|
||||
class DefaultFileRequest : public AsyncRequest {
|
||||
public:
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
~OnlineFileRequest() override;
|
||||
|
||||
void networkIsReachableAgain();
|
||||
void schedule();
|
||||
void schedule(optional<Timestamp> expires);
|
||||
void completed(Response);
|
||||
|
||||
@@ -64,6 +65,19 @@ public:
|
||||
|
||||
void add(OnlineFileRequest* request) {
|
||||
allRequests.insert(request);
|
||||
if (resourceTransform) {
|
||||
// When there's a Resource transform callback set, replace the resource with the
|
||||
// transformed one before proceeding to schedule the request.
|
||||
request->request =
|
||||
resourceTransform(request->resource.kind, std::move(request->resource.url),
|
||||
[request](std::string&& url) {
|
||||
request->request.release();
|
||||
request->resource.url = std::move(url);
|
||||
request->schedule();
|
||||
});
|
||||
} else {
|
||||
request->schedule();
|
||||
}
|
||||
}
|
||||
|
||||
void remove(OnlineFileRequest* request) {
|
||||
@@ -131,6 +145,10 @@ public:
|
||||
return activeRequests.find(request) != activeRequests.end();
|
||||
}
|
||||
|
||||
void setResourceTransform(ResourceTransform&& transform) {
|
||||
resourceTransform = std::move(transform);
|
||||
}
|
||||
|
||||
private:
|
||||
void networkIsReachableAgain() {
|
||||
for (auto& request : allRequests) {
|
||||
@@ -138,6 +156,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
ResourceTransform resourceTransform;
|
||||
|
||||
/**
|
||||
* The lifetime of a request is:
|
||||
*
|
||||
@@ -196,12 +216,18 @@ std::unique_ptr<AsyncRequest> OnlineFileSource::request(const Resource& resource
|
||||
return std::make_unique<OnlineFileRequest>(std::move(res), std::move(callback), *impl);
|
||||
}
|
||||
|
||||
void OnlineFileSource::setResourceTransform(ResourceTransform&& transform) {
|
||||
impl->setResourceTransform(std::move(transform));
|
||||
}
|
||||
|
||||
OnlineFileRequest::OnlineFileRequest(Resource resource_, Callback callback_, OnlineFileSource::Impl& impl_)
|
||||
: impl(impl_),
|
||||
resource(std::move(resource_)),
|
||||
callback(std::move(callback_)) {
|
||||
impl.add(this);
|
||||
}
|
||||
|
||||
void OnlineFileRequest::schedule() {
|
||||
// Force an immediate first request if we don't have an expiration time.
|
||||
if (resource.priorExpires) {
|
||||
schedule(resource.priorExpires);
|
||||
|
||||
Reference in New Issue
Block a user