diff --git a/app/Server/Factory.php b/app/Server/Factory.php index 8efd8f6..fba4170 100644 --- a/app/Server/Factory.php +++ b/app/Server/Factory.php @@ -106,7 +106,7 @@ class Factory protected function addAdminRoutes() { - $adminCondition = 'request.headers.get("Host") matches "/'.config('expose.dashboard_subdomain').'./i"'; + $adminCondition = 'request.headers.get("Host") matches "/'.config('expose.dashboard_subdomain').'\./i"'; $this->router->get('/', LoginController::class, $adminCondition); $this->router->post('/', VerifyLoginController::class, $adminCondition); @@ -121,6 +121,8 @@ class Factory app()->singleton(Configuration::class, function ($app) { return new Configuration($this->hostname, $this->port); }); + + return $this; } protected function bindSubdomainGenerator() @@ -128,6 +130,8 @@ class Factory app()->singleton(SubdomainGenerator::class, function ($app) { return $app->make(RandomSubdomainGenerator::class); }); + + return $this; } protected function bindConnectionManager() @@ -135,23 +139,20 @@ class Factory app()->singleton(ConnectionManagerContract::class, function ($app) { return $app->make(ConnectionManager::class); }); + + return $this; } public function createServer() { $socket = new Server("{$this->host}:{$this->port}", $this->loop); - $this->bindConfiguration(); - - $this->bindSubdomainGenerator(); - - $this->bindDatabase(); - - $this->ensureDatabaseIsInitialized(); - - $this->bindConnectionManager(); - - $this->addAdminRoutes(); + $this->bindConfiguration() + ->bindSubdomainGenerator() + ->bindDatabase() + ->ensureDatabaseIsInitialized() + ->bindConnectionManager() + ->addAdminRoutes(); $controlConnection = $this->addControlConnectionRoute(); @@ -176,6 +177,8 @@ class Factory $factory = new \Clue\React\SQLite\Factory($this->loop); return $factory->openLazy(base_path('database/expose.db')); }); + + return $this; } protected function ensureDatabaseIsInitialized() @@ -193,6 +196,8 @@ class Factory foreach ($migrations as $migration) { $db->exec($migration->getContents()); } + + return $this; } public function validateAuthTokens(bool $validate) diff --git a/app/Server/Http/Controllers/TunnelMessageController.php b/app/Server/Http/Controllers/TunnelMessageController.php index 20e4b50..3966617 100644 --- a/app/Server/Http/Controllers/TunnelMessageController.php +++ b/app/Server/Http/Controllers/TunnelMessageController.php @@ -9,6 +9,7 @@ use App\Server\Connections\ControlConnection; use GuzzleHttp\Psr7\Response; use Illuminate\Http\Request; use Illuminate\Pipeline\Pipeline; +use Illuminate\Support\Str; use Nyholm\Psr7\Factory\Psr17Factory; use Ratchet\ConnectionInterface; use Ratchet\RFC6455\Messaging\Frame; @@ -37,10 +38,14 @@ class TunnelMessageController extends PostController public function handle(Request $request, ConnectionInterface $httpConnection) { - $controlConnection = $this->connectionManager->findControlConnectionForSubdomain($this->detectSubdomain($request)); + $subdomain = $this->detectSubdomain($request); + + $controlConnection = $this->connectionManager->findControlConnectionForSubdomain($subdomain); if (is_null($controlConnection)) { - $httpConnection->send(str(new Response(404, [], 'Not found'))); + $httpConnection->send( + respond_html($this->getView('server.errors.404', ['subdomain' => $subdomain])) + ); $httpConnection->close(); return; } @@ -50,9 +55,9 @@ class TunnelMessageController extends PostController protected function detectSubdomain(Request $request): ?string { - $domainParts = explode('.', $request->getHost()); + $subdomain = Str::before($request->getHost(), '.'.$this->configuration->hostname()); - return trim($domainParts[0]); + return $subdomain === $request->getHost() ? null : $subdomain; } protected function sendRequestToClient(Request $request, ControlConnection $controlConnection, ConnectionInterface $httpConnection) @@ -85,7 +90,7 @@ class TunnelMessageController extends PostController $host = $this->configuration->hostname(); - if (! $request->isSecure()) { + if (!$request->isSecure()) { $host .= ":{$this->configuration->port()}"; } @@ -93,7 +98,7 @@ class TunnelMessageController extends PostController $request->headers->set('X-Forwarded-Proto', $request->isSecure() ? 'https' : 'http'); $request->headers->set('X-Expose-Request-ID', uniqid()); $request->headers->set('Upgrade-Insecure-Requests', 1); - $request->headers->set('X-Exposed-By', config('app.name') . ' '. config('app.version')); + $request->headers->set('X-Exposed-By', config('app.name') . ' ' . config('app.version')); $request->headers->set('X-Original-Host', "{$controlConnection->subdomain}.{$host}"); return $request; diff --git a/resources/views/server/errors/404.twig b/resources/views/server/errors/404.twig new file mode 100644 index 0000000..342b72b --- /dev/null +++ b/resources/views/server/errors/404.twig @@ -0,0 +1 @@ +The tunnel {{ subdomain }} was not found.