Mercurial > hg > cmmr2012-drupal-site
diff core/modules/big_pipe/src/Render/BigPipeResponse.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/big_pipe/src/Render/BigPipeResponse.php Thu Jul 05 14:24:15 2018 +0000 @@ -0,0 +1,122 @@ +<?php + +namespace Drupal\big_pipe\Render; + +use Drupal\Core\Render\HtmlResponse; + +/** + * 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. + * + * @see \Drupal\big_pipe\Render\BigPipe + * + * @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. + */ +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; + } + +}