Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SendApiProblemResponseListener modifies content #2

Open
weierophinney opened this issue Dec 31, 2019 · 0 comments
Open

SendApiProblemResponseListener modifies content #2

weierophinney opened this issue Dec 31, 2019 · 0 comments

Comments

@weierophinney
Copy link
Contributor

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));
            }
        }
    }
}

Originally posted by @marc-mabe at zfcampus/zf-api-problem#54

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

No branches or pull requests

1 participant