@@ -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
@@ -125,6 +126,22 @@ public function getFile()
125
126
return $ this ->file ;
126
127
}
127
128
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
+
128
145
/**
129
146
* Automatically sets the Last-Modified header according the file modification date.
130
147
*
@@ -306,7 +323,23 @@ public function sendContent()
306
323
$ out = fopen ('php://output ' , 'w ' );
307
324
$ file = fopen ($ this ->file ->getPathname (), 'r ' );
308
325
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
+ }
310
343
311
344
fclose ($ out );
312
345
fclose ($ file );
0 commit comments