Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send Entire Request, Including Query Params, To Prerender #40

Merged
merged 3 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,22 @@ return [
| See: https://docs.guzzlephp.org/en/stable/request-options.html#timeout
|
*/

'timeout' => env('PRERENDER_TIMEOUT', 0),

/*
|--------------------------------------------------------------------------
| Query Parameters
|--------------------------------------------------------------------------
|
| By default, request query parameters are not sent to prerender when
| requesting the prerendered page. Setting this to true will cause the full
| URL, including query parameters, to be sent to prerender.
|
*/

'full_url' => env('PRERENDER_FULL_URL', false),

];
```

Expand Down
14 changes: 14 additions & 0 deletions config/prerender.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,20 @@
| See: https://docs.guzzlephp.org/en/stable/request-options.html#timeout
|
*/

'timeout' => env('PRERENDER_TIMEOUT', 0),

/*
|--------------------------------------------------------------------------
| Query Parameters
|--------------------------------------------------------------------------
|
| By default, request query parameters are not sent to prerender when
| requesting the prerendered page. Setting this to true will cause the full
| URL, including query parameters, to be sent to prerender.
|
*/

'full_url' => env('PRERENDER_FULL_URL', false),

];
42 changes: 32 additions & 10 deletions src/PrerenderMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ class PrerenderMiddleware
*/
private $returnSoftHttpCodes;

/**
* Send the full request URL to prerender.
*
* @var bool
*/
private $useFullURL;

/**
* Creates a new PrerenderMiddleware instance.
*/
Expand All @@ -88,6 +95,7 @@ public function __construct(Guzzle $client)
$this->prerenderToken = $config['prerender_token'];
$this->whitelist = $config['whitelist'];
$this->blacklist = $config['blacklist'];
$this->useFullURL = $config['full_url'];
}

/**
Expand Down Expand Up @@ -195,18 +203,10 @@ private function getPrerenderedPageResponse(Request $request): ?ResponseInterfac
$headers['X-Prerender-Token'] = $this->prerenderToken;
}

$protocol = $request->isSecure() ? 'https' : 'http';

try {
// Return the Guzzle Response
$host = $request->getHost();
$path = $request->Path();
// Fix "//" 404 error
if ($path === '/') {
$path = '';
}
$url = $this->generatePrerenderUrl($request);

return $this->client->get($this->prerenderUri.'/'.urlencode($protocol.'://'.$host.'/'.$path), compact('headers'));
return $this->client->get($this->prerenderUri.'/'.urlencode($url), compact('headers'));
} catch (RequestException $exception) {
if (!$this->returnSoftHttpCodes && !empty($exception->getResponse()) && $exception->getResponse()->getStatusCode() === 404) {
abort(404);
Expand Down Expand Up @@ -250,4 +250,26 @@ private function isListed($needles, array $list): bool

return false;
}

/**
* Generate the request URL to send to prerender. When useFullURL is false, the legacy URL
* generation logic is used
*/
private function generatePrerenderUrl(Request $request): string
{
if ($this->useFullURL) {
return $request->fullUrl();
}

$protocol = $request->isSecure() ? 'https' : 'http';
$host = $request->getHost();
$path = $request->Path();

// Fix "//" 404 error
if ($path === '/') {
$path = '';
}

return $protocol.'://'.$host.'/'.$path;
}
}
37 changes: 37 additions & 0 deletions tests/PrerenderMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,45 @@ public function it_should_not_prerender_page_if_request_times_out()
->assertSee('GET - Success');
}

/** @test */
public function it_does_not_send_query_strings_to_prerender_by_default()
{
$this->app->bind(Client::class, function () {
return $this->createMockUrlTrackingClient();
});

$this->allowSymfonyUserAgent();

$this->get('/test-middleware?withQueryParam=true')
->assertHeader('prerender.io-mock', true)
->assertSuccessful()
->assertSee(urlencode('/test-middleware'))
->assertDontSee('withQueryParam');
}

/** @test */
public function it_sends_full_query_string_to_prerender()
{
$this->app->bind(Client::class, function () {
return $this->createMockUrlTrackingClient();
});

$this->allowSymfonyUserAgent();
$this->allowQueryParams();

$this->get('/test-middleware?withQueryParam=true')
->assertHeader('prerender.io-mock', true)
->assertSuccessful()
->assertSee(urlencode('/test-middleware?withQueryParam=true'));
}

private function allowSymfonyUserAgent()
{
config()->set('prerender.crawler_user_agents', ['symfony']);
}

private function allowQueryParams()
{
config()->set('prerender.full_url', true);
}
}
18 changes: 18 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Http\Kernel;
use Illuminate\Support\Facades\Route;
use Psr\Http\Message\RequestInterface;

class TestCase extends \Orchestra\Testbench\TestCase
{
Expand Down Expand Up @@ -62,6 +63,23 @@ protected function createMockTimeoutClient(): Client
return new Client(['handler' => $stack]);
}

protected function createMockUrlTrackingClient(): Client
{
$mock = new MockHandler([
function (RequestInterface $request) {
return new Response(
200,
['prerender.io-mock' => true],
(string) $request->getUri()
);
},
]);

$stack = HandlerStack::create($mock);

return new Client(['handler' => $stack]);
}

protected function setupRoutes(): void
{
Route::get('test-middleware', function () {
Expand Down
Loading