Optimized code.

This commit is contained in:
李铭昕 2019-08-29 10:55:56 +08:00
parent 09baa12d22
commit cab20303cf
5 changed files with 61 additions and 39 deletions

View File

@ -7,6 +7,7 @@
- [#418](https://github.com/hyperf-cloud/hyperf/pull/418) Allows send WebSocket message to any fd in current server, even the worker process does not hold the fd
- [#420](https://github.com/hyperf-cloud/hyperf/pull/420) Added listener for model.
- [#441](https://github.com/hyperf-cloud/hyperf/pull/441) Automatically close the spare redis client when it is used in low frequency.
- [#455](https://github.com/hyperf-cloud/hyperf/pull/455) Added download method for Response.
## Changed

View File

@ -13,8 +13,8 @@ declare(strict_types=1);
namespace Hyperf\HttpMessage\Server;
use Hyperf\HttpMessage\Cookie\Cookie;
use Hyperf\HttpMessage\Stream\FileInterface;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpMessage\Stream\SwooleFileStream;
class Response extends \Hyperf\HttpMessage\Base\Response
{
@ -47,8 +47,8 @@ class Response extends \Hyperf\HttpMessage\Base\Response
$this->buildSwooleResponse($this->swooleResponse, $this);
$content = $this->getBody();
if($content instanceof SwooleFileStream){
return $this->swooleResponse->sendfile($content->getContents());
if ($content instanceof FileInterface) {
return $this->swooleResponse->sendfile($content->getFilename());
}
$this->swooleResponse->end($content->getContents());
}
@ -101,7 +101,7 @@ class Response extends \Hyperf\HttpMessage\Base\Response
/*
* Cookies
*/
foreach ((array)$this->cookies as $domain => $paths) {
foreach ((array) $this->cookies as $domain => $paths) {
foreach ($paths ?? [] as $path => $item) {
foreach ($item ?? [] as $name => $cookie) {
if ($cookie instanceof Cookie) {

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
namespace Hyperf\HttpMessage\Stream;
interface FileInterface
{
public function getFilename(): string;
}

View File

@ -12,11 +12,10 @@ declare(strict_types=1);
namespace Hyperf\HttpMessage\Stream;
use Psr\Http\Message\StreamInterface;
use InvalidArgumentException;
use Psr\Http\Message\StreamInterface;
class SwooleFileStream implements StreamInterface
class SwooleFileStream implements StreamInterface, FileInterface
{
/**
* @var string
@ -31,15 +30,15 @@ class SwooleFileStream implements StreamInterface
/**
* SwooleFileStream constructor.
*
* @param string $file_path
* @param string $file
*/
public function __construct(string $file_path)
public function __construct(string $file)
{
if (!file_exists($file_path)) {
if (! file_exists($file)) {
throw new InvalidArgumentException('Not a file');
}
$this->contents = $file_path;
$this->size = filesize($file_path);
$this->contents = $file;
$this->size = filesize($file);
}
/**
@ -88,7 +87,7 @@ class SwooleFileStream implements StreamInterface
*/
public function getSize()
{
if (!$this->size) {
if (! $this->size) {
$this->size = filesize($this->getContents());
}
return $this->size;
@ -97,8 +96,8 @@ class SwooleFileStream implements StreamInterface
/**
* Returns the current position of the file read/write pointer.
*
* @return int Position of the file pointer
* @throws \RuntimeException on error
* @return int Position of the file pointer
*/
public function tell()
{
@ -170,8 +169,8 @@ class SwooleFileStream implements StreamInterface
* Write data to the stream.
*
* @param string $string the string that is to be written
* @return int returns the number of bytes written to the stream
* @throws \RuntimeException on failure
* @return int returns the number of bytes written to the stream
*/
public function write($string)
{
@ -194,9 +193,9 @@ class SwooleFileStream implements StreamInterface
* @param int $length Read up to $length bytes from the object and return
* them. Fewer than $length bytes may be returned if underlying stream
* call returns fewer bytes.
* @throws \RuntimeException if an error occurs
* @return string returns the data read from the stream, or an empty string
* if no bytes are available
* @throws \RuntimeException if an error occurs
*/
public function read($length)
{
@ -206,9 +205,9 @@ class SwooleFileStream implements StreamInterface
/**
* Returns the remaining contents in a string.
*
* @return string
* @throws \RuntimeException if unable to read or an error occurs while
* reading
* @return string
*/
public function getContents()
{
@ -230,4 +229,9 @@ class SwooleFileStream implements StreamInterface
{
throw new \BadMethodCallException('Not implemented');
}
public function getFilename(): string
{
return $this->getContents();
}
}

View File

@ -13,8 +13,8 @@ declare(strict_types=1);
namespace Hyperf\HttpServer;
use BadMethodCallException;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpMessage\Stream\SwooleFileStream;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\HttpServer\Exception\Http\EncodingException;
use Hyperf\Utils\ApplicationContext;
@ -112,36 +112,20 @@ class Response implements PsrResponseInterface, ResponseInterface
}
/**
* Automatically sets the ETag header according to the checksum of the file.
* @param string $filePath
* @param bool $weak
* @return string
*/
protected function autoEtag(string $filePath, $weak = false): string
{
$etag = sha1_file($filePath);
if (0 !== strpos($etag, '"')) {
$etag = '"' . $etag . '"';
}
return (true === $weak ? 'W/' : '') . $etag;
}
/**
* @param string $pathToFile
* @param string $file
* @param string $name
* @return PsrResponseInterface
*/
public function download(string $pathToFile, string $name = ''): PsrResponseInterface
public function download(string $file, string $name = ''): PsrResponseInterface
{
$filename = $name ?: basename($pathToFile);
$filename = $name ?: basename($file);
return $this->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Type', 'application/octet-stream')
->withHeader('Content-Disposition', "attachment; filename={$filename}")
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Pragma', 'public')
->withHeader('ETag', $this->autoEtag($pathToFile))
->withBody(new SwooleFileStream($pathToFile));
->withHeader('ETag', $this->etag($file))
->withBody(new SwooleFileStream($file));
}
/**
@ -378,6 +362,21 @@ class Response implements PsrResponseInterface, ResponseInterface
return $this->getResponse()->getReasonPhrase();
}
/**
* Get ETag header according to the checksum of the file.
* @param string $file
* @param bool $weak
* @return string
*/
protected function etag(string $file, $weak = false): string
{
$etag = sha1_file($file);
if (strpos($etag, '"') !== 0) {
$etag = '"' . $etag . '"';
}
return ($weak === true ? 'W/' : '') . $etag;
}
/**
* @param array|Arrayable|Jsonable $data
* @throws EncodingException when the data encoding error