generated from yiisoft/package-template
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add source code and tests, update support files (#1)
- Loading branch information
Showing
28 changed files
with
2,711 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,6 @@ jobs: | |
- windows-latest | ||
|
||
php: | ||
- 7.4 | ||
- 8.0 | ||
|
||
steps: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,6 @@ jobs: | |
- ubuntu-latest | ||
|
||
php: | ||
- 7.4 | ||
- 8.0 | ||
|
||
steps: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,6 @@ jobs: | |
- ubuntu-latest | ||
|
||
php: | ||
- 7.4 | ||
- 8.0 | ||
|
||
steps: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# _____ Change Log | ||
# Yii Middleware Change Log | ||
|
||
## 1.0.0 under development | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,11 @@ | ||
<?xml version="1.0"?> | ||
<psalm | ||
errorLevel="2" | ||
errorLevel="4" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns="https://getpsalm.org/schema/config" | ||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" | ||
> | ||
<projectFiles> | ||
<directory name="src" /> | ||
<ignoreFiles> | ||
<directory name="vendor"/> | ||
</ignoreFiles> | ||
</projectFiles> | ||
</psalm> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Yii\Middleware; | ||
|
||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
use Psr\Http\Server\MiddlewareInterface; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
use RuntimeException; | ||
|
||
use function count; | ||
use function in_array; | ||
use function is_array; | ||
use function is_callable; | ||
use function is_string; | ||
use function strtolower; | ||
|
||
/** | ||
* Basic network resolver updates an instance of server request with protocol from special headers. | ||
* | ||
* It can be used in the following cases: | ||
* - not required IP resolve to access the user's IP | ||
* - user's IP is already resolved (eg `ngx_http_realip_module` or similar) | ||
*/ | ||
final class BasicNetworkResolver implements MiddlewareInterface | ||
{ | ||
private const DEFAULT_PROTOCOL_AND_ACCEPTABLE_VALUES = [ | ||
'http' => ['http'], | ||
'https' => ['https', 'on'], | ||
]; | ||
|
||
/** | ||
* @psalm-var array<string, array|callable|null> | ||
*/ | ||
private array $protocolHeaders = []; | ||
|
||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface | ||
{ | ||
$newScheme = null; | ||
|
||
foreach ($this->protocolHeaders as $header => $data) { | ||
if (!$request->hasHeader($header)) { | ||
continue; | ||
} | ||
|
||
$headerValues = $request->getHeader($header); | ||
|
||
if (is_callable($data)) { | ||
$newScheme = $data($headerValues, $header, $request); | ||
if ($newScheme === null) { | ||
continue; | ||
} | ||
|
||
if (!is_string($newScheme)) { | ||
throw new RuntimeException('The scheme is neither string nor null.'); | ||
} | ||
|
||
if ($newScheme === '') { | ||
throw new RuntimeException('The scheme cannot be an empty string.'); | ||
} | ||
|
||
break; | ||
} | ||
|
||
$headerValue = strtolower($headerValues[0]); | ||
|
||
foreach ($data as $protocol => $acceptedValues) { | ||
if (!in_array($headerValue, $acceptedValues, true)) { | ||
continue; | ||
} | ||
$newScheme = $protocol; | ||
break 2; | ||
} | ||
} | ||
|
||
$uri = $request->getUri(); | ||
|
||
if ($newScheme !== null && $newScheme !== $uri->getScheme()) { | ||
$request = $request->withUri($uri->withScheme($newScheme)); | ||
} | ||
|
||
return $handler->handle($request); | ||
} | ||
|
||
/** | ||
* With added header to check for determining whether the connection is made via HTTP or HTTPS (or any protocol). | ||
* | ||
* The match of header names and values is case-insensitive. | ||
* It's not advisable to put insecure/untrusted headers here. | ||
* | ||
* Accepted types of values: | ||
* - NULL (default): {{DEFAULT_PROTOCOL_AND_ACCEPTABLE_VALUES}} | ||
* - callable: custom function for getting the protocol | ||
* ```php | ||
* ->withProtocolHeader('x-forwarded-proto', function(array $values, string $header, ServerRequestInterface $request) { | ||
* return $values[0] === 'https' ? 'https' : 'http'; | ||
* return null; // If it doesn't make sense. | ||
* }); | ||
* ``` | ||
* - array: The array keys are protocol string and the array value is a list of header values that indicate the protocol. | ||
* ```php | ||
* ->withProtocolHeader('x-forwarded-proto', [ | ||
* 'http' => ['http'], | ||
* 'https' => ['https'] | ||
* ]); | ||
* ``` | ||
* | ||
* @param string $header | ||
* @param array|callable|null $values | ||
* | ||
* @return self | ||
* | ||
* @see DEFAULT_PROTOCOL_AND_ACCEPTABLE_VALUES | ||
*/ | ||
public function withAddedProtocolHeader(string $header, $values = null): self | ||
{ | ||
$new = clone $this; | ||
$header = strtolower($header); | ||
|
||
if ($values === null) { | ||
$new->protocolHeaders[$header] = self::DEFAULT_PROTOCOL_AND_ACCEPTABLE_VALUES; | ||
return $new; | ||
} | ||
|
||
if (is_callable($values)) { | ||
$new->protocolHeaders[$header] = $values; | ||
return $new; | ||
} | ||
|
||
if (!is_array($values)) { | ||
throw new RuntimeException('Accepted values is not array nor callable.'); | ||
} | ||
|
||
if (count($values) === 0) { | ||
throw new RuntimeException('Accepted values cannot be an empty array.'); | ||
} | ||
|
||
$new->protocolHeaders[$header] = []; | ||
|
||
foreach ($values as $protocol => $acceptedValues) { | ||
if (!is_string($protocol)) { | ||
throw new RuntimeException('The protocol must be type of string.'); | ||
} | ||
|
||
if ($protocol === '') { | ||
throw new RuntimeException('The protocol cannot be an empty string'); | ||
} | ||
|
||
$new->protocolHeaders[$header][$protocol] = array_map('strtolower', (array) $acceptedValues); | ||
} | ||
|
||
return $new; | ||
} | ||
|
||
public function withoutProtocolHeader(string $header): self | ||
{ | ||
$new = clone $this; | ||
unset($new->protocolHeaders[strtolower($header)]); | ||
return $new; | ||
} | ||
|
||
public function withoutProtocolHeaders(?array $headers = null): self | ||
{ | ||
$new = clone $this; | ||
|
||
if ($headers === null) { | ||
$new->protocolHeaders = []; | ||
return $new; | ||
} | ||
|
||
foreach ($headers as $header) { | ||
$new = $new->withoutProtocolHeader($header); | ||
} | ||
|
||
return $new; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Yii\Middleware\Exception; | ||
|
||
use Yiisoft\FriendlyException\FriendlyExceptionInterface; | ||
|
||
final class BadUriPrefixException extends \Exception implements FriendlyExceptionInterface | ||
{ | ||
public function getName(): string | ||
{ | ||
return 'Bad URI prefix'; | ||
} | ||
|
||
public function getSolution(): ?string | ||
{ | ||
return "Most likely you have specified the wrong URI prefix.\n" | ||
. "Make sure that path from the web address contains the specified prefix (immediately after the domain part).\n" | ||
. "The prefix value usually begins with a slash and must not end with a slash.\n" | ||
. "The prefix should be exact match. We're not trimming it or adding anything to it."; | ||
} | ||
} |
Oops, something went wrong.