@@ -206,11 +206,21 @@ public static function encode($response, TcpConnection $connection)
206
206
}
207
207
208
208
if (isset ($ response ->file )) {
209
- $ file = $ response ->file ;
210
- $ body_len = (int )\filesize ($ file );
211
- $ response ->header ('Content-Length ' , $ body_len );
212
- if ($ body_len < 1024 * 1024 ) {
213
- $ connection ->send ((string )$ response . file_get_contents ($ file , false , null , 0 , $ body_len ), true );
209
+ $ file = $ response ->file ['file ' ];
210
+ $ offset = $ response ->file ['offset ' ];
211
+ $ length = $ response ->file ['length ' ];
212
+ $ file_size = (int )\filesize ($ file );
213
+ $ body_len = $ length > 0 ? $ length : $ file_size - $ offset ;
214
+ $ response ->withHeaders (array (
215
+ 'Content-Length ' => $ body_len ,
216
+ 'Accept-Ranges ' => 'bytes ' ,
217
+ ));
218
+ if ($ offset || $ length ) {
219
+ $ offset_end = $ offset + $ body_len - 1 ;
220
+ $ response ->header ('Content-Range ' , "bytes $ offset- $ offset_end/ $ file_size " );
221
+ }
222
+ if ($ body_len < 2 * 1024 * 1024 ) {
223
+ $ connection ->send ((string )$ response . file_get_contents ($ file , false , null , $ offset , $ body_len ), true );
214
224
return '' ;
215
225
}
216
226
$ handler = \fopen ($ file , 'r ' );
@@ -219,7 +229,7 @@ public static function encode($response, TcpConnection $connection)
219
229
return '' ;
220
230
}
221
231
$ connection ->send ((string )$ response , true );
222
- static ::sendStream ($ connection , $ handler );
232
+ static ::sendStream ($ connection , $ handler, $ offset , $ length );
223
233
return '' ;
224
234
}
225
235
@@ -231,16 +241,34 @@ public static function encode($response, TcpConnection $connection)
231
241
*
232
242
* @param TcpConnection $connection
233
243
* @param $handler
244
+ * @param $offset
245
+ * @param $length
234
246
*/
235
- protected static function sendStream (TcpConnection $ connection , $ handler )
247
+ protected static function sendStream (TcpConnection $ connection , $ handler, $ offset = 0 , $ length = 0 )
236
248
{
237
249
$ connection ->bufferFull = false ;
250
+ if ($ offset !== 0 ) {
251
+ \fseek ($ handler , $ offset );
252
+ }
253
+ $ offset_end = $ offset + $ length ;
238
254
// Read file content from disk piece by piece and send to client.
239
- $ do_write = function () use ($ connection , $ handler ) {
255
+ $ do_write = function () use ($ connection , $ handler, $ length , $ offset_end ) {
240
256
// Send buffer not full.
241
257
while ($ connection ->bufferFull === false ) {
242
258
// Read from disk.
243
- $ buffer = \fread ($ handler , 8192 );
259
+ $ size = 1024 * 1024 ;
260
+ if ($ length !== 0 ) {
261
+ $ tell = \ftell ($ handler );
262
+ $ remain_size = $ offset_end - $ tell ;
263
+ if ($ remain_size <= 0 ) {
264
+ fclose ($ handler );
265
+ $ connection ->onBufferDrain = null ;
266
+ return ;
267
+ }
268
+ $ size = $ remain_size > $ size ? $ size : $ remain_size ;
269
+ }
270
+
271
+ $ buffer = \fread ($ handler , $ size );
244
272
// Read eof.
245
273
if ($ buffer === '' || $ buffer === false ) {
246
274
fclose ($ handler );
0 commit comments