Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

SendApiProblemResponseListener modifies content #54

Open
marc-mabe opened this issue Feb 6, 2017 · 1 comment
Open

SendApiProblemResponseListener modifies content #54

marc-mabe opened this issue Feb 6, 2017 · 1 comment

Comments

@marc-mabe
Copy link

I have noticed, that SendApiProblemResponseListener is modifying the response content AFTER sending headers (if display_exceptions is enabled).

I have a Content-Length header based on response content but this header is now responding a wrong length as it doesn't know if the content gets modified afterwords.

On the same time I'm automatically pretty printing the response if the request contains header X-Pretty: 1 but this will also be ignored as the content gets rewritten in this case.

What is the reason to overwrite HttpResponseSender instead of listening on EVENT_FINISH?

This is my broken code:

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $eventManager  = $e->getApplication()->getEventManager();
        $eventManager->attach(MvcEvent::EVENT_FINISH, [$this, 'onFinish'], -1000);
    }

    public function onFinish(MvcEvent $event)
    {
        $response = $event->getResponse();
        $request  = $event->getRequest();

        if ($request instanceof HttpRequest && $response instanceof HttpResponse && !($response instanceof HttpStreamResponse)) {
            $rqHeaders = $request->getHeaders();
            $rsHeaders = $response->getHeaders();
            $rsContent = $response->getContent();

            // pretty print JSON response
            if ($rqHeaders->has('X-Pretty')
                && $rqHeaders->get('X-Pretty')->getFieldValue() === '1'
                && is_string($rsContent) && $rsContent
                && $rsHeaders->has('Content-Type')
                && preg_match('/^application\\/(.*\\-)?json/', $rsHeaders->get('Content-Type')->getFieldValue())
            ) {
                $rsContentDecode = json_decode($rsContent);
                if ($rsContentDecode !== null) {
                    $prettyOptions = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
                    $rsContent     = json_encode($rsContentDecode, $prettyOptions);
                    $response->setContent($rsContent);

                    if ($rsHeaders->has('Content-Length')) {
                        $rsHeaders->removeHeader($rsHeaders->get('Content-Length'));
                    }
                    $rsHeaders->addHeaderLine('Content-Length', strlen($rsContent));
                }
            }

            // Send Content-Length header if possible
            if (is_string($rsContent) && !$rsHeaders->has('Content-Length')) {
                $rsHeaders->addHeaderLine('Content-Length', strlen($rsContent));
            }
        }
    }
}
@weierophinney
Copy link
Member

This repository has been closed and moved to laminas-api-tools/api-tools-api-problem; a new issue has been opened at laminas-api-tools/api-tools-api-problem#2.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants