Skip to content

Commit

Permalink
Default url rewrites to /index.php (#1072)
Browse files Browse the repository at this point in the history
If a requested file path can't be resolved (file or folder don't exist)
the request file path is rewritten to /index.php.

## What problem is it solving?

Ensures a response when requesting WordPress permalink URLs like
`/category/uncategorized/` using `php.request`.

## How is the problem addressed?

The code assumed that a path which isn't a PHP file is a folder and
requested the index.php file in that folder.
In the case of WordPress URLs the path might not be a folder so adding
index.php would break a valid request.

To address this, index.php is added to the end of the path only if the
path is a valid directory.
If not, the path is rewritten to index.php in the root folder.

## Testing Instructions

- Confirm that tests pass
  • Loading branch information
bgrgicak authored Mar 1, 2024
1 parent c4d526b commit 8447d91
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
36 changes: 32 additions & 4 deletions packages/php-wasm/node/src/test/php-request-handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ describe.each(SupportedPHPVersions)(
*/
php.writeFile(
'/index.php',
`<?php
`<?php
echo json_encode($_POST);`
);
const response = await handler.request({
Expand All @@ -163,7 +163,7 @@ describe.each(SupportedPHPVersions)(
*/
php.writeFile(
'/index.php',
`<?php
`<?php
move_uploaded_file($_FILES["myFile"]["tmp_name"], '/tmp/moved.txt');
echo json_encode(file_exists('/tmp/moved.txt'));`
);
Expand All @@ -180,7 +180,7 @@ describe.each(SupportedPHPVersions)(
it('Should allow mixing data and files when `body` is a JavaScript object', async () => {
php.writeFile(
'/index.php',
`<?php
`<?php
move_uploaded_file($_FILES["myFile"]["tmp_name"], '/tmp/moved.txt');
echo json_encode(array_merge(
$_POST,
Expand All @@ -203,7 +203,7 @@ describe.each(SupportedPHPVersions)(
it('Should handle an empty file object and post data', async () => {
await php.writeFile(
'/index.php',
`<?php
`<?php
echo json_encode($_POST);`
);
const response = await handler.request({
Expand Down Expand Up @@ -235,6 +235,34 @@ describe.each(SupportedPHPVersions)(
expect((await response1).httpStatusCode).toEqual(200);
expect((await response2).httpStatusCode).toEqual(502);
});

it('should return 200 and pass query strings when a valid request is made to a PHP file', async () => {
php.writeFile('/test.php', `<?php echo $_GET['key'];`);
const response = await handler.request({
url: '/test.php?key=value',
});
expect(response.httpStatusCode).toEqual(200);
expect(response.text).toEqual('value');
});

it('should return 200 status and pass query strings when a valid request is made to a WordPress permalink', async () => {
php.writeFile('/index.php', `<?php echo $_GET['key'];`);
const response = await handler.request({
url: '/category/uncategorized/?key=value',
});
expect(response.httpStatusCode).toEqual(200);
expect(response.text).toEqual('value');
});

it('should return 200 and pass query strings when a valid request is made to a folder', async () => {
php.mkdirTree('/folder');
php.writeFile('/folder/index.php', `<?php echo $_GET['key'];`);
const response = await handler.request({
url: '/folder/?key=value',
});
expect(response.httpStatusCode).toEqual(200);
expect(response.text).toEqual('value');
});
}
);

Expand Down
15 changes: 8 additions & 7 deletions packages/php-wasm/universal/src/lib/php-request-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,17 +268,18 @@ export class PHPRequestHandler implements RequestHandler {
#resolvePHPFilePath(requestedPath: string): string {
let filePath = removePathPrefix(requestedPath, this.#PATHNAME);

// If the path mentions a .php extension, that's our file's path.
if (filePath.includes('.php')) {
// If the path mentions a .php extension, that's our file's path.
filePath = filePath.split('.php')[0] + '.php';
} else {
// Otherwise, let's assume the file is $request_path/index.php
} else if (this.php.isDir(`${this.#DOCROOT}${filePath}`)) {
if (!filePath.endsWith('/')) {
filePath += '/';
}
if (!filePath.endsWith('index.php')) {
filePath += 'index.php';
filePath = `${filePath}/`;
}
// If the path is a directory, let's assume the file is index.php
filePath = `${filePath}index.php`;
} else {
// Otherwise, let's assume the file is /index.php
filePath = '/index.php';
}

const resolvedFsPath = `${this.#DOCROOT}${filePath}`;
Expand Down

0 comments on commit 8447d91

Please sign in to comment.