contentLength = $contentLength; } /** * Get content length * * @return int|null */ public function getContentLength() { return $this->contentLength; } /** * Get the response as stream * * @return resource */ public function getStream() { return $this->stream; } /** * Set the response stream * * @param resource $stream * @return $this */ public function setStream($stream) { $this->stream = $stream; return $this; } /** * Get the cleanup trigger * * @return bool */ public function getCleanup() { return $this->cleanup; } /** * Set the cleanup trigger * * @param bool $cleanup */ public function setCleanup($cleanup = true) { $this->cleanup = $cleanup; } /** * Get file name associated with the stream * * @return string */ public function getStreamName() { return $this->streamName; } /** * Set file name associated with the stream * * @param string $streamName Name to set * @return $this */ public function setStreamName($streamName) { $this->streamName = $streamName; return $this; } /** * Create a new Zend\Http\Response\Stream object from a stream * * @param string $responseString * @param resource $stream * @return $this * @throws Exception\InvalidArgumentException * @throws Exception\OutOfRangeException */ public static function fromStream($responseString, $stream) { if (! is_resource($stream) || get_resource_type($stream) !== 'stream') { throw new Exception\InvalidArgumentException('A valid stream is required'); } $headerComplete = false; $headersString = ''; $responseArray = []; if ($responseString) { $responseArray = explode("\n", $responseString); } while (! empty($responseArray)) { $nextLine = array_shift($responseArray); $headersString .= $nextLine . "\n"; $nextLineTrimmed = trim($nextLine); if ($nextLineTrimmed == '') { $headerComplete = true; break; } } if (! $headerComplete) { while (false !== ($nextLine = fgets($stream))) { $headersString .= trim($nextLine) . "\r\n"; if ($nextLine == "\r\n" || $nextLine == "\n") { $headerComplete = true; break; } } } if (! $headerComplete) { throw new Exception\OutOfRangeException('End of header not found'); } /** @var Stream $response */ $response = static::fromString($headersString); if (is_resource($stream)) { $response->setStream($stream); } if (! empty($responseArray)) { $response->content = implode("\n", $responseArray); } $headers = $response->getHeaders(); foreach ($headers as $header) { if ($header instanceof \Zend\Http\Header\ContentLength) { $response->setContentLength((int) $header->getFieldValue()); $contentLength = $response->getContentLength(); if (strlen($response->content) > $contentLength) { throw new Exception\OutOfRangeException(sprintf( 'Too much content was extracted from the stream (%d instead of %d bytes)', strlen($response->content), $contentLength )); } break; } } return $response; } /** * Get the response body as string * * This method returns the body of the HTTP response (the content), as it * should be in it's readable version - that is, after decoding it (if it * was decoded), deflating it (if it was gzip compressed), etc. * * If you want to get the raw body (as transferred on wire) use * $this->getRawBody() instead. * * @return string */ public function getBody() { if ($this->stream !== null) { $this->readStream(); } return parent::getBody(); } /** * Get the raw response body (as transferred "on wire") as string * * If the body is encoded (with Transfer-Encoding, not content-encoding - * IE "chunked" body), gzip compressed, etc. it will not be decoded. * * @return string */ public function getRawBody() { if ($this->stream) { $this->readStream(); } return $this->content; } /** * Read stream content and return it as string * * Function reads the remainder of the body from the stream and closes the stream. * * @return string */ protected function readStream() { $contentLength = $this->getContentLength(); if (null !== $contentLength) { $bytes = $contentLength - $this->contentStreamed; } else { $bytes = -1; // Read the whole buffer } if (! is_resource($this->stream) || $bytes == 0) { return ''; } $this->content .= stream_get_contents($this->stream, $bytes); $this->contentStreamed += strlen($this->content); if ($this->getContentLength() == $this->contentStreamed) { $this->stream = null; } } /** * Destructor */ public function __destruct() { if (is_resource($this->stream)) { $this->stream = null; //Could be listened by others } if ($this->cleanup) { ErrorHandler::start(E_WARNING); unlink($this->streamName); ErrorHandler::stop(); } } }