Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 96c2579

Browse files
committed
ADD RequestHelper with method stringify (for easier debugging).
ADD UriHelper siteUrl support to X-Forwarded-Host and X-Forwarded-Port ADD expected testcases for added features
1 parent 364736f commit 96c2579

File tree

6 files changed

+344
-2
lines changed

6 files changed

+344
-2
lines changed

‎dev/Request.php‎

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
namespace Francerz\HttpUtils\Dev;
4+
5+
use Psr\Http\Message\MessageInterface;
6+
use Psr\Http\Message\RequestInterface;
7+
use Psr\Http\Message\StreamInterface;
8+
use Psr\Http\Message\UriInterface;
9+
10+
class Request implements RequestInterface
11+
{
12+
private $requestTarget;
13+
private $method;
14+
private $uri;
15+
private $version;
16+
private $headers = [];
17+
private $body;
18+
19+
/**
20+
* @param UriInterface|string $uri
21+
* @param string $method
22+
*/
23+
public function __construct($uri, string $method = 'GET')
24+
{
25+
$this->method = $method;
26+
$this->uri = $uri instanceof UriInterface ? $uri : new Uri($uri);
27+
$this->version = '1.1';
28+
$this->body = new Stream();
29+
}
30+
31+
public function getRequestTarget(): string
32+
{
33+
return $this->requestTarget;
34+
}
35+
36+
public function withRequestTarget(string $requestTarget): RequestInterface
37+
{
38+
$clone = clone $this;
39+
$clone->requestTarget = $requestTarget;
40+
return $clone;
41+
}
42+
43+
public function getMethod(): string
44+
{
45+
return $this->method;
46+
}
47+
48+
public function withMethod(string $method): RequestInterface
49+
{
50+
$clone = clone $this;
51+
$clone->method = $method;
52+
return $clone;
53+
}
54+
55+
public function getUri(): UriInterface
56+
{
57+
return $this->uri;
58+
}
59+
60+
public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface
61+
{
62+
$clone = clone $this;
63+
$clone->uri = $uri;
64+
return $clone;
65+
}
66+
67+
public function getProtocolVersion(): string
68+
{
69+
return $this->version;
70+
}
71+
72+
public function withProtocolVersion(string $version): MessageInterface
73+
{
74+
$clone = clone $this;
75+
$clone->version = $version;
76+
return $clone;
77+
}
78+
79+
public function getHeaders(): array
80+
{
81+
return $this->headers;
82+
}
83+
84+
public function hasHeader(string $name): bool
85+
{
86+
return isset($this->headers[$name]);
87+
}
88+
89+
public function getHeader(string $name): array
90+
{
91+
return $this->headers[$name] ?? [];
92+
}
93+
94+
public function withHeader(string $name, $value): MessageInterface
95+
{
96+
$clone = clone $this;
97+
$clone->headers[$name] = is_array($value) ? $value : [$value];
98+
return $clone;
99+
}
100+
101+
public function withAddedHeader(string $name, $value): MessageInterface
102+
{
103+
$clone = clone $this;
104+
$clone->headers[$name] = is_array($value) ?
105+
array_merge($clone->headers[$name], is_array($value) ? $value : [$value]) :
106+
array_merge($clone->headers[$name], [$value]);
107+
return $clone;
108+
}
109+
110+
public function getHeaderLine(string $name): string
111+
{
112+
if (!isset($this->headers[$name])) {
113+
return '';
114+
}
115+
return implode(',', $this->headers[$name]);
116+
}
117+
118+
public function withoutHeader(string $name): MessageInterface
119+
{
120+
$clone = clone $this;
121+
unset($clone->headers[$name]);
122+
return $clone;
123+
}
124+
125+
public function getBody(): StreamInterface
126+
{
127+
return $this->body;
128+
}
129+
130+
public function withBody(StreamInterface $body): MessageInterface
131+
{
132+
$clone = clone $this;
133+
$clone->body = $body;
134+
return $clone;
135+
}
136+
}

‎dev/Uri.php‎

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
namespace Francerz\HttpUtils\Dev;
4+
5+
use Francerz\Http\Utils\UriHelper;
6+
use Psr\Http\Message\UriInterface;
7+
8+
class Uri implements UriInterface
9+
{
10+
private $scheme;
11+
private $user;
12+
private $password;
13+
private $host;
14+
private $port;
15+
private $path;
16+
private $query;
17+
private $fragment;
18+
19+
public function __construct(string $uri)
20+
{
21+
$uriParts = parse_url($uri);
22+
$this->scheme = $uriParts['scheme'];
23+
$this->user = $uriParts['user'] ?? '';
24+
$this->password = $uriParts['pass'] ?? null;
25+
$this->host = $uriParts['host'] ?? '';
26+
$this->port = $uriParts['port'] ?? null;
27+
$this->path = $uriParts['path'] ?? '/';
28+
$this->query = $uriParts['query'] ?? '';
29+
$this->fragment = $uriParts['fragment'] ?? '';
30+
}
31+
32+
public function getScheme(): string
33+
{
34+
return $this->scheme;
35+
}
36+
37+
public function getAuthority(): string
38+
{
39+
$authority = $this->host;
40+
if (!empty($this->user)) {
41+
$authority = $this->getUserInfo() . '@' . $authority;
42+
}
43+
if (isset($this->port)) {
44+
$authority .= ':' . $this->port;
45+
}
46+
return $authority;
47+
}
48+
49+
public function getUserInfo(): string
50+
{
51+
$userInfo = $this->user;
52+
if (isset($this->password)) {
53+
$userInfo = ':' . $this->password;
54+
}
55+
return $userInfo;
56+
}
57+
58+
public function getHost(): string
59+
{
60+
return $this->host;
61+
}
62+
63+
public function getPort(): ?int
64+
{
65+
return $this->port;
66+
}
67+
68+
public function getPath(): string
69+
{
70+
return $this->path;
71+
}
72+
73+
public function getQuery(): string
74+
{
75+
return $this->query;
76+
}
77+
78+
public function getFragment(): string
79+
{
80+
return $this->fragment;
81+
}
82+
83+
public function withScheme(string $scheme): UriInterface
84+
{
85+
$clone = clone $this;
86+
$clone->scheme = $scheme;
87+
return $clone;
88+
}
89+
90+
public function withUserInfo(string $user, ?string $password = null): UriInterface
91+
{
92+
$clone = clone $this;
93+
$clone->user = $user;
94+
$clone->password = $password;
95+
return $clone;
96+
}
97+
98+
public function withHost(string $host): UriInterface
99+
{
100+
$clone = clone $this;
101+
$clone->host = $host;
102+
return $clone;
103+
}
104+
105+
public function withPort(?int $port): UriInterface
106+
{
107+
$clone = clone $this;
108+
$clone->port = $port;
109+
return $clone;
110+
}
111+
112+
public function withPath(string $path): UriInterface
113+
{
114+
$clone = clone $this;
115+
$clone->path = $path;
116+
return $clone;
117+
}
118+
119+
public function withQuery(string $query): UriInterface
120+
{
121+
$clone = clone $this;
122+
$clone->query = $query;
123+
return $clone;
124+
}
125+
126+
public function withFragment(string $fragment): UriInterface
127+
{
128+
$clone = clone $this;
129+
$clone->fragment = $fragment;
130+
return $clone;
131+
}
132+
133+
public function __toString(): string
134+
{
135+
return UriHelper::buildStringFromParts([
136+
'scheme' => $this->scheme,
137+
'user' => $this->user,
138+
'pass' => $this->password,
139+
'host' => $this->host,
140+
'port' => $this->port,
141+
'path' => $this->path,
142+
'query' => $this->query,
143+
'fragment' => $this->fragment
144+
]);
145+
}
146+
}

‎src/utils/RequestHelper.php‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Francerz\Http\Utils;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
7+
class RequestHelper
8+
{
9+
public static function stringify(RequestInterface $request)
10+
{
11+
$path = $request->getUri()->getPath();
12+
if (!empty($queryString = $request->getUri()->getQuery())) {
13+
$path .= '?' . $queryString;
14+
}
15+
$string = sprintf(
16+
"%s %s HTTP/%s\n",
17+
$request->getMethod(),
18+
$path,
19+
$request->getProtocolVersion()
20+
);
21+
foreach ($request->getHeaders() as $name => $values) {
22+
$string .= sprintf("%s: %s\n", $name, implode(', ', $values));
23+
}
24+
$string .= "\n" . $request->getBody();
25+
return $string;
26+
}
27+
}

‎src/utils/UriHelper.php‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public static function getPathInfo(?string $requestUri = null, ?string $scriptNa
205205
return '/' . ltrim($pathInfo, '/');
206206
}
207207

208-
private static function buildStringFromParts(array $uriParts): string
208+
public static function buildStringFromParts(array $uriParts): string
209209
{
210210
$join[] = $scheme = $uriParts['scheme'] ?? 'http';
211211
$join[] = '://';
@@ -245,6 +245,12 @@ public static function getSiteUrl(?string $path = null, array $sapiVars = [], bo
245245
$sapiVars['REQUEST_URI'] = $sapiVars['SCRIPT_NAME'] ?? '';
246246
$uri = static::getCurrentString($sapiVars, $cached);
247247
$uriParts = parse_url($uri);
248+
if (isset($sapiVars['HTTP_X_FORWARDED_HOST'])) {
249+
$uriParts['host'] = $sapiVars['HTTP_X_FORWARDED_HOST'];
250+
}
251+
if (isset($sapiVars['HTTP_X_FORWARDED_PORT'])) {
252+
$uriParts['port'] = $sapiVars['HTTP_X_FORWARDED_PORT'];
253+
}
248254
if (isset($sapiVars['HTTP_X_FORWARDED_PREFIX'])) {
249255
$uriParts['path'] =
250256
'/' . ltrim($sapiVars['HTTP_X_FORWARDED_PREFIX'], '/') .

‎test/RequestHelperTest.php‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Francerz\Http\Utils\Tests;
4+
5+
use Francerz\Http\Utils\RequestHelper;
6+
use Francerz\HttpUtils\Dev\Request;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class RequestHelperTest extends TestCase
10+
{
11+
public function testStringify()
12+
{
13+
$request = new Request('http://www.example.com/test/path?query=string#fragment');
14+
$request = $request->withHeader('Host', 'www.example.com');
15+
16+
$this->assertEquals(
17+
"GET /test/path?query=string HTTP/1.1\n" .
18+
"Host: www.example.com\n" .
19+
"\n",
20+
RequestHelper::stringify($request)
21+
);
22+
}
23+
}

‎test/UriHelperTest.php‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<?php
22

3+
namespace Francerz\Http\Utils\Tests;
4+
35
use Francerz\Http\Utils\UriHelper;
46
use PHPUnit\Framework\TestCase;
7+
use ReflectionClass;
58

69
use function Francerz\Http\Utils\baseUrl;
710
use function Francerz\Http\Utils\siteUrl;
@@ -112,12 +115,13 @@ public function testGetSiteUrl()
112115
);
113116

114117
$this->assertEquals(
115-
'https://localhost:3000/public/index.php/some/path',
118+
'https://www.domain.com:3000/public/index.php/some/path',
116119
siteUrl('/some/path', [
117120
'HTTPS' => 'on',
118121
'SERVER_NAME' => 'localhost',
119122
'SERVER_PORT' => 3000,
120123
'SCRIPT_NAME' => 'index.php',
124+
'HTTP_X_FORWARDED_HOST' => 'www.domain.com',
121125
'HTTP_X_FORWARDED_PREFIX' => '/public'
122126
], false)
123127
);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /