public function setBody($body, $contentType = null)
 {
     $this->body = EntityBody::factory($body);
     // Auto detect the Content-Type from the path of the request if possible
     if ($contentType === null && !$this->hasHeader('Content-Type')) {
         $contentType = $this->body->getContentType() ?: Mimetypes::getInstance()->fromFilename($this->getPath());
     }
     if ($contentType) {
         $this->setHeader('Content-Type', $contentType);
     }
     // Always add the Expect 100-Continue header if the body cannot be rewound. This helps with redirects.
     if (!$this->body->isSeekable() && $this->expectCutoff !== false) {
         $this->setHeader('Expect', '100-Continue');
     }
     // Set the Content-Length header if it can be determined
     $size = $this->body->getContentLength();
     if ($size !== null && $size !== false) {
         $this->setHeader('Content-Length', $size);
         if ($size > $this->expectCutoff) {
             $this->setHeader('Expect', '100-Continue');
         }
     } elseif (!$this->hasHeader('Content-Length')) {
         if ('1.1' == $this->protocolVersion) {
             $this->setHeader('Transfer-Encoding', 'chunked');
         } else {
             throw new RequestException('Cannot determine Content-Length and cannot use chunked Transfer-Encoding when using HTTP/1.0');
         }
     }
     return $this;
 }
 /**
  * {@inheritdoc}
  */
 public function setBody($body, $contentType = null, $tryChunkedTransfer = false)
 {
     $this->body = EntityBody::factory($body);
     $this->removeHeader('Content-Length');
     if ($contentType) {
         $this->setHeader('Content-Type', (string) $contentType);
     }
     // Always add the Expect 100-Continue header if the body cannot be rewound. This helps with redirects.
     if (!$this->body->isSeekable() && $this->expectCutoff !== false) {
         $this->setHeader('Expect', '100-Continue');
     }
     if ($tryChunkedTransfer) {
         $this->setHeader('Transfer-Encoding', 'chunked');
     } else {
         $this->removeHeader('Transfer-Encoding');
         // Set the Content-Length header if it can be determined
         $size = $this->body->getContentLength();
         if ($size !== null && $size !== false) {
             $this->setHeader('Content-Length', $size);
             if ($size > $this->expectCutoff) {
                 $this->setHeader('Expect', '100-Continue');
             }
         } elseif ('1.1' == $this->protocolVersion) {
             $this->setHeader('Transfer-Encoding', 'chunked');
         } else {
             throw new RequestException('Cannot determine Content-Length and cannot use chunked Transfer-Encoding when using HTTP/1.0');
         }
     }
     return $this;
 }
 /**
  * @param EntityBodyInterface $body     The upload body
  * @param int                 $partSize The size of parts to split the upload into. Default is the 4GB max
  *
  * @throws InvalidArgumentException when the part size is invalid (i.e. not a power of 2 of 1MB)
  * @throws InvalidArgumentException when the body is not seekable (must be able to rewind after calculating hashes)
  * @throws InvalidArgumentException when the archive size is less than one byte
  */
 public function __construct(EntityBodyInterface $body, $partSize)
 {
     $this->partSize = $partSize;
     // Make sure the part size is valid
     $validPartSizes = array_map(function ($value) {
         return pow(2, $value) * Size::MB;
     }, range(0, 12));
     if (!in_array($this->partSize, $validPartSizes)) {
         throw new InvalidArgumentException('The part size must be a megabyte multiplied by a power of 2 and no ' . 'greater than 4 gigabytes.');
     }
     // Validate body
     if (!$body->isSeekable()) {
         throw new InvalidArgumentException('The upload body must be seekable.');
     }
     $this->generateUploadParts($body);
     // Validate archive size
     if ($this->archiveSize < 1) {
         throw new InvalidArgumentException('The archive size must be at least 1 byte.');
     }
 }