Skip to content

Commit

Permalink
[Service Worker] Support redirects to relative URLs in Safari (#1978)
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrgicak authored Nov 14, 2024
1 parent 13cd12a commit 5746dfc
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
1 change: 1 addition & 0 deletions packages/php-wasm/node-polyfills/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import './lib/blob';
import './lib/custom-event';
import './lib/url';
23 changes: 23 additions & 0 deletions packages/php-wasm/node-polyfills/src/lib/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { currentJsRuntime } from './current-js-runtime';

if (currentJsRuntime === 'NODE') {
/**
* Polyfill for URL.canParse if it's missing.
*
* URL.canParse is available since Node 19.9.0,
* but Playground currently uses Node 18.18.0.
*
* This implementation is based on the one from `core-js`
* by Denis Pushkarev, https://github.com/zloirock
* https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.can-parse.js
*/
if (typeof URL.canParse !== 'function') {
globalThis.URL.canParse = function (url: string) {
try {
return !!new URL(url);
} catch (e) {
return false;
}
};
}
}
4 changes: 1 addition & 3 deletions packages/php-wasm/universal/src/lib/php-request-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,7 @@ export class PHPRequestHandler {
* @param request - PHP Request data.
*/
async request(request: PHPRequest): Promise<PHPResponse> {
const isAbsolute =
request.url.startsWith('http://') ||
request.url.startsWith('https://');
const isAbsolute = URL.canParse(request.url);
const requestedUrl = new URL(
// Remove the hash part of the URL as it's not meant for the server.
request.url.split('#')[0],
Expand Down
25 changes: 25 additions & 0 deletions packages/php-wasm/web-service-worker/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,31 @@ export async function convertFetchEventToPHPRequest(event: FetchEvent) {
throw e;
}

/**
* Safari has a bug that prevents Service Workers from redirecting relative URLs.
* When attempting to redirect to a relative URL, the network request will return an error.
* See the Webkit bug for details: https://bugs.webkit.org/show_bug.cgi?id=282427.
*
* Because PHP and WordPress can redirect to both relative and absolute URLs
* using the `location` header we need to ensure redirects are processed
* correctly by the Service Worker.
*
* As a workaround for Safari Service Workers, we use `Response.redirect()`
* for all redirect responses (300-399 status codes) coming from PHP.
* This solution was suggested in the Webkit bug comment:
* https://bugs.webkit.org/show_bug.cgi?id=282427#c2
*/
if (
phpResponse.httpStatusCode >= 300 &&
phpResponse.httpStatusCode <= 399 &&
phpResponse.headers['location']
) {
return Response.redirect(
phpResponse.headers['location'][0],
phpResponse.httpStatusCode
);
}

return new Response(phpResponse.bytes, {
headers: phpResponse.headers,
status: phpResponse.httpStatusCode,
Expand Down
12 changes: 1 addition & 11 deletions packages/playground/wordpress/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,9 @@ export async function setupPlatformLevelMuPlugins(php: UniversalPHP) {
* Reload page to ensure the user is logged in correctly.
* WordPress uses cookies to determine if the user is logged in,
* so we need to reload the page to ensure the cookies are set.
*
* Both WordPress home url and REQUEST_URI may include the site scope
* subdirectory.
* To prevent the redirect from including two scopes, we need to
* remove the scope from the REQUEST_URI if it's present.
*/
$redirect_url = $_SERVER['REQUEST_URI'];
if (strpos($redirect_url, '/scope:') === 0) {
$parts = explode('/', $redirect_url);
$redirect_url = '/' . implode('/', array_slice($parts, 2));
}
wp_redirect(
home_url($redirect_url),
$_SERVER['REQUEST_URI'],
302
);
exit;
Expand Down

0 comments on commit 5746dfc

Please sign in to comment.