PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zend-http/src/Response/Stream.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 297 lines | 145 code | 33 blank | 119 comment | 28 complexity | 9422486ef464229ba2d1b74fb9074109 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Http\Response;
  10. use Zend\Http\Exception;
  11. use Zend\Http\Response;
  12. use Zend\Stdlib\ErrorHandler;
  13. /**
  14. * Represents an HTTP response message as PHP stream resource
  15. */
  16. class Stream extends Response
  17. {
  18. /**
  19. * The Content-Length value, if set
  20. *
  21. * @var int
  22. */
  23. protected $contentLength = null;
  24. /**
  25. * The portion of the body that has already been streamed
  26. *
  27. * @var int
  28. */
  29. protected $contentStreamed = 0;
  30. /**
  31. * Response as stream
  32. *
  33. * @var resource
  34. */
  35. protected $stream;
  36. /**
  37. * The name of the file containing the stream
  38. *
  39. * Will be empty if stream is not file-based.
  40. *
  41. * @var string
  42. */
  43. protected $streamName;
  44. /**
  45. * Should we clean up the stream file when this response is closed?
  46. *
  47. * @var bool
  48. */
  49. protected $cleanup;
  50. /**
  51. * Set content length
  52. *
  53. * @param int $contentLength
  54. */
  55. public function setContentLength($contentLength = null)
  56. {
  57. $this->contentLength = $contentLength;
  58. }
  59. /**
  60. * Get content length
  61. *
  62. * @return int|null
  63. */
  64. public function getContentLength()
  65. {
  66. return $this->contentLength;
  67. }
  68. /**
  69. * Get the response as stream
  70. *
  71. * @return resource
  72. */
  73. public function getStream()
  74. {
  75. return $this->stream;
  76. }
  77. /**
  78. * Set the response stream
  79. *
  80. * @param resource $stream
  81. * @return Stream
  82. */
  83. public function setStream($stream)
  84. {
  85. $this->stream = $stream;
  86. return $this;
  87. }
  88. /**
  89. * Get the cleanup trigger
  90. *
  91. * @return bool
  92. */
  93. public function getCleanup()
  94. {
  95. return $this->cleanup;
  96. }
  97. /**
  98. * Set the cleanup trigger
  99. *
  100. * @param bool $cleanup
  101. */
  102. public function setCleanup($cleanup = true)
  103. {
  104. $this->cleanup = $cleanup;
  105. }
  106. /**
  107. * Get file name associated with the stream
  108. *
  109. * @return string
  110. */
  111. public function getStreamName()
  112. {
  113. return $this->streamName;
  114. }
  115. /**
  116. * Set file name associated with the stream
  117. *
  118. * @param string $streamName Name to set
  119. * @return Stream
  120. */
  121. public function setStreamName($streamName)
  122. {
  123. $this->streamName = $streamName;
  124. return $this;
  125. }
  126. /**
  127. * Create a new Zend\Http\Response\Stream object from a stream
  128. *
  129. * @param string $responseString
  130. * @param resource $stream
  131. * @return Stream
  132. * @throws Exception\InvalidArgumentException
  133. * @throws Exception\OutOfRangeException
  134. */
  135. public static function fromStream($responseString, $stream)
  136. {
  137. if (!is_resource($stream) || get_resource_type($stream) !== 'stream') {
  138. throw new Exception\InvalidArgumentException('A valid stream is required');
  139. }
  140. $headerComplete = false;
  141. $headersString = '';
  142. $responseArray = array();
  143. if ($responseString) {
  144. $responseArray = explode("\n", $responseString);
  145. }
  146. while (count($responseArray)) {
  147. $nextLine = array_shift($responseArray);
  148. $headersString .= $nextLine."\n";
  149. $nextLineTrimmed = trim($nextLine);
  150. if ($nextLineTrimmed == '') {
  151. $headerComplete = true;
  152. break;
  153. }
  154. }
  155. if (!$headerComplete) {
  156. while (false !== ($nextLine = fgets($stream))) {
  157. $headersString .= trim($nextLine)."\r\n";
  158. if ($nextLine == "\r\n" || $nextLine == "\n") {
  159. $headerComplete = true;
  160. break;
  161. }
  162. }
  163. }
  164. if (!$headerComplete) {
  165. throw new Exception\OutOfRangeException('End of header not found');
  166. }
  167. /** @var Stream $response */
  168. $response = static::fromString($headersString);
  169. if (is_resource($stream)) {
  170. $response->setStream($stream);
  171. }
  172. if (count($responseArray)) {
  173. $response->content = implode("\n", $responseArray);
  174. }
  175. $headers = $response->getHeaders();
  176. foreach ($headers as $header) {
  177. if ($header instanceof \Zend\Http\Header\ContentLength) {
  178. $response->setContentLength((int) $header->getFieldValue());
  179. $contentLength = $response->getContentLength();
  180. if (strlen($response->content) > $contentLength) {
  181. throw new Exception\OutOfRangeException(sprintf(
  182. 'Too much content was extracted from the stream (%d instead of %d bytes)',
  183. strlen($response->content),
  184. $contentLength
  185. ));
  186. }
  187. break;
  188. }
  189. }
  190. return $response;
  191. }
  192. /**
  193. * Get the response body as string
  194. *
  195. * This method returns the body of the HTTP response (the content), as it
  196. * should be in it's readable version - that is, after decoding it (if it
  197. * was decoded), deflating it (if it was gzip compressed), etc.
  198. *
  199. * If you want to get the raw body (as transferred on wire) use
  200. * $this->getRawBody() instead.
  201. *
  202. * @return string
  203. */
  204. public function getBody()
  205. {
  206. if ($this->stream !== null) {
  207. $this->readStream();
  208. }
  209. return parent::getBody();
  210. }
  211. /**
  212. * Get the raw response body (as transferred "on wire") as string
  213. *
  214. * If the body is encoded (with Transfer-Encoding, not content-encoding -
  215. * IE "chunked" body), gzip compressed, etc. it will not be decoded.
  216. *
  217. * @return string
  218. */
  219. public function getRawBody()
  220. {
  221. if ($this->stream) {
  222. $this->readStream();
  223. }
  224. return $this->content;
  225. }
  226. /**
  227. * Read stream content and return it as string
  228. *
  229. * Function reads the remainder of the body from the stream and closes the stream.
  230. *
  231. * @return string
  232. */
  233. protected function readStream()
  234. {
  235. $contentLength = $this->getContentLength();
  236. if (null !== $contentLength) {
  237. $bytes = $contentLength - $this->contentStreamed;
  238. } else {
  239. $bytes = -1; // Read the whole buffer
  240. }
  241. if (!is_resource($this->stream) || $bytes == 0) {
  242. return '';
  243. }
  244. $this->content .= stream_get_contents($this->stream, $bytes);
  245. $this->contentStreamed += strlen($this->content);
  246. if ($this->getContentLength() == $this->contentStreamed) {
  247. $this->stream = null;
  248. }
  249. }
  250. /**
  251. * Destructor
  252. */
  253. public function __destruct()
  254. {
  255. if (is_resource($this->stream)) {
  256. $this->stream = null; //Could be listened by others
  257. }
  258. if ($this->cleanup) {
  259. ErrorHandler::start(E_WARNING);
  260. unlink($this->streamName);
  261. ErrorHandler::stop();
  262. }
  263. }
  264. }