mirror of
https://github.com/bitinflow/expose.git
synced 2026-03-14 05:55:54 +00:00
Compare commits
5 Commits
2.2.2
...
fix-http-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
763b45a77e | ||
|
|
f137ea298b | ||
|
|
2f457352c5 | ||
|
|
c5cdd8c352 | ||
|
|
6f72d719bf |
@@ -60,16 +60,11 @@ class Client
|
|||||||
return $sharedUrl;
|
return $sharedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = Arr::get($parsedUrl, 'host', Arr::get($parsedUrl, 'path'));
|
$host = Arr::get($parsedUrl, 'host', Arr::get($parsedUrl, 'path', 'localhost'));
|
||||||
|
$scheme = Arr::get($parsedUrl, 'scheme', 'http');
|
||||||
|
$port = Arr::get($parsedUrl, 'port', $scheme === 'https' ? 443 : 80);
|
||||||
|
|
||||||
if (Arr::get($parsedUrl, 'scheme') === 'https') {
|
return sprintf('%s://%s:%s', $scheme, $host, $port);
|
||||||
$url .= ':443';
|
|
||||||
}
|
|
||||||
if (! is_null($port = Arr::get($parsedUrl, 'port'))) {
|
|
||||||
$url .= ":{$port}";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function connectToServer(string $sharedUrl, $subdomain, $authToken = ''): PromiseInterface
|
public function connectToServer(string $sharedUrl, $subdomain, $authToken = ''): PromiseInterface
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ use function GuzzleHttp\Psr7\str;
|
|||||||
use Laminas\Http\Request;
|
use Laminas\Http\Request;
|
||||||
use Psr\Http\Message\RequestInterface;
|
use Psr\Http\Message\RequestInterface;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
use Ratchet\Client\WebSocket;
|
use Ratchet\Client\WebSocket;
|
||||||
use Ratchet\RFC6455\Messaging\Frame;
|
use Ratchet\RFC6455\Messaging\Frame;
|
||||||
use React\EventLoop\LoopInterface;
|
use React\EventLoop\LoopInterface;
|
||||||
use React\Socket\Connector;
|
use React\Socket\Connector;
|
||||||
|
use React\Stream\ReadableStreamInterface;
|
||||||
|
|
||||||
class HttpClient
|
class HttpClient
|
||||||
{
|
{
|
||||||
@@ -84,22 +86,17 @@ class HttpClient
|
|||||||
protected function sendRequestToApplication(RequestInterface $request, $proxyConnection = null)
|
protected function sendRequestToApplication(RequestInterface $request, $proxyConnection = null)
|
||||||
{
|
{
|
||||||
(new Browser($this->loop, $this->createConnector()))
|
(new Browser($this->loop, $this->createConnector()))
|
||||||
->withOptions([
|
->withFollowRedirects(false)
|
||||||
'followRedirects' => false,
|
->withRejectErrorResponse(false)
|
||||||
'obeySuccessCode' => false,
|
->requestStreaming($request->getMethod(), $this->getExposeUri($request), $request->getHeaders(), $request->getBody())
|
||||||
'streaming' => true,
|
|
||||||
])
|
|
||||||
->send($request)
|
|
||||||
->then(function (ResponseInterface $response) use ($proxyConnection) {
|
->then(function (ResponseInterface $response) use ($proxyConnection) {
|
||||||
if (! isset($response->buffer)) {
|
if (! isset($response->buffer)) {
|
||||||
$response = $this->rewriteResponseHeaders($response);
|
|
||||||
|
|
||||||
$response->buffer = str($response);
|
$response->buffer = str($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sendChunkToServer($response->buffer, $proxyConnection);
|
$this->sendChunkToServer($response->buffer, $proxyConnection);
|
||||||
|
|
||||||
/* @var $body \React\Stream\ReadableStreamInterface */
|
/* @var $body ReadableStreamInterface */
|
||||||
$body = $response->getBody();
|
$body = $response->getBody();
|
||||||
|
|
||||||
$this->logResponse(str($response));
|
$this->logResponse(str($response));
|
||||||
@@ -136,24 +133,14 @@ class HttpClient
|
|||||||
return Request::fromString($data);
|
return Request::fromString($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function rewriteResponseHeaders(ResponseInterface $response)
|
private function getExposeUri(RequestInterface $request): UriInterface
|
||||||
{
|
{
|
||||||
if (! $response->hasHeader('Location')) {
|
$exposeProto = $request->getHeader('x-expose-proto')[0];
|
||||||
return $response;
|
$exposeHost = explode(':', $request->getHeader('x-expose-host')[0]);
|
||||||
}
|
|
||||||
|
|
||||||
$location = $response->getHeaderLine('Location');
|
return $request->getUri()
|
||||||
|
->withScheme($exposeProto)
|
||||||
if (! strstr($location, $this->connectionData->host)) {
|
->withHost($exposeHost[0])
|
||||||
return $response;
|
->withPort($exposeHost[1]);
|
||||||
}
|
|
||||||
|
|
||||||
$location = str_replace(
|
|
||||||
$this->connectionData->host,
|
|
||||||
$this->configuration->getUrl($this->connectionData->subdomain),
|
|
||||||
$location
|
|
||||||
);
|
|
||||||
|
|
||||||
return $response->withHeader('Location', $location);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,15 +45,13 @@ class ConnectionManager implements ConnectionManagerContract
|
|||||||
|
|
||||||
public function storeConnection(string $host, ?string $subdomain, ConnectionInterface $connection): ControlConnection
|
public function storeConnection(string $host, ?string $subdomain, ConnectionInterface $connection): ControlConnection
|
||||||
{
|
{
|
||||||
$clientId = (string) uniqid();
|
$connection->client_id = sha1(uniqid('', true));
|
||||||
|
|
||||||
$connection->client_id = $clientId;
|
|
||||||
|
|
||||||
$storedConnection = new ControlConnection(
|
$storedConnection = new ControlConnection(
|
||||||
$connection,
|
$connection,
|
||||||
$host,
|
$host,
|
||||||
$subdomain ?? $this->subdomainGenerator->generateSubdomain(),
|
$subdomain ?? $this->subdomainGenerator->generateSubdomain(),
|
||||||
$clientId,
|
$connection->client_id,
|
||||||
$this->getAuthTokenFromConnection($connection)
|
$this->getAuthTokenFromConnection($connection)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -113,9 +113,13 @@ class TunnelMessageController extends Controller
|
|||||||
$host .= ":{$this->configuration->port()}";
|
$host .= ":{$this->configuration->port()}";
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->headers->set('Host', $controlConnection->host);
|
$exposeUrl = parse_url($controlConnection->host);
|
||||||
|
|
||||||
|
$request->headers->set('Host', "{$controlConnection->subdomain}.{$host}");
|
||||||
$request->headers->set('X-Forwarded-Proto', $request->isSecure() ? 'https' : 'http');
|
$request->headers->set('X-Forwarded-Proto', $request->isSecure() ? 'https' : 'http');
|
||||||
$request->headers->set('X-Expose-Request-ID', uniqid());
|
$request->headers->set('X-Expose-Request-ID', sha1(uniqid('', true)));
|
||||||
|
$request->headers->set('X-Expose-Host', sprintf('%s:%s', $exposeUrl['host'], $exposeUrl['port']));
|
||||||
|
$request->headers->set('X-Expose-Proto', $exposeUrl['scheme']);
|
||||||
$request->headers->set('Upgrade-Insecure-Requests', 1);
|
$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}");
|
$request->headers->set('X-Original-Host', "{$controlConnection->subdomain}.{$host}");
|
||||||
|
|||||||
Reference in New Issue
Block a user