Magento2 change response before full page cache

So, finally I have a real solution. So I was able to track down Magento2 full page cache and turned out that it does the caching as a plugin: Magento\PageCache\Model\App\FrontController\BuiltinPlugin in the aroundDispatch.

$this->kernel->process($result);

Does the work of storing the serialized $response object.

So the solution was to create a plugin for the after event:

Roland/HelloWorld/etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Controller\ResultInterface">
        <plugin name="change-result-before-cache" type="Roland\HelloWorld\Model\Plugins\ChangeResult"/>
    </type>
</config>

Roland/HelloWorld/Model/Plugins/ChangeResult.php

<?php

namespace Roland\HelloWorld\Model\Plugins;

use Magento\Framework\App\Response\Http as ResponseHttp;


class ChangeResult {

    public function afterRenderResult(ResponseHttp $response) {
        $response->setBody(preg_replace('/<\/head>/', '<script>alert("' . time() . '");</script>' . '</head>', $response->getBody(), 1));
    }

}

The result

When page cache enabled, you should always see the same timestamp for every refresh.

Related docs

How Magento2 plugins work - Alan Storm Magento 2 Full page caching - Alan Storm