Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.

Commit 5e80d23

Browse files
authored
Merge pull request #456 from hezachary/master
Add Gzip support on response chunk mode
2 parents 41fe378 + b2da170 commit 5e80d23

File tree

3 files changed

+337
-10
lines changed

3 files changed

+337
-10
lines changed

src/Server/Manager.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ public function onRequest($swooleRequest, $swooleResponse)
225225
$illuminateResponse = $sandbox->run($illuminateRequest);
226226

227227
// send response
228-
Response::make($illuminateResponse, $swooleResponse)->send();
228+
Response::make($illuminateResponse, $swooleResponse, $swooleRequest)->send();
229229
} catch (Throwable $e) {
230230
try {
231231
$exceptionResponse = $this->app
@@ -234,7 +234,7 @@ public function onRequest($swooleRequest, $swooleResponse)
234234
$illuminateRequest,
235235
$this->normalizeException($e)
236236
);
237-
Response::make($exceptionResponse, $swooleResponse)->send();
237+
Response::make($exceptionResponse, $swooleResponse, $swooleRequest)->send();
238238
} catch (Throwable $e) {
239239
$this->logServerError($e);
240240
}

src/Transformers/Response.php

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Http\Response as IlluminateResponse;
66
use Swoole\Http\Response as SwooleResponse;
7+
use Swoole\Http\Request as SwooleRequest;
78
use Symfony\Component\HttpFoundation\BinaryFileResponse;
89
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
910
use Symfony\Component\HttpFoundation\StreamedResponse;
@@ -17,6 +18,11 @@ class Response
1718
*/
1819
protected $swooleResponse;
1920

21+
/**
22+
* @var \Swoole\Http\Request
23+
*/
24+
protected $swooleRequest;
25+
2026
/**
2127
* @var \Illuminate\Http\Response
2228
*/
@@ -27,24 +33,27 @@ class Response
2733
*
2834
* @param $illuminateResponse
2935
* @param \Swoole\Http\Response $swooleResponse
36+
* @param \Swoole\Http\Request $swooleRequest
3037
*
3138
* @return \SwooleTW\Http\Transformers\Response
3239
*/
33-
public static function make($illuminateResponse, SwooleResponse $swooleResponse)
40+
public static function make($illuminateResponse, SwooleResponse $swooleResponse, SwooleRequest $swooleRequest)
3441
{
35-
return new static($illuminateResponse, $swooleResponse);
42+
return new static($illuminateResponse, $swooleResponse, $swooleRequest);
3643
}
3744

3845
/**
3946
* Response constructor.
4047
*
4148
* @param mixed $illuminateResponse
4249
* @param \Swoole\Http\Response $swooleResponse
50+
* @param \Swoole\Http\Request $swooleRequest
4351
*/
44-
public function __construct($illuminateResponse, SwooleResponse $swooleResponse)
52+
public function __construct($illuminateResponse, SwooleResponse $swooleResponse, SwooleRequest $swooleRequest)
4553
{
4654
$this->setIlluminateResponse($illuminateResponse);
4755
$this->setSwooleResponse($swooleResponse);
56+
$this->setSwooleRequest($swooleRequest);
4857
}
4958

5059
/**
@@ -117,22 +126,30 @@ protected function sendContent()
117126
} elseif ($illuminateResponse instanceof BinaryFileResponse) {
118127
$this->swooleResponse->sendfile($illuminateResponse->getFile()->getPathname());
119128
} else {
120-
$this->sendInChunk($illuminateResponse->getContent());
129+
$chunkGzip = $this->canGzipContent($illuminateResponse->headers->get('Content-Encoding'));
130+
$this->sendInChunk($illuminateResponse->getContent(), $chunkGzip);
121131
}
122132
}
123133

124134
/**
125135
* Send content in chunk
126136
*
127137
* @param string $content
138+
* @param bool $chunkGzip
128139
*/
129-
protected function sendInChunk($content)
140+
protected function sendInChunk($content, $chunkGzip)
130141
{
131142
if (strlen($content) <= static::CHUNK_SIZE) {
132143
$this->swooleResponse->end($content);
133144
return;
134145
}
135146

147+
// Swoole Chunk mode does not support compress by default, this patch only supports gzip
148+
if ($chunkGzip) {
149+
$this->swooleResponse->header('Content-Encoding', 'gzip');
150+
$content = gzencode($content, config('swoole_http.server.options.http_compression_level', 3));
151+
}
152+
136153
foreach (str_split($content, static::CHUNK_SIZE) as $chunk) {
137154
$this->swooleResponse->write($chunk);
138155
}
@@ -184,4 +201,37 @@ public function getIlluminateResponse()
184201
{
185202
return $this->illuminateResponse;
186203
}
204+
205+
/**
206+
* @param \Swoole\Http\Request $swooleRequest
207+
*
208+
* @return \SwooleTW\Http\Transformers\Response
209+
*/
210+
protected function setSwooleRequest(SwooleRequest $swooleRequest)
211+
{
212+
$this->swooleRequest = $swooleRequest;
213+
214+
return $this;
215+
}
216+
217+
/**
218+
* @return \Swoole\Http\Request
219+
*/
220+
public function getSwooleRequest()
221+
{
222+
return $this->swooleRequest;
223+
}
224+
225+
/**
226+
* @param string $responseContentEncoding
227+
* @return bool
228+
*/
229+
protected function canGzipContent($responseContentEncoding)
230+
{
231+
return empty($responseContentEncoding) &&
232+
config('swoole_http.server.options.http_compression', true) &&
233+
!empty($this->swooleRequest->header['accept-encoding']) &&
234+
strpos($this->swooleRequest->header['accept-encoding'], 'gzip') !== false &&
235+
function_exists('gzencode');
236+
}
187237
}

0 commit comments

Comments
 (0)