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) Remove the send() method from Environment\Response and Console\Response to SendResponseListener
3) Improve SendResponseListener, so that it will be able to send a list of standard response objects (Cli\Response, PhpEnvironment\Response, Stream\Response).
4) Remove the registration of the SendResponseListener from ViewManager
5) Add the SendResponseListener registration in Zend\Mvc\Application
Is that a BC break? We are only changing listeners, not framework code (except the remove of the send() method in PhpEnvironment\Response, but I guess nobody is using this method directory, because it will be called by the SendResponseListener). We can also leave these methods in the response object untouched but never call it and mark it as deprecated.
Example use case: