Skip to content

Commit a6d1646

Browse files
committed
Keep fetch-with-cors-proxy on HTTPS paths
1 parent 11fb6b1 commit a6d1646

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { afterEach, describe, expect, it, vi } from 'vitest';
2+
import { fetchWithCorsProxy } from './fetch-with-cors-proxy';
3+
4+
describe('fetchWithCorsProxy', () => {
5+
afterEach(() => {
6+
vi.restoreAllMocks();
7+
});
8+
9+
it('upgrades plain HTTP requests to HTTPS before fetching directly', async () => {
10+
const fetchMock = vi
11+
.spyOn(globalThis, 'fetch')
12+
.mockResolvedValue(new Response('ok'));
13+
14+
await fetchWithCorsProxy('http://example.com/resource.zip');
15+
16+
expect(fetchMock).toHaveBeenCalledTimes(1);
17+
const directRequest = fetchMock.mock.calls[0][0] as Request;
18+
expect(directRequest.url).toBe('https://example.com/resource.zip');
19+
});
20+
21+
it('upgrades HTTP URLs before retrying via the CORS proxy', async () => {
22+
const fetchMock = vi
23+
.spyOn(globalThis, 'fetch')
24+
.mockRejectedValueOnce(new Error('network fail'))
25+
.mockResolvedValueOnce(new Response('proxied'));
26+
27+
await fetchWithCorsProxy(
28+
'http://example.com/wp-cron.php',
29+
undefined,
30+
'https://proxy.test/?url='
31+
);
32+
33+
expect(fetchMock).toHaveBeenCalledTimes(2);
34+
const initialRequest = fetchMock.mock.calls[0][0] as Request;
35+
expect(initialRequest.url).toBe('https://example.com/wp-cron.php');
36+
37+
const proxiedRequest = fetchMock.mock.calls[1][0] as Request;
38+
expect(proxiedRequest.url).toBe(
39+
'https://proxy.test/?url=https://example.com/wp-cron.php'
40+
);
41+
});
42+
});

packages/php-wasm/web/src/lib/fetch-with-cors-proxy.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,18 @@ export async function fetchWithCorsProxy(
66
corsProxyUrl?: string,
77
playgroundUrl?: string
88
): Promise<Response> {
9-
const requestObject =
9+
let requestObject =
1010
typeof input === 'string' ? new Request(input, init) : input;
11+
const playgroundUrlObj = playgroundUrl ? new URL(playgroundUrl) : null;
12+
let requestUrlObj = playgroundUrlObj
13+
? new URL(requestObject.url, playgroundUrlObj)
14+
: new URL(requestObject.url);
15+
if (requestUrlObj.protocol === 'http:') {
16+
requestUrlObj.protocol = 'https:';
17+
const httpsUrl = requestUrlObj.toString();
18+
requestObject = await cloneRequest(requestObject, { url: httpsUrl });
19+
requestUrlObj = new URL(httpsUrl);
20+
}
1121
if (!corsProxyUrl) {
1222
return await fetch(requestObject);
1323
}
@@ -17,12 +27,6 @@ export async function fetchWithCorsProxy(
1727
* won't be able to reach it. At best, it will produce a cryptic error
1828
* message. At worst, it will time out, making the user wait for 30 seconds.
1929
*/
20-
const playgroundUrlObj = playgroundUrl ? new URL(playgroundUrl) : null;
21-
const requestUrlObj = new URL(
22-
requestObject.url,
23-
playgroundUrlObj || undefined
24-
);
25-
2630
if (
2731
playgroundUrlObj &&
2832
requestUrlObj.protocol === playgroundUrlObj.protocol &&

0 commit comments

Comments
 (0)