@@ -34,6 +34,7 @@ class BinaryFileResponse extends Response
3434 protected $ offset = 0 ;
3535 protected $ maxlen = -1 ;
3636 protected $ deleteFileAfterSend = false ;
37+ protected $ chunkSize = 8 * 1024 ;
3738
3839 /**
3940 * @param \SplFileInfo|string $file The file to stream
@@ -125,6 +126,22 @@ public function getFile()
125126 return $ this ->file ;
126127 }
127128
129+ /**
130+ * Sets the response stream chunk size.
131+ *
132+ * @return $this
133+ */
134+ public function setChunkSize (int $ chunkSize ): self
135+ {
136+ if ($ chunkSize < 1 || $ chunkSize > \PHP_INT_MAX ) {
137+ throw new \LogicException ('The chunk size of a BinaryFileResponse cannot be less than 1 or greater than PHP_INT_MAX. ' );
138+ }
139+
140+ $ this ->chunkSize = $ chunkSize ;
141+
142+ return $ this ;
143+ }
144+
128145 /**
129146 * Automatically sets the Last-Modified header according the file modification date.
130147 *
@@ -306,7 +323,23 @@ public function sendContent()
306323 $ out = fopen ('php://output ' , 'w ' );
307324 $ file = fopen ($ this ->file ->getPathname (), 'r ' );
308325
309- stream_copy_to_stream ($ file , $ out , $ this ->maxlen , $ this ->offset );
326+ ignore_user_abort (true );
327+
328+ if (0 !== $ this ->offset ) {
329+ fseek ($ file , $ this ->offset );
330+ }
331+
332+ $ length = $ this ->maxlen ;
333+ while ($ length && !feof ($ file )) {
334+ $ read = ($ length > $ this ->chunkSize ) ? $ this ->chunkSize : $ length ;
335+ $ length -= $ read ;
336+
337+ stream_copy_to_stream ($ file , $ out , $ read );
338+
339+ if (connection_aborted ()) {
340+ break ;
341+ }
342+ }
310343
311344 fclose ($ out );
312345 fclose ($ file );
0 commit comments