Skip to content

Commit

Permalink
fix(http): pass original url as query param on the proxy url (#7527) (#…
Browse files Browse the repository at this point in the history
…7604)

Co-authored-by: Michael Wolz <[email protected]>
  • Loading branch information
jcesarmobile and michaelwolz authored Aug 5, 2024
1 parent bb23779 commit 1c830ad
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 63 deletions.
12 changes: 4 additions & 8 deletions android/capacitor/src/main/assets/native-bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,19 @@ var nativeBridge = (function (exports) {
return { data: body, type: 'json' };
};
const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
const CAPACITOR_HTTPS_INTERCEPTOR = '/_capacitor_https_interceptor_';
const CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM = 'u';
// TODO: export as Cap function
const isRelativeOrProxyUrl = (url) => !url ||
!(url.startsWith('http:') || url.startsWith('https:')) ||
url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1 ||
url.indexOf(CAPACITOR_HTTPS_INTERCEPTOR) > -1;
url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1;
// TODO: export as Cap function
const createProxyUrl = (url, win) => {
var _a, _b;
if (isRelativeOrProxyUrl(url))
return url;
const proxyUrl = new URL(url);
const bridgeUrl = new URL((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getServerUrl()) !== null && _b !== void 0 ? _b : '');
const isHttps = proxyUrl.protocol === 'https:';
bridgeUrl.search = proxyUrl.search;
bridgeUrl.hash = proxyUrl.hash;
bridgeUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${encodeURIComponent(proxyUrl.host)}${proxyUrl.pathname}`;
bridgeUrl.pathname = CAPACITOR_HTTP_INTERCEPTOR;
bridgeUrl.searchParams.append(CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM, url);
return bridgeUrl.toString();
};
const initBridge = (w) => {
Expand Down
5 changes: 5 additions & 0 deletions android/capacitor/src/main/java/com/getcapacitor/Bridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,13 @@ public class Bridge {
public static final String CAPACITOR_FILE_START = "/_capacitor_file_";
public static final String CAPACITOR_CONTENT_START = "/_capacitor_content_";
public static final String CAPACITOR_HTTP_INTERCEPTOR_START = "/_capacitor_http_interceptor_";

/** @deprecated CAPACITOR_HTTPS_INTERCEPTOR_START is no longer required. All proxied requests are handled via CAPACITOR_HTTP_INTERCEPTOR_START instead */
@Deprecated
public static final String CAPACITOR_HTTPS_INTERCEPTOR_START = "/_capacitor_https_interceptor_";

public static final String CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM = "u";

public static final int DEFAULT_ANDROID_WEBVIEW_VERSION = 60;
public static final int MINIMUM_ANDROID_WEBVIEW_VERSION = 55;
public static final int DEFAULT_HUAWEI_WEBVIEW_VERSION = 10;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
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;
Expand Down Expand Up @@ -172,13 +171,7 @@ private static Uri parseAndVerifyUrl(String url) {
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
Uri loadingUrl = request.getUrl();

if (
null != loadingUrl.getPath() &&
(
loadingUrl.getPath().startsWith(Bridge.CAPACITOR_HTTP_INTERCEPTOR_START) ||
loadingUrl.getPath().startsWith(Bridge.CAPACITOR_HTTPS_INTERCEPTOR_START)
)
) {
if (null != loadingUrl.getPath() && loadingUrl.getPath().startsWith(Bridge.CAPACITOR_HTTP_INTERCEPTOR_START)) {
Logger.debug("Handling CapacitorHttp request: " + loadingUrl);
try {
return handleCapacitorHttpRequest(request);
Expand Down Expand Up @@ -259,16 +252,7 @@ private String getReasonPhraseFromResponseCode(int code) {
}

private WebResourceResponse handleCapacitorHttpRequest(WebResourceRequest request) throws IOException {
boolean isHttps =
request.getUrl().getPath() != null && request.getUrl().getPath().startsWith(Bridge.CAPACITOR_HTTPS_INTERCEPTOR_START);

String urlString = request
.getUrl()
.toString()
.replace(bridge.getLocalUrl(), isHttps ? "https:/" : "http:/")
.replace(Bridge.CAPACITOR_HTTP_INTERCEPTOR_START, "")
.replace(Bridge.CAPACITOR_HTTPS_INTERCEPTOR_START, "");
urlString = URLDecoder.decode(urlString, "UTF-8");
String urlString = request.getUrl().getQueryParameter(Bridge.CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM);
URL url = new URL(urlString);
JSObject headers = new JSObject();

Expand Down
16 changes: 5 additions & 11 deletions core/native-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,27 +130,21 @@ const convertBody = async (
};

const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
const CAPACITOR_HTTPS_INTERCEPTOR = '/_capacitor_https_interceptor_';
const CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM = 'u';

// TODO: export as Cap function
const isRelativeOrProxyUrl = (url: string | undefined): boolean =>
!url ||
!(url.startsWith('http:') || url.startsWith('https:')) ||
url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1 ||
url.indexOf(CAPACITOR_HTTPS_INTERCEPTOR) > -1;
url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1;

// TODO: export as Cap function
const createProxyUrl = (url: string, win: WindowCapacitor): string => {
if (isRelativeOrProxyUrl(url)) return url;

const proxyUrl = new URL(url);
const bridgeUrl = new URL(win.Capacitor?.getServerUrl() ?? '');
const isHttps = proxyUrl.protocol === 'https:';
bridgeUrl.search = proxyUrl.search;
bridgeUrl.hash = proxyUrl.hash;
bridgeUrl.pathname = `${
isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR
}/${encodeURIComponent(proxyUrl.host)}${proxyUrl.pathname}`;
bridgeUrl.pathname = CAPACITOR_HTTP_INTERCEPTOR;
bridgeUrl.searchParams.append(CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM, url);

return bridgeUrl.toString();
};

Expand Down
2 changes: 2 additions & 0 deletions ios/Capacitor/Capacitor/CapacitorBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol {
public static let capacitorSite = "https://capacitorjs.com/"
public static let fileStartIdentifier = "/_capacitor_file_"
public static let httpInterceptorStartIdentifier = "/_capacitor_http_interceptor_"
@available(*, deprecated, message: "`httpsInterceptorStartIdentifier` is no longer required. All proxied requests are handled via `httpInterceptorStartIdentifier` instead")
public static let httpsInterceptorStartIdentifier = "/_capacitor_https_interceptor_"
public static let httpInterceptorUrlParam = "u"
public static let defaultScheme = "capacitor"

var webViewAssetHandler: WebViewAssetHandler
Expand Down
23 changes: 5 additions & 18 deletions ios/Capacitor/Capacitor/WebViewAssetHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
return
}

if url.path.starts(with: CapacitorBridge.httpsInterceptorStartIdentifier) {
handleCapacitorHttpRequest(urlSchemeTask, localUrl, true)
return
}

if stringToLoad.starts(with: CapacitorBridge.fileStartIdentifier) {
startPath = stringToLoad.replacingOccurrences(of: CapacitorBridge.fileStartIdentifier, with: "")
} else {
Expand Down Expand Up @@ -138,21 +133,13 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler {
func handleCapacitorHttpRequest(_ urlSchemeTask: WKURLSchemeTask, _ localUrl: URL, _ isHttpsRequest: Bool) {
var urlRequest = urlSchemeTask.request
guard let url = urlRequest.url else { return }
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")

let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
if let targetUrl = urlComponents?.queryItems?.first(where: { $0.name == CapacitorBridge.httpInterceptorUrlParam })?.value,
!targetUrl.isEmpty {
urlRequest.url = URL(string: targetUrl)
}

// Only replace first occurrence of the hostname
if let range = targetUrl.range(of: (localUrl.host ?? InstanceDescriptorDefaults.hostname) + "/") {
targetUrl = targetUrl.replacingCharacters(in: range, with: "")
}

urlRequest.url = URL(string: targetUrl.removingPercentEncoding ?? targetUrl)

let urlSession = URLSession.shared
let task = urlSession.dataTask(with: urlRequest) { (data, response, error) in
DispatchQueue.main.async {
Expand Down
12 changes: 4 additions & 8 deletions ios/Capacitor/Capacitor/assets/native-bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,19 @@ var nativeBridge = (function (exports) {
return { data: body, type: 'json' };
};
const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
const CAPACITOR_HTTPS_INTERCEPTOR = '/_capacitor_https_interceptor_';
const CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM = 'u';
// TODO: export as Cap function
const isRelativeOrProxyUrl = (url) => !url ||
!(url.startsWith('http:') || url.startsWith('https:')) ||
url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1 ||
url.indexOf(CAPACITOR_HTTPS_INTERCEPTOR) > -1;
url.indexOf(CAPACITOR_HTTP_INTERCEPTOR) > -1;
// TODO: export as Cap function
const createProxyUrl = (url, win) => {
var _a, _b;
if (isRelativeOrProxyUrl(url))
return url;
const proxyUrl = new URL(url);
const bridgeUrl = new URL((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getServerUrl()) !== null && _b !== void 0 ? _b : '');
const isHttps = proxyUrl.protocol === 'https:';
bridgeUrl.search = proxyUrl.search;
bridgeUrl.hash = proxyUrl.hash;
bridgeUrl.pathname = `${isHttps ? CAPACITOR_HTTPS_INTERCEPTOR : CAPACITOR_HTTP_INTERCEPTOR}/${encodeURIComponent(proxyUrl.host)}${proxyUrl.pathname}`;
bridgeUrl.pathname = CAPACITOR_HTTP_INTERCEPTOR;
bridgeUrl.searchParams.append(CAPACITOR_HTTP_INTERCEPTOR_URL_PARAM, url);
return bridgeUrl.toString();
};
const initBridge = (w) => {
Expand Down

0 comments on commit 1c830ad

Please sign in to comment.