@@ -34,6 +34,7 @@ class BinaryFileResponse extends Response
34
34
protected $ offset = 0 ;
35
35
protected $ maxlen = -1 ;
36
36
protected $ deleteFileAfterSend = false ;
37
+ protected $ chunkSize = 8 * 1024 ;
37
38
38
39
/**
39
40
* @param \SplFileInfo|string $file The file to stream
@@ -124,6 +125,22 @@ public function getFile()
124
125
return $ this ->file ;
125
126
}
126
127
128
+ /**
129
+ * Sets the response stream chunk size.
130
+ *
131
+ * @return $this
132
+ */
133
+ public function setChunkSize (int $ chunkSize ): self
134
+ {
135
+ if ($ chunkSize < 1 || $ chunkSize > \PHP_INT_MAX ) {
136
+ throw new \LogicException ('The chunk size of a BinaryFileResponse cannot be less than 1 or greater than PHP_INT_MAX. ' );
137
+ }
138
+
139
+ $ this ->chunkSize = $ chunkSize ;
140
+
141
+ return $ this ;
142
+ }
143
+
127
144
/**
128
145
* Automatically sets the Last-Modified header according the file modification date.
129
146
*/
@@ -303,7 +320,23 @@ public function sendContent()
303
320
$ out = fopen ('php://output ' , 'w ' );
304
321
$ file = fopen ($ this ->file ->getPathname (), 'r ' );
305
322
306
- stream_copy_to_stream ($ file , $ out , $ this ->maxlen , $ this ->offset );
323
+ ignore_user_abort (true );
324
+
325
+ if (0 !== $ this ->offset ) {
326
+ fseek ($ file , $ this ->offset );
327
+ }
328
+
329
+ $ length = $ this ->maxlen ;
330
+ while ($ length && !feof ($ file )) {
331
+ $ read = ($ length > $ this ->chunkSize ) ? $ this ->chunkSize : $ length ;
332
+ $ length -= $ read ;
333
+
334
+ stream_copy_to_stream ($ file , $ out , $ read );
335
+
336
+ if (connection_aborted ()) {
337
+ break ;
338
+ }
339
+ }
307
340
308
341
fclose ($ out );
309
342
fclose ($ file );
0 commit comments