22
33namespace Utopia ;
44
5+ use Utopia \Compression \Compression ;
6+
57class Response
68{
79 /**
@@ -245,6 +247,21 @@ class Response
245247 */
246248 protected int $ size = 0 ;
247249
250+ /**
251+ * @var string
252+ */
253+ protected string $ acceptEncoding = '' ;
254+
255+ /**
256+ * @var int
257+ */
258+ protected int $ compressionMinSize = App::COMPRESSION_MIN_SIZE_DEFAULT ;
259+
260+ /**
261+ * @var mixed
262+ */
263+ protected mixed $ compressionSupported = [];
264+
248265 /**
249266 * Response constructor.
250267 *
@@ -270,6 +287,43 @@ public function setContentType(string $type, string $charset = ''): static
270287 return $ this ;
271288 }
272289
290+ /**
291+ * Set accept encoding
292+ *
293+ * Set HTTP accept encoding header.
294+ *
295+ * @param string $acceptEncoding
296+ */
297+ public function setAcceptEncoding (string $ acceptEncoding ): static
298+ {
299+ $ this ->acceptEncoding = $ acceptEncoding ;
300+ return $ this ;
301+ }
302+
303+ /**
304+ * Set min compression size
305+ *
306+ * Set minimum size for compression to be applied in bytes.
307+ *
308+ * @param int $compressionMinSize
309+ */
310+ public function setCompressionMinSize (int $ compressionMinSize ): static
311+ {
312+ $ this ->compressionMinSize = $ compressionMinSize ;
313+ return $ this ;
314+ }
315+
316+ /**
317+ * Set supported compression algorithms
318+ *
319+ * @param mixed $compressionSupported
320+ */
321+ public function setCompressionSupported (mixed $ compressionSupported ): static
322+ {
323+ $ this ->compressionSupported = $ compressionSupported ;
324+ return $ this ;
325+ }
326+
273327 /**
274328 * Get content type
275329 *
@@ -473,36 +527,50 @@ public function send(string $body = ''): void
473527 return ;
474528 }
475529
476- $ this ->sent = true ;
530+ $ serverHeader = $ this ->headers ['Server ' ] ?? 'Utopia/Http ' ;
531+ $ this ->addHeader ('Server ' , $ serverHeader );
532+ $ this ->addHeader ('X-Debug-Speed ' , (string ) (microtime (true ) - $ this ->startTime ));
477533
478- $ this ->addHeader ( ' X-Debug-Speed ' , ( string ) ( \microtime ( true ) - $ this -> startTime ) );
534+ $ this ->appendCookies ( );
479535
480- $ this
481- ->appendCookies ()
482- ->appendHeaders ();
536+ // Compress body
537+ if (
538+ !empty ($ this ->acceptEncoding ) &&
539+ isset ($ this ->compressed [$ this ->contentType ]) &&
540+ strlen ($ body ) > $ this ->compressionMinSize
541+ ) {
542+ $ algorithm = Compression::fromAcceptEncoding ($ this ->acceptEncoding , $ this ->compressionSupported );
483543
484- if (!$ this ->disablePayload ) {
485- $ length = strlen ($ body );
544+ if ($ algorithm ) {
545+ $ body = $ algorithm ->compress ($ body );
546+ $ this ->addHeader ('Content-Encoding ' , $ algorithm ->getContentEncoding ());
547+ $ this ->addHeader ('Vary ' , 'Accept-Encoding ' );
548+ }
549+ }
486550
487- $ this ->size = $ this -> size + strlen ( implode ( "\n" , $ this -> headers )) + $ length ;
551+ $ this ->appendHeaders () ;
488552
489- if (array_key_exists (
490- $ this ->contentType ,
491- $ this ->compressed
492- ) && ($ length <= self ::CHUNK_SIZE )) { // Dont compress with GZIP / Brotli if header is not listed and size is bigger than 2mb
493- $ this ->end ($ body );
494- } else {
495- for ($ i = 0 ; $ i < ceil ($ length / self ::CHUNK_SIZE ); $ i ++) {
496- $ this ->write (substr ($ body , ($ i * self ::CHUNK_SIZE ), min (self ::CHUNK_SIZE , $ length - ($ i * self ::CHUNK_SIZE ))));
497- }
553+ // Send response
554+ if ($ this ->disablePayload ) {
555+ $ this ->end ();
556+ return ;
557+ }
498558
499- $ this ->end ();
500- }
559+ $ headerSize = strlen (implode ("\n" , $ this ->headers ));
560+ $ bodyLength = strlen ($ body );
561+ $ this ->size += $ headerSize + $ bodyLength ;
501562
502- $ this ->disablePayload ();
563+ if ($ bodyLength <= self ::CHUNK_SIZE ) {
564+ $ this ->end ($ body );
503565 } else {
566+ $ chunks = str_split ($ body , self ::CHUNK_SIZE );
567+ foreach ($ chunks as $ chunk ) {
568+ $ this ->write ($ chunk );
569+ }
504570 $ this ->end ();
505571 }
572+
573+ $ this ->disablePayload ();
506574 }
507575
508576 /**
0 commit comments