Skip to content

Commit

Permalink
fix: request handler output buffer handling
Browse files Browse the repository at this point in the history
Previously, Acorn with the experimental request handler enabled broke WordPress static caching plugins like WP Rocket. This happened because the caching plugins work at a higher level than Acorn, but Acorn cleared all output buffers before the caching plugin could handle the contents.

Fixes #406
  • Loading branch information
RafaelKr committed Dec 16, 2024
1 parent 88096b5 commit 31d858d
Showing 1 changed file with 37 additions and 19 deletions.
56 changes: 37 additions & 19 deletions src/Roots/Acorn/Application/Concerns/Bootable.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,33 +143,37 @@ protected function enableHttpsInConsole(): void
*/
protected function registerWordPressRoute(): void
{
Route::any('{any?}', fn () => tap(response(''), function (Response $response) {
foreach (headers_list() as $header) {
[$header, $value] = preg_split("/:\s{0,1}/", $header, 2);
Route::any('{any?}', fn (Request $request) => tap(
response(''),
function (Response $response) use ($request) {
foreach (headers_list() as $header) {
[$header, $value] = preg_split("/:\s{0,1}/", $header, 2);

if (! headers_sent()) {
header_remove($header);
}
if (! headers_sent()) {
header_remove($header);
}

$response->header($header, $value, $header !== 'Set-Cookie');
}
$response->header($header, $value, $header !== 'Set-Cookie');
}

if ($this->hasDebugModeEnabled()) {
$response->header('X-Powered-By', $this->version());
}
if ($this->hasDebugModeEnabled()) {
$response->header('X-Powered-By', $this->version());
}

$response->setStatusCode(http_response_code());
$response->setStatusCode(http_response_code());

$content = '';
// get the output buffer content from our shutdown handler
$content = $request->request->get('wp_ob_content');

$levels = ob_get_level();
$levels = ob_get_level();

for ($i = 0; $i < $levels; $i++) {
$content .= ob_get_clean();
}
for ($i = 0; $i < $levels; $i++) {
$content .= ob_get_contents();
}

$response->setContent($content);
}))
$response->setContent($content);
})
)
->where('any', '.*')
->name('wordpress');
}
Expand Down Expand Up @@ -220,9 +224,23 @@ protected function registerRequestHandler(

$route->middleware('wordpress');

// We need to save our start level as there might be higher level output buffer handlers due to caching plugins.
$startLevel = ob_get_level();
ob_start();

remove_action('shutdown', 'wp_ob_end_flush_all', 1);
add_action('shutdown', function () use ($request, $startLevel) {
// Clean buffer only until our start level, keep possible higher level buffers to their handlers
$levels = ob_get_level() - $startLevel;
$content = '';

for ($i = 0; $i < $levels; $i++) {
$content .= ob_get_clean();
}

// Save content onto request to have it available in the Response handler
$request->request->set('wp_ob_content', $content);
}, 1);
add_action('shutdown', fn () => $this->handleRequest($request), 100);
}

Expand Down

0 comments on commit 31d858d

Please sign in to comment.