From 514409aeb93ad65be105bbe2da8d2cd86ff159b0 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Fri, 23 Feb 2024 10:05:36 +0100 Subject: [PATCH] fix(http): handle proxy urls with port (#7273) --- android/capacitor/src/main/assets/native-bridge.js | 7 ++++--- .../java/com/getcapacitor/WebViewLocalServer.java | 2 ++ core/native-bridge.ts | 4 ++-- ios/Capacitor/Capacitor/WebViewAssetHandler.swift | 3 +-- ios/Capacitor/Capacitor/assets/native-bridge.js | 11 +++++------ 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/android/capacitor/src/main/assets/native-bridge.js b/android/capacitor/src/main/assets/native-bridge.js index c796e3964..6a9227f03 100644 --- a/android/capacitor/src/main/assets/native-bridge.js +++ b/android/capacitor/src/main/assets/native-bridge.js @@ -144,10 +144,10 @@ var nativeBridge = (function (exports) { return url; let proxyUrl = new URL(url); const isHttps = proxyUrl.protocol === 'https:'; - const originalHostname = proxyUrl.hostname; + const originalHost = encodeURIComponent(proxyUrl.host); const originalPathname = proxyUrl.pathname; proxyUrl = new URL((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getServerUrl()) !== null && _b !== void 0 ? _b : ''); - proxyUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${originalHostname}${originalPathname}`; + proxyUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${originalHost}${originalPathname}`; return proxyUrl.toString(); }; const initBridge = (w) => { @@ -678,7 +678,8 @@ var nativeBridge = (function (exports) { else { this.response = nativeResponse.data; } - this.responseText = ((_a = (nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type'])) === null || _a === void 0 ? void 0 : _a.startsWith('application/json')) + this.responseText = ((_a = (nativeResponse.headers['Content-Type'] || + nativeResponse.headers['content-type'])) === null || _a === void 0 ? void 0 : _a.startsWith('application/json')) ? JSON.stringify(nativeResponse.data) : nativeResponse.data; this.responseURL = nativeResponse.url; diff --git a/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java b/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java index 9e893a0fa..b6a77c49f 100755 --- a/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java +++ b/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java @@ -30,6 +30,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; @@ -266,6 +267,7 @@ private WebResourceResponse handleCapacitorHttpRequest(WebResourceRequest reques .replace(bridge.getLocalUrl(), isHttps ? "https:/" : "http:/") .replace(Bridge.CAPACITOR_HTTP_INTERCEPTOR_START, "") .replace(Bridge.CAPACITOR_HTTPS_INTERCEPTOR_START, ""); + urlString = URLDecoder.decode(urlString, "UTF-8"); URL url = new URL(urlString); JSObject headers = new JSObject(); diff --git a/core/native-bridge.ts b/core/native-bridge.ts index 764534951..666087559 100644 --- a/core/native-bridge.ts +++ b/core/native-bridge.ts @@ -134,13 +134,13 @@ const createProxyUrl = (url: string, win: WindowCapacitor): string => { let proxyUrl = new URL(url); const isHttps = proxyUrl.protocol === 'https:'; - const originalHostname = proxyUrl.hostname; + const originalHost = encodeURIComponent(proxyUrl.host); const originalPathname = proxyUrl.pathname; proxyUrl = new URL(win.Capacitor?.getServerUrl() ?? ''); proxyUrl.pathname = `${ isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR - }/${originalHostname}${originalPathname}`; + }/${originalHost}${originalPathname}`; return proxyUrl.toString(); }; diff --git a/ios/Capacitor/Capacitor/WebViewAssetHandler.swift b/ios/Capacitor/Capacitor/WebViewAssetHandler.swift index 8c980ac26..22ae3aa5c 100644 --- a/ios/Capacitor/Capacitor/WebViewAssetHandler.swift +++ b/ios/Capacitor/Capacitor/WebViewAssetHandler.swift @@ -141,7 +141,6 @@ open class WebViewAssetHandler: NSObject, WKURLSchemeHandler { var targetUrl = url.absoluteString .replacingOccurrences(of: CapacitorBridge.httpInterceptorStartIdentifier, with: "") .replacingOccurrences(of: CapacitorBridge.httpsInterceptorStartIdentifier, with: "") - // Only replace first occurrence of the scheme if let range = targetUrl.range(of: localUrl.scheme ?? InstanceDescriptorDefaults.scheme) { targetUrl = targetUrl.replacingCharacters(in: range, with: isHttpsRequest ? "https" : "http") @@ -152,7 +151,7 @@ open class WebViewAssetHandler: NSObject, WKURLSchemeHandler { targetUrl = targetUrl.replacingCharacters(in: range, with: "") } - urlRequest.url = URL(string: targetUrl) + urlRequest.url = URL(string: targetUrl.removingPercentEncoding ?? targetUrl) let urlSession = URLSession.shared let task = urlSession.dataTask(with: urlRequest) { (data, response, error) in diff --git a/ios/Capacitor/Capacitor/assets/native-bridge.js b/ios/Capacitor/Capacitor/assets/native-bridge.js index abac3c8d0..6a9227f03 100644 --- a/ios/Capacitor/Capacitor/assets/native-bridge.js +++ b/ios/Capacitor/Capacitor/assets/native-bridge.js @@ -144,10 +144,10 @@ var nativeBridge = (function (exports) { return url; let proxyUrl = new URL(url); const isHttps = proxyUrl.protocol === 'https:'; - const originalHostname = proxyUrl.hostname; + const originalHost = encodeURIComponent(proxyUrl.host); const originalPathname = proxyUrl.pathname; proxyUrl = new URL((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getServerUrl()) !== null && _b !== void 0 ? _b : ''); - proxyUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${originalHostname}${originalPathname}`; + proxyUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${originalHost}${originalPathname}`; return proxyUrl.toString(); }; const initBridge = (w) => { @@ -678,7 +678,8 @@ var nativeBridge = (function (exports) { else { this.response = nativeResponse.data; } - this.responseText = ((_a = (nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type'])) === null || _a === void 0 ? void 0 : _a.startsWith('application/json')) + this.responseText = ((_a = (nativeResponse.headers['Content-Type'] || + nativeResponse.headers['content-type'])) === null || _a === void 0 ? void 0 : _a.startsWith('application/json')) ? JSON.stringify(nativeResponse.data) : nativeResponse.data; this.responseURL = nativeResponse.url; @@ -751,9 +752,7 @@ var nativeBridge = (function (exports) { if (isRelativeOrProxyUrl(this._url)) { return win.CapacitorWebXMLHttpRequest.getResponseHeader.call(this, name); } - // The search for the name is case insenstive. The Swift Code makes sure that the keys - // in the headers dictionary are already lowercased. - return this._headers[name.toLowerCase()]; + return this._headers[name]; }; Object.setPrototypeOf(xhr, prototype); return xhr;