From e2d07ef026851689af0fe361d226e2657a2fff94 Mon Sep 17 00:00:00 2001 From: Niklas Merz Date: Mon, 5 Oct 2020 18:57:13 +0200 Subject: [PATCH 1/6] Add proxy dummy --- .../Classes/Public/CDVURLSchemeHandler.m | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m index 6c88ceb69..982437024 100644 --- a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m +++ b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m @@ -43,6 +43,58 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id )ur if ([scheme isEqualToString:self.viewController.appScheme]) { 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 && self.isRunning) { + NSLog(@"Proxy error: %@", error); + [urlSchemeTask didFailWithError:error]; + return; + } + + // 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 { if ([stringToLoad isEqualToString:@""] || [url.pathExtension isEqualToString:@""]) { startPath = [startPath stringByAppendingPathComponent:self.viewController.startPage]; From 214df59aae2c2961cab2c957dd6f76cd898bf802 Mon Sep 17 00:00:00 2001 From: Niklas Merz Date: Mon, 5 Oct 2020 19:16:58 +0200 Subject: [PATCH 2/6] first working version --- .../Classes/Public/CDVURLSchemeHandler.h | 1 + .../Classes/Public/CDVURLSchemeHandler.m | 58 +++++++++++-------- cordova-js-src/plugin/ios/wkwebkit.js | 6 ++ 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/CordovaLib/Classes/Public/CDVURLSchemeHandler.h b/CordovaLib/Classes/Public/CDVURLSchemeHandler.h index 1cd84d09d..304cc6498 100644 --- a/CordovaLib/Classes/Public/CDVURLSchemeHandler.h +++ b/CordovaLib/Classes/Public/CDVURLSchemeHandler.h @@ -25,6 +25,7 @@ @interface CDVURLSchemeHandler : NSObject @property (nonatomic, strong) CDVViewController* viewController; +@property (nonatomic) Boolean isRunning; - (instancetype)initWithVC:(CDVViewController *)controller; diff --git a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m index 982437024..cbefb8a04 100644 --- a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m +++ b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m @@ -37,8 +37,14 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id )ur { NSString * startPath = [[NSBundle mainBundle] pathForResource:self.viewController.wwwFolderName ofType: nil]; NSURL * url = urlSchemeTask.request.URL; - NSString * stringToLoad = url.path; NSString * scheme = url.scheme; + self.isRunning = true; + Boolean loadFile = true; + NSDictionary * header = urlSchemeTask.request.allHTTPHeaderFields; + NSMutableString * stringToLoad = [NSMutableString string]; + [stringToLoad appendString:url.path]; + NSString * method = urlSchemeTask.request.HTTPMethod; + NSData * body = urlSchemeTask.request.HTTPBody; if ([scheme isEqualToString:self.viewController.appScheme]) { if ([stringToLoad hasPrefix:@"/_app_file_"]) { @@ -104,31 +110,33 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id )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]; - } + if(loadFile) { + 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]; + [urlSchemeTask didReceiveResponse:response]; + [urlSchemeTask didReceiveData:data]; + [urlSchemeTask didFinish]; + } } diff --git a/cordova-js-src/plugin/ios/wkwebkit.js b/cordova-js-src/plugin/ios/wkwebkit.js index 35c819cf1..7a34d293c 100644 --- a/cordova-js-src/plugin/ios/wkwebkit.js +++ b/cordova-js-src/plugin/ios/wkwebkit.js @@ -35,6 +35,12 @@ var WkWebKit = { if (path.startsWith('file://')) { return window.CDV_ASSETS_URL + path.replace('file://', '/_app_file_'); } + if (path.startsWith('http://')) { + return window.CDV_ASSETS_URL + '/_http_proxy_' + encodeURIComponent(path.replace('http://', '')); + } + if (path.startsWith('https://')) { + return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); + } return path; } }; From 0f2e22ce8803c4db2bb11dde9b89f4b6ee75c9a5 Mon Sep 17 00:00:00 2001 From: Niklas Merz Date: Mon, 5 Oct 2020 19:23:39 +0200 Subject: [PATCH 3/6] JS --- CordovaLib/cordova.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CordovaLib/cordova.js b/CordovaLib/cordova.js index 51c783d0a..0742366f0 100644 --- a/CordovaLib/cordova.js +++ b/CordovaLib/cordova.js @@ -1798,6 +1798,12 @@ var WkWebKit = { if (path.startsWith('file://')) { return window.CDV_ASSETS_URL + path.replace('file://', '/_app_file_'); } + if (path.startsWith('http://')) { + return window.CDV_ASSETS_URL + '/_http_proxy_' + encodeURIComponent(path.replace('http://', '')); + } + if (path.startsWith('https://')) { + return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); + } return path; } }; From 70efc66d047c872c9d2d4a24bc4ab24c188ecce2 Mon Sep 17 00:00:00 2001 From: Niklas Merz Date: Wed, 7 Oct 2020 16:20:35 +0200 Subject: [PATCH 4/6] Move proxy to own function --- CordovaLib/cordova.js | 12 ++++++++++++ cordova-js-src/plugin/ios/wkwebkit.js | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/CordovaLib/cordova.js b/CordovaLib/cordova.js index 0742366f0..02b29fc26 100644 --- a/CordovaLib/cordova.js +++ b/CordovaLib/cordova.js @@ -1805,6 +1805,18 @@ var WkWebKit = { return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); } return path; + }, + convertProxyUrl: function (path) { + if (!path || !window.CDV_ASSETS_URL) { + return path; + } + if (path.startsWith('http://')) { + return window.CDV_ASSETS_URL + '/_http_proxy_' + encodeURIComponent(path.replace('http://', '')); + } + if (path.startsWith('https://')) { + return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); + } + return path; } }; diff --git a/cordova-js-src/plugin/ios/wkwebkit.js b/cordova-js-src/plugin/ios/wkwebkit.js index 7a34d293c..3b8f1c556 100644 --- a/cordova-js-src/plugin/ios/wkwebkit.js +++ b/cordova-js-src/plugin/ios/wkwebkit.js @@ -42,6 +42,18 @@ var WkWebKit = { return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); } return path; + }, + convertProxyUrl: function (path) { + if (!path || !window.CDV_ASSETS_URL) { + return path; + } + if (path.startsWith('http://')) { + return window.CDV_ASSETS_URL + '/_http_proxy_' + encodeURIComponent(path.replace('http://', '')); + } + if (path.startsWith('https://')) { + return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); + } + return path; } }; From 92b8352bec42fa4e68fae04b256885d7647a3732 Mon Sep 17 00:00:00 2001 From: Niklas Merz Date: Wed, 7 Oct 2020 16:23:48 +0200 Subject: [PATCH 5/6] Implement stopped schemetask --- CordovaLib/Classes/Public/CDVURLSchemeHandler.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m index cbefb8a04..0fb1c9153 100644 --- a/CordovaLib/Classes/Public/CDVURLSchemeHandler.m +++ b/CordovaLib/Classes/Public/CDVURLSchemeHandler.m @@ -94,7 +94,7 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id )ur }; } - // Do not use urlSchemeTask if it has been closed in stopURLSchemeTask + // Do not use urlSchemeTask if it has been closed in stopURLSchemeTask. Otherwise the app will crash. if(self.isRunning) { [urlSchemeTask didReceiveResponse:response]; [urlSchemeTask didReceiveData:data]; @@ -142,7 +142,7 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id )ur - (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id)urlSchemeTask { - + self.isRunning = false; } -(NSString *) getMimeType:(NSString *)fileExtension { From 829cc31defc223e7bf4cbfbada303afd8178f11b Mon Sep 17 00:00:00 2001 From: Niklas Merz Date: Wed, 7 Oct 2020 16:31:21 +0200 Subject: [PATCH 6/6] Fix JS copy error --- CordovaLib/cordova.js | 6 ------ cordova-js-src/plugin/ios/wkwebkit.js | 7 ------- 2 files changed, 13 deletions(-) diff --git a/CordovaLib/cordova.js b/CordovaLib/cordova.js index 02b29fc26..8054199f8 100644 --- a/CordovaLib/cordova.js +++ b/CordovaLib/cordova.js @@ -1798,12 +1798,6 @@ var WkWebKit = { if (path.startsWith('file://')) { return window.CDV_ASSETS_URL + path.replace('file://', '/_app_file_'); } - if (path.startsWith('http://')) { - return window.CDV_ASSETS_URL + '/_http_proxy_' + encodeURIComponent(path.replace('http://', '')); - } - if (path.startsWith('https://')) { - return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); - } return path; }, convertProxyUrl: function (path) { diff --git a/cordova-js-src/plugin/ios/wkwebkit.js b/cordova-js-src/plugin/ios/wkwebkit.js index 3b8f1c556..2e1b265ab 100644 --- a/cordova-js-src/plugin/ios/wkwebkit.js +++ b/cordova-js-src/plugin/ios/wkwebkit.js @@ -35,13 +35,6 @@ var WkWebKit = { if (path.startsWith('file://')) { return window.CDV_ASSETS_URL + path.replace('file://', '/_app_file_'); } - if (path.startsWith('http://')) { - return window.CDV_ASSETS_URL + '/_http_proxy_' + encodeURIComponent(path.replace('http://', '')); - } - if (path.startsWith('https://')) { - return window.CDV_ASSETS_URL + '/_https_proxy_' + encodeURIComponent(path.replace('https://', '')); - } - return path; }, convertProxyUrl: function (path) { if (!path || !window.CDV_ASSETS_URL) {