Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ios/IONAssetHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

@property (nonatomic, strong) NSString * basePath;
@property (nonatomic, strong) NSString * scheme;
@property (nonatomic) Boolean isRunning;

-(void)setAssetPath:(NSString *)assetPath;
- (instancetype)initWithBasePath:(NSString *)basePath andScheme:(NSString *)scheme;
Expand Down
113 changes: 87 additions & 26 deletions src/ios/IONAssetHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,72 @@ - (instancetype)initWithBasePath:(NSString *)basePath andScheme:(NSString *)sche

- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask
{
self.isRunning = true;
Boolean loadFile = true;
NSString * startPath = @"";
NSURL * url = urlSchemeTask.request.URL;
NSString * stringToLoad = url.path;
NSDictionary * header = urlSchemeTask.request.allHTTPHeaderFields;
NSMutableString * stringToLoad = [NSMutableString string];
[stringToLoad appendString:url.path];
NSString * scheme = url.scheme;
NSString * method = urlSchemeTask.request.HTTPMethod;
NSData * body = urlSchemeTask.request.HTTPBody;
NSData * data;
NSInteger statusCode;

if ([scheme isEqualToString:self.scheme]) {
if ([stringToLoad hasPrefix:@"/_app_file_"]) {
startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_app_file_" withString:@""];
} else if ([stringToLoad hasPrefix:@"/_http_proxy_"]||[stringToLoad hasPrefix:@"/_https_proxy_"]) {
if(url.query) {
[stringToLoad appendString:@"?"];
[stringToLoad appendString:url.query];
}
loadFile = false;
startPath = [stringToLoad stringByReplacingOccurrencesOfString:@"/_http_proxy_" withString:@"http://"];
startPath = [startPath stringByReplacingOccurrencesOfString:@"/_https_proxy_" withString:@"https://"];
NSURL * requestUrl = [NSURL URLWithString:startPath];
WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:method];
[request setURL:requestUrl];
if (body) {
[request setHTTPBody:body];
}
[request setAllHTTPHeaderFields:header];
[request setHTTPShouldHandleCookies:YES];

[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error) {
NSLog(@"Proxy error: %@", error);
}

// set cookies to WKWebView
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if(httpResponse) {
NSArray* cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[httpResponse allHeaderFields] forURL:response.URL];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:httpResponse.URL mainDocumentURL:nil];
cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

for (NSHTTPCookie* c in cookies)
{
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//running in background thread is necessary because setCookie otherwise fails
dispatch_async(dispatch_get_main_queue(), ^(void){
[cookieStore setCookie:c completionHandler:nil];
});
});
};
}

// Do not use urlSchemeTask if it has been closed in stopURLSchemeTask
if(self.isRunning) {
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
}
}] resume];
} else {
startPath = self.basePath;
if ([stringToLoad isEqualToString:@""] || [url.pathExtension isEqualToString:@""]) {
Expand All @@ -36,36 +94,39 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)ur
}
}
}
NSError * fileError = nil;
NSData * data = nil;
if ([self isMediaExtension:url.pathExtension]) {
data = [NSData dataWithContentsOfFile:startPath options:NSDataReadingMappedIfSafe error:&fileError];
}
if (!data || fileError) {
data = [[NSData alloc] initWithContentsOfFile:startPath];
}
NSInteger statusCode = 200;
if (!data) {
statusCode = 404;
}
NSURL * localUrl = [NSURL URLWithString:url.absoluteString];
NSString * mimeType = [self getMimeType:url.pathExtension];
id response = nil;
if (data && [self isMediaExtension:url.pathExtension]) {
response = [[NSURLResponse alloc] initWithURL:localUrl MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil];
} else {
NSDictionary * headers = @{ @"Content-Type" : mimeType, @"Cache-Control": @"no-cache"};
response = [[NSHTTPURLResponse alloc] initWithURL:localUrl statusCode:statusCode HTTPVersion:nil headerFields:headers];
}

[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];

if(loadFile) {
NSError * fileError = nil;
data = nil;
if ([self isMediaExtension:url.pathExtension]) {
data = [NSData dataWithContentsOfFile:startPath options:NSDataReadingMappedIfSafe error:&fileError];
}
if (!data || fileError) {
data = [[NSData alloc] initWithContentsOfFile:startPath];
}
statusCode = 200;
if (!data) {
statusCode = 404;
}
NSURL * localUrl = [NSURL URLWithString:url.absoluteString];
NSString * mimeType = [self getMimeType:url.pathExtension];
id response = nil;
if (data && [self isMediaExtension:url.pathExtension]) {
response = [[NSURLResponse alloc] initWithURL:localUrl MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil];
} else {
NSDictionary * headers = @{ @"Content-Type" : mimeType, @"Cache-Control": @"no-cache"};
response = [[NSHTTPURLResponse alloc] initWithURL:localUrl statusCode:statusCode HTTPVersion:nil headerFields:headers];
}

[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
}
}

- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask
{
self.isRunning = false;
NSLog(@"stop");
}

Expand Down
8 changes: 8 additions & 0 deletions src/www/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ var exec = require('cordova/exec');

var WebView = {
convertFileSrc: function(url) {
const convertHttp = !location.protocol.startsWith("http") && !location.protocol.startsWith("https")

if (!url) {
return url;
}
Expand All @@ -11,6 +13,12 @@ var WebView = {
if (url.startsWith('file://')) {
return window.WEBVIEW_SERVER_URL + url.replace('file://', '/_app_file_');
}
if (url.startsWith('http://') && convertHttp) {
return window.WEBVIEW_SERVER_URL + url.replace('http://', '/_http_proxy_');
}
if (url.startsWith('https://') && convertHttp) {
return window.WEBVIEW_SERVER_URL + url.replace('https://', '/_https_proxy_');
}
if (url.startsWith('content://')) {
return window.WEBVIEW_SERVER_URL + url.replace('content:/', '/_app_content_');
}
Expand Down