Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/cakephp/cakephp/src/Http/ResponseTransformer.php
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         3.3.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Cake\Http;

use
Cake\Http\Response as CakeResponse;
use
Psr\Http\Message\ResponseInterface as PsrResponse;
use
Zend\Diactoros\Response as DiactorosResponse;
use
Zend\Diactoros\Stream;

/**
 * This class converts PSR7 responses into CakePHP ones and back again.
 *
 * By bridging the CakePHP and PSR7 responses together, applications
 * can be embedded as PSR7 middleware in a fully compatible way.
 *
 * @internal
 * @deprecated 3.4.0 No longer used. Will be removed in 4.0.0
 */
class ResponseTransformer
{
   
/**
     * Convert a PSR7 Response into a CakePHP one.
     *
     * @param \Psr\Http\Message\ResponseInterface $response The response to convert.
     * @return \Cake\Http\Response The equivalent CakePHP response
     */
   
public static function toCake(PsrResponse $response)
    {
       
$body = static::getBody($response);
       
$data = [
           
'status' => $response->getStatusCode(),
           
'body' => $body['body'],
        ];
       
$cake = new CakeResponse($data);
        if (
$body['file']) {
           
$cake->file($body['file']);
        }
       
$cookies = static::parseCookies($response->getHeader('Set-Cookie'));
        foreach (
$cookies as $cookie) {
           
$cake->cookie($cookie);
        }
       
$headers = static::collapseHeaders($response);
       
$cake->header($headers);

        if (!empty(
$headers['Content-Type'])) {
           
$cake->type($headers['Content-Type']);
        }

        return
$cake;
    }

   
/**
     * Get the response body from a PSR7 Response.
     *
     * @param \Psr\Http\Message\ResponseInterface $response The response to convert.
     * @return array A hash of 'body' and 'file'
     */
   
protected static function getBody(PsrResponse $response)
    {
       
$stream = $response->getBody();
        if (
$stream->getMetadata('wrapper_type') === 'plainfile') {
            return [
'body' => '', 'file' => $stream->getMetadata('uri')];
        }
        if (
$stream->getSize() === 0) {
            return [
'body' => '', 'file' => false];
        }
       
$stream->rewind();

        return [
'body' => $stream->getContents(), 'file' => false];
    }

   
/**
     * Parse the Set-Cookie headers in a PSR7 response
     * into the format CakePHP expects.
     *
     * @param array $cookieHeader A list of Set-Cookie headers.
     * @return array Parsed cookie data.
     */
   
protected static function parseCookies(array $cookieHeader)
    {
       
$cookies = [];
        foreach (
$cookieHeader as $cookie) {
            if (
strpos($cookie, '";"') !== false) {
               
$cookie = str_replace('";"', '{__cookie_replace__}', $cookie);
               
$parts = preg_split('/\;[ \t]*/', $cookie);
               
$parts = str_replace('{__cookie_replace__}', '";"', $parts);
            } else {
               
$parts = preg_split('/\;[ \t]*/', $cookie);
            }

            list(
$name, $value) = explode('=', array_shift($parts), 2);
           
$parsed = ['name' => $name, 'value' => urldecode($value)];

            foreach (
$parts as $part) {
                if (
strpos($part, '=') !== false) {
                    list(
$key, $value) = explode('=', $part);
                } else {
                   
$key = $part;
                   
$value = true;
                }

               
$key = strtolower($key);
                if (
$key === 'httponly') {
                   
$key = 'httpOnly';
                }
                if (
$key === 'expires') {
                   
$key = 'expire';
                   
$value = strtotime($value);
                }
                if (!isset(
$parsed[$key])) {
                   
$parsed[$key] = $value;
                }
            }
           
$cookies[] = $parsed;
        }

        return
$cookies;
    }

   
/**
     * Convert a PSR7 Response headers into a flat array
     *
     * @param \Psr\Http\Message\ResponseInterface $response The response to convert.
     * @return array Headers.
     */
   
protected static function collapseHeaders(PsrResponse $response)
    {
       
$out = [];
        foreach (
$response->getHeaders() as $name => $value) {
            if (
count($value) === 1) {
               
$out[$name] = $value[0];
            } else {
               
$out[$name] = $value;
            }
        }

        return
$out;
    }

   
/**
     * Convert a CakePHP response into a PSR7 one.
     *
     * @param \Cake\Http\Response $response The CakePHP response to convert
     * @return \Psr\Http\Message\ResponseInterface $response The equivalent PSR7 response.
     */
   
public static function toPsr(CakeResponse $response)
    {
       
$status = $response->statusCode();
       
$headers = $response->header();
        if (!isset(
$headers['Content-Type'])) {
           
$headers = static::setContentType($headers, $response);
        }
       
$cookies = $response->cookie();
        if (
$cookies) {
           
$headers['Set-Cookie'] = static::buildCookieHeader($cookies);
        }
       
$stream = static::getStream($response);

        return new
DiactorosResponse($stream, $status, $headers);
    }

   
/**
     * Add in the Content-Type header if necessary.
     *
     * @param array $headers The headers to update
     * @param \Cake\Http\Response $response The CakePHP response to convert
     * @return array The updated headers.
     */
   
protected static function setContentType($headers, $response)
    {
        if (isset(
$headers['Content-Type'])) {
            return
$headers;
        }
        if (
in_array($response->statusCode(), [204, 304])) {
            return
$headers;
        }

       
$whitelist = [
           
'application/javascript', 'application/json', 'application/xml', 'application/rss+xml',
        ];

       
$type = $response->type();
       
$charset = $response->charset();

       
$hasCharset = false;
        if (
$charset && (strpos($type, 'text/') === 0 || in_array($type, $whitelist))) {
           
$hasCharset = true;
        }

       
$value = $type;
        if (
$hasCharset) {
           
$value = "{$type}; charset={$charset}";
        }
       
$headers['Content-Type'] = $value;

        return
$headers;
    }

   
/**
     * Convert an array of cookies into header lines.
     *
     * @param array $cookies The cookies to serialize.
     * @return array A list of cookie header values.
     */
   
protected static function buildCookieHeader($cookies)
    {
       
$headers = [];
        foreach (
$cookies as $cookie) {
           
$parts = [
               
sprintf('%s=%s', urlencode($cookie['name']), urlencode($cookie['value'])),
            ];
            if (
$cookie['expire']) {
               
$cookie['expire'] = gmdate('D, d M Y H:i:s T', $cookie['expire']);
            }
           
$attributes = [
               
'expire' => 'Expires=%s',
               
'path' => 'Path=%s',
               
'domain' => 'Domain=%s',
               
'httpOnly' => 'HttpOnly',
               
'secure' => 'Secure',
            ];
            foreach (
$attributes as $key => $attr) {
                if (
$cookie[$key]) {
                   
$parts[] = sprintf($attr, $cookie[$key]);
                }
            }
           
$headers[] = implode('; ', $parts);
        }

        return
$headers;
    }

   
/**
     * Get the stream for the new response.
     *
     * @param \Cake\Http\Response $response The cake response to extract the body from.
     * @return \Psr\Http\Message\StreamInterface|string The stream.
     */
   
protected static function getStream($response)
    {
       
$stream = 'php://memory';
       
$body = $response->body();
        if (
is_string($body) && strlen($body)) {
           
$stream = new Stream('php://memory', 'wb');
           
$stream->write($body);

            return
$stream;
        }
        if (
is_callable($body)) {
           
$stream = new CallbackStream($body);

            return
$stream;
        }
       
$file = $response->getFile();
        if (
$file) {
           
$stream = new Stream($file->path, 'rb');

            return
$stream;
        }

        return
$stream;
    }
}