encodeKey() public static method

Raw URL encode a key and allow for '/' characters
public static encodeKey ( string $key ) : string
$key string Key to encode
return string Returns the encoded key
 /**
  * Changes how buckets are referenced in the HTTP request
  *
  * @param Event $event Event emitted
  */
 public function onCommandBeforeSend(Event $event)
 {
     $command = $event['command'];
     $bucket = $command['Bucket'];
     $request = $command->getRequest();
     $pathStyle = false;
     if ($key = $command['Key']) {
         // Modify the command Key to account for the {/Key*} explosion into an array
         if (is_array($key)) {
             $command['Key'] = $key = implode('/', $key);
         }
     }
     // Set the key and bucket on the request
     $request->getParams()->set('bucket', $bucket)->set('key', $key);
     // Switch to virtual if PathStyle is disabled, or not a DNS compatible bucket name, or the scheme is
     // http, or the scheme is https and there are no dots in the host header (avoids SSL issues)
     if (!$command['PathStyle'] && $command->getClient()->isValidBucketName($bucket) && !($command->getRequest()->getScheme() == 'https' && strpos($bucket, '.'))) {
         // Switch to virtual hosted bucket
         $request->setHost($bucket . '.' . $request->getHost());
         $request->setPath(preg_replace("#^/{$bucket}#", '', $request->getPath()));
     } else {
         $pathStyle = true;
     }
     if (!$bucket) {
         $request->getParams()->set('s3.resource', '/');
     } elseif ($pathStyle) {
         // Path style does not need a trailing slash
         $request->getParams()->set('s3.resource', '/' . rawurlencode($bucket) . ($key ? '/' . S3Client::encodeKey($key) : ''));
     } else {
         // Bucket style needs a trailing slash
         $request->getParams()->set('s3.resource', '/' . rawurlencode($bucket) . ($key ? '/' . S3Client::encodeKey($key) : '/'));
     }
 }
Example #2
0
 public function createPresignedUrl(RequestInterface $request, CredentialsInterface $credentials, $expires)
 {
     // Operate on a clone of the request, so the original is not altered.
     $request = clone $request;
     // URL encoding already occurs in the URI template expansion. Undo that
     // and encode using the same encoding as GET object, PUT object, etc.
     $path = S3Client::encodeKey(rawurldecode($request->getPath()));
     $request->setPath($path);
     // Make sure to handle temporary credentials
     if ($token = $credentials->getSecurityToken()) {
         $request->setHeader('X-Amz-Security-Token', $token);
         $request->getQuery()->set('X-Amz-Security-Token', $token);
     }
     if ($expires instanceof \DateTime) {
         $expires = $expires->getTimestamp();
     } elseif (!is_numeric($expires)) {
         $expires = strtotime($expires);
     }
     // Set query params required for pre-signed URLs
     $query = $request->getQuery();
     $query['AWSAccessKeyId'] = $credentials->getAccessKeyId();
     $query['Expires'] = $expires;
     $query['Signature'] = $this->signString($this->createCanonicalizedString($request, $expires), $credentials);
     // Move X-Amz-* headers to the query string
     foreach ($request->getHeaders() as $name => $header) {
         $name = strtolower($name);
         if (strpos($name, 'x-amz-') === 0) {
             $request->getQuery()->set($name, implode(',', $header));
             $request->removeHeader($name);
         }
     }
     return $request->getUrl();
 }
 private function modifyRequest(RequestInterface $request, CommandInterface $command)
 {
     $uri = $request->getUri();
     $path = $uri->getPath();
     $bucket = $command['Bucket'];
     $path = $this->removeBucketFromPath($path, $bucket);
     // Modify the Key to make sure the key is encoded, but slashes are not.
     if ($command['Key']) {
         $path = S3Client::encodeKey(rawurldecode($path));
     }
     return $request->withUri($uri->withPath($path));
 }
 /**
  * Changes how buckets are referenced in the HTTP request
  *
  * @param PreparedEvent $event Event emitted
  */
 public function setBucketStyle(PreparedEvent $event)
 {
     $command = $event->getCommand();
     $request = $event->getRequest();
     $bucket = $command['Bucket'];
     $path = $request->getPath();
     if (!$bucket || isset(self::$exclusions[$command->getName()])) {
         return;
     }
     if ($this->bucketEndpoint) {
         $path = $this->removeBucketFromPath($path, $bucket);
     } elseif (!$command['PathStyle'] && S3Client::isBucketDnsCompatible($bucket) && !($request->getScheme() == 'https' && strpos($bucket, '.'))) {
         // Switch to virtual if PathStyle is disabled, or not a DNS
         // compatible bucket name, or the scheme is https and there are no
         // dots in the hostheader (avoids SSL issues).
         $request->setHost($bucket . '.' . $request->getHost());
         $path = $this->removeBucketFromPath($path, $bucket);
     }
     // Modify the Key to make sure the key is encoded, but slashes are not.
     if ($command['Key']) {
         $path = S3Client::encodeKey(rawurldecode($path));
     }
     $request->setPath($path);
 }
Example #5
0
 public function copy($path1, $path2)
 {
     $path1 = $this->normalizePath($path1);
     $path2 = $this->normalizePath($path2);
     if ($this->is_file($path1)) {
         try {
             $result = $this->connection->copyObject(array('Bucket' => $this->bucket, 'Key' => $this->cleanKey($path2), 'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1)));
             $this->testTimeout();
         } catch (S3Exception $e) {
             \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
             return false;
         }
     } else {
         if ($this->file_exists($path2)) {
             return false;
         }
         try {
             $result = $this->connection->copyObject(array('Bucket' => $this->bucket, 'Key' => $path2 . '/', 'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1 . '/')));
             $this->testTimeout();
         } catch (S3Exception $e) {
             \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
             return false;
         }
         $dh = $this->opendir($path1);
         if (is_resource($dh)) {
             while (($file = readdir($dh)) !== false) {
                 if ($file === '.' || $file === '..') {
                     continue;
                 }
                 $source = $path1 . '/' . $file;
                 $target = $path2 . '/' . $file;
                 $this->copy($source, $target);
             }
         }
     }
     return true;
 }
Example #6
0
 /**
  * Create a canonicalized resource for a request
  *
  * @param RequestInterface $request Request for the resource
  *
  * @return string
  */
 private function createCanonicalizedResource(RequestInterface $request)
 {
     $buffer = $request->getParams()->get('s3.resource');
     // When sending a raw HTTP request (e.g. $client->get())
     if (null === $buffer) {
         $bucket = $request->getParams()->get('bucket') ?: $this->parseBucketName($request);
         // Use any specified bucket name, the parsed bucket name, or no bucket name when interacting with GetService
         $buffer = $bucket ? "/{$bucket}" : '';
         // Remove encoding from the path and use the S3 specific encoding
         $path = S3Client::encodeKey(rawurldecode($request->getPath()));
         // if the bucket was path style, then ensure that the bucket wasn't duplicated in the resource
         $buffer .= preg_replace("#^/{$bucket}/{$bucket}#", "/{$bucket}", $path);
     }
     // Remove double slashes
     $buffer = str_replace('//', '/', $buffer);
     // Add sub resource parameters
     $query = $request->getQuery();
     $first = true;
     foreach ($this->signableQueryString as $key) {
         if ($query->hasKey($key)) {
             $value = $query[$key];
             $buffer .= $first ? '?' : '&';
             $first = false;
             $buffer .= $key;
             // Don't add values for empty sub-resources
             if ($value !== '' && $value !== false && $value !== null && $value !== QueryString::BLANK) {
                 $buffer .= "={$value}";
             }
         }
     }
     return $buffer;
 }
Example #7
0
 public function copy($path1, $path2)
 {
     $path1 = $this->normalizePath($path1);
     $path2 = $this->normalizePath($path2);
     if ($this->is_file($path1)) {
         try {
             $this->getConnection()->copyObject(array('Bucket' => $this->bucket, 'Key' => $this->cleanKey($path2), 'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1)));
             $this->testTimeout();
         } catch (S3Exception $e) {
             \OCP\Util::logException('files_external', $e);
             return false;
         }
     } else {
         $this->remove($path2);
         try {
             $this->getConnection()->copyObject(array('Bucket' => $this->bucket, 'Key' => $path2 . '/', 'CopySource' => S3Client::encodeKey($this->bucket . '/' . $path1 . '/')));
             $this->testTimeout();
         } catch (S3Exception $e) {
             \OCP\Util::logException('files_external', $e);
             return false;
         }
         $dh = $this->opendir($path1);
         if (is_resource($dh)) {
             while (($file = readdir($dh)) !== false) {
                 if (\OC\Files\Filesystem::isIgnoredDir($file)) {
                     continue;
                 }
                 $source = $path1 . '/' . $file;
                 $target = $path2 . '/' . $file;
                 $this->copy($source, $target);
             }
         }
     }
     return true;
 }
Example #8
0
 /**
  * encodeKey
  *
  * @param string $key
  *
  * @return string
  */
 public static function encodeKey($key)
 {
     return S3Client::encodeKey($key);
 }
Example #9
0
 public function testProperlyEncodesPrefixKeys()
 {
     $this->assertEquals('/foo/baz%20/bar%21', S3Client::encodeKey('/foo/baz /bar!'));
     $client = $this->getServiceBuilder()->get('s3', true);
     $command = $client->getCommand('PutObject', array('Key' => 'foo/baz /bar!', 'Bucket' => 'test', 'Body' => ''));
     $command->prepare();
     $this->assertEquals('/foo/baz%20/bar%21', $command->getRequest()->getPath());
     $this->assertEquals('test.s3.amazonaws.com', $command->getRequest()->getHost());
 }
Example #10
0
 protected function computePath($path)
 {
     $this->ensureBucketExists();
     return S3Client::encodeKey($path);
 }
 /**
  * Changes how buckets are referenced in the HTTP request
  *
  * @param Event $event Event emitted
  */
 public function onCommandAfterPrepare(Event $event)
 {
     $command = $event['command'];
     $bucket = $command['Bucket'];
     $request = $command->getRequest();
     // Skip operations that do not need the bucket moved to the host.
     if (isset(self::$exclusions[$command->getName()])) {
         return;
     }
     if ($key = $command['Key']) {
         // Modify the command Key to account for the {/Key*} explosion into an array
         if (is_array($key)) {
             $command['Key'] = $key = implode('/', $key);
         }
     }
     // Set the key and bucket on the request
     $request->getParams()->set('bucket', $bucket)->set('key', $key);
     // Switch to virtual if PathStyle is disabled, or not a DNS compatible bucket name, or the scheme is
     // http, or the scheme is https and there are no dots in the host header (avoids SSL issues)
     // This is the initial code, automatically switching to VirtualHost
     /*
     if (!$command['PathStyle'] && $command->getClient()->isValidBucketName($bucket)
         && !($command->getRequest()->getScheme() == 'https' && strpos($bucket, '.'))
     ) {
         // Switch to virtual hosted bucket
         $request->setHost($bucket . '.' . $request->getHost());
         $request->setPath(preg_replace("#^/{$bucket}#", '', $request->getPath()));
     } else {
         $pathStyle = true;
     }
     */
     $pathStyle = true;
     if (!$bucket) {
         $request->getParams()->set('s3.resource', '/');
     } elseif ($pathStyle) {
         // Path style does not need a trailing slash
         $path = $request->getPath();
         $request->setHost(str_replace($bucket . ".", "", $request->getHost()));
         $request->setPath('/' . rawurlencode($bucket) . ($path == "/" ? "" : $path));
         $request->getParams()->set('s3.resource', '/' . rawurlencode($bucket) . ($key ? '/' . S3Client::encodeKey($key) : ''));
     } else {
         // Bucket style needs a trailing slash
         $request->getParams()->set('s3.resource', '/' . rawurlencode($bucket) . ($key ? '/' . S3Client::encodeKey($key) : '/'));
     }
 }