Response returned only after kernel.terminate event
fastcgi, nginx, symfony
Solution
This issue turned out to be very specific to my setup (Nginx, PHP-FCGI, Symfony).
There were a handful of issues in play that caused the issue:
- Symfony does not include a `Content-Length` nor `Connection: close` header
- PHP-FCGI does not support the `fastcgi_finish_request` function
- Nginx buffers the response from PHP-FCGI because Gzip is on
The solution was to switch from PHP-FCGI to PHP-FPM in order to get support for `fastcgi_finish_request`. Symfony internally calls this before executing the kernel terminate logic thereby definitively closing the connection.
Another way to solve this would be to turn off Gzip on Nginx, but this wasn't really an option for me.
Problem
My understanding of `kernel.terminate` is that it triggers after the response has been returned to the client. In my testing tough, this does not appear to be the case. If I put a `sleep(10)` in the function that's called on kernel.terminate. the browser also waits for 10 seconds. The processing seems to be happening before the response is sent. I have the following in config: ``` calendar: class: Acme\CalendarBundle\Service\CalendarService arguments: [ @odm.document_manager, @logger, @security.context, @event_dispatcher ] tags: - { name: kernel.event_subscriber } ``` My subscriber class: ``` class CalendarService implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( 'kernel.terminate' => 'onKernelTerminate' ); } public function onKernelTerminate() { sleep(10); echo "hello"; } } ``` UPDATE This appears to be related to Symfony not sending a `Content-Length` header. If I generate that, the response return properly. ``` // app_dev.php ... $kernel = new AppKernel('dev', true); $kernel->loadClassCache(); $request = Request::createFromGlobals(); $response = $kernel->handle($request); // --- START EDITS --- $size = strlen($response->getContent()); $response->headers->set('Content-Length', $size); $response->headers->set('Connection', 'close'); // ---- END EDITS ---- $response->send(); $kernel->terminate($request, $response); ```