Skip to content

Commit

Permalink
Shorten and simplify path to CORS proxy (#2063)
Browse files Browse the repository at this point in the history
## Motivation for the change, related issues

The CORS proxy URL is long and requires the user to remember a specific
PHP file path.
```
https://wordpress-playground-cors-proxy.net/cors-proxy.php
```

Let's shorten the URL and let people forget the PHP file name. With this
PR,

`https://wordpress-playground-cors-proxy.net/cors-proxy.php?https://example.com/`
can be replaced with
`https://wordpress-playground-cors-proxy.net/?https://example.com/`
or
`https://wordpress-playground-cors-proxy.net/https://example.com/`

## Implementation details

Instead of trying to derive the target URL by removing
`$_SERVER['SCRIPT_NAME']` from `$_SERVER['REQUEST_URI']`, we switch to
taking the target URL from `$_SERVER['PATH_INFO']` or
`$_SERVER['QUERY_STRING']`.

In addition, we take advantage of WP Cloud's default script path and
have that script define PATH_INFO if it doesn't exist. It shouldn't
exist because WP Cloud isn't configured to provide path info today.
(`$_SERVER['PATH_INFO']` === `/additional/info` when
`$_SERVER['REQUEST_URI']` === '/path-to-script.php/additional/info').

## Testing Instructions (or ideally a Blueprint)

- Run unit tests from php-cors-proxy dir with `sh test.sh`
- Run CORS proxy deploy workflow and test manually with proxy site. The
following proxy URLs should all work:
-
https://wordpress-playground-cors-proxy.net/cors-proxy.php?https://wordpress.org/
- https://wordpress-playground-cors-proxy.net/?https://wordpress.org/
    - https://wordpress-playground-cors-proxy.net/https://wordpress.org/
  • Loading branch information
brandonpayton authored Dec 6, 2024
1 parent 518c2c2 commit d22c728
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 19 deletions.
11 changes: 11 additions & 0 deletions packages/playground/php-cors-proxy-deployment/__wp__/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

if (
empty( $_SERVER['PATH_INFO'] ) &&
!str_starts_with($_SERVER['REQUEST_URI'], '/?')
) {
// Allow proxied URL to be provided via request URI,
// even though WP cloud servers don't provided PATH_INFO.
$_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
}
require __DIR__ . '/../cors-proxy.php';
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SITE_API_BASE="$( "$SITE_PHP" -r 'require "/scripts/env.php"; echo SITE_API_BASE

echo Adding config file to updated proxy files
cp ~/cors-proxy-deployment/cors-proxy-config.php ~/updated-proxy-files/
cp -R ~/cors-proxy-deployment/__wp__ ~/updated-proxy-files/

echo Syncing staged files to production
rsync -av --delete --no-perms --omit-dir-times ~/updated-proxy-files/ /srv/htdocs/
Expand Down
17 changes: 7 additions & 10 deletions packages/playground/php-cors-proxy/cors-proxy-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,18 @@ function get_target_url($server_data=null) {
if ($server_data === null) {
$server_data = $_SERVER;
}
$requestUri = $server_data['REQUEST_URI'];
$targetUrl = $requestUri;

// Remove the current script name from the beginning of $targetUrl
if (strpos($targetUrl, $server_data['SCRIPT_NAME']) === 0) {
$targetUrl = substr($targetUrl, strlen($server_data['SCRIPT_NAME']));
$path_info = $server_data['PATH_INFO'] ?? '';
if (str_starts_with($path_info, '/') && strlen($path_info) > 1) {
return substr($path_info, 1);
}

// Remove the leading slash or question mark, depending on the method
// used to access the script
if (str_starts_with($targetUrl, '/') || str_starts_with($targetUrl, '?')) {
$targetUrl = substr($targetUrl, 1);
$query_string = $server_data['QUERY_STRING'] ?? '';
if (!empty($server_data['QUERY_STRING'])) {
return $query_string;
}

return $targetUrl;
return false;
}

function get_current_script_uri($targetUrl, $request_uri)
Expand Down
10 changes: 9 additions & 1 deletion packages/playground/php-cors-proxy/cors-proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@
echo "Bad Request\n\nNo URL provided";
exit;
}
$resolved = url_validate_and_resolve($targetUrl);

try {
$resolved = url_validate_and_resolve($targetUrl);
} catch (CorsProxyException $e) {
http_response_code(400);
echo "Bad Request\n\n" . $e->getMessage();
exit;
}

$host = $resolved['host'];
$resolvedIp = $resolved['ip'];

Expand Down
44 changes: 36 additions & 8 deletions packages/playground/php-cors-proxy/tests/ProxyFunctionsTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,48 @@ public function testGetTargetUrl($server_data, $expected_target_url)

static public function providerGetTargetUrl() {
return [
'Simple request' => [
'Request with server-provided PATH_INFO' => [
[
'REQUEST_URI' => '/cors-proxy/proxy.php/http://example.com',
'SCRIPT_NAME' => '/cors-proxy/proxy.php',
'PATH_INFO' => '/http://example.com',
],
'http://example.com'
],
'Request with query params' => [
'Request with server-provided single-slash PATH_INFO' => [
[
'REQUEST_URI' => '/cors-proxy/proxy.php/http://example.com?test=1',
'SCRIPT_NAME' => '/cors-proxy/proxy.php',
'PATH_INFO' => '/',
],
'http://example.com?test=1'
]
false,
],
'Request with server-provided empty PATH_INFO' => [
[
'PATH_INFO' => '',
],
false,
],
'Request with server-provided PATH_INFO and QUERY_STRING' => [
[
'PATH_INFO' => '/http://example.com/from-path-info',
'QUERY_STRING' => 'http://example.com/from-query-string',
],
'http://example.com/from-path-info'
],
'Request with server-provided slash PATH_INFO and QUERY_STRING' => [
[
'PATH_INFO' => '/',
'QUERY_STRING' => 'http://example.com/from-query-string',
],
'http://example.com/from-query-string'
],
'Request with just query params' => [
[
'QUERY_STRING' => 'http://example.com/from-query-string',
],
'http://example.com/from-query-string'
],
'Request with neither PATH_INFO nor QUERY_STRING' => [
[],
false
],
];
}
public function testGetCurrentScriptUri()
Expand Down

0 comments on commit d22c728

Please sign in to comment.