class BigPipeResponse

Same name in other branches
  1. 9 core/modules/big_pipe/src/Render/BigPipeResponse.php \Drupal\big_pipe\Render\BigPipeResponse
  2. 10 core/modules/big_pipe/src/Render/BigPipeResponse.php \Drupal\big_pipe\Render\BigPipeResponse
  3. 11.x core/modules/big_pipe/src/Render/BigPipeResponse.php \Drupal\big_pipe\Render\BigPipeResponse

A response that is sent in chunks by the BigPipe service.

Note we cannot use \Symfony\Component\HttpFoundation\StreamedResponse because it makes the content inaccessible (hidden behind a callback), which means no middlewares are able to modify the content anymore.

@internal This is a temporary solution until a generic response emitter interface is created in https://www.drupal.org/node/2577631. Only code internal to BigPipe should instantiate or type hint to this class.

Hierarchy

Expanded class hierarchy of BigPipeResponse

See also

\Drupal\big_pipe\Render\BigPipe

3 files declare their use of BigPipeResponse
BigPipeResponseAttachmentsProcessorTest.php in core/modules/big_pipe/tests/src/Unit/Render/BigPipeResponseAttachmentsProcessorTest.php
HtmlResponseBigPipeSubscriber.php in core/modules/big_pipe/src/EventSubscriber/HtmlResponseBigPipeSubscriber.php
ManyPlaceholderTest.php in core/modules/big_pipe/tests/src/Unit/Render/ManyPlaceholderTest.php

File

core/modules/big_pipe/src/Render/BigPipeResponse.php, line 21

Namespace

Drupal\big_pipe\Render
View source
class BigPipeResponse extends HtmlResponse {
    
    /**
     * The BigPipe service.
     *
     * @var \Drupal\big_pipe\Render\BigPipe
     */
    protected $bigPipe;
    
    /**
     * The original HTML response.
     *
     * Still contains placeholders. Its cacheability metadata and attachments are
     * for everything except the placeholders (since those are not yet rendered).
     *
     * @see \Drupal\Core\Render\StreamedResponseInterface
     * @see ::getStreamedResponse()
     *
     * @var \Drupal\Core\Render\HtmlResponse
     */
    protected $originalHtmlResponse;
    
    /**
     * Constructs a new BigPipeResponse.
     *
     * @param \Drupal\Core\Render\HtmlResponse $response
     *   The original HTML response.
     */
    public function __construct(HtmlResponse $response) {
        parent::__construct('', $response->getStatusCode(), []);
        $this->originalHtmlResponse = $response;
        $this->populateBasedOnOriginalHtmlResponse();
    }
    
    /**
     * Returns the original HTML response.
     *
     * @return \Drupal\Core\Render\HtmlResponse
     *   The original HTML response.
     */
    public function getOriginalHtmlResponse() {
        return $this->originalHtmlResponse;
    }
    
    /**
     * Populates this BigPipeResponse object based on the original HTML response.
     */
    protected function populateBasedOnOriginalHtmlResponse() {
        // Clone the HtmlResponse's data into the new BigPipeResponse.
        $this->headers = clone $this->originalHtmlResponse->headers;
        $this->setStatusCode($this->originalHtmlResponse
            ->getStatusCode())
            ->setContent($this->originalHtmlResponse
            ->getContent())
            ->setAttachments($this->originalHtmlResponse
            ->getAttachments())
            ->addCacheableDependency($this->originalHtmlResponse
            ->getCacheableMetadata());
        // A BigPipe response can never be cached, because it is intended for a
        // single user.
        // @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
        $this->setPrivate();
        // Inform surrogates how they should handle BigPipe responses:
        // - "no-store" specifies that the response should not be stored in cache;
        //   it is only to be used for the original request
        // - "content" identifies what processing surrogates should perform on the
        //   response before forwarding it. We send, "BigPipe/1.0", which surrogates
        //   should not process at all, and in fact, they should not even buffer it
        //   at all.
        // @see http://www.w3.org/TR/edge-arch/
        $this->headers
            ->set('Surrogate-Control', 'no-store, content="BigPipe/1.0"');
        // Add header to support streaming on NGINX + php-fpm (nginx >= 1.5.6).
        $this->headers
            ->set('X-Accel-Buffering', 'no');
    }
    
    /**
     * Sets the BigPipe service to use.
     *
     * @param \Drupal\big_pipe\Render\BigPipe $big_pipe
     *   The BigPipe service.
     */
    public function setBigPipeService(BigPipe $big_pipe) {
        $this->bigPipe = $big_pipe;
    }
    
    /**
     * {@inheritdoc}
     */
    public function sendContent() {
        $this->bigPipe
            ->sendContent($this);
        // All BigPipe placeholders are processed, so update this response's
        // attachments.
        unset($this->attachments['big_pipe_placeholders']);
        unset($this->attachments['big_pipe_nojs_placeholders']);
        return $this;
    }

}

Members

Title Sort descending Modifiers Object type Summary
AttachmentsTrait::$attachments protected property The attachments for this response.
AttachmentsTrait::addAttachments public function
AttachmentsTrait::getAttachments public function
AttachmentsTrait::setAttachments public function
BigPipeResponse::$bigPipe protected property The BigPipe service.
BigPipeResponse::$originalHtmlResponse protected property The original HTML response.
BigPipeResponse::getOriginalHtmlResponse public function Returns the original HTML response.
BigPipeResponse::populateBasedOnOriginalHtmlResponse protected function Populates this BigPipeResponse object based on the original HTML response.
BigPipeResponse::sendContent public function
BigPipeResponse::setBigPipeService public function Sets the BigPipe service to use.
BigPipeResponse::__construct public function Constructs a new BigPipeResponse.
CacheableResponseTrait::$cacheabilityMetadata protected property The cacheability metadata.
CacheableResponseTrait::addCacheableDependency public function
CacheableResponseTrait::getCacheableMetadata public function
HtmlResponse::setContent public function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.