This commit is contained in:
Marcel Pociot
2020-05-04 16:00:13 +02:00
parent 2d49b648b0
commit f8464d2b4d
4 changed files with 78 additions and 21 deletions

View File

@@ -15,6 +15,8 @@ use function Ratchet\Client\connect;
class Client class Client
{ {
protected const MAX_CONNECTION_RETRIES = 3;
/** @var LoopInterface */ /** @var LoopInterface */
protected $loop; protected $loop;
@@ -24,6 +26,9 @@ class Client
/** @var CliRequestLogger */ /** @var CliRequestLogger */
protected $logger; protected $logger;
/** @var int */
protected $connectionRetries = 0;
/** @var int */ /** @var int */
protected $timeConnected = 0; protected $timeConnected = 0;
@@ -72,15 +77,17 @@ class Client
connect($wsProtocol."://{$this->configuration->host()}:{$this->configuration->port()}/expose/control?authToken={$authToken}", [], [ connect($wsProtocol."://{$this->configuration->host()}:{$this->configuration->port()}/expose/control?authToken={$authToken}", [], [
'X-Expose-Control' => 'enabled', 'X-Expose-Control' => 'enabled',
], $this->loop) ], $this->loop)
->then(function (WebSocket $clientConnection) use ($sharedUrl, $subdomain, $deferred) { ->then(function (WebSocket $clientConnection) use ($sharedUrl, $subdomain, $deferred, $authToken) {
$this->connectionRetries = 0;
$connection = ControlConnection::create($clientConnection); $connection = ControlConnection::create($clientConnection);
$connection->authenticate($sharedUrl, $subdomain); $connection->authenticate($sharedUrl, $subdomain);
$clientConnection->on('close', function() use ($deferred) { $clientConnection->on('close', function() use ($deferred, $sharedUrl, $subdomain, $authToken) {
$this->logger->error('Connection to server closed.'); $this->logger->error('Connection to server closed.');
$this->exit($deferred); $this->retryConnectionOrExit($sharedUrl, $subdomain, $authToken);
}); });
$connection->on('authenticationFailed', function ($data) use ($deferred) { $connection->on('authenticationFailed', function ($data) use ($deferred) {
@@ -124,7 +131,11 @@ class Client
$deferred->resolve(); $deferred->resolve();
}); });
}, function (\Exception $e) use ($deferred) { }, function (\Exception $e) use ($deferred, $sharedUrl, $subdomain, $authToken) {
if ($this->connectionRetries > 0) {
$this->retryConnectionOrExit($sharedUrl, $subdomain, $authToken);
return;
}
$this->logger->error("Could not connect to the server."); $this->logger->error("Could not connect to the server.");
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
@@ -142,4 +153,19 @@ class Client
exit(1); exit(1);
}); });
} }
protected function retryConnectionOrExit(string $sharedUrl, $subdomain, $authToken = '')
{
$this->connectionRetries++;
if ($this->connectionRetries <= static::MAX_CONNECTION_RETRIES) {
$this->loop->addTimer($this->connectionRetries, function() use ($sharedUrl, $subdomain, $authToken) {
$this->logger->info("Retrying connection ({$this->connectionRetries}/".static::MAX_CONNECTION_RETRIES.")");
$this->connectToServer($sharedUrl, $subdomain, $authToken);
});
} else {
exit(1);
}
}
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
return [ return [
'host' => 'localhost', 'host' => 'expose.dev',
'port' => 8080, 'port' => 443,
'auth_token' => '', 'auth_token' => '',
'admin' => [ 'admin' => [

View File

@@ -100,8 +100,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="p-5 flex flex-row"> <div class="p-5 flex flex-col md:flex-row">
<div class="w-1/3 flex flex-col mr-5"> <div class="w-full md:w-1/3 flex flex-col mr-5">
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8"> <div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
<div class="flex mb-4"> <div class="flex mb-4">
<span class="h-8 inline-flex rounded-md shadow-sm"> <span class="h-8 inline-flex rounded-md shadow-sm">
@@ -142,10 +142,25 @@
@{ log.request.uri } @{ log.request.uri }
</p> </p>
<span class="text-xs">@{ log.subdomain }</span> <span class="text-xs">@{ log.subdomain }</span>
<span class="text-xs text-gray-600">@{ log.performed_at }</span>
</td> </td>
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 text-gray-500"> <td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 text-gray-500">
<div v-if="log.response"> <div v-if="log.response">
@{ log.response.status } - @{ log.response.reason } <span
v-if="log.response.status >= 200 && log.response.status < 300"
class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-green-100 text-green-800">
@{ log.response.status } - @{ log.response.reason }
</span>
<span
v-if="log.response.status >= 400 && log.response.status < 500"
class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-yellow-100 text-yellow-800">
@{ log.response.status } - @{ log.response.reason }
</span>
<span
v-if="log.response.status >= 500"
class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-red-100 text-red-800">
@{ log.response.status } - @{ log.response.reason }
</span>
</div> </div>
<div v-else> <div v-else>
... ...
@@ -162,7 +177,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="w-2/3 ml-5"> <div class="w-full md:w-2/3 mt-5 md:mt-0 md:ml-5">
<div v-if="currentLog" class="bg-white shadow overflow-hidden sm:rounded-lg"> <div v-if="currentLog" class="bg-white shadow overflow-hidden sm:rounded-lg">
<div class="px-4 py-5 border-b border-gray-200 sm:px-6"> <div class="px-4 py-5 border-b border-gray-200 sm:px-6">
<h3 class="text-lg leading-6 font-medium text-gray-900 flex"> <h3 class="text-lg leading-6 font-medium text-gray-900 flex">
@@ -185,7 +200,23 @@
</span> </span>
</h3> </h3>
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500"> <p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
Status code: @{ currentLog.response?.status}
<span class="text-xs text-gray-600">Received at: @{ currentLog.performed_at }</span>
<span
v-if="currentLog.response?.status >= 200 && currentLog.response?.status < 300"
class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-green-100 text-green-800">
@{ currentLog.response?.status } - @{ currentLog.response?.reason }
</span>
<span
v-if="currentLog.response?.status >= 400 && currentLog.response?.status < 500"
class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-yellow-100 text-yellow-800">
@{ currentLog.response?.status } - @{ currentLog.response?.reason }
</span>
<span
v-if="currentLog.response?.status >= 500"
class="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-red-100 text-red-800">
@{ currentLog.response?.status } - @{ currentLog.response?.reason }
</span>
</p> </p>
</div> </div>
<div> <div>
@@ -225,7 +256,7 @@
<div v-for="(value, name) in currentLog.request.query" <div v-for="(value, name) in currentLog.request.query"
:key="'query_' + name" :key="'query_' + name"
class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500"> <dt class="text-sm leading-5 font-medium text-gray-700">
@{ name } @{ name }
</dt> </dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@@ -241,7 +272,7 @@
<div v-for="parameter in currentLog.request.post" <div v-for="parameter in currentLog.request.post"
:key="'post_' + parameter.name" :key="'post_' + parameter.name"
class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500"> <dt class="text-sm leading-5 font-medium text-gray-700">
@{ parameter.name } @{ parameter.name }
</dt> </dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@@ -259,7 +290,7 @@
<div v-for="(value, header) in currentLog.request.headers" <div v-for="(value, header) in currentLog.request.headers"
:key="header" :key="header"
class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500"> <dt class="text-sm leading-5 font-medium text-gray-700">
@{ header } @{ header }
</dt> </dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@@ -281,7 +312,7 @@
<div v-for="(value, header) in currentLog.response.headers" <div v-for="(value, header) in currentLog.response.headers"
:key="header" :key="header"
class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500"> <dt class="text-sm leading-5 font-medium text-gray-700">
@{ header } @{ header }
</dt> </dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
@@ -297,7 +328,7 @@
<div v-for="(value, key) in currentLog.request.additional_data" <div v-for="(value, key) in currentLog.request.additional_data"
:key="'debug'+key" :key="'debug'+key"
class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm leading-5 font-medium text-gray-500"> <dt class="text-sm leading-5 font-medium text-gray-700">
@{ key } @{ key }
</dt> </dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">

View File

@@ -70,7 +70,7 @@ class AdminTest extends TestCase
$this->app['config']['expose.admin.validate_auth_tokens'] = false; $this->app['config']['expose.admin.validate_auth_tokens'] = false;
/** @var ResponseInterface $response */ /** @var ResponseInterface $response */
$this->await($this->browser->post('http://127.0.0.1:8080/settings', [ $this->await($this->browser->post('http://127.0.0.1:8080/api/settings', [
'Host' => 'expose.localhost', 'Host' => 'expose.localhost',
'Authorization' => base64_encode("username:secret"), 'Authorization' => base64_encode("username:secret"),
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'
@@ -85,7 +85,7 @@ class AdminTest extends TestCase
public function it_can_create_users() public function it_can_create_users()
{ {
/** @var Response $response */ /** @var Response $response */
$response = $this->await($this->browser->post('http://127.0.0.1:8080/users', [ $response = $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [
'Host' => 'expose.localhost', 'Host' => 'expose.localhost',
'Authorization' => base64_encode("username:secret"), 'Authorization' => base64_encode("username:secret"),
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'
@@ -103,7 +103,7 @@ class AdminTest extends TestCase
public function it_can_delete_users() public function it_can_delete_users()
{ {
/** @var Response $response */ /** @var Response $response */
$this->await($this->browser->post('http://127.0.0.1:8080/users', [ $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [
'Host' => 'expose.localhost', 'Host' => 'expose.localhost',
'Authorization' => base64_encode("username:secret"), 'Authorization' => base64_encode("username:secret"),
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'
@@ -112,7 +112,7 @@ class AdminTest extends TestCase
]))); ])));
$this->await($this->browser->delete('http://127.0.0.1:8080/users/1', [ $this->await($this->browser->delete('http://127.0.0.1:8080/api/users/1', [
'Host' => 'expose.localhost', 'Host' => 'expose.localhost',
'Authorization' => base64_encode("username:secret"), 'Authorization' => base64_encode("username:secret"),
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'
@@ -125,7 +125,7 @@ class AdminTest extends TestCase
public function it_can_list_all_users() public function it_can_list_all_users()
{ {
/** @var Response $response */ /** @var Response $response */
$this->await($this->browser->post('http://127.0.0.1:8080/users', [ $this->await($this->browser->post('http://127.0.0.1:8080/api/users', [
'Host' => 'expose.localhost', 'Host' => 'expose.localhost',
'Authorization' => base64_encode("username:secret"), 'Authorization' => base64_encode("username:secret"),
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'