From 42abe70f9934645792bd054f42d8b3e3070aa485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=C2=B7x?= Date: Wed, 29 Sep 2021 15:41:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- http-handler/Client/Client.php | 51 ++-- http-handler/Client/ClientAbstracts.php | 308 ++++++--------------- http-handler/Client/Curl.php | 61 ++-- http-handler/Client/HttpClient.php | 64 ----- http-handler/Client/HttpParse.php | 2 +- http-handler/Client/IClient.php | 128 ++++----- http-handler/Client/Result.php | 175 ------------ http-message/Message.php | 11 + kiri-engine/Abstracts/TraitApplication.php | 4 +- 9 files changed, 189 insertions(+), 615 deletions(-) delete mode 100644 http-handler/Client/HttpClient.php delete mode 100644 http-handler/Client/Result.php diff --git a/http-handler/Client/Client.php b/http-handler/Client/Client.php index 303619e9..83e1fbaa 100644 --- a/http-handler/Client/Client.php +++ b/http-handler/Client/Client.php @@ -7,11 +7,14 @@ */ declare(strict_types=1); -namespace Http\Client; +namespace Http\Handler\Client; use Exception; +use Http\Message\Response; +use Http\Message\Stream; use JetBrains\PhpStorm\Pure; -use Swoole\Coroutine\Http\Client as SClient; +use Psr\Http\Message\ResponseInterface; +use Swoole\Coroutine\Http\Client as SwowClient; /** * Class Client @@ -24,12 +27,12 @@ class Client extends ClientAbstracts * @param string $method * @param $path * @param array $params - * @return array|string|Result + * @return ResponseInterface * @throws Exception */ - public function request(string $method, $path, array $params = []): array|string|Result + public function request(string $method, $path, array $params = []): ResponseInterface { - return $this->setMethod($method) + return $this->withMethod($method) ->coroutine( $this->matchHost($path), $this->paramEncode($params) @@ -40,33 +43,23 @@ class Client extends ClientAbstracts /** * @param $url * @param array|string $data - * @return array|string|Result + * @return ResponseInterface * @throws Exception 使用swoole协程方式请求 */ - private function coroutine($url, array|string $data = []): array|string|Result + private function coroutine($url, array|string $data = []): ResponseInterface { try { $client = $this->generate_client($data, ...$url); - $this->setData(''); if ($client->statusCode < 0) { throw new Exception($client->errMsg); } - $body = $this->resolve($client->getHeaders(), $client->body); - if (in_array($client->getStatusCode(), [200, 201])) { - return $this->structure($body, $data, $client->getHeaders()); - } - if (is_string($body)) { - $message = 'Request error code ' . $client->getStatusCode(); - } else { - $message = $this->searchMessageByData($body); - } - return $this->fail($client->getStatusCode(), $message, $body, $client->getHeaders()); + return (new Response())->withStatus($client->getStatusCode()) + ->withHeaders($client->getHeaders()) + ->withBody(new Stream($client->getBody())); } catch (\Throwable $exception) { $this->addError($exception, 'rpc'); - return $this->fail(500, $exception->getMessage(), [ - 'file' => $exception->getFile(), - 'line' => $exception->getLine() - ], []); + return (new Response())->withStatus(-1)->withHeaders([]) + ->withBody(new Stream(jTraceEx($exception))); } } @@ -76,18 +69,18 @@ class Client extends ClientAbstracts * @param $host * @param $isHttps * @param $path - * @return SClient + * @return SwowClient */ - private function generate_client($data, $host, $isHttps, $path): SClient + private function generate_client($data, $host, $isHttps, $path): SwowClient { if ($isHttps || $this->isSSL()) { - $client = new SClient($host, 443, true); + $client = new SwowClient($host, 443, true); } else { - $client = new SClient($host, $this->getPort(), false); + $client = new SwowClient($host, $this->getPort(), false); } $client->set($this->settings()); if (!empty($this->getAgent())) { - $this->addHeader('User-Agent', $this->getAgent()); + $this->withAddedHeader('User-Agent', $this->getAgent()); } $client->setHeaders($this->getHeader()); $client->setMethod(strtoupper($this->getMethod())); @@ -98,12 +91,12 @@ class Client extends ClientAbstracts /** - * @param SClient $client + * @param SwowClient $client * @param $path * @param $data * @return string */ - private function setParams(SClient $client, $path, $data): string + private function setParams(SwowClient $client, $path, $data): string { if ($this->isGet()) { if (!empty($data)) $path .= '?' . $data; diff --git a/http-handler/Client/ClientAbstracts.php b/http-handler/Client/ClientAbstracts.php index 1e01c7dc..69426f10 100644 --- a/http-handler/Client/ClientAbstracts.php +++ b/http-handler/Client/ClientAbstracts.php @@ -1,13 +1,17 @@ _data = ''; - } - - /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function post(string $path, array $params = []): array|int|string|Result + public function post(string $path, array $params = []): ResponseInterface { return $this->request(self::POST, $path, $params); } @@ -84,9 +77,9 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function put(string $path, array $params = []): array|int|string|Result + public function put(string $path, array $params = []): ResponseInterface { return $this->request(self::PUT, $path, $params); } @@ -94,19 +87,21 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $contentType + * @return ClientAbstracts */ - public function setContentType(string $contentType): void + public function withContentType(string $contentType): static { $this->header['Content-Type'] = $contentType; + return $this; } /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function head(string $path, array $params = []): array|int|string|Result + public function head(string $path, array $params = []): ResponseInterface { return $this->request(self::HEAD, $path, $params); } @@ -115,9 +110,9 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function get(string $path, array $params = []): array|int|string|Result + public function get(string $path, array $params = []): ResponseInterface { return $this->request(self::GET, $path, $params); } @@ -125,9 +120,9 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function option(string $path, array $params = []): array|int|string|Result + public function option(string $path, array $params = []): ResponseInterface { return $this->request(self::OPTIONS, $path, $params); } @@ -135,9 +130,9 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function delete(string $path, array $params = []): array|int|string|Result + public function delete(string $path, array $params = []): ResponseInterface { return $this->request(self::DELETE, $path, $params); } @@ -145,9 +140,9 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function options(string $path, array $params = []): array|int|string|Result + public function options(string $path, array $params = []): ResponseInterface { return $this->request(self::OPTIONS, $path, $params); @@ -156,9 +151,9 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $path * @param array $params - * @return array|int|string|Result + * @return ResponseInterface */ - public function upload(string $path, array $params = []): array|int|string|Result + public function upload(string $path, array $params = []): ResponseInterface { return $this->request(self::UPLOAD, $path, $params); } @@ -175,7 +170,7 @@ abstract class ClientAbstracts extends Component implements IClient /** * @return int */ - protected function getHostPort(): int + #[Pure] protected function getHostPort(): int { if (!empty($this->getPort())) { return $this->getPort(); @@ -188,14 +183,15 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $host + * @return ClientAbstracts */ - public function setHost(string $host): void + public function withHost(string $host): static { $this->host = $host; - if ($this->use_swoole) { + if (Context::inCoroutine()) { $this->host = System::gethostbyname($host); } - $this->addHeader('Host', $host); + return $this->withAddedHeader('Host', $host); } /** @@ -208,35 +204,39 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param array $header + * @return ClientAbstracts */ - public function setHeader(array $header): void + public function withHeader(array $header): static { $this->header = $header; + return $this; } /** * @param array $header - * @return array + * @return ClientAbstracts */ - public function setHeaders(array $header): array + public function withHeaders(array $header): static { if (empty($header)) { - return []; + return $this; } foreach ($header as $key => $val) { $this->header[$key] = $val; } - return $this->header; + return $this; } /** * @param $key * @param $value + * @return ClientAbstracts */ - public function addHeader($key, $value): void + public function withAddedHeader($key, $value): static { $this->header[$key] = $value; + return $this; } /** @@ -249,26 +249,22 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param int $value + * @return ClientAbstracts */ - public function setTimeout(int $value): void + public function withTimeout(int $value): static { $this->timeout = $value; + return $this; } - /** - * @return Closure|null - */ - public function getCallback(): ?Closure - { - return $this->callback; - } /** * @param Closure|null $value + * @return ClientAbstracts */ - public function setCallback(?Closure $value): void + public function withCallback(?Closure $value): static { - $this->callback = $value; + return $this; } /** @@ -283,7 +279,7 @@ abstract class ClientAbstracts extends Component implements IClient * @param string $value * @return static */ - public function setMethod(string $value): static + public function withMethod(string $value): static { $this->method = $value; return $this; @@ -299,10 +295,12 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param bool $isSSL + * @return ClientAbstracts */ - public function setIsSSL(bool $isSSL): void + public function withIsSSL(bool $isSSL): static { $this->isSSL = $isSSL; + return $this; } /** @@ -315,59 +313,14 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $agent + * @return ClientAbstracts */ - public function setAgent(string $agent): void + public function withAgent(string $agent): static { $this->agent = $agent; + return $this; } - /** - * @return string - */ - public function getErrorCodeField(): string - { - return $this->errorCodeField; - } - - /** - * @param string $errorCodeField - */ - public function setErrorCodeField(string $errorCodeField): void - { - $this->errorCodeField = $errorCodeField; - } - - /** - * @return string - */ - public function getErrorMsgField(): string - { - return $this->errorMsgField; - } - - /** - * @param string $errorMsgField - */ - public function setErrorMsgField(string $errorMsgField): void - { - $this->errorMsgField = $errorMsgField; - } - - /** - * @return bool - */ - public function isUseSwoole(): bool - { - return $this->use_swoole; - } - - /** - * @param bool $use_swoole - */ - public function setUseSwoole(bool $use_swoole): void - { - $this->use_swoole = $use_swoole; - } /** * @return string @@ -379,10 +332,12 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $ssl_cert_file + * @return ClientAbstracts */ - public function setSslCertFile(string $ssl_cert_file): void + public function withSslCertFile(string $ssl_cert_file): static { $this->ssl_cert_file = $ssl_cert_file; + return $this; } /** @@ -395,10 +350,12 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $ssl_key_file + * @return ClientAbstracts */ - public function setSslKeyFile(string $ssl_key_file): void + public function withSslKeyFile(string $ssl_key_file): static { $this->ssl_key_file = $ssl_key_file; + return $this; } /** @@ -411,16 +368,18 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param string $ssl_key_file + * @return static */ - public function setCa(string $ssl_key_file): void + public function withCa(string $ssl_key_file): static { $this->ca = $ssl_key_file; + return $this; } /** * @return int */ - public function getPort(): int + #[Pure] public function getPort(): int { if ($this->isSSL()) { return 443; @@ -433,42 +392,34 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param int $port + * @return ClientAbstracts */ - public function setPort(int $port): void + public function withPort(int $port): static { $this->port = $port; + return $this; } - /** - * @return string - */ - public function getMessage(): string - { - return $this->_message; - } /** - * @param string $message + * @return StreamInterface */ - public function setMessage(string $message): void - { - $this->_message = $message; - } - - /** - * @return string - */ - public function getData(): string + public function getData(): StreamInterface { return $this->_data; } /** - * @param string $data + * @param string|StreamInterface $data + * @return ClientAbstracts */ - public function setData(string $data): void + public function withBody(string|StreamInterface $data): static { + if (is_string($data)) { + $data = new Stream($data); + } $this->_data = $data; + return $this; } /** @@ -482,7 +433,7 @@ abstract class ClientAbstracts extends Component implements IClient /** * @param int $connect_timeout */ - public function setConnectTimeout(int $connect_timeout): void + public function withConnectTimeout(int $connect_timeout): void { $this->connect_timeout = $connect_timeout; } @@ -517,7 +468,7 @@ abstract class ClientAbstracts extends Component implements IClient * @param $url * @return bool */ - #[Pure] protected function isHttp($url): bool + protected function isHttp($url): bool { return str_starts_with($url, 'http://'); } @@ -526,7 +477,7 @@ abstract class ClientAbstracts extends Component implements IClient * @param $url * @return bool */ - #[Pure] protected function isHttps($url): bool + protected function isHttps($url): bool { return str_starts_with($url, 'https://'); } @@ -594,78 +545,6 @@ abstract class ClientAbstracts extends Component implements IClient } - /** - * @param $body - * @param $_data - * @param array $header - * @param int $statusCode - * @return mixed 构建返回体 - * 构建返回体 - */ - protected function structure($body, $_data, $header = [], $statusCode = 200): mixed - { - if ($this->callback instanceof Closure) { - $result = call_user_func($this->callback, $body, $_data, $header); - } else { - $result = $this->parseResult($body, $header, $statusCode); - } - return $result; - } - - - /** - * @param $body - * @param $header - * @param $statusCode - * @return Result - */ - private function parseResult($body, $header, $statusCode): Result - { - if (is_string($body)) { - $result['code'] = 0; - $result['message'] = ''; - } else { - $result['code'] = $body[$this->errorCodeField] ?? 0; - $result['message'] = $this->searchMessageByData($body); - } - $result['data'] = $body; - $result['header'] = $header; - $result['httpStatus'] = $statusCode; - return new Result($result); - } - - - /** - * @param $body - * @return mixed - */ - protected function searchMessageByData($body): mixed - { - $parent = []; - if (empty($this->errorMsgField)) { - return 'system success.'; - } - $explode = explode('.', $this->errorMsgField); - if (!isset($body[$explode[0]])) { - return 'system success.'; - } - foreach ($explode as $item) { - if (empty($item)) { - continue; - } - if (empty($parent)) { - $parent = $body[$item]; - continue; - } - if (is_string($parent) || !isset($parent[$item])) { - break; - } - $parent = $parent[$item]; - } - return !empty($parent) ? $parent : 'system success.'; - } - - /** * @return bool * check isPost Request @@ -755,7 +634,7 @@ abstract class ClientAbstracts extends Component implements IClient $host = $this->getHost(); if ($string == '/') { $string = ''; - } else if (strpos($string, '/') !== 0) { + } else if (!str_starts_with($string, '/')) { $string = '/' . $string; } return [$host, $this->isSSL(), $string]; @@ -767,7 +646,7 @@ abstract class ClientAbstracts extends Component implements IClient * @param $params * @return string */ - #[Pure] protected function joinGetParams($path, $params): string + protected function joinGetParams($path, $params): string { if (empty($params)) { return $path; @@ -778,29 +657,10 @@ abstract class ClientAbstracts extends Component implements IClient if (str_contains($path, '?')) { [$path, $getParams] = explode('?', $path); } - if (!isset($getParams) || empty($getParams)) { + if (empty($getParams)) { return $path . '?' . $params; } return $path . '?' . $params . '&' . $getParams; } - - /** - * @param $code - * @param $message - * @param $data - * @param $header - * @return Result - */ - protected function fail($code, $message, $data = [], $header = []): Result - { - return new Result([ - 'code' => $code, - 'message' => $message, - 'data' => $data, - 'header' => $header, - ]); - } - - } diff --git a/http-handler/Client/Curl.php b/http-handler/Client/Curl.php index e76e3452..9c1a0d4b 100644 --- a/http-handler/Client/Curl.php +++ b/http-handler/Client/Curl.php @@ -1,17 +1,20 @@ joinGetParams($path, $params); @@ -131,67 +134,39 @@ class Curl extends ClientAbstracts /** * @param $curl - * @return Result|bool|array|string + * @return ResponseInterface * @throws Exception */ - private function execute($curl): Result|bool|array|string + private function execute($curl): ResponseInterface { $output = curl_exec($curl); + curl_close($curl); if ($output === false) { - $response = $this->fail(400, curl_error($curl)); + $response = (new Response())->withStatus(400)->withBody(new Stream(curl_error($curl))); } else { - $response = $this->parseResponse($curl, $output); + $response = $this->explode($output); } - $this->cleanData(); return $response; } /** - * @param $curl * @param $output - * @param array $params - * @return mixed + * @return ResponseInterface * @throws Exception */ - private function parseResponse($curl, $output, array $params = []): mixed + private function explode($output): ResponseInterface { - curl_close($curl); - if ($output === FALSE) { - return $this->fail(500, $output); - } - [$header, $body, $status] = $this->explode($output); - if ($status != 200 && $status != 201) { - $data = $this->fail($status, $body, [], $header); - } else { - $data = $this->structure($body, $params, $header); - } - return $data; - } - - - /** - * @param $output - * @return array - * @throws Exception - */ - private function explode($output): array - { - if (empty($output) || !str_contains($output, "\r\n\r\n")) { - throw new Exception('Get data null.'); - } - [$header, $body] = explode("\r\n\r\n", $output, 2); if ($header == 'HTTP/1.1 100 Continue') { [$header, $body] = explode("\r\n\r\n", $body, 2); } $header = explode("\r\n", $header); + $status = explode(' ', array_shift($header)); - $status = (int)explode(' ', trim($header[0]))[1]; - $header = $this->headerFormat($header); - - return [$header, $this->resolve($header, $body), $status]; + return (new Response())->withStatus(intval($status[1]))->withHeaders($this->headerFormat($header)) + ->withBody(new Stream($body)); } /** @@ -204,7 +179,7 @@ class Curl extends ClientAbstracts foreach ($headers as $val) { $trim = explode(': ', trim($val)); - $_tmp[strtolower($trim[0])] = $trim[1] ?? ''; + $_tmp[strtolower($trim[0])] = [$trim[1] ?? '']; } return $_tmp; } diff --git a/http-handler/Client/HttpClient.php b/http-handler/Client/HttpClient.php deleted file mode 100644 index 0fa8c950..00000000 --- a/http-handler/Client/HttpClient.php +++ /dev/null @@ -1,64 +0,0 @@ - -1) { - return Client::NewRequest(); - } - return Curl::NewRequest(); - } - - - /** - * @return Curl - */ - #[Pure] public function getCurl(): Curl - { - return Curl::NewRequest(); - } - - - /** - * @return Client - */ - #[Pure] public function getCoroutine(): Client - { - return Client::NewRequest(); - } - - - /** - * @param string $name - * @param array $arguments - * @return void - */ - public function __call(string $name, array $arguments) - { - if (!method_exists($this, $name)) { - return static::NewRequest()->{$name}(...$arguments); - } - return $this->{$name}(...$arguments); - } - - -} diff --git a/http-handler/Client/HttpParse.php b/http-handler/Client/HttpParse.php index ba46c2fd..a7201afc 100644 --- a/http-handler/Client/HttpParse.php +++ b/http-handler/Client/HttpParse.php @@ -1,7 +1,7 @@ setAssignment($data); - } - - - /** - * @param $data - * @return $this - */ - public function setAssignment($data): static - { - foreach ($data as $key => $val) { - if (!property_exists($this, $key)) { - continue; - } - $this->$key = $val; - } - return $this; - } - - - /** - * @param $name - * @return mixed - */ - public function __get($name): mixed - { - return $this->$name; - } - - /** - * @param $name - * @param $value - */ - public function __set($name, $value) - { - $this->$name = $value; - } - - /** - * @return array - */ - public function getHeaders(): array - { - $_tmp = []; - if (!is_array($this->header)) { - return $_tmp; - } - foreach ($this->header as $key => $val) { - if ($key == 0) { - $_tmp['pro'] = $val; - } else { - if (str_contains($val, ': ')) { - $trim = explode(': ', $val); - - $_tmp[strtolower($trim[0])] = $trim[1]; - } else { - $_tmp[$key] = $val; - } - } - } - return $_tmp; - } - - - /** - * @return array - */ - public function getTime(): array - { - return [ - 'startTime' => $this->startTime, - 'requestTime' => $this->requestTime, - 'runTime' => $this->runTime, - ]; - } - - /** - * @param $key - * @param $data - * @return $this - * @throws Exception - */ - public function setAttr($key, $data): static - { - if (!property_exists($this, $key)) { - throw new Exception('未查找到相应对象属性'); - } - $this->$key = $data; - return $this; - } - - /** - * @param int $status - * @return bool - */ - #[Pure] public function isResultsOK(int $status = 0): bool - { - if (!$this->httpIsOk()) { - return false; - } - return $this->code === $status; - } - - /** - * @return bool - */ - public function httpIsOk(): bool - { - return in_array($this->httpStatus, [100, 101, 200, 201, 202, 203, 204, 205, 206]); - } - - /** - * @return mixed - */ - public function getBody(): mixed - { - return $this->data; - } - - /** - * @return string - */ - public function getMessage(): string - { - return $this->message; - } - - /** - * @return string|int - */ - public function getCode(): string|int - { - return $this->code; - } -} diff --git a/http-message/Message.php b/http-message/Message.php index 43b364be..09d81c0c 100644 --- a/http-message/Message.php +++ b/http-message/Message.php @@ -194,6 +194,17 @@ trait Message } + /** + * @param array $headers + * @return static + */ + public function withHeaders(array $headers): static + { + $this->headers = $headers; + return $this; + } + + /** * @param $name * @param $value diff --git a/kiri-engine/Abstracts/TraitApplication.php b/kiri-engine/Abstracts/TraitApplication.php index 619667b3..a6e5af63 100644 --- a/kiri-engine/Abstracts/TraitApplication.php +++ b/kiri-engine/Abstracts/TraitApplication.php @@ -7,8 +7,8 @@ namespace Kiri\Abstracts; use Annotation\Annotation as SAnnotation; use Database\Connection; use Database\DatabasesProviders; -use Http\Client\Client; -use Http\Client\Curl; +use Http\Handler\Client\Client; +use Http\Handler\Client\Curl; use Http\Handler\Router; use Server\Server; use Kiri\Crontab\Producer;