-
-
Notifications
You must be signed in to change notification settings - Fork 95
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
Experimental Request Handler breaks WP Rocket #406
Comments
I created a patch which at least works with WP Rocket. I'll post it with some info later this week. |
The problem I identified was that the code is running in the following order:
I now modified the the previous steps as follows: The code diff below is based on Acorn 4.3.0. The comments starting with diff --git a/src/Roots/Acorn/Bootloader.php b/src/Roots/Acorn/Bootloader.php
index de0a3ca..ffdcbe4 100644
--- a/src/Roots/Acorn/Bootloader.php
+++ b/src/Roots/Acorn/Bootloader.php
@@ -3,6 +3,7 @@
namespace Roots\Acorn;
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
+use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Env;
use Illuminate\Support\Facades\Facade;
@@ -203,7 +204,7 @@ class Bootloader
protected function registerDefaultRoute(): void
{
$this->app->make('router')
- ->any('{any?}', fn () => tap(response(''), function (Response $response) {
+ // [5] Pass in request
+ ->any('{any?}', fn (Request $request) => tap(response(''), function (Response $response) use ($request) {
foreach (headers_list() as $header) {
[$header, $value] = explode(': ', $header, 2);
@@ -218,12 +219,12 @@ class Bootloader
$response->header('X-Powered-By', $this->app->version());
}
- $content = '';
+ // [5] Get content attached to the request
+ $content = $request->request->get('wp_ob_content');
$levels = ob_get_level();
for ($i = 0; $i < $levels; $i++) {
- $content .= ob_get_clean();
+ // [5] Don't clean the output_buffer
+ $content .= ob_get_contents();
}
$response->setContent($content);
@@ -286,9 +288,20 @@ class Bootloader
$route->middleware($isApi ? $config['api'] : $config['web']);
+ // [2] Save ob starting level
+ $startLevel = ob_get_level();
ob_start();
remove_action('shutdown', 'wp_ob_end_flush_all', 1);
+ // [3] Add shutdown handler to end output buffering with the same priority as default WordPress does it
+ add_action('shutdown', function () use ($request, $startLevel) {
+ // [4] Clean buffer only until start level
+ $levels = ob_get_level() - $startLevel;
+ $content = '';
+
+ for ( $i = 0; $i < $levels; $i++ ) {
+ $content .= ob_get_clean();
+ }
+
+ // [4] Save content onto request to have it available in [5]
+ $request->request->set('wp_ob_content', $content);
+ }, 1);
add_action('shutdown', fn () => $this->handleRequest($kernel, $request), 100);
}
This change works for WP Rocket and should also work for all other plugins which have an "outer" output buffer (a buffer started before Acorn). At least when the outer buffer is handled after a I'm not 100% sure if this change could lead to duplicated output. But I wouldn't expect that as original WordPress already flushes the buffer at |
Care to get a PR up for testing? |
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 roots#406
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 roots#406
Version
4.3.0
What did you expect to happen?
In a Radicle project we have the experimental Request handler enabled via
ACORN_ENABLE_EXPERIMENTAL_WORDPRESS_REQUEST_HANDLER=true
.We now installed WP Rocket (Previously we had WP Optimize where it also didn't work).
It should create static html files inside
public/content/cache/wp-rocket/example.com
What actually happens?
It only creates those static html files when the experimental request handler is disabled.
It's related to output buffering. WP Rocket receives an empty output buffer at https://github.com/wp-media/wp-rocket/blob/09708aa55d362a9535ad4d45cb68280325efaecb/inc/classes/Buffer/class-cache.php#L259
The order of calls is:
maybe_init_process
callsob_start( [ $this, 'maybe_process_buffer' ] );
maybe_process_buffer
is called with an empty string https://github.com/wp-media/wp-rocket/blob/09708aa55d362a9535ad4d45cb68280325efaecb/inc/classes/Buffer/class-cache.php#L256When we disable the experimental request handler the buffer contains the correct content and the static file is generated.
Steps to reproduce
ACORN_ENABLE_EXPERIMENTAL_WORDPRESS_REQUEST_HANDLER=true
to.env
composer install wp-media/wp-rocket
define( 'WP_CACHE', true ); // Added by WP Rocket
to wp-config.php, but that should be fine for testing. Can be disabled via https://docs.wp-rocket.me/article/958-how-to-use-wp-rocket-with-bedrock-wordpress-boilerplate)public/content/cache/wp-rocket/your-domain.localhost
(or the wp-content path which is configured without Radicle)ACORN_ENABLE_EXPERIMENTAL_WORDPRESS_REQUEST_HANDLER=true
from.env
System info
No response
Log output
No response
Please confirm this isn't a support request.
Yes
The text was updated successfully, but these errors were encountered: