public function send(ResponseInterface $response) { http_response_code($response->getStatusCode()); foreach ($response->getHeaders() as $header => $values) { foreach ($values as $value) { header($header . ':' . $value, false); } } Psr7\copy_to_stream($response->getBody(), $this->environment->getStdOut()); }
public function testStopsCopyToSteamWhenReadFailsWithMaxLen() { $s1 = Psr7\stream_for('foobaz'); $s1 = FnStream::decorate($s1, ['read' => function () { return ''; }]); $s2 = Psr7\stream_for(''); Psr7\copy_to_stream($s1, $s2, 10); $this->assertEquals('', (string) $s2); }
protected function createPart($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 Psr7\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, $data); $body = Psr7\stream_for(); Psr7\copy_to_stream($source, $body); $data['ContentLength'] = $body->getSize(); } // Do not create a part if the body size is zero. if ($body->getSize() === 0) { return false; } $body->seek(0); $data['Body'] = $body; return $data; }
/** * Drains the source stream into the "sink" client option. * * @param StreamInterface $source * @param StreamInterface $sink * * @return StreamInterface * @throws \RuntimeException when the sink option is invalid. */ private function drain(StreamInterface $source, StreamInterface $sink) { Psr7\copy_to_stream($source, $sink); $sink->seek(0); $source->close(); return $sink; }
/** * 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; } // Handle the situation where the body size is unknown. // Read up to 5MB into a buffer to determine how to upload the body. $buffer = Psr7\stream_for(); Psr7\copy_to_stream($body, $buffer, MultipartUploader::PART_MIN_SIZE); // If body < 5MB, use PutObject with the buffer. if ($buffer->getSize() < MultipartUploader::PART_MIN_SIZE) { $buffer->seek(0); $body = $buffer; return false; } // If body >= 5 MB, then use multipart. [YES] if ($body->isSeekable()) { // If the body is seekable, just rewind the body. $body->seek(0); } else { // If the body is non-seekable, stitch the rewind the buffer and // the partially read body together into one stream. This avoids // unnecessary disc usage and does not require seeking on the // original stream. $buffer->seek(0); $body = new Psr7\AppendStream([$buffer, $body]); } return true; }
protected function createPart($seekable, $number) { $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 = Psr7\try_fopen($this->source->getMetadata('uri'), 'r'); $body = $this->limitPartStream(Psr7\stream_for($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 = Psr7\stream_for(); Psr7\copy_to_stream($source, $body); } // Do not create a part if the body size is zero. if ($body->getSize() === 0) { return false; } $body->seek(0); $data['body'] = $body; $lastByte = $this->source->tell() - 1; $data['range'] = "bytes {$firstByte}-{$lastByte}/*"; return $data; }
/** * Drains the source stream into the "sink" client option. * * @param StreamInterface $source * @param StreamInterface $sink * @param string $contentLength Header specifying the amount of * data to read. * * @return StreamInterface * @throws \RuntimeException when the sink option is invalid. */ private function drain(StreamInterface $source, StreamInterface $sink, $contentLength) { // If a content-length header is provided, then stop reading once // that number of bytes has been read. This can prevent infinitely // reading from a stream when dealing with servers that do not honor // Connection: Close headers. Psr7\copy_to_stream($source, $sink, strlen($contentLength) > 0 && (int) $contentLength > 0 ? (int) $contentLength : -1); $sink->seek(0); $source->close(); return $sink; }
/** * Download an object to a specified location. * * Example: * ``` * $object->downloadToFile('my-file.txt'); * ``` * * @param string $path Path to download file to. * @param array $options [optional] Configuration Options. * @return StreamInterface */ public function downloadToFile($path, array $options = []) { $destination = Psr7\stream_for(fopen($path, 'w')); Psr7\copy_to_stream($this->connection->downloadObject($options + $this->identity), $destination); $destination->seek(0); return $destination; }