/** * Implements module logic for given hook * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request A request object * @param \AppserverIo\Psr\HttpMessage\ResponseInterface $response A response object * @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext A requests context instance * @param int $hook The current hook to process logic for * * @return bool * @throws \AppserverIo\Server\Exceptions\ModuleException */ public function process(RequestInterface $request, ResponseInterface $response, RequestContextInterface $requestContext, $hook) { // In php an interface is, by definition, a fixed contract. It is immutable. // So we have to declare the right ones afterwards... /** * @var $request \AppserverIo\Psr\HttpMessage\RequestInterface */ /** * @var $response \AppserverIo\Psr\HttpMessage\ResponseInterface */ // if false hook is comming do nothing if (ModuleHooks::RESPONSE_PRE !== $hook) { return; } // check if content type header exists if not stop processing if (!$response->hasHeader(Protocol::HEADER_CONTENT_TYPE)) { return; } // check if no accept encoding headers are sent if (!$request->hasHeader(Protocol::HEADER_ACCEPT_ENCODING)) { return; } // check if response was encoded before and exit than if ($response->hasHeader(Protocol::HEADER_CONTENT_ENCODING)) { return; } // do not deflate on proxy requests because proxy servers are responsible for sending correct responses if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) === 'proxy') { // stop processing return; } // check if request accepts deflate if (strpos($request->getHeader(Protocol::HEADER_ACCEPT_ENCODING), 'deflate') !== false) { // get stream meta data $streamMetaData = stream_get_meta_data($response->getBodyStream()); /** * Currently it's not possible to apply zlib.deflate filter on memory (php://memory) or * temp (php://temp) streams due to a bug in that zlib library., * * So for now we'll check if stream type is not MEMORY in case of static files and add * deflate filter just for static files served via core module. * * @link https://bugs.php.net/bug.php?id=48725 */ if ($streamMetaData['stream_type'] !== 'MEMORY' && $this->isRelevantMimeType($response->getHeader(Protocol::HEADER_CONTENT_TYPE))) { // apply encoding filter to response body stream stream_filter_append($response->getBodyStream(), 'zlib.deflate', STREAM_FILTER_READ); // rewind current body stream @rewind($response->getBodyStream()); // copy body stream to make use of filter in read mode $deflateBodyStream = fopen('php://memory', 'w+b'); // copy stream with appended filter to new deflate body stream stream_copy_to_stream($response->getBodyStream(), $deflateBodyStream); // reset body stream on response $response->setBodyStream($deflateBodyStream); // set encoding header info $response->addHeader(Protocol::HEADER_CONTENT_ENCODING, 'deflate'); } } }