|
2 | 2 |
|
3 | 3 | declare const self: ServiceWorkerGlobalScope;
|
4 | 4 |
|
5 |
| -import { getURLScope, removeURLScope, setURLScope } from '@php-wasm/scopes'; |
| 5 | +import { getURLScope, removeURLScope } from '@php-wasm/scopes'; |
| 6 | +import { applyRewriteRules } from '@php-wasm/universal'; |
6 | 7 | import {
|
7 | 8 | awaitReply,
|
8 | 9 | convertFetchEventToPHPRequest,
|
9 | 10 | initializeServiceWorker,
|
10 | 11 | cloneRequest,
|
11 | 12 | broadcastMessageExpectReply,
|
12 |
| - getRequestHeaders, |
13 | 13 | } from '@php-wasm/web-service-worker';
|
| 14 | +import { wordPressRewriteRules } from '@wp-playground/wordpress'; |
14 | 15 |
|
15 | 16 | if (!(self as any).document) {
|
16 | 17 | // Workaround: vite translates import.meta.url
|
@@ -47,66 +48,44 @@ initializeServiceWorker({
|
47 | 48 |
|
48 | 49 | const { staticAssetsDirectory } = await getScopedWpDetails(scope!);
|
49 | 50 |
|
50 |
| - let workerResponse = await convertFetchEventToPHPRequest(event); |
51 |
| - // If we get a 404, try to apply the WordPress URL rewrite rules. |
52 |
| - let rewrittenUrlString: string | undefined = undefined; |
53 |
| - if (workerResponse.status === 404) { |
54 |
| - for (const url of rewriteWordPressUrl(unscopedUrl, scope!)) { |
55 |
| - rewrittenUrlString = url.toString(); |
56 |
| - workerResponse = await convertFetchEventToPHPRequest( |
57 |
| - await cloneFetchEvent(event, rewrittenUrlString) |
58 |
| - ); |
59 |
| - if ( |
60 |
| - workerResponse.status !== 404 || |
61 |
| - workerResponse.headers.get('x-file-type') === 'static' |
62 |
| - ) { |
63 |
| - break; |
64 |
| - } |
| 51 | + const workerResponse = await convertFetchEventToPHPRequest(event); |
| 52 | + if ( |
| 53 | + workerResponse.status === 404 && |
| 54 | + workerResponse.headers.get('x-file-type') === 'static' |
| 55 | + ) { |
| 56 | + // If we get a 404 for a static file, try to fetch it from |
| 57 | + // the from the static assets directory at the remote server. |
| 58 | + const requestedUrl = new URL(event.request.url); |
| 59 | + const resolvedUrl = removeURLScope(requestedUrl); |
| 60 | + resolvedUrl.pathname = applyRewriteRules( |
| 61 | + resolvedUrl.pathname, |
| 62 | + wordPressRewriteRules |
| 63 | + ); |
| 64 | + if ( |
| 65 | + // Vite dev server requests |
| 66 | + !resolvedUrl.pathname.startsWith('/@fs') && |
| 67 | + !resolvedUrl.pathname.startsWith('/assets') |
| 68 | + ) { |
| 69 | + resolvedUrl.pathname = `/${staticAssetsDirectory}${resolvedUrl.pathname}`; |
65 | 70 | }
|
66 |
| - } |
67 |
| - |
68 |
| - if (workerResponse.status === 404) { |
69 |
| - if (workerResponse.headers.get('x-file-type') === 'static') { |
70 |
| - // If we get a 404 for a static file, try to fetch it from |
71 |
| - // the from the static assets directory at the remote server. |
72 |
| - const requestedUrl = new URL( |
73 |
| - rewrittenUrlString || event.request.url |
74 |
| - ); |
75 |
| - const resolvedUrl = removeURLScope(requestedUrl); |
76 |
| - if ( |
77 |
| - // Vite dev server requests |
78 |
| - !resolvedUrl.pathname.startsWith('/@fs') && |
79 |
| - !resolvedUrl.pathname.startsWith('/assets') |
80 |
| - ) { |
81 |
| - resolvedUrl.pathname = `/${staticAssetsDirectory}${resolvedUrl.pathname}`; |
| 71 | + const request = await cloneRequest(event.request, { |
| 72 | + url: resolvedUrl, |
| 73 | + }); |
| 74 | + return fetch(request).catch((e) => { |
| 75 | + if (e?.name === 'TypeError') { |
| 76 | + // This could be an ERR_HTTP2_PROTOCOL_ERROR that sometimes |
| 77 | + // happen on playground.wordpress.net. Let's add a randomized |
| 78 | + // delay and retry once |
| 79 | + return new Promise((resolve) => { |
| 80 | + setTimeout(() => { |
| 81 | + resolve(fetch(request)); |
| 82 | + }, Math.random() * 1500); |
| 83 | + }) as Promise<Response>; |
82 | 84 | }
|
83 |
| - const request = await cloneRequest(event.request, { |
84 |
| - url: resolvedUrl, |
85 |
| - }); |
86 |
| - return fetch(request).catch((e) => { |
87 |
| - if (e?.name === 'TypeError') { |
88 |
| - // This could be an ERR_HTTP2_PROTOCOL_ERROR that sometimes |
89 |
| - // happen on playground.wordpress.net. Let's add a randomized |
90 |
| - // delay and retry once |
91 |
| - return new Promise((resolve) => { |
92 |
| - setTimeout(() => { |
93 |
| - resolve(fetch(request)); |
94 |
| - }, Math.random() * 1500); |
95 |
| - }) as Promise<Response>; |
96 |
| - } |
97 | 85 |
|
98 |
| - // Otherwise let's just re-throw the error |
99 |
| - throw e; |
100 |
| - }); |
101 |
| - } else { |
102 |
| - const indexPhp = setURLScope( |
103 |
| - new URL('/index.php', unscopedUrl), |
104 |
| - scope! |
105 |
| - ); |
106 |
| - workerResponse = await convertFetchEventToPHPRequest( |
107 |
| - await cloneFetchEvent(event, indexPhp.toString()) |
108 |
| - ); |
109 |
| - } |
| 86 | + // Otherwise let's just re-throw the error |
| 87 | + throw e; |
| 88 | + }); |
110 | 89 | }
|
111 | 90 |
|
112 | 91 | // Path the block-editor.js file to ensure the site editor's iframe
|
@@ -240,49 +219,10 @@ function emptyHtml() {
|
240 | 219 | );
|
241 | 220 | }
|
242 | 221 |
|
243 |
| -async function cloneFetchEvent(event: FetchEvent, rewriteUrl: string) { |
244 |
| - return new FetchEvent(event.type, { |
245 |
| - ...event, |
246 |
| - request: await cloneRequest(event.request, { |
247 |
| - headers: { |
248 |
| - ...getRequestHeaders(event.request), |
249 |
| - 'x-rewrite-url': rewriteUrl, |
250 |
| - }, |
251 |
| - }), |
252 |
| - }); |
253 |
| -} |
254 |
| - |
255 | 222 | type WPModuleDetails = {
|
256 | 223 | staticAssetsDirectory: string;
|
257 | 224 | };
|
258 | 225 |
|
259 |
| -/** |
260 |
| - * Rewrite the URL according to WordPress .htaccess rules. |
261 |
| - */ |
262 |
| -function* rewriteWordPressUrl(unscopedUrl: URL, scope: string) { |
263 |
| - // RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) wordpress/$2 [L] |
264 |
| - const rewrittenUrl = unscopedUrl.pathname |
265 |
| - .toString() |
266 |
| - .replace( |
267 |
| - /^\/([_0-9a-zA-Z-]+\/)?(wp-(content|admin|includes).*)/, |
268 |
| - '/$2' |
269 |
| - ); |
270 |
| - if (rewrittenUrl !== unscopedUrl.pathname) { |
271 |
| - // Something changed, let's try the rewritten URL |
272 |
| - const url = new URL(rewrittenUrl, unscopedUrl); |
273 |
| - yield setURLScope(url, scope); |
274 |
| - } |
275 |
| - |
276 |
| - // RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ wordpress/$2 [L] |
277 |
| - if (unscopedUrl.pathname.endsWith('.php')) { |
278 |
| - // The URL ends with .php, let's try to rewrite it to |
279 |
| - // a .php file in the WordPress root directory |
280 |
| - const filename = unscopedUrl.pathname.split('/').pop(); |
281 |
| - const url = new URL('/' + filename, unscopedUrl); |
282 |
| - yield setURLScope(url, scope); |
283 |
| - } |
284 |
| -} |
285 |
| - |
286 | 226 | const scopeToWpModule: Record<string, WPModuleDetails> = {};
|
287 | 227 | async function getScopedWpDetails(scope: string): Promise<WPModuleDetails> {
|
288 | 228 | if (!scopeToWpModule[scope]) {
|
|
0 commit comments