From 2d3349eee632e7357ed1eb6905444194a28a4ec0 Mon Sep 17 00:00:00 2001 From: Wolfy-J Date: Mon, 26 Oct 2020 21:02:56 +0300 Subject: - working on new cmd and logger setup --- src/Diactoros/ServerRequestFactory.php | 26 ---- src/Diactoros/StreamFactory.php | 57 --------- src/Diactoros/UploadedFileFactory.php | 36 ------ src/Exception/RoadRunnerException.php | 2 +- src/Exceptions/RoadRunnerException.php | 18 --- src/Http/HttpClient.php | 75 ++++++++++++ src/Http/PSR7Client.php | 217 +++++++++++++++++++++++++++++++++ src/HttpClient.php | 75 ------------ src/Logger/.empty | 0 src/Metrics.php | 80 ------------ src/Metrics/Metrics.php | 80 ++++++++++++ src/Metrics/MetricsInterface.php | 64 ++++++++++ src/MetricsInterface.php | 64 ---------- src/PSR7Client.php | 217 --------------------------------- src/WorkerInterface.php | 0 15 files changed, 437 insertions(+), 574 deletions(-) delete mode 100755 src/Diactoros/ServerRequestFactory.php delete mode 100755 src/Diactoros/StreamFactory.php delete mode 100755 src/Diactoros/UploadedFileFactory.php delete mode 100755 src/Exceptions/RoadRunnerException.php create mode 100644 src/Http/HttpClient.php create mode 100644 src/Http/PSR7Client.php delete mode 100755 src/HttpClient.php create mode 100644 src/Logger/.empty delete mode 100755 src/Metrics.php create mode 100644 src/Metrics/Metrics.php create mode 100644 src/Metrics/MetricsInterface.php delete mode 100755 src/MetricsInterface.php delete mode 100755 src/PSR7Client.php create mode 100644 src/WorkerInterface.php (limited to 'src') diff --git a/src/Diactoros/ServerRequestFactory.php b/src/Diactoros/ServerRequestFactory.php deleted file mode 100755 index 3fcf8e29..00000000 --- a/src/Diactoros/ServerRequestFactory.php +++ /dev/null @@ -1,26 +0,0 @@ -createStreamFromResource($resource); - } - - /** - * @inheritdoc - */ - public function createStreamFromFile(string $file, string $mode = 'rb'): StreamInterface - { - $resource = fopen($file, $mode); - - if (! \is_resource($resource)) { - throw new RuntimeException('Cannot create stream'); - } - - return $this->createStreamFromResource($resource); - } - - /** - * @inheritdoc - */ - public function createStreamFromResource($resource): StreamInterface - { - return new Stream($resource); - } -} diff --git a/src/Diactoros/UploadedFileFactory.php b/src/Diactoros/UploadedFileFactory.php deleted file mode 100755 index 45773287..00000000 --- a/src/Diactoros/UploadedFileFactory.php +++ /dev/null @@ -1,36 +0,0 @@ -getSize(); - } - - /** @var resource $stream */ - return new UploadedFile($stream, $size, $error, $clientFilename, $clientMediaType); - } -} diff --git a/src/Exception/RoadRunnerException.php b/src/Exception/RoadRunnerException.php index f83c3dd4..cd657502 100755 --- a/src/Exception/RoadRunnerException.php +++ b/src/Exception/RoadRunnerException.php @@ -9,6 +9,6 @@ declare(strict_types=1); namespace Spiral\RoadRunner\Exception; -class RoadRunnerException extends \Spiral\RoadRunner\Exceptions\RoadRunnerException +class RoadRunnerException extends \RuntimeException { } diff --git a/src/Exceptions/RoadRunnerException.php b/src/Exceptions/RoadRunnerException.php deleted file mode 100755 index 43967893..00000000 --- a/src/Exceptions/RoadRunnerException.php +++ /dev/null @@ -1,18 +0,0 @@ -worker = $worker; + } + + /** + * @return Worker + */ + public function getWorker(): Worker + { + return $this->worker; + } + + /** + * @return mixed[]|null Request information as ['ctx'=>[], 'body'=>string] + * or null if termination request or invalid context. + */ + public function acceptRequest(): ?array + { + $body = $this->getWorker()->receive($ctx); + if (empty($body) && empty($ctx)) { + // termination request + return null; + } + + $ctx = json_decode($ctx, true); + if ($ctx === null) { + // invalid context + return null; + } + + return ['ctx' => $ctx, 'body' => $body]; + } + + /** + * Send response to the application server. + * + * @param int $status Http status code + * @param string $body Body of response + * @param string[][] $headers An associative array of the message's headers. Each + * key MUST be a header name, and each value MUST be an array of strings + * for that header. + */ + public function respond(int $status, string $body, array $headers = []): void + { + if (empty($headers)) { + // this is required to represent empty header set as map and not as array + $headers = new \stdClass(); + } + + $this->getWorker()->send( + $body, + (string) json_encode(['status' => $status, 'headers' => $headers]) + ); + } +} diff --git a/src/Http/PSR7Client.php b/src/Http/PSR7Client.php new file mode 100644 index 00000000..94a9457b --- /dev/null +++ b/src/Http/PSR7Client.php @@ -0,0 +1,217 @@ +httpClient = new HttpClient($worker); + $this->requestFactory = $requestFactory ?? new Diactoros\ServerRequestFactory(); + $this->streamFactory = $streamFactory ?? new Diactoros\StreamFactory(); + $this->uploadsFactory = $uploadsFactory ?? new Diactoros\UploadedFileFactory(); + $this->originalServer = $_SERVER; + } + + /** + * @return Worker + */ + public function getWorker(): Worker + { + return $this->httpClient->getWorker(); + } + + /** + * @return ServerRequestInterface|null + */ + public function acceptRequest(): ?ServerRequestInterface + { + $rawRequest = $this->httpClient->acceptRequest(); + if ($rawRequest === null) { + return null; + } + + $_SERVER = $this->configureServer($rawRequest['ctx']); + + $request = $this->requestFactory->createServerRequest( + $rawRequest['ctx']['method'], + $rawRequest['ctx']['uri'], + $_SERVER + ); + + parse_str($rawRequest['ctx']['rawQuery'], $query); + + $request = $request + ->withProtocolVersion(static::fetchProtocolVersion($rawRequest['ctx']['protocol'])) + ->withCookieParams($rawRequest['ctx']['cookies']) + ->withQueryParams($query) + ->withUploadedFiles($this->wrapUploads($rawRequest['ctx']['uploads'])); + + foreach ($rawRequest['ctx']['attributes'] as $name => $value) { + $request = $request->withAttribute($name, $value); + } + + foreach ($rawRequest['ctx']['headers'] as $name => $value) { + $request = $request->withHeader($name, $value); + } + + if ($rawRequest['ctx']['parsed']) { + return $request->withParsedBody(json_decode($rawRequest['body'], true)); + } + + if ($rawRequest['body'] !== null) { + return $request->withBody($this->streamFactory->createStream($rawRequest['body'])); + } + + return $request; + } + + /** + * Send response to the application server. + * + * @param ResponseInterface $response + */ + public function respond(ResponseInterface $response): void + { + $this->httpClient->respond( + $response->getStatusCode(), + $response->getBody()->__toString(), + $response->getHeaders() + ); + } + + /** + * Returns altered copy of _SERVER variable. Sets ip-address, + * request-time and other values. + * + * @param mixed[] $ctx + * @return mixed[] + */ + protected function configureServer(array $ctx): array + { + $server = $this->originalServer; + + $server['REQUEST_URI'] = $ctx['uri']; + $server['REQUEST_TIME'] = time(); + $server['REQUEST_TIME_FLOAT'] = microtime(true); + $server['REMOTE_ADDR'] = $ctx['attributes']['ipAddress'] ?? $ctx['remoteAddr'] ?? '127.0.0.1'; + $server['REQUEST_METHOD'] = $ctx['method']; + + $server['HTTP_USER_AGENT'] = ''; + foreach ($ctx['headers'] as $key => $value) { + $key = strtoupper(str_replace('-', '_', $key)); + if (\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH'])) { + $server[$key] = implode(', ', $value); + } else { + $server['HTTP_' . $key] = implode(', ', $value); + } + } + + return $server; + } + + /** + * Wraps all uploaded files with UploadedFile. + * + * @param array[] $files + * + * @return UploadedFileInterface[]|mixed[] + */ + private function wrapUploads($files): array + { + if (empty($files)) { + return []; + } + + $result = []; + foreach ($files as $index => $f) { + if (!isset($f['name'])) { + $result[$index] = $this->wrapUploads($f); + continue; + } + + if (UPLOAD_ERR_OK === $f['error']) { + $stream = $this->streamFactory->createStreamFromFile($f['tmpName']); + } else { + $stream = $this->streamFactory->createStream(); + } + + $result[$index] = $this->uploadsFactory->createUploadedFile( + $stream, + $f['size'], + $f['error'], + $f['name'], + $f['mime'] + ); + } + + return $result; + } + + /** + * Normalize HTTP protocol version to valid values + * + * @param string $version + * @return string + */ + private static function fetchProtocolVersion(string $version): string + { + $v = substr($version, 5); + + if ($v === '2.0') { + return '2'; + } + + // Fallback for values outside of valid protocol versions + if (!in_array($v, static::$allowedVersions, true)) { + return '1.1'; + } + + return $v; + } +} diff --git a/src/HttpClient.php b/src/HttpClient.php deleted file mode 100755 index 4ca152c8..00000000 --- a/src/HttpClient.php +++ /dev/null @@ -1,75 +0,0 @@ -worker = $worker; - } - - /** - * @return Worker - */ - public function getWorker(): Worker - { - return $this->worker; - } - - /** - * @return mixed[]|null Request information as ['ctx'=>[], 'body'=>string] - * or null if termination request or invalid context. - */ - public function acceptRequest(): ?array - { - $body = $this->getWorker()->receive($ctx); - if (empty($body) && empty($ctx)) { - // termination request - return null; - } - - $ctx = json_decode($ctx, true); - if ($ctx === null) { - // invalid context - return null; - } - - return ['ctx' => $ctx, 'body' => $body]; - } - - /** - * Send response to the application server. - * - * @param int $status Http status code - * @param string $body Body of response - * @param string[][] $headers An associative array of the message's headers. Each - * key MUST be a header name, and each value MUST be an array of strings - * for that header. - */ - public function respond(int $status, string $body, array $headers = []): void - { - if (empty($headers)) { - // this is required to represent empty header set as map and not as array - $headers = new \stdClass(); - } - - $this->getWorker()->send( - $body, - (string) json_encode(['status' => $status, 'headers' => $headers]) - ); - } -} diff --git a/src/Logger/.empty b/src/Logger/.empty new file mode 100644 index 00000000..e69de29b diff --git a/src/Metrics.php b/src/Metrics.php deleted file mode 100755 index d6b6e1da..00000000 --- a/src/Metrics.php +++ /dev/null @@ -1,80 +0,0 @@ -rpc = $rpc; - } - - /** - * @inheritDoc - */ - public function add(string $name, float $value, array $labels = []): void - { - try { - $this->rpc->call('metrics.Add', compact('name', 'value', 'labels')); - } catch (RPCException $e) { - throw new MetricException($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * @inheritDoc - */ - public function sub(string $name, float $value, array $labels = []): void - { - try { - $this->rpc->call('metrics.Sub', compact('name', 'value', 'labels')); - } catch (RPCException $e) { - throw new MetricException($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * @inheritDoc - */ - public function observe(string $name, float $value, array $labels = []): void - { - try { - $this->rpc->call('metrics.Observe', compact('name', 'value', 'labels')); - } catch (RPCException $e) { - throw new MetricException($e->getMessage(), $e->getCode(), $e); - } - } - - /** - * @inheritDoc - */ - public function set(string $name, float $value, array $labels = []): void - { - try { - $this->rpc->call('metrics.Set', compact('name', 'value', 'labels')); - } catch (RPCException $e) { - throw new MetricException($e->getMessage(), $e->getCode(), $e); - } - } -} diff --git a/src/Metrics/Metrics.php b/src/Metrics/Metrics.php new file mode 100644 index 00000000..d6b6e1da --- /dev/null +++ b/src/Metrics/Metrics.php @@ -0,0 +1,80 @@ +rpc = $rpc; + } + + /** + * @inheritDoc + */ + public function add(string $name, float $value, array $labels = []): void + { + try { + $this->rpc->call('metrics.Add', compact('name', 'value', 'labels')); + } catch (RPCException $e) { + throw new MetricException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * @inheritDoc + */ + public function sub(string $name, float $value, array $labels = []): void + { + try { + $this->rpc->call('metrics.Sub', compact('name', 'value', 'labels')); + } catch (RPCException $e) { + throw new MetricException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * @inheritDoc + */ + public function observe(string $name, float $value, array $labels = []): void + { + try { + $this->rpc->call('metrics.Observe', compact('name', 'value', 'labels')); + } catch (RPCException $e) { + throw new MetricException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * @inheritDoc + */ + public function set(string $name, float $value, array $labels = []): void + { + try { + $this->rpc->call('metrics.Set', compact('name', 'value', 'labels')); + } catch (RPCException $e) { + throw new MetricException($e->getMessage(), $e->getCode(), $e); + } + } +} diff --git a/src/Metrics/MetricsInterface.php b/src/Metrics/MetricsInterface.php new file mode 100644 index 00000000..ec2009b0 --- /dev/null +++ b/src/Metrics/MetricsInterface.php @@ -0,0 +1,64 @@ +httpClient = new HttpClient($worker); - $this->requestFactory = $requestFactory ?? new Diactoros\ServerRequestFactory(); - $this->streamFactory = $streamFactory ?? new Diactoros\StreamFactory(); - $this->uploadsFactory = $uploadsFactory ?? new Diactoros\UploadedFileFactory(); - $this->originalServer = $_SERVER; - } - - /** - * @return Worker - */ - public function getWorker(): Worker - { - return $this->httpClient->getWorker(); - } - - /** - * @return ServerRequestInterface|null - */ - public function acceptRequest(): ?ServerRequestInterface - { - $rawRequest = $this->httpClient->acceptRequest(); - if ($rawRequest === null) { - return null; - } - - $_SERVER = $this->configureServer($rawRequest['ctx']); - - $request = $this->requestFactory->createServerRequest( - $rawRequest['ctx']['method'], - $rawRequest['ctx']['uri'], - $_SERVER - ); - - parse_str($rawRequest['ctx']['rawQuery'], $query); - - $request = $request - ->withProtocolVersion(static::fetchProtocolVersion($rawRequest['ctx']['protocol'])) - ->withCookieParams($rawRequest['ctx']['cookies']) - ->withQueryParams($query) - ->withUploadedFiles($this->wrapUploads($rawRequest['ctx']['uploads'])); - - foreach ($rawRequest['ctx']['attributes'] as $name => $value) { - $request = $request->withAttribute($name, $value); - } - - foreach ($rawRequest['ctx']['headers'] as $name => $value) { - $request = $request->withHeader($name, $value); - } - - if ($rawRequest['ctx']['parsed']) { - return $request->withParsedBody(json_decode($rawRequest['body'], true)); - } - - if ($rawRequest['body'] !== null) { - return $request->withBody($this->streamFactory->createStream($rawRequest['body'])); - } - - return $request; - } - - /** - * Send response to the application server. - * - * @param ResponseInterface $response - */ - public function respond(ResponseInterface $response): void - { - $this->httpClient->respond( - $response->getStatusCode(), - $response->getBody()->__toString(), - $response->getHeaders() - ); - } - - /** - * Returns altered copy of _SERVER variable. Sets ip-address, - * request-time and other values. - * - * @param mixed[] $ctx - * @return mixed[] - */ - protected function configureServer(array $ctx): array - { - $server = $this->originalServer; - - $server['REQUEST_URI'] = $ctx['uri']; - $server['REQUEST_TIME'] = time(); - $server['REQUEST_TIME_FLOAT'] = microtime(true); - $server['REMOTE_ADDR'] = $ctx['attributes']['ipAddress'] ?? $ctx['remoteAddr'] ?? '127.0.0.1'; - $server['REQUEST_METHOD'] = $ctx['method']; - - $server['HTTP_USER_AGENT'] = ''; - foreach ($ctx['headers'] as $key => $value) { - $key = strtoupper(str_replace('-', '_', $key)); - if (\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH'])) { - $server[$key] = implode(', ', $value); - } else { - $server['HTTP_' . $key] = implode(', ', $value); - } - } - - return $server; - } - - /** - * Wraps all uploaded files with UploadedFile. - * - * @param array[] $files - * - * @return UploadedFileInterface[]|mixed[] - */ - private function wrapUploads($files): array - { - if (empty($files)) { - return []; - } - - $result = []; - foreach ($files as $index => $f) { - if (!isset($f['name'])) { - $result[$index] = $this->wrapUploads($f); - continue; - } - - if (UPLOAD_ERR_OK === $f['error']) { - $stream = $this->streamFactory->createStreamFromFile($f['tmpName']); - } else { - $stream = $this->streamFactory->createStream(); - } - - $result[$index] = $this->uploadsFactory->createUploadedFile( - $stream, - $f['size'], - $f['error'], - $f['name'], - $f['mime'] - ); - } - - return $result; - } - - /** - * Normalize HTTP protocol version to valid values - * - * @param string $version - * @return string - */ - private static function fetchProtocolVersion(string $version): string - { - $v = substr($version, 5); - - if ($v === '2.0') { - return '2'; - } - - // Fallback for values outside of valid protocol versions - if (!in_array($v, static::$allowedVersions, true)) { - return '1.1'; - } - - return $v; - } -} diff --git a/src/WorkerInterface.php b/src/WorkerInterface.php new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3