├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json └── src ├── Psr7Response.php ├── Psr7ServerRequest.php └── Zend └── Request.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file, in reverse chronological order by release. 4 | 5 | ## 1.2.1 - TBD 6 | 7 | ### Added 8 | 9 | - Nothing. 10 | 11 | ### Changed 12 | 13 | - Nothing. 14 | 15 | ### Deprecated 16 | 17 | - Nothing. 18 | 19 | ### Removed 20 | 21 | - Nothing. 22 | 23 | ### Fixed 24 | 25 | - Nothing. 26 | 27 | ## 1.2.0 - 2018-12-20 28 | 29 | ### Added 30 | 31 | - [#41](https://github.com/zendframework/zend-psr7bridge/pull/41) adds support for PHP 7.3. 32 | 33 | ### Changed 34 | 35 | - Nothing. 36 | 37 | ### Deprecated 38 | 39 | - Nothing. 40 | 41 | ### Removed 42 | 43 | - [#41](https://github.com/zendframework/zend-psr7bridge/pull/41) removes support for zend-stdlib v2 releases. 44 | 45 | ### Fixed 46 | 47 | - Nothing. 48 | 49 | ## 1.1.1 - 2018-12-20 50 | 51 | ### Added 52 | 53 | - Nothing. 54 | 55 | ### Changed 56 | 57 | - Nothing. 58 | 59 | ### Deprecated 60 | 61 | - Nothing. 62 | 63 | ### Removed 64 | 65 | - Nothing. 66 | 67 | ### Fixed 68 | 69 | - [#40](https://github.com/zendframework/zend-psr7bridge/pull/40) fixes how headers are translated from PSR-7 to zend-http. Previously, they 70 | were always cast to `GenericHeader` instances; now, the bridge uses `Psr7Response::psr7HeadersToString` 71 | to pass them to `Zend\Http\Headers::fromString()`, ensuring that the more 72 | specific zend-http `HeaderInterface` instance types are created. 73 | 74 | ## 1.1.0 - 2018-09-27 75 | 76 | ### Added 77 | 78 | - Nothing. 79 | 80 | ### Changed 81 | 82 | - [#38](https://github.com/zendframework/zend-psr7bridge/pull/38) updates the zendframework/zend-diactoros constraint to allow either the 83 | 1.Y or 2.Y series, as they are compatible for the purposes of this package. 84 | 85 | ### Deprecated 86 | 87 | - Nothing. 88 | 89 | ### Removed 90 | 91 | - Nothing. 92 | 93 | ### Fixed 94 | 95 | - Nothing. 96 | 97 | ## 1.0.2 - 2018-02-14 98 | 99 | ### Added 100 | 101 | - Nothing. 102 | 103 | ### Changed 104 | 105 | - Nothing. 106 | 107 | ### Deprecated 108 | 109 | - Nothing. 110 | 111 | ### Removed 112 | 113 | - Nothing. 114 | 115 | ### Fixed 116 | 117 | - [#35](https://github.com/zendframework/zend-psr7bridge/pull/35) fixes the 118 | Response from a PSR-7 Stream object with php://memory stream 119 | 120 | ## 1.0.1 - 2017-12-18 121 | 122 | ### Added 123 | 124 | - Nothing. 125 | 126 | ### Changed 127 | 128 | - Nothing. 129 | 130 | ### Deprecated 131 | 132 | - Nothing. 133 | 134 | ### Removed 135 | 136 | - Nothing. 137 | 138 | ### Fixed 139 | 140 | - [#23](https://github.com/zendframework/zend-psr7bridge/pull/23) fixed the 141 | upload of a file when error is not UPLOAD_ERR_OK 142 | - [#26](https://github.com/zendframework/zend-psr7bridge/pull/26) fixes the 143 | Stream response from a PSR-7 Stream object 144 | - [#28](https://github.com/zendframework/zend-psr7bridge/pull/28) fixes the 145 | baseUrl from a PSR-7 Server request 146 | 147 | ## 1.0.0 - 2017-08-02 148 | 149 | ### Added 150 | 151 | - [#19](https://github.com/zendframework/zend-psr7bridge/pull/19) adds support 152 | for PHP 7.1. 153 | 154 | - [#19](https://github.com/zendframework/zend-psr7bridge/pull/19) adds support 155 | for PHP 7.2. 156 | 157 | ### Changed 158 | 159 | - [#15](https://github.com/zendframework/zend-psr7bridge/pull/15) updates the 160 | behavior of `Psr7ServerRequest::fromZend()` to check if the request is a 161 | `Zend\Http\PhpEnvironment\Request` and, if so, use the return value of its 162 | `getServer()` method to seed the PSR-7 request's server parameters. 163 | 164 | ### Deprecated 165 | 166 | - Nothing. 167 | 168 | ### Removed 169 | 170 | - [#19](https://github.com/zendframework/zend-psr7bridge/pull/19) removes 171 | support for PHP 5.5. 172 | 173 | - [#19](https://github.com/zendframework/zend-psr7bridge/pull/19) removes 174 | support for HHVM. 175 | 176 | ### Fixed 177 | 178 | - Nothing. 179 | 180 | ## 0.2.2 - 2016-05-10 181 | 182 | ### Added 183 | 184 | - [#8](https://github.com/zendframework/zend-psr7bridge/pull/8) adds and 185 | publishes the documentation to https://zendframework.github.io/zend-psr7bridge/ 186 | 187 | ### Deprecated 188 | 189 | - Nothing. 190 | 191 | ### Removed 192 | 193 | - Nothing. 194 | 195 | ### Fixed 196 | 197 | - [#7](https://github.com/zendframework/zend-psr7bridge/pull/7) fixes 198 | the logic in `Psr7ServerRequest::convertUploadedFiles()` to ensure that the 199 | `tmp_name` is provided to the `$_FILES` structure from the PSR-7 uploaded 200 | files. 201 | - [#7](https://github.com/zendframework/zend-psr7bridge/pull/7) fixes 202 | the logic in `Psr7ServerRequest::convertFilesToUploaded()` to iterate the 203 | entire value provided it, instead of a fictitious `file` key. 204 | 205 | ## 0.2.1 - 2015-12-15 206 | 207 | ### Added 208 | 209 | - Nothing. 210 | 211 | ### Deprecated 212 | 213 | - Nothing. 214 | 215 | ### Removed 216 | 217 | - Nothing. 218 | 219 | ### Fixed 220 | 221 | - [#5](https://github.com/zendframework/zend-psr7bridge/pull/5) Updates 222 | `Psr7ServerRequest::fromZend()` to inject the generated PSR-7 request 223 | instance with the zend-http cookies. 224 | 225 | ## 0.2.0 - 2015-09-28 226 | 227 | ### Added 228 | 229 | - [#3](https://github.com/zendframework/zend-psr7bridge/pull/3) Adds support for 230 | zend-http -> PSR-7 request tanslation. 231 | - [#3](https://github.com/zendframework/zend-psr7bridge/pull/3) Adds support for 232 | PSR-7 <-> zend-http response tanslation. 233 | 234 | ### Deprecated 235 | 236 | - Nothing. 237 | 238 | ### Removed 239 | 240 | - Nothing. 241 | 242 | ### Fixed 243 | 244 | - Nothing. 245 | 246 | ## 0.1.1 - 2015-08-18 247 | 248 | ### Added 249 | 250 | - Nothing. 251 | 252 | ### Deprecated 253 | 254 | - Nothing. 255 | 256 | ### Removed 257 | 258 | - Nothing. 259 | 260 | ### Fixed 261 | 262 | - [#2](https://github.com/zendframework/zend-psr7bridge/pull/2) updates 263 | `Zend\Psr7Bridge\Zend\Request`'s constructor to call `setUri()` instead of 264 | `setRequestUri()`. 265 | 266 | ## 0.1.0 - 2015-08-06 267 | 268 | Initial release! 269 | 270 | ### Added 271 | 272 | - `Zend\Psr7Bridge\Psr7ServerRequest::toZend($request, $shallow = false)` allows 273 | converting a `Psr\Http\Message\ServerRequestInterface` to a 274 | `Zend\Http\PhpEnvironment\Request` instance. The `$shallow` flag, when 275 | enabled, will omit the body content, body parameters, and upload files from 276 | the zend-http request (e.g., for routing purposes). 277 | 278 | ### Deprecated 279 | 280 | - Nothing. 281 | 282 | ### Removed 283 | 284 | - Nothing. 285 | 286 | ### Fixed 287 | 288 | - Nothing. 289 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005-2017, Zend Technologies USA, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | - Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | - Neither the name of Zend Technologies USA, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zend-psr7bridge 2 | 3 | > ## Repository abandoned 2019-12-31 4 | > 5 | > This repository has moved to [laminas/laminas-psr7bridge](https://github.com/laminas/laminas-psr7bridge). 6 | 7 | [![Build Status](https://secure.travis-ci.org/zendframework/zend-psr7bridge.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-psr7bridge) 8 | [![Coverage Status](https://coveralls.io/repos/github/zendframework/zend-psr7bridge/badge.svg?branch=master)](https://coveralls.io/github/zendframework/zend-psr7bridge?branch=master) 9 | 10 | Code for converting [PSR-7](http://www.php-fig.org/psr/psr-7/) messages to 11 | [zend-http](https://docs.zendframework.com/zend-http) messages, and vice 12 | versa. 13 | 14 | - Issues: https://github.com/zendframework/zend-psr7bridge/issues 15 | - Documentation: https://docs.zendframework.com/zend-psr7bridge/ 16 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zendframework/zend-psr7bridge", 3 | "description": "PSR-7 <-> zend-http message conversions", 4 | "license": "BSD-3-Clause", 5 | "keywords": [ 6 | "zf", 7 | "http", 8 | "psr", 9 | "psr-7", 10 | "zend", 11 | "zendframework" 12 | ], 13 | "support": { 14 | "docs": "https://docs.zendframework.com/zend-psr7bridge/", 15 | "issues": "https://github.com/zendframework/zend-psr7bridge/issues", 16 | "source": "https://github.com/zendframework/zend-psr7bridge", 17 | "rss": "https://github.com/zendframework/zend-psr7bridge/releases.atom", 18 | "slack": "https://zendframework-slack.herokuapp.com", 19 | "forum": "https://discourse.zendframework.com/c/questions/components" 20 | }, 21 | "require": { 22 | "php": "^5.6 || ^7.0", 23 | "psr/http-message": "^1.0", 24 | "zendframework/zend-diactoros": "^1.7 || ^2.0", 25 | "zendframework/zend-http": "^2.7" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^5.7.15 || ^6.5.6", 29 | "zendframework/zend-coding-standard": "~1.0.0" 30 | }, 31 | "conflict": { 32 | "zendframework/zend-stdlib": "< 3.2.1" 33 | }, 34 | "autoload": { 35 | "psr-4": { 36 | "Zend\\Psr7Bridge\\": "src/" 37 | } 38 | }, 39 | "autoload-dev": { 40 | "psr-4": { 41 | "ZendTest\\Psr7Bridge\\": "test/" 42 | } 43 | }, 44 | "config": { 45 | "sort-packages": true 46 | }, 47 | "extra": { 48 | "branch-alias": { 49 | "dev-master": "1.2.x-dev", 50 | "dev-develop": "1.3.x-dev" 51 | } 52 | }, 53 | "scripts": { 54 | "check": [ 55 | "@cs-check", 56 | "@test" 57 | ], 58 | "cs-check": "phpcs", 59 | "cs-fix": "phpcbf", 60 | "test": "phpunit --colors=always", 61 | "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Psr7Response.php: -------------------------------------------------------------------------------- 1 | getBody()->getMetadata('uri'); 34 | 35 | if ($uri === static::URI_TEMP || $uri === static::URI_MEMORY) { 36 | $response = sprintf( 37 | "HTTP/%s %d %s\r\n%s\r\n%s", 38 | $psr7Response->getProtocolVersion(), 39 | $psr7Response->getStatusCode(), 40 | $psr7Response->getReasonPhrase(), 41 | self::psr7HeadersToString($psr7Response), 42 | (string)$psr7Response->getBody() 43 | ); 44 | 45 | return ZendResponse::fromString($response); 46 | } 47 | 48 | $response = new ZendResponse\Stream(); 49 | $zendHeaders = Headers::fromString(self::psr7HeadersToString($psr7Response)); 50 | $response->setStatusCode($psr7Response->getStatusCode()); 51 | $response->setHeaders($zendHeaders); 52 | $response->setStream(fopen($uri, 'rb')); 53 | 54 | return $response; 55 | } 56 | 57 | /** 58 | * Convert a Zend\Http\Response in a PSR-7 response, using zend-diactoros 59 | * 60 | * @param ZendResponse $zendResponse 61 | * 62 | * @return Response 63 | */ 64 | public static function fromZend(ZendResponse $zendResponse) 65 | { 66 | $body = new Stream('php://temp', 'wb+'); 67 | $body->write($zendResponse->getBody()); 68 | 69 | return new Response( 70 | $body, 71 | $zendResponse->getStatusCode(), 72 | $zendResponse->getHeaders()->toArray() 73 | ); 74 | } 75 | 76 | /** 77 | * Convert the PSR-7 headers to string 78 | * 79 | * @param ResponseInterface $psr7Response 80 | * 81 | * @return string 82 | */ 83 | private static function psr7HeadersToString(ResponseInterface $psr7Response) 84 | { 85 | $headers = ''; 86 | foreach ($psr7Response->getHeaders() as $name => $value) { 87 | $headers .= $name . ": " . implode(", ", $value) . "\r\n"; 88 | } 89 | 90 | return $headers; 91 | } 92 | 93 | /** 94 | * Do not allow instantiation. 95 | */ 96 | private function __construct() 97 | { 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Psr7ServerRequest.php: -------------------------------------------------------------------------------- 1 | getMethod(), 35 | $psr7Request->getUri(), 36 | $psr7Request->getHeaders(), 37 | $psr7Request->getCookieParams(), 38 | $psr7Request->getQueryParams(), 39 | [], 40 | [], 41 | $psr7Request->getServerParams() 42 | ); 43 | } 44 | 45 | $zendRequest = new Zend\Request( 46 | $psr7Request->getMethod(), 47 | $psr7Request->getUri(), 48 | $psr7Request->getHeaders(), 49 | $psr7Request->getCookieParams(), 50 | $psr7Request->getQueryParams(), 51 | $psr7Request->getParsedBody() ?: [], 52 | self::convertUploadedFiles($psr7Request->getUploadedFiles()), 53 | $psr7Request->getServerParams() 54 | ); 55 | $zendRequest->setContent($psr7Request->getBody()); 56 | 57 | return $zendRequest; 58 | } 59 | 60 | /** 61 | * Convert a Zend\Http\Response in a PSR-7 response, using zend-diactoros 62 | * 63 | * @param ZendRequest $zendRequest 64 | * @return ServerRequest 65 | */ 66 | public static function fromZend(ZendRequest $zendRequest) 67 | { 68 | $body = new Stream('php://memory', 'wb+'); 69 | $body->write($zendRequest->getContent()); 70 | 71 | $headers = empty($zendRequest->getHeaders()) ? [] : $zendRequest->getHeaders()->toArray(); 72 | $query = empty($zendRequest->getQuery()) ? [] : $zendRequest->getQuery()->toArray(); 73 | $post = empty($zendRequest->getPost()) ? [] : $zendRequest->getPost()->toArray(); 74 | $files = empty($zendRequest->getFiles()) ? [] : $zendRequest->getFiles()->toArray(); 75 | 76 | $request = new ServerRequest( 77 | $zendRequest instanceof ZendPhpEnvironmentRequest ? iterator_to_array($zendRequest->getServer()) : [], 78 | self::convertFilesToUploaded($files), 79 | $zendRequest->getUriString(), 80 | $zendRequest->getMethod(), 81 | $body, 82 | $headers 83 | ); 84 | $request = $request->withQueryParams($query); 85 | 86 | $cookie = $zendRequest->getCookie(); 87 | if (false !== $cookie) { 88 | $request = $request->withCookieParams($cookie->getArrayCopy()); 89 | } 90 | 91 | return $request->withParsedBody($post); 92 | } 93 | 94 | /** 95 | * Convert a PSR-7 uploaded files structure to a $_FILES structure 96 | * 97 | * @param \Psr\Http\Message\UploadedFileInterface[] 98 | * @return array 99 | */ 100 | private static function convertUploadedFiles(array $uploadedFiles) 101 | { 102 | $files = []; 103 | foreach ($uploadedFiles as $name => $upload) { 104 | if (is_array($upload)) { 105 | $files[$name] = self::convertUploadedFiles($upload); 106 | continue; 107 | } 108 | 109 | $uploadError = $upload->getError(); 110 | $isUploadError = $uploadError !== UPLOAD_ERR_OK; 111 | 112 | $files[$name] = [ 113 | 'name' => $upload->getClientFilename(), 114 | 'type' => $upload->getClientMediaType(), 115 | 'size' => $upload->getSize(), 116 | 'tmp_name' => ! $isUploadError ? $upload->getStream()->getMetadata('uri') : '', 117 | 'error' => $uploadError, 118 | ]; 119 | } 120 | return $files; 121 | } 122 | 123 | /** 124 | * Convert a Zend\Http file structure to PSR-7 uploaded files 125 | * 126 | * @param array 127 | * @return UploadedFile[] 128 | */ 129 | private static function convertFilesToUploaded(array $files) 130 | { 131 | $uploadedFiles = []; 132 | foreach ($files as $name => $value) { 133 | if (is_array($value)) { 134 | $uploadedFiles[$name] = self::convertFilesToUploaded($value); 135 | continue; 136 | } 137 | return new UploadedFile( 138 | $files['tmp_name'], 139 | $files['size'], 140 | $files['error'], 141 | $files['name'], 142 | $files['type'] 143 | ); 144 | } 145 | return $uploadedFiles; 146 | } 147 | 148 | /** 149 | * Do not allow instantiation. 150 | */ 151 | private function __construct() 152 | { 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/Zend/Request.php: -------------------------------------------------------------------------------- 1 | setAllowCustomMethods(true); 45 | 46 | $this->setMethod($method); 47 | // Remove the "http(s)://hostname" part from the URI 48 | $this->setRequestUri(preg_replace('#^[^/:]+://[^/]+#', '', (string) $uri)); 49 | $this->setUri((string) $uri); 50 | 51 | $headerCollection = $this->getHeaders(); 52 | foreach ($headers as $name => $values) { 53 | foreach ($values as $value) { 54 | $headerCollection->addHeaderLine($name, $value); 55 | } 56 | } 57 | 58 | if (! empty($cookies)) { 59 | $headerCollection->addHeader(new Cookie($cookies)); 60 | } 61 | 62 | $this->setQuery(new Parameters($queryStringArguments)); 63 | $this->setPost(new Parameters($postParameters)); 64 | $this->setFiles(new Parameters($uploadedFiles)); 65 | 66 | // Do not use `setServerParams()`, as that extracts headers, URI, etc. 67 | $this->serverParams = new Parameters($serverParams); 68 | } 69 | } 70 | --------------------------------------------------------------------------------