Skip to content
This repository was archived by the owner on Feb 10, 2023. It is now read-only.

Commit aea3020

Browse files
Add WellKnownPsr17Factory::createServerRequest/UriFromGlobals()
1 parent 470f70d commit aea3020

File tree

7 files changed

+203
-58
lines changed

7 files changed

+203
-58
lines changed

src/Internal/Guzzle/GuzzlePsr7Stream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace FriendsOfPHP\WellKnownImplementations\Internal\Guzzle;
1111

12-
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7StreamHelper;
12+
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7Helper;
1313
use GuzzleHttp\Psr7\Stream;
1414

1515
/**
@@ -22,6 +22,6 @@ class GuzzlePsr7Stream extends Stream
2222
*/
2323
public function __construct($content = '', string $mode = null)
2424
{
25-
parent::__construct(Psr7StreamHelper::toResource($content, $mode));
25+
parent::__construct(Psr7Helper::toResource($content, $mode));
2626
}
2727
}

src/Internal/Laminas/LaminasPsr7Stream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace FriendsOfPHP\WellKnownImplementations\Internal\Laminas;
1111

12-
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7StreamHelper;
12+
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7Helper;
1313
use Laminas\Diactoros\Stream;
1414

1515
/**
@@ -23,7 +23,7 @@ class LaminasPsr7Stream extends Stream
2323
public function __construct($content = '', string $mode = null)
2424
{
2525
if (null === $mode && \is_string($content)) {
26-
$content = Psr7StreamHelper::toResource($content, $mode);
26+
$content = Psr7Helper::toResource($content, $mode);
2727
}
2828

2929
parent::__construct($content, $mode ?? 'r');

src/Internal/Nyholm/NyholmPsr7Stream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace FriendsOfPHP\WellKnownImplementations\Internal\Nyholm;
1111

12-
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7StreamHelper;
12+
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7Helper;
1313
use Nyholm\Psr7\Stream;
1414

1515
/**
@@ -23,7 +23,7 @@ class NyholmPsr7Stream extends Stream
2323
public function __construct($content = '', string $mode = null)
2424
{
2525
if (!\is_resource($content)) {
26-
$content = Psr7StreamHelper::toResource($content, $mode);
26+
$content = Psr7Helper::toResource($content, $mode);
2727
}
2828

2929
static $sync;

src/Internal/Psr7Helper.php

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
3+
/*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace FriendsOfPHP\WellKnownImplementations\Internal;
11+
12+
use FriendsOfPHP\WellKnownImplementations\WellKnownPsr7Stream;
13+
use FriendsOfPHP\WellKnownImplementations\WellKnownPsr7UploadedFile;
14+
use Psr\Http\Message\ServerRequestInterface;
15+
use Psr\Http\Message\UploadedFileInterface;
16+
use Psr\Http\Message\UriInterface;
17+
18+
/**
19+
* Helps provide portability accross PSR-7 implementations.
20+
*
21+
* The code in this class is inspired by the "nyholm/psr7", "guzzlehttp/psr7"
22+
* and "symfony/http-foundation" packages, all licenced under MIT.
23+
*
24+
* Copyright (c) 2015 Michael Dowling <[email protected]>
25+
* Copyright (c) 2015 Márk Sági-Kazár <[email protected]>
26+
* Copyright (c) 2015 Graham Campbell <[email protected]>
27+
* Copyright (c) 2016 Tobias Schultze <[email protected]>
28+
* Copyright (c) 2016 George Mponos <[email protected]>
29+
* Copyright (c) 2016-2018 Tobias Nyholm <[email protected]>
30+
*
31+
* @internal
32+
*/
33+
class Psr7Helper
34+
{
35+
/**
36+
* @param string|resource $content
37+
*
38+
* @return resource
39+
*/
40+
public static function toResource($content, ?string $mode)
41+
{
42+
if (\is_resource($content)) {
43+
return $content;
44+
}
45+
46+
if (null === $mode) {
47+
$h = fopen('php://temp', 'r+');
48+
fwrite($h, $content);
49+
rewind($h);
50+
51+
return $h;
52+
}
53+
54+
if ('' === $content) {
55+
throw new \RuntimeException('Path cannot be empty');
56+
}
57+
58+
if (false === $h = @fopen($content, $mode)) {
59+
if ('' === $mode || false === \in_array($mode[0], ['r', 'w', 'a', 'x', 'c'], true)) {
60+
throw new \InvalidArgumentException(sprintf('The mode "%s" is invalid.', $mode));
61+
}
62+
63+
throw new \RuntimeException(sprintf('The file "%s" cannot be opened: %s', $content, error_get_last()['message'] ?? ''));
64+
}
65+
66+
return $h;
67+
}
68+
69+
public static function buildServerRequestFromGlobals(ServerRequestInterface $request, array $server, array $files): ServerRequestInterface
70+
{
71+
$request = $request
72+
->withProtocolVersion(isset($server['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $server['SERVER_PROTOCOL']) : '1.1')
73+
->withUploadedFiles(self::normalizeFiles($files));
74+
75+
$headers = [];
76+
foreach ($server as $key => $value) {
77+
if (0 === strpos($key, 'HTTP_')) {
78+
$key = substr($key, 5);
79+
} elseif (!\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) {
80+
continue;
81+
}
82+
$key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
83+
84+
$headers[$key] = $value;
85+
}
86+
87+
if (!isset($headers['Authorization'])) {
88+
if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
89+
$headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
90+
} elseif (isset($_SERVER['PHP_AUTH_USER'])) {
91+
$headers['Authorization'] = 'Basic '.base64_encode($_SERVER['PHP_AUTH_USER'].':'.($_SERVER['PHP_AUTH_PW'] ?? ''));
92+
} elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
93+
$headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
94+
}
95+
}
96+
97+
foreach ($headers as $key => $value) {
98+
try {
99+
$request = $request->withHeader($key, $value);
100+
} catch (\InvalidArgumentException $e) {
101+
// ignore invalid headers
102+
}
103+
104+
}
105+
106+
return $request;
107+
}
108+
109+
public static function buildUriFromGlobals(UriInterface $uri, array $server): UriInterface
110+
{
111+
$uri = $uri->withScheme(!empty($server['HTTPS']) && 'off' !== strtolower($server['HTTPS']) ? 'https' : 'http');
112+
113+
$hasPort = false;
114+
if (isset($server['HTTP_HOST'])) {
115+
$parts = parse_url('http://'.$server['HTTP_HOST']);
116+
117+
if ($parts['host'] ?? false) {
118+
$uri = $uri->withHost($parts['host']);
119+
}
120+
121+
if ($parts['port'] ?? false) {
122+
$hasPort = true;
123+
$uri = $uri->withPort($parts['port']);
124+
}
125+
} elseif (isset($server['SERVER_NAME'])) {
126+
$uri = $uri->withHost($server['SERVER_NAME']);
127+
} elseif (isset($server['SERVER_ADDR'])) {
128+
$uri = $uri->withHost($server['SERVER_ADDR']);
129+
}
130+
131+
if (!$hasPort && isset($server['SERVER_PORT'])) {
132+
$uri = $uri->withPort($server['SERVER_PORT']);
133+
}
134+
135+
$hasQuery = false;
136+
if (isset($server['REQUEST_URI'])) {
137+
$requestUriParts = explode('?', $server['REQUEST_URI'], 2);
138+
$uri = $uri->withPath($requestUriParts[0]);
139+
if (isset($requestUriParts[1])) {
140+
$hasQuery = true;
141+
$uri = $uri->withQuery($requestUriParts[1]);
142+
}
143+
}
144+
145+
if (!$hasQuery && isset($server['QUERY_STRING'])) {
146+
$uri = $uri->withQuery($server['QUERY_STRING']);
147+
}
148+
149+
return $uri;
150+
}
151+
152+
public static function normalizeFiles(array $files): array
153+
{
154+
$normalized = [];
155+
156+
foreach ($files as $key => $value) {
157+
if ($value instanceof UploadedFileInterface) {
158+
$normalized[$key] = $value;
159+
} elseif (!\is_array($value)) {
160+
continue;
161+
} elseif (!isset($value['tmp_name'])) {
162+
$normalized[$key] = self::normalizeFiles($value);
163+
} elseif (\is_array($value['tmp_name'])) {
164+
foreach ($value['tmp_name'] as $k => $v) {
165+
$file = new WellKnownPsr7Stream($value['tmp_name'][$k], 'r');
166+
$normalized[$key][$k] = new WellKnownPsr7UploadedFile($file, $value['size'][$k], $value['error'][$k], $value['name'][$k], $value['type'][$k]);
167+
}
168+
} else {
169+
$file = new WellKnownPsr7Stream($value['tmp_name'], 'r');
170+
$normalized[$key] = new WellKnownPsr7UploadedFile($file, $value['size'], $value['error'], $value['name'], $value['type']);
171+
}
172+
}
173+
174+
return $normalized;
175+
}
176+
}

src/Internal/Psr7StreamHelper.php

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/Internal/Slim/SlimPsr7Stream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace FriendsOfPHP\WellKnownImplementations\Internal\Slim;
1111

12-
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7StreamHelper;
12+
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7Helper;
1313
use Slim\Psr7\Stream;
1414

1515
/**
@@ -22,6 +22,6 @@ class SlimPsr7Stream extends Stream
2222
*/
2323
public function __construct($content = '', string $mode = null)
2424
{
25-
parent::__construct(Psr7StreamHelper::toResource($content, $mode));
25+
parent::__construct(Psr7Helper::toResource($content, $mode));
2626
}
2727
}

src/WellKnownPsr17Factory.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace FriendsOfPHP\WellKnownImplementations;
1111

12+
use FriendsOfPHP\WellKnownImplementations\Internal\Psr7Helper;
1213
use Psr\Http\Message\RequestFactoryInterface;
1314
use Psr\Http\Message\RequestInterface;
1415
use Psr\Http\Message\ResponseFactoryInterface;
@@ -45,6 +46,19 @@ public function createServerRequest(string $method, $uri, array $serverParams =
4546
return new WellKnownPsr7ServerRequest(...\func_get_args());
4647
}
4748

49+
public function createServerRequestFromGlobals(array $server = null, array $get = null, array $post = null, array $cookie = null, array $files = null, StreamInterface $body = null): ServerRequestInterface
50+
{
51+
$server = $server ?? $_SERVER;
52+
$request = new WellKnownPsr7ServerRequest($server['REQUEST_METHOD'] ?? 'GET', $this->createUriFromGlobals($server), $server);
53+
54+
return Psr7Helper::buildServerRequestFromGlobals($request, $server, $files ?? $_FILES)
55+
->withQueryParams($get ?? $_GET)
56+
->withParsedBody($post ?? $_POST)
57+
->withCookieParams($cookie ?? $_COOKIE)
58+
->withBody($body ?? new WellKnownPsr7Stream('php://input', 'r+'));
59+
;
60+
}
61+
4862
public function createStream(string $content = ''): StreamInterface
4963
{
5064
return new WellKnownPsr7Stream($content);
@@ -72,4 +86,9 @@ public function createUri(string $uri = ''): UriInterface
7286
{
7387
return new WellKnownPsr7Uri(...\func_get_args());
7488
}
89+
90+
public function createUriFromGlobals(array $server = null): UriInterface
91+
{
92+
return Psr7Helper::buildUriFromGlobals(new WellKnownPsr7Uri(''), $server ?? $_SERVER);
93+
}
7594
}

0 commit comments

Comments
 (0)