/**
  * 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;
 }
示例#2
0
 /**
  * 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();
 }
示例#3
0
 /**
  * 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');
     }
 }
示例#4
0
 public function getSize()
 {
     if ($this->size != null) {
         return $this->size;
     }
     if ($this->stream instanceof StreamInterface) {
         return $this->stream->getSize();
     }
     return null;
 }
示例#5
0
 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;
 }
示例#8
0
 /**
  * @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();
 }
示例#11
0
 /**
  * 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());
 }
示例#14
0
 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];
 }
示例#18
0
 /**
  * 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;
         }
     }
 }
示例#19
0
 private function streamStr(StreamInterface $body)
 {
     return $body->getSize() < $this->config['stream_size'] ? (string) $body : 'stream(size=' . $body->getSize() . ')';
 }
示例#20
0
 protected function runMatches(StreamInterface $stream)
 {
     return $stream->getSize() == $this->expected;
 }