public function testStopsCopyToSteamWhenReadFailsWithMaxLen() { $s1 = Stream::factory('foobaz'); $s1 = FnStream::decorate($s1, ['read' => function () { return ''; }]); $s2 = Stream::factory(''); Utils::copyToStream($s1, $s2, 10); $this->assertEquals('', (string) $s2); }
/** * {@inheritdoc} */ public function fetch(FeedInterface $feed, StateInterface $state) { $response = $this->get($feed->getSource(), $this->getCacheKey($feed)); $feed->setSource($response->getEffectiveUrl()); // 304, nothing to see here. if ($response->getStatusCode() == 304) { $state->setMessage($this->t('The feed has not been updated.')); throw new EmptyFeedException(); } // Copy the temp stream to a real file. $download_file = drupal_tempnam('temporary://', 'feeds_http_fetcher'); $dest_stream = Utils::create(fopen($download_file, 'w+')); Utils::copyToStream($response->getBody(), $dest_stream); $response->getBody()->close(); $dest_stream->close(); return new HttpFetcherResult($download_file, $response->getHeaders()); }
/** * Drains the stream into the "save_to" client option. * * @param resource $stream * @param string|resource|StreamInterface $dest * * @return Stream * @throws \RuntimeException when the save_to option is invalid. */ private function drain($stream, $dest) { if (is_resource($stream)) { if (!is_resource($dest)) { $stream = Stream::factory($stream); } else { stream_copy_to_stream($stream, $dest); fclose($stream); rewind($dest); return $dest; } } // Stream the response into the destination stream $dest = is_string($dest) ? new Stream(Utils::open($dest, 'r+')) : Stream::factory($dest); Utils::copyToStream($stream, $dest); $dest->seek(0); $stream->close(); return $dest; }
/** * Drain the stream into the destination stream */ private function getSaveToBody(RequestInterface $request, StreamInterface $stream) { if ($saveTo = $request->getConfig()['save_to']) { // Stream the response into the destination stream $saveTo = is_string($saveTo) ? new Stream(Utils::open($saveTo, 'r+')) : Stream::factory($saveTo); } else { // Stream into the default temp stream $saveTo = Stream::factory(); } Utils::copyToStream($stream, $saveTo); $saveTo->seek(0); $stream->close(); return $saveTo; }
protected function getCreatePartFn() { return function ($seekable) { $data = []; $firstByte = $this->source->tell(); // Read from the source to create the body stream. This also // calculates the linear and tree hashes as the data is read. if ($seekable) { // Case 1: Stream is seekable, can make stream from new handle. $body = Utils::open($this->source->getMetadata('uri'), 'r'); $body = $this->limitPartStream(Stream::factory($body)); // Create another stream decorated with hashing streams and read // through it, so we can get the hash values for the part. $decoratedBody = $this->decorateWithHashes($body, $data); while (!$decoratedBody->eof()) { $decoratedBody->read(1048576); } // Seek the original source forward to the end of the range. $this->source->seek($this->source->tell() + $body->getSize()); } else { // Case 2: Stream is not seekable, must store part in temp stream. $source = $this->limitPartStream($this->source); $source = $this->decorateWithHashes($source, $data); $body = Stream::factory(); Utils::copyToStream($source, $body); } $body->seek(0); $data['body'] = $body; $lastByte = $this->source->tell() - 1; $data['range'] = "bytes {$firstByte}-{$lastByte}/*"; return $data; }; }
/** * Determines if the body should be uploaded using PutObject or the * Multipart Upload System. It also modifies the passed-in $body as needed * to support the upload. * * @param StreamInterface $body Stream representing the body. * @param integer $threshold Minimum bytes before using Multipart. * * @return bool */ private function requiresMultipart(StreamInterface &$body, $threshold) { // If body size known, compare to threshold to determine if Multipart. if ($body->getSize() !== null) { return $body->getSize() < $threshold ? false : true; } // Handle the situation where the body size is unknown. // Read up to 5MB into a buffer to determine how to upload the body. $buffer = Stream::factory(); Utils::copyToStream($body, $buffer, 5242880); // If body < 5MB, use PutObject with the buffer. if ($buffer->getSize() < 5242880) { $buffer->seek(0); $body = $buffer; return false; } // If >= 5 MB, and seekable, use Multipart with rewound body. if ($body->isSeekable()) { $body->seek(0); return true; } // If >= 5 MB, and non-seekable, use Multipart, but stitch the // buffer and the body together into one stream. This avoids // needing to seek and unnecessary disc usage, while requiring // only the 5 MB buffer to be re-read by the Multipart system. $buffer->seek(0); $body = new AppendStream([$buffer, $body]); return true; }
protected function getCreatePartFn() { return function ($seekable, $number) { // Initialize the array of part data that will be returned. $data = ['PartNumber' => $number]; // Read from the source to create the body stream. if ($seekable) { // Case 1: Source is seekable, use lazy stream to defer work. $body = $this->limitPartStream(new LazyOpenStream($this->source->getMetadata('uri'), 'r')); } else { // Case 2: Stream is not seekable; must store in temp stream. $source = $this->limitPartStream($this->source); $source = $this->decorateWithHashes($source, function ($result, $type) use(&$data) { $data['Content' . strtoupper($type)] = $result; }); $body = Stream::factory(); Utils::copyToStream($source, $body); $data['ContentLength'] = $body->getSize(); } $body->seek(0); $data['Body'] = $body; return $data; }; }