Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/AccessLogHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ private function logWhenClosed(ServerRequestInterface $request, ResponseInterfac
if ($body instanceof ReadableStreamInterface && $body->isReadable()) {
$size = 0;
$body->on('data', function (string $chunk) use (&$size) {
$size += strlen($chunk);
$size += \strlen($chunk);
});

$body->on('close', function () use (&$size, $request, $response, $start) {
$this->log($request, $response, $size, $this->now() - $start);
});
} else {
$this->log($request, $response, $body->getSize() ?? strlen((string) $body), $this->now() - $start);
$this->log($request, $response, $body->getSize() ?? \strlen((string) $body), $this->now() - $start);
}
}

Expand All @@ -122,19 +122,19 @@ private function log(ServerRequestInterface $request, ResponseInterface $respons
$this->logger->log(
($request->getAttribute('remote_addr') ?? $request->getServerParams()['REMOTE_ADDR'] ?? '-') . ' ' .
'"' . $this->escape($method) . ' ' . $this->escape($request->getRequestTarget()) . ' HTTP/' . $request->getProtocolVersion() . '" ' .
$status . ' ' . $responseSize . ' ' . sprintf('%.3F', $time < 0 ? 0 : $time)
$status . ' ' . $responseSize . ' ' . \sprintf('%.3F', $time < 0 ? 0 : $time)
);
}

private function escape(string $s): string
{
return (string) preg_replace_callback('/[\x00-\x1F\x7F-\xFF"\\\\]+/', function (array $m) {
return str_replace('%', '\x', rawurlencode($m[0]));
return (string) \preg_replace_callback('/[\x00-\x1F\x7F-\xFF"\\\\]+/', function (array $m) {
return \str_replace('%', '\x', \rawurlencode($m[0]));
}, $s);
}

private function now(): float
{
return $this->hasHighResolution ? hrtime(true) * 1e-9 : microtime(true);
return $this->hasHighResolution ? \hrtime(true) * 1e-9 : \microtime(true);
}
}
8 changes: 4 additions & 4 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public function __invoke(ServerRequestInterface $request): ResponseInterface
if ($response instanceof PromiseInterface) {
/** @throws void */
$response = await($response);
assert($response instanceof ResponseInterface);
\assert($response instanceof ResponseInterface);
}

return $response;
Expand All @@ -308,14 +308,14 @@ public function __invoke(ServerRequestInterface $request): ResponseInterface
private function handleRequest(ServerRequestInterface $request)
{
$response = ($this->handler)($request);
assert($response instanceof ResponseInterface || $response instanceof PromiseInterface || $response instanceof \Generator);
\assert($response instanceof ResponseInterface || $response instanceof PromiseInterface || $response instanceof \Generator);

if ($response instanceof \Generator) {
if ($response->valid()) {
$response = $this->coroutine($response);
} else {
$response = $response->getReturn();
assert($response instanceof ResponseInterface);
\assert($response instanceof ResponseInterface);
}
}

Expand All @@ -336,7 +336,7 @@ private function coroutine(\Generator $generator): PromiseInterface
}

$promise = $generator->current();
assert($promise instanceof PromiseInterface);
\assert($promise instanceof PromiseInterface);

$promise->then(function ($value) use ($generator, $next) {
$generator->send($value);
Expand Down
28 changes: 14 additions & 14 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public function callable(string $class): callable
// Check `$handler` references a class name that is callable, i.e. has an `__invoke()` method.
// This initial version is intentionally limited to checking the method name only.
// A follow-up version will likely use reflection to check request handler argument types.
if (!is_callable($handler)) {
if (!\is_callable($handler)) {
throw new \Error(
'Request handler ' . \explode("\0", $class)[0] . ' has no public __invoke() method'
);
Expand All @@ -115,7 +115,7 @@ public function callable(string $class): callable
*/
public function getEnv(string $name): ?string
{
assert(\preg_match('/^[A-Z][A-Z0-9_]+$/', $name) === 1);
\assert(\preg_match('/^[A-Z][A-Z0-9_]+$/', $name) === 1);

if ($this->container instanceof ContainerInterface && $this->container->has($name)) {
$value = $this->container->get($name);
Expand Down Expand Up @@ -180,7 +180,7 @@ public function getErrorHandler(): ErrorHandler
*/
private function loadObject(string $name, int $depth = 64) /*: object (PHP 7.2+) */
{
assert(\is_array($this->container));
\assert(\is_array($this->container));

if (\array_key_exists($name, $this->container)) {
if (\is_string($this->container[$name])) {
Expand Down Expand Up @@ -226,13 +226,13 @@ private function loadObject(string $name, int $depth = 64) /*: object (PHP 7.2+)
);
}

assert($this->container[$name] instanceof $name);
\assert($this->container[$name] instanceof $name);

return $this->container[$name];
}

// Check `$name` references a valid class name that can be autoloaded
if (!\class_exists($name, true) && !interface_exists($name, false) && !trait_exists($name, false)) {
if (!\class_exists($name, true) && !\interface_exists($name, false) && !\trait_exists($name, false)) {
throw new \Error('Class ' . $name . ' not found');
}

Expand Down Expand Up @@ -287,7 +287,7 @@ private function loadParameter(\ReflectionParameter $parameter, int $depth, bool
throw new \Error(self::parameterError($parameter, $for) . ' is recursive');
}

assert(\is_array($this->container));
\assert(\is_array($this->container));
$type = $parameter->getType();

// abort for union types (PHP 8.0+) and intersection types (PHP 8.1+)
Expand All @@ -306,7 +306,7 @@ private function loadParameter(\ReflectionParameter $parameter, int $depth, bool
} // @codeCoverageIgnoreEnd

// load container variables if parameter name is known
assert($type === null || $type instanceof \ReflectionNamedType);
\assert($type === null || $type instanceof \ReflectionNamedType);
if ($allowVariables && $this->hasVariable($parameter->getName())) {
$value = $this->loadVariable($parameter->getName(), $depth);

Expand Down Expand Up @@ -355,13 +355,13 @@ private function hasVariable(string $name): bool
*/
private function loadVariable(string $name, int $depth = 64) /*: object|string|int|float|bool|null (PHP 8.0+) */
{
assert($this->hasVariable($name));
assert(\is_array($this->container) || !$this->container->has($name));
\assert($this->hasVariable($name));
\assert(\is_array($this->container) || !$this->container->has($name));

if (\is_array($this->container) && ($this->container[$name] ?? null) instanceof \Closure) {
// build list of factory parameters based on parameter types
$factory = $this->container[$name];
assert($factory instanceof \Closure);
\assert($factory instanceof \Closure);
$closure = new \ReflectionFunction($factory);
$params = $this->loadFunctionParams($closure, $depth - 1, true, '$' . $name);

Expand All @@ -378,17 +378,17 @@ private function loadVariable(string $name, int $depth = 64) /*: object|string|i
} elseif (\is_array($this->container) && \array_key_exists($name, $this->container)) {
$value = $this->container[$name];
} elseif (isset($_ENV[$name])) {
assert(\is_string($_ENV[$name]));
\assert(\is_string($_ENV[$name]));
$value = $_ENV[$name];
} elseif (isset($_SERVER[$name])) {
assert(\is_string($_SERVER[$name]));
\assert(\is_string($_SERVER[$name]));
$value = $_SERVER[$name];
} else {
$value = \getenv($name);
assert($this->useProcessEnv && $value !== false);
\assert($this->useProcessEnv && $value !== false);
}

assert(\is_object($value) || \is_scalar($value) || $value === null);
\assert(\is_object($value) || \is_scalar($value) || $value === null);
return $value;
}

Expand Down
2 changes: 1 addition & 1 deletion src/FilesystemHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function __construct(string $root)
public function __invoke(ServerRequestInterface $request): ResponseInterface
{
$local = $request->getAttribute('path', '');
assert(\is_string($local));
\assert(\is_string($local));
$path = \rtrim($this->root . '/' . $local, '/');

// local path should not contain "./", "../", "//" or null bytes or start with slash
Expand Down
4 changes: 2 additions & 2 deletions src/Io/FiberHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ public function __invoke(ServerRequestInterface $request, callable $next)
$deferred = null;
$fiber = new \Fiber(function () use ($request, $next, &$deferred) {
$response = $next($request);
assert($response instanceof ResponseInterface || $response instanceof PromiseInterface || $response instanceof \Generator);
\assert($response instanceof ResponseInterface || $response instanceof PromiseInterface || $response instanceof \Generator);

// if the next request handler returns immediately, the fiber can terminate immediately without using a Deferred
// if the next request handler suspends the fiber, we only reach this point after resuming the fiber, so the code below will have assigned a Deferred
/** @var ?Deferred<ResponseInterface> $deferred */
if ($deferred !== null) {
assert($response instanceof ResponseInterface);
\assert($response instanceof ResponseInterface);
$deferred->resolve($response);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Io/LogStreamHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function log(string $message): void
$prefix = \date('Y-m-d H:i:s', (int) $time) . \sprintf('.%03d ', (int) (($time - (int) $time) * 1e3));

$ret = \fwrite($this->stream, $prefix . $message . \PHP_EOL);
assert(\is_int($ret));
\assert(\is_int($ret));
}

private function isAbsolutePath(string $path): bool
Expand Down
2 changes: 1 addition & 1 deletion src/Io/MiddlewareHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MiddlewareHandler
/** @param list<callable> $handlers */
public function __construct(array $handlers)
{
assert(count($handlers) >= 2);
\assert(\count($handlers) >= 2);

$this->handlers = $handlers;
}
Expand Down
12 changes: 6 additions & 6 deletions src/Io/RouteHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function map(array $methods, string $route, $handler, ...$handlers): void
$handlers = [$handler];
}

$last = key($handlers);
$last = \key($handlers);
$container = $this->container;
foreach ($handlers as $i => $handler) {
if ($handler instanceof Container && $i !== $last) {
Expand All @@ -66,7 +66,7 @@ public function map(array $methods, string $route, $handler, ...$handlers): void
}

/** @var non-empty-array<callable> $handlers */
$handler = \count($handlers) > 1 ? new MiddlewareHandler(array_values($handlers)) : \reset($handlers);
$handler = \count($handlers) > 1 ? new MiddlewareHandler(\array_values($handlers)) : \reset($handlers);
$this->routeDispatcher = null;
$this->routeCollector->addRoute($methods, $route, $handler);
}
Expand All @@ -88,15 +88,15 @@ public function __invoke(ServerRequestInterface $request)
}

$routeInfo = $this->routeDispatcher->dispatch($request->getMethod(), $target);
assert(\is_array($routeInfo) && isset($routeInfo[0]));
\assert(\is_array($routeInfo) && isset($routeInfo[0]));

// happy path: matching route found, assign route attributes and invoke request handler
if ($routeInfo[0] === \FastRoute\Dispatcher::FOUND) {
$handler = $routeInfo[1];
$vars = $routeInfo[2];

foreach ($vars as $key => $value) {
$request = $request->withAttribute($key, rawurldecode($value));
$request = $request->withAttribute($key, \rawurldecode($value));
}

return $handler($request);
Expand All @@ -108,8 +108,8 @@ public function __invoke(ServerRequestInterface $request)
}

// unexpected request method for route: report error `405 Method Not Allowed`
assert($routeInfo[0] === \FastRoute\Dispatcher::METHOD_NOT_ALLOWED);
assert(\is_array($routeInfo[1]) && \count($routeInfo[1]) > 0);
\assert($routeInfo[0] === \FastRoute\Dispatcher::METHOD_NOT_ALLOWED);
\assert(\is_array($routeInfo[1]) && \count($routeInfo[1]) > 0);

return $this->errorHandler->requestMethodNotAllowed($routeInfo[1]);
}
Expand Down
30 changes: 15 additions & 15 deletions src/Io/SapiHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function requestFromGlobals(): ServerRequestInterface
} else {
foreach ($_SERVER as $key => $value) {
if (\strpos($key, 'HTTP_') === 0) {
$key = str_replace(' ', '-', \ucwords(\strtolower(\str_replace('_', ' ', \substr($key, 5)))));
$key = \str_replace(' ', '-', \ucwords(\strtolower(\str_replace('_', ' ', \substr($key, 5)))));
$headers[$key] = $value;

if ($host === null && $key === 'Host') {
Expand All @@ -73,15 +73,15 @@ public function requestFromGlobals(): ServerRequestInterface
$url = (($_SERVER['HTTPS'] ?? null) === 'on' ? 'https://' : 'http://') . $target;
}

$body = file_get_contents('php://input');
assert(\is_string($body));
$body = \file_get_contents('php://input');
\assert(\is_string($body));

$request = new ServerRequest(
$_SERVER['REQUEST_METHOD'] ?? 'GET',
$url,
$headers,
$body,
substr($_SERVER['SERVER_PROTOCOL'] ?? 'http/1.1', 5),
\substr($_SERVER['SERVER_PROTOCOL'] ?? 'http/1.1', 5),
$_SERVER
);
if ($host === null) {
Expand Down Expand Up @@ -121,22 +121,22 @@ public function sendResponse(ResponseInterface $response): void

// remove default "Content-Type" header set by PHP (default_mimetype)
if (!$response->hasHeader('Content-Type')) {
header('Content-Type:');
header_remove('Content-Type');
\header('Content-Type:');
\header_remove('Content-Type');
}

// send all headers without applying default "; charset=utf-8" set by PHP (default_charset)
$old = ini_get('default_charset');
assert(\is_string($old));
ini_set('default_charset', '');
$old = \ini_get('default_charset');
\assert(\is_string($old));
\ini_set('default_charset', '');
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header($name . ': ' . $value, false);
\header($name . ': ' . $value, false);
}
}
ini_set('default_charset', $old);
\ini_set('default_charset', $old);

header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status . ' ' . $response->getReasonPhrase());
\header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status . ' ' . $response->getReasonPhrase());

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'HEAD' || $status === Response::STATUS_NO_CONTENT || $status === Response::STATUS_NOT_MODIFIED) {
$body->close();
Expand All @@ -145,8 +145,8 @@ public function sendResponse(ResponseInterface $response): void

if ($body instanceof ReadableStreamInterface) {
// try to disable nginx buffering (http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering)
if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') === 0) {
header('X-Accel-Buffering: no');
if (isset($_SERVER['SERVER_SOFTWARE']) && \strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') === 0) {
\header('X-Accel-Buffering: no');
}

// clear output buffer to show streaming output (default in cli-server)
Expand All @@ -157,7 +157,7 @@ public function sendResponse(ResponseInterface $response): void
// flush data whenever stream reports one data chunk
$body->on('data', function ($chunk) {
echo $chunk;
flush();
\flush();
});
} else {
echo $body;
Expand Down