Security update for Core, with self-updated composer
[yaffs-website] / vendor / zendframework / zend-diactoros / src / Response / SapiEmitterTrait.php
index bbfecfce2454f670fa2ad838570ddb49110b4473..ce9612c823152270658e0bd087bc308afb35bd13 100644 (file)
@@ -1,35 +1,35 @@
 <?php
 /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @see       http://github.com/zendframework/zend-diactoros for the canonical source repository
- * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com)
+ * @see       https://github.com/zendframework/zend-diactoros for the canonical source repository
+ * @copyright Copyright (c) 2015-2017 Zend Technologies USA Inc. (http://www.zend.com)
  * @license   https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
  */
 
 namespace Zend\Diactoros\Response;
 
 use Psr\Http\Message\ResponseInterface;
+use RuntimeException;
 
 trait SapiEmitterTrait
 {
     /**
-     * Inject the Content-Length header if is not already present.
+     * Checks to see if content has previously been sent.
      *
-     * @param ResponseInterface $response
-     * @return ResponseInterface
+     * If either headers have been sent or the output buffer contains content,
+     * raises an exception.
+     *
+     * @throws RuntimeException if headers have already been sent.
+     * @throws RuntimeException if output is present in the output buffer.
      */
-    private function injectContentLength(ResponseInterface $response)
+    private function assertNoPreviousOutput()
     {
-        if (! $response->hasHeader('Content-Length')) {
-            // PSR-7 indicates int OR null for the stream size; for null values,
-            // we will not auto-inject the Content-Length.
-            if (null !== $response->getBody()->getSize()) {
-                return $response->withHeader('Content-Length', (string) $response->getBody()->getSize());
-            }
+        if (headers_sent()) {
+            throw new RuntimeException('Unable to emit response; headers already sent');
         }
 
-        return $response;
+        if (ob_get_level() > 0 && ob_get_length() > 0) {
+            throw new RuntimeException('Output has been emitted previously; cannot emit response');
+        }
     }
 
     /**
@@ -38,17 +38,25 @@ trait SapiEmitterTrait
      * Emits the status line using the protocol version and status code from
      * the response; if a reason phrase is available, it, too, is emitted.
      *
+     * It is important to mention that this method should be called after
+     * `emitHeaders()` in order to prevent PHP from changing the status code of
+     * the emitted response.
+     *
      * @param ResponseInterface $response
+     *
+     * @see \Zend\Diactoros\Response\SapiEmitterTrait::emitHeaders()
      */
     private function emitStatusLine(ResponseInterface $response)
     {
         $reasonPhrase = $response->getReasonPhrase();
+        $statusCode   = $response->getStatusCode();
+
         header(sprintf(
             'HTTP/%s %d%s',
             $response->getProtocolVersion(),
-            $response->getStatusCode(),
+            $statusCode,
             ($reasonPhrase ? ' ' . $reasonPhrase : '')
-        ));
+        ), true, $statusCode);
     }
 
     /**
@@ -63,37 +71,22 @@ trait SapiEmitterTrait
      */
     private function emitHeaders(ResponseInterface $response)
     {
+        $statusCode = $response->getStatusCode();
+
         foreach ($response->getHeaders() as $header => $values) {
             $name  = $this->filterHeader($header);
-            $first = true;
+            $first = $name === 'Set-Cookie' ? false : true;
             foreach ($values as $value) {
                 header(sprintf(
                     '%s: %s',
                     $name,
                     $value
-                ), $first);
+                ), $first, $statusCode);
                 $first = false;
             }
         }
     }
 
-    /**
-     * Loops through the output buffer, flushing each, before emitting
-     * the response.
-     *
-     * @param int|null $maxBufferLevel Flush up to this buffer level.
-     */
-    private function flush($maxBufferLevel = null)
-    {
-        if (null === $maxBufferLevel) {
-            $maxBufferLevel = ob_get_level();
-        }
-
-        while (ob_get_level() > $maxBufferLevel) {
-            ob_end_flush();
-        }
-    }
-
     /**
      * Filter a header name to wordcase
      *