This commit is contained in:
2021-08-04 10:15:18 +08:00
parent fa09277f1f
commit d688ca175b
+217 -217
View File
@@ -14,10 +14,7 @@ use HttpServer\Abstracts\HttpService;
use HttpServer\Http\Formatter\HtmlFormatter; use HttpServer\Http\Formatter\HtmlFormatter;
use HttpServer\Http\Formatter\JsonFormatter; use HttpServer\Http\Formatter\JsonFormatter;
use HttpServer\Http\Formatter\XmlFormatter; use HttpServer\Http\Formatter\XmlFormatter;
use HttpServer\IInterface\IFormatter; use Snowflake\Exception\NotFindClassException;
use Snowflake\Core\Help;
use Snowflake\Snowflake;
use Swoole\Coroutine;
use Swoole\Http\Response as SResponse; use Swoole\Http\Response as SResponse;
/** /**
@@ -27,259 +24,262 @@ use Swoole\Http\Response as SResponse;
class Response extends HttpService class Response extends HttpService
{ {
const JSON = 'json'; const JSON = 'json';
const XML = 'xml'; const XML = 'xml';
const HTML = 'html'; const HTML = 'html';
/** @var ?string */ /** @var ?string */
public ?string $format = null; public ?string $format = null;
/** @var int */ /** @var int */
public int $statusCode = 200; public int $statusCode = 200;
public array $headers = []; public array $headers = [];
public array $cookies = []; public array $cookies = [];
private float $startTime = 0; private float $startTime = 0;
private mixed $endData; private mixed $endData;
const FORMAT_MAPS = [ const FORMAT_MAPS = [
self::JSON => JsonFormatter::class, self::JSON => JsonFormatter::class,
self::XML => XmlFormatter::class, self::XML => XmlFormatter::class,
self::HTML => HtmlFormatter::class self::HTML => HtmlFormatter::class
]; ];
public int $fd = 0; public int $fd = 0;
/** /**
* @param $format * @param $format
* @return $this * @return $this
*/ */
public function setFormat($format): static public function setFormat($format): static
{ {
if (empty($format)) { if (empty($format)) {
return $this; return $this;
} }
$this->format = $format; $this->format = $format;
return $this; return $this;
} }
/** /**
* @param $content * @param $content
* @return string * @return string
*/ */
public function toHtml($content): string public function toHtml($content): string
{ {
$this->format = self::HTML; $this->format = self::HTML;
return (string)$content; return (string)$content;
} }
/** /**
* @param $content * @param $content
* @return string|bool * @return string|bool
*/ */
public function toJson($content): string|bool public function toJson($content): string|bool
{ {
$this->format = self::JSON; $this->format = self::JSON;
return json_encode($content, JSON_UNESCAPED_UNICODE); return json_encode($content, JSON_UNESCAPED_UNICODE);
} }
/** /**
* @param $content * @param $content
* @return mixed * @return mixed
*/ */
public function toXml($content): mixed public function toXml($content): mixed
{ {
$this->format = self::XML; $this->format = self::XML;
return $content; return $content;
} }
/** /**
* @param $key * @param $key
* @param $value * @param $value
* @return Response * @return Response
*/ */
public function addHeader($key, $value): static public function addHeader($key, $value): static
{ {
$this->headers[$key] = $value; $this->headers[$key] = $value;
return $this; return $this;
} }
/** /**
* @param $name * @param $name
* @param null $value * @param null $value
* @param null $expires * @param null $expires
* @param null $path * @param null $path
* @param null $domain * @param null $domain
* @param null $secure * @param null $secure
* @param null $httponly * @param null $httponly
* @param null $samesite * @param null $samesite
* @param null $priority * @param null $priority
* @return Response * @return Response
*/ */
public function addCookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null, $priority = null): static public function addCookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null, $priority = null): static
{ {
$this->cookies[] = func_get_args(); $this->cookies[] = func_get_args();
return $this; return $this;
} }
/** /**
* @param $statusCode * @param $statusCode
*/ */
public function setStatusCode($statusCode) public function setStatusCode($statusCode)
{ {
$this->statusCode = $statusCode; $this->statusCode = $statusCode;
} }
/** /**
* @return string * @return string
*/ */
public function getResponseFormat(): string public function getResponseFormat(): string
{ {
return match ($this->format) { return match ($this->format) {
Response::HTML => 'text/html;charset=utf-8', Response::HTML => 'text/html;charset=utf-8',
Response::XML => 'application/xml;charset=utf-8', Response::XML => 'application/xml;charset=utf-8',
default => 'application/json;charset=utf-8', default => 'application/json;charset=utf-8',
}; };
} }
/** /**
* @param mixed $context * @param mixed $context
* @param int $statusCode * @param int $statusCode
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function getBuilder(mixed $data, SResponse $response = null): static public function getBuilder(mixed $data, SResponse $response = null): static
{ {
if ($response != null) { if ($response != null) {
$this->configure($response); $this->configure($response);
} }
return $this->setContent($data); return $this->setContent($data);
} }
/** /**
* @param \Swoole\Http\Response|null $response * @param \Swoole\Http\Response|null $response
* @throws \Exception * @throws \Exception
*/ */
public function configure(SResponse $response = null): static public function configure(SResponse $response = null): static
{ {
$response->setStatusCode($this->statusCode); $response->setStatusCode($this->statusCode);
$response->header('Content-Type', $this->getResponseFormat()); $response->header('Content-Type', $this->getResponseFormat());
$response->header('Run-Time', $this->getRuntime()); $response->header('Run-Time', $this->getRuntime());
if (!empty($this->headers)) { if (!empty($this->headers)) {
foreach ($this->headers as $name => $header) { foreach ($this->headers as $name => $header) {
$response->header($name, $header); $response->header($name, $header);
} }
} }
if (!empty($this->cookies)) { if (!empty($this->cookies)) {
foreach ($this->cookies as $header) { foreach ($this->cookies as $header) {
$response->setCookie(...$header); $response->setCookie(...$header);
} }
} }
return $this; return $this;
} }
/** /**
* @param mixed $content * @param mixed $content
*/ * @param int $statusCode
public function setContent(mixed $content, $statusCode = 200, $format = null): static * @param null $format
{ * @return Response
$this->endData = $content; */
$this->setStatusCode($statusCode); public function setContent(mixed $content,int $statusCode = 200, $format = null): static
$this->setFormat($format); {
return $this; $this->endData = $content;
} $this->setStatusCode($statusCode);
$this->setFormat($format);
return $this;
}
/** /**
* @return string * @return string
* @throws \ReflectionException * @throws \ReflectionException
* @throws \Snowflake\Exception\NotFindClassException * @throws NotFindClassException
*/ */
public function getContent(): string public function getContent(): string
{ {
if (empty($this->endData) || is_string($this->endData)) { if (empty($this->endData) || is_string($this->endData)) {
return $this->endData; return $this->endData;
} }
$class = Response::FORMAT_MAPS[$this->format] ?? HtmlFormatter::class; $class = Response::FORMAT_MAPS[$this->format] ?? HtmlFormatter::class;
return \di($class)->send($this->endData)->getData(); return \di($class)->send($this->endData)->getData();
} }
/** /**
* @param $url * @param $url
* @param array $param * @param array $param
* @return int * @return int
*/ */
public function redirect($url, array $param = []): mixed public function redirect($url, array $param = []): mixed
{ {
if (!empty($param)) { if (!empty($param)) {
$url .= '?' . http_build_query($param); $url .= '?' . http_build_query($param);
} }
$url = ltrim($url, '/'); $url = ltrim($url, '/');
if (!preg_match('/^http/', $url)) { if (!preg_match('/^http/', $url)) {
$url = '/' . $url; $url = '/' . $url;
} }
/** @var SResponse $response */ /** @var SResponse $response */
$response = Context::getContext('response'); $response = Context::getContext('response');
if (!empty($response)) { if (!empty($response)) {
return $response->redirect($url); return $response->redirect($url);
} }
return false; return false;
} }
/** /**
* @param string $path * @param string $path
* @param int $offset * @param int $offset
* @param int $limit * @param int $limit
* @param int $sleep * @param int $sleep
* @return string * @return string
*/ */
public function sendFile(string $path, int $offset = 0, int $limit = 1024000, int $sleep = 0): string public function sendFile(string $path, int $offset = 0, int $limit = 1024000, int $sleep = 0): string
{ {
$open = fopen($path, 'r'); $open = fopen($path, 'r');
$stat = fstat($open); $stat = fstat($open);
/** @var SResponse $response */ /** @var SResponse $response */
$response = Context::getContext('response'); $response = Context::getContext('response');
$response->header('Content-length', $stat['size']); $response->header('Content-length', $stat['size']);
while ($file = fread($open, $limit)) { while ($file = fread($open, $limit)) {
$response->write($file); $response->write($file);
fseek($open, $offset); fseek($open, $offset);
if ($sleep > 0) sleep($sleep); if ($sleep > 0) sleep($sleep);
if ($offset >= $stat['size']) { if ($offset >= $stat['size']) {
break; break;
} }
$offset += $limit; $offset += $limit;
} }
$response->end(); $response->end();
return ''; return '';
} }
/** /**
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function getRuntime(): string public function getRuntime(): string
{ {
return sprintf('%.5f', microtime(TRUE) - request()->getStartTime()); return sprintf('%.5f', microtime(TRUE) - request()->getStartTime());
} }
} }