/** * 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. * @var StreamInterface $buffer */ $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; }
/** * Sends response to output. * @param IRequest $request * @param IResponse $response */ public function send(IRequest $request, IResponse $response) { // Set response headers for the file download $response->setHeader('Content-Length', $this->stream->getSize()); $response->setHeader('Content-Type', $this->contentType); $response->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '";'); while (!$this->stream->eof()) { echo $this->stream->read(4000000.0); } $this->stream->close(); }
/** * StreamRange constructor. * @param StreamInterface $stream * @param string $range * @throws */ public function __construct(StreamInterface $stream, $range) { $range = trim($range); $length = $stream->getSize(); if (preg_match('/^(\\d+)\\-$/', $range, $match)) { $this->firstPos = intval($match[1]); if ($this->firstPos > $length - 1) { throw new StreamRangeException('HTTP/1.1 416 Requested Range Not Satisfiable'); } $this->lastPos = $length - 1; } elseif (preg_match('/^(\\d+)\\-(\\d+)$/', $range, $match)) { $this->firstPos = intval($match[1]); $this->lastPos = intval($match[2]); if ($this->lastPos < $this->firstPos || $this->lastPos > $length - 1) { throw new StreamRangeException('HTTP/1.1 416 Requested Range Not Satisfiable'); } } elseif (preg_match('/^\\-(\\d+)$/', $range, $match)) { $suffixLength = intval($match[1]); if ($suffixLength === 0 || $suffixLength > $length) { throw new StreamRangeException('HTTP/1.1 416 Requested Range Not Satisfiable'); } $this->firstPos = $length - $suffixLength; $this->lastPos = $length - 1; } else { throw new StreamRangeException('HTTP/1.1 416 Requested Range Not Satisfiable'); } }
public function getSize() { if ($this->size != null) { return $this->size; } if ($this->stream instanceof StreamInterface) { return $this->stream->getSize(); } return null; }
public function testReadAndWrite() { $this->assertEquals(0, $this->stream->getSize()); $this->stream->write("Hello World, And All Developers!"); $this->assertEquals(32, $this->stream->getSize()); // size $this->assertEquals(32, $this->stream->tell()); // pointer $this->stream->rewind(); $this->assertEquals(0, $this->stream->tell()); $this->assertFalse($this->stream->eof()); $this->assertEquals("Hell", $this->stream->read(4)); $this->assertEquals("o World, ", $this->stream->read(9)); $this->assertEquals("And All Developers!", $this->stream->getContents()); $this->assertTrue($this->stream->eof()); $this->stream->seek(12); $this->assertEquals(6, $this->stream->write('Hum...')); $this->assertEquals("ll Developers!", $this->stream->getContents()); $this->assertEquals("Hello World,Hum...ll Developers!", $this->stream->__toString()); }
private function cropContent(StreamInterface $stream = null) { if (null === $stream) { return ''; } if ($stream->getSize() <= $this->maxBodySize) { return (string) $stream; } $stream->seek(0); return '(partial content)' . $stream->read($this->maxBodySize) . '(...)'; }
/** * SOSPAction header is removed in SOAP 1.2 and now expressed as a value of * an (optional) "action" parameter of the "application/soap+xml" media type. * @link https://www.w3.org/TR/soap12-part0/#L4697 * @return array */ private function prepareSoap12Headers() { $headers = []; if ($this->httpMethod == 'POST') { $headers['Content-Length'] = $this->soapMessage->getSize(); $headers['Content-Type'] = 'application/soap+xml; charset="utf-8"' . '; action="' . $this->soapAction . '"'; } else { $headers['Accept'] = 'application/soap+xml'; } return $headers; }
/** * @param StreamInterface $stream Decorated stream * @param bool $useFileBuffer Whether to use a file buffer (write to a file, if data exceed a certain size) * by default, set this to false to only use memory * @param int $memoryBuffer In conjunction with using file buffer, limit (in bytes) from which it begins to buffer * the data in a file */ public function __construct(StreamInterface $stream, $useFileBuffer = true, $memoryBuffer = 2097152) { $this->stream = $stream; $this->size = $stream->getSize(); if ($useFileBuffer) { $this->resource = fopen('php://temp/maxmemory:' . $memoryBuffer, 'rw+'); } else { $this->resource = fopen('php://memory', 'rw+'); } if (false === $this->resource) { throw new \RuntimeException('Cannot create a resource over temp or memory implementation'); } }
/** * Helper method used to correctly resolve StreamInterface stats. * * @param StreamInterface $stream * @return array */ private function getStreamStats(StreamInterface $stream) { $mode = $this->mode; if (empty($mode)) { if ($stream->isReadable()) { $mode = 'r'; } if ($stream->isWritable()) { $mode = !empty($mode) ? 'r+' : 'w'; } } return ['dev' => 0, 'ino' => 0, 'mode' => self::$modes[$mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => (string) $stream->getSize(), 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0]; }
/** * {@inheritdoc} */ public function getSize() { return $this->stream->getSize(); }
/** * Upload data to tracker * * @param string|StreamInterface|UploadedFileInterface $file * @param string $key * @param string $class * @param bool $use_file * * @return bool * @throws Exception */ public function put($file, $key, $class, $use_file = true) { if ($key === null) { throw new InvalidArgumentException(get_class($this) . "::put key cannot be null"); } if ($use_file) { if ($file instanceof UploadedFileInterface) { $fh = $file->getStream()->detach(); $length = $file->getSize(); } elseif ($file instanceof StreamInterface) { $fh = $file->detach(); $length = $file->getSize(); } elseif (is_resource($file) && get_resource_type($file) == 'stream') { $fh = $file; } else { $fh = fopen($file, 'r'); } if (!$fh) { throw new RuntimeException(get_class($this) . "::put failed to open file"); } if (!$length) { $length = filesize($file); } } else { $fh = fopen('php://memory', 'rw'); if ($fh === false) { throw new RuntimeException(get_class($this) . "::put failed to open memory stream"); } fwrite($fh, $file); rewind($fh); $length = strlen($file); } //CREATE_OPEN domain=%s&key=%s&class=%s&multi_dest=%d $location = $this->doRequest('CREATE_OPEN', ['domain' => $this->domain, 'key' => $key, 'class' => $class]); $uri = $location['path']; $ch = curl_init(); curl_setopt($ch, CURLOPT_INFILE, $fh); curl_setopt($ch, CURLOPT_INFILESIZE, $length); curl_setopt($ch, CURLOPT_TIMEOUT, $this->request_timeout); curl_setopt($ch, CURLOPT_PUT, $this->request_timeout); curl_setopt($ch, CURLOPT_URL, $uri); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Expect: ']); $response = curl_exec($ch); fclose($fh); if ($response === false) { $error = curl_error($ch); curl_close($ch); throw new RuntimeException(get_class($this) . "::put {$error}"); } curl_close($ch); $this->doRequest('CREATE_CLOSE', ['key' => $key, 'class' => $class, 'domain' => $this->domain, 'devid' => $location['devid'], 'fid' => $location['fid'], 'path' => urldecode($uri)]); return true; }
/** * {@inheritdoc} */ public function getSize() { return $this->decoratedStream->getSize() - $this->offset; }
public function testHasSize() { $this->assertEquals(3, $this->b->getSize()); }
public function stream_stat() { static $modeMap = ['r' => 33060, 'r+' => 33206, 'w' => 33188]; return ['dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0]; }
/** * Add extra headers if they are missing. * * @param string $name * @param StreamInterface $stream * @param string $filename * @param array &$headers */ private function prepareHeaders($name, StreamInterface $stream, $filename, array &$headers) { $hasFilename = $filename === '0' || $filename; // Set a default content-disposition header if one was not provided if (!$this->hasHeader($headers, 'content-disposition')) { $headers['Content-Disposition'] = sprintf('form-data; name="%s"', $name); if ($hasFilename) { $headers['Content-Disposition'] .= sprintf('; filename="%s"', basename($filename)); } } // Set a default content-length header if one was not provided if (!$this->hasHeader($headers, 'content-length')) { if ($length = $stream->getSize()) { $headers['Content-Length'] = (string) $length; } } // Set a default Content-Type if one was not provided if (!$this->hasHeader($headers, 'content-type') && $hasFilename) { if ($type = $this->getMimetypeHelper()->getMimetypeFromFilename($filename)) { $headers['Content-Type'] = $type; } } }
/** * Uploads the contents of the resource (this could be a file handle) to Communibase * * @param StreamInterface $resource * @param string $name * @param string $destinationPath * @param string $id * * @return array|mixed * * @throws \RuntimeException | Exception */ public function updateBinary(StreamInterface $resource, $name, $destinationPath, $id = '') { $metaData = ['path' => $destinationPath]; if (!empty($id)) { if (!static::isIdValid($id)) { throw new Exception('Id is invalid, please use a correctly formatted id'); } return $this->doPut('File.json/crud/' . $id, [], ['filename' => $name, 'length' => $resource->getSize(), 'uploadDate' => date('c'), 'metadata' => $metaData, 'content' => base64_encode($resource->getContents())]); } $options = ['multipart' => [['name' => 'File', 'filename' => $name, 'contents' => $resource], ['name' => 'metadata', 'contents' => json_encode($metaData)]]]; $response = $this->call('post', ['File.json/binary', $options]); return $this->parseResult($response->getBody(), $response->getStatusCode()); }
/** * @return array */ private function createElement($name, StreamInterface $stream, $filename, array $headers) { // Set a default content-disposition header if one was no provided $disposition = $this->getHeader($headers, 'content-disposition'); if (!$disposition) { $headers['Content-Disposition'] = $filename === '0' || $filename ? sprintf('form-data; name="%s"; filename="%s"', $name, basename($filename)) : "form-data; name=\"{$name}\""; } // Set a default content-length header if one was no provided $length = $this->getHeader($headers, 'content-length'); if (!$length) { if ($length = $stream->getSize()) { $headers['Content-Length'] = (string) $length; } } // Set a default Content-Type if one was not supplied $type = $this->getHeader($headers, 'content-type'); if (!$type && ($filename === '0' || $filename)) { if ($type = mimetype_from_filename($filename)) { $headers['Content-Type'] = $type; } } return [$stream, $headers]; }
/** * Sends Body. * * @param Psr\Http\Message\StreamInterface $body The body to send as stream * * @author Benjamin Carl <*****@*****.**> * @return void * @access protected */ protected function sendBody(Stream $body) { // I don't trust that this will be at the beginning of the stream, so reset. $body->rewind(); // writing to an arbitrary stream. // @todo Use stream operations to make this more robust and allow $bytes = 0; if ($bytes = $body->getSize() && $bytes < 500) { print $body->getContents(); } else { while (!$body->eof()) { $data = $body->read(1024); print $data; } } }
private function streamStr(StreamInterface $body) { return $body->getSize() < $this->config['stream_size'] ? (string) $body : 'stream(size=' . $body->getSize() . ')'; }
protected function runMatches(StreamInterface $stream) { return $stream->getSize() == $this->expected; }