@@ -364,49 +364,55 @@ public function path(string $dir): void
364364 /**
365365 * Processes each routes middleware.
366366 *
367- * @param array<int, callable> $middleware Middleware attached to the route.
368- * @param array<mixed> $params `$route->params`.
367+ * @param Route $route The route to process the middleware for.
369368 * @param string $event_name If this is the before or after method.
370369 */
371- protected function processMiddleware (array $ middleware , array $ params , string $ event_name ): bool
370+ protected function processMiddleware (Route $ route , string $ event_name ): bool
372371 {
373372 $ at_least_one_middleware_failed = false ;
374373
375- foreach ($ middleware as $ middleware ) {
374+ $ middlewares = $ event_name === Dispatcher::FILTER_BEFORE ? $ route ->middleware : array_reverse ($ route ->middleware );
375+ $ params = $ route ->params ;
376+
377+ foreach ($ middlewares as $ middleware ) {
376378 $ middleware_object = false ;
377379
378- if ($ event_name === ' before ' ) {
380+ if ($ event_name === Dispatcher:: FILTER_BEFORE ) {
379381 // can be a callable or a class
380382 $ middleware_object = (is_callable ($ middleware ) === true
381383 ? $ middleware
382- : (method_exists ($ middleware , ' before ' ) === true
383- ? [$ middleware , ' before ' ]
384+ : (method_exists ($ middleware , Dispatcher:: FILTER_BEFORE ) === true
385+ ? [$ middleware , Dispatcher:: FILTER_BEFORE ]
384386 : false
385387 )
386388 );
387- } elseif ($ event_name === ' after ' ) {
389+ } elseif ($ event_name === Dispatcher:: FILTER_AFTER ) {
388390 // must be an object. No functions allowed here
389391 if (
390392 is_object ($ middleware ) === true
391393 && !($ middleware instanceof Closure)
392- && method_exists ($ middleware , ' after ' ) === true
394+ && method_exists ($ middleware , Dispatcher:: FILTER_AFTER ) === true
393395 ) {
394- $ middleware_object = [$ middleware , ' after ' ];
396+ $ middleware_object = [$ middleware , Dispatcher:: FILTER_AFTER ];
395397 }
396398 }
397399
398400 if ($ middleware_object === false ) {
399401 continue ;
400402 }
401403
402- if ($ this ->response ()->v2_output_buffering === false ) {
404+ $ use_v3_output_buffering =
405+ $ this ->response ()->v2_output_buffering === false &&
406+ $ route ->is_streamed === false ;
407+
408+ if ($ use_v3_output_buffering === true ) {
403409 ob_start ();
404410 }
405411
406412 // It's assumed if you don't declare before, that it will be assumed as the before method
407413 $ middleware_result = $ middleware_object ($ params );
408414
409- if ($ this -> response ()-> v2_output_buffering === false ) {
415+ if ($ use_v3_output_buffering === true ) {
410416 $ this ->response ()->write (ob_get_clean ());
411417 }
412418
@@ -462,16 +468,36 @@ public function _start(): void
462468 $ params [] = $ route ;
463469 }
464470
471+ // If this route is to be streamed, we need to output the headers now
472+ if ($ route ->is_streamed === true ) {
473+ $ response ->status ($ route ->streamed_headers ['status ' ]);
474+ unset($ route ->streamed_headers ['status ' ]);
475+ $ response ->header ('X-Accel-Buffering ' , 'no ' );
476+ $ response ->header ('Connection ' , 'close ' );
477+ foreach ($ route ->streamed_headers as $ header => $ value ) {
478+ $ response ->header ($ header , $ value );
479+ }
480+
481+ // We obviously don't know the content length right now. This must be false.
482+ $ response ->content_length = false ;
483+ $ response ->sendHeaders ();
484+ $ response ->markAsSent ();
485+ }
486+
465487 // Run any before middlewares
466488 if (count ($ route ->middleware ) > 0 ) {
467- $ at_least_one_middleware_failed = $ this ->processMiddleware ($ route-> middleware , $ route -> params , 'before ' );
489+ $ at_least_one_middleware_failed = $ this ->processMiddleware ($ route , 'before ' );
468490 if ($ at_least_one_middleware_failed === true ) {
469491 $ failed_middleware_check = true ;
470492 break ;
471493 }
472494 }
473495
474- if ($ response ->v2_output_buffering === false ) {
496+ $ use_v3_output_buffering =
497+ $ this ->response ()->v2_output_buffering === false &&
498+ $ route ->is_streamed === false ;
499+
500+ if ($ use_v3_output_buffering === true ) {
475501 ob_start ();
476502 }
477503
@@ -481,18 +507,14 @@ public function _start(): void
481507 $ params
482508 );
483509
484- if ($ response -> v2_output_buffering === false ) {
510+ if ($ use_v3_output_buffering === true ) {
485511 $ response ->write (ob_get_clean ());
486512 }
487513
488514 // Run any before middlewares
489515 if (count ($ route ->middleware ) > 0 ) {
490516 // process the middleware in reverse order now
491- $ at_least_one_middleware_failed = $ this ->processMiddleware (
492- array_reverse ($ route ->middleware ),
493- $ route ->params ,
494- 'after '
495- );
517+ $ at_least_one_middleware_failed = $ this ->processMiddleware ($ route , 'after ' );
496518
497519 if ($ at_least_one_middleware_failed === true ) {
498520 $ failed_middleware_check = true ;
@@ -774,8 +796,10 @@ public function _jsonp(
774796 $ this ->response ()
775797 ->status ($ code )
776798 ->header ('Content-Type ' , 'application/javascript; charset= ' . $ charset )
777- ->write ($ callback . '( ' . $ json . '); ' )
778- ->send ();
799+ ->write ($ callback . '( ' . $ json . '); ' );
800+ if ($ this ->response ()->v2_output_buffering === true ) {
801+ $ this ->response ()->send ();
802+ }
779803 }
780804
781805 /**
0 commit comments