public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $err = null)
{
if ($err !== null && $this->raiseThrowables) {
$this->raiseThrowableFromError($err);
}
if (null !== $err) {
$this->triggerErrorDeprecation();
}
if (!$this->responsePrototype) {
$this->setResponsePrototype($response);
}
$dispatch = $this->dispatch;
$done = $this->nextDelegate;
$request = $this->resetPath($request);
// No middleware remains; done
if ($this->queue->isEmpty()) {
return $this->dispatchNextDelegate($done, $request, $response, $err);
}
$layer = $this->queue->dequeue();
$path = $request->getUri()->getPath() ?: '/';
$route = $layer->path;
$normalizedRoute = strlen($route) > 1 ? rtrim($route, '/') : $route;
// Skip if layer path does not match current url
if (substr(strtolower($path), 0, strlen($normalizedRoute)) !== strtolower($normalizedRoute)) {
return $this($request, $response, $err);
}
// Skip if match is not at a border ('/', '.', or end)
$border = $this->getBorder($path, $normalizedRoute);
if ($border && '/' !== $border && '.' !== $border) {
return $this($request, $response, $err);
}
// Trim off the part of the url that matches the layer route
if (!empty($route) && $route !== '/') {
$request = $this->stripRouteFromPath($request, $route);
}
$result = $dispatch($layer, $err, $request, $response, $this);
return $result instanceof ResponseInterface ? $result : $response;
}