Currently we have Zend\Mvc\Application attaching 3 Listeners:
RouteListener, DisptachListener and ViewManager.
The ViewManager registers the SendResponseListener and the latter does:
As Zend\Http\PhpEnvironment\Response and Console\Response are the only response objects, which have a send() method, these are the only responses you can send in zf2.
However you can return any response object in your controller, the mvc dispatch will get short-circuited and you end up in the MvcEvent::EVENT_FINISH event. No response will be send. So when you return a StreamResponse in your controller (for file download in secured area f.e.), the stream will not get send.
The whole work-flow is a bit ugly. First the SendResponseListener should not be in Zend\Mvc\View and instead in Zend\Mvc. Sending a response is not part of the view layer. It's part of the mvc layer. The response object should not be responsible for sending itself. We have a SendResponseListener, it should be it's job.
1) Move the SendResponseListener one level up (Mvc Package, no View subpackage).
2) Mark the send() method from Environment\Response and Console\Response as deprecated
3) SendResponseListener triggers sendResponse event, additional listener (PhpEnvironmentResponseSender, CliResponseSender) will get attached to the sendrepsonselistener by default.
4) Remove the registration of the SendResponseListener from ViewManager
5) Add the SendResponseListener registration in Zend\Mvc\Application
Example use case: