diff --git a/src/StreamWrapper.php b/src/StreamWrapper.php index bc6bf01..6aa1b14 100644 --- a/src/StreamWrapper.php +++ b/src/StreamWrapper.php @@ -211,7 +211,7 @@ public function getExternalUrl() { // otherwise it returns an external URL to an image that has not been // created yet. if ($path_segments[0] === 'styles' && !file_exists((string) $this->uri)) { - return $this->url($this::stylesCallback . '/' . $this->uri->getBucket() . $this->uri->getPath(), array('absolute' => TRUE)); + return $this->url($this::stylesCallback . '/' . $this->uri->getBucket() . $this->uri->getPath(), array('absolute' => TRUE)); } // Allow other modules to change the download link type. @@ -221,16 +221,6 @@ public function getExternalUrl() { // $args = array_merge($args, module_invoke_all('amazons3_url_info', $local_path, $args)); // UI overrides. - // Torrent URLs. - // @todo Torrents are now getObjectTorrent(). - /** - $torrent = $args['download_type'] === 'torrent' ? TRUE : FALSE; - foreach ($this->torrents as $path) { - if ($path === '*' || preg_match('#' . strtr($path, '#', '\#') . '#', $local_path)) { - $args['download_type'] = 'torrent'; - break; - } - }**/ // Presigned URLs. // @todo Presigned URLs are now createPresignedUrl @@ -251,8 +241,14 @@ public function getExternalUrl() { $expiry = time() + 60 * 60 * 24; } + // Torrent URLs. + $path = $this->getLocalPath(); + if ($this->useTorrent()) { + $path .= '?torrent'; + } + // Generate a standard URL. - $url = static::$client->getObjectUrl($this->uri->getBucket(), $this->getLocalPath(), $expiry, $args); + $url = static::$client->getObjectUrl($this->uri->getBucket(), $path, $expiry, $args); return $url; } @@ -388,18 +384,43 @@ protected function getContentDispositionAttachment() { } /** + * Find if this URI should force a download. + * * @return bool + * TRUE if the local path of the stream URI should force a download. FALSE + * otherwise. */ protected function forceDownload() { - foreach ($this->config->getSaveAsPaths() as $path) { - if ($path === '*' || preg_match( - '#' . strtr($path, '#', '\#') . '#', - $this->getLocalPath() - ) - ) { + return $this->matchPathRegex($this->getLocalPath(), $this->config->getSaveAsPaths()); + } + + /** + * Find if a path matches a set of patterns. + * + * @param string $path + * The path to test against $patterns. + * @param array $patterns + * An array of regular expression patterns, without start and end markers. + * + * @return bool + * TRUE if $path matches at least one pattern, FALSE otherwise. + */ + protected static function matchPathRegex($path, array $patterns) { + foreach ($patterns as $pattern) { + if ($pattern === '*' || preg_match('#' . strtr($pattern, '#', '\#') . '#', $path)) { return TRUE; } } return FALSE; } + + /** + * Find if the URI should be returned as a torrent. + * + * @return bool + * TRUE if a torrent should be served, FALSE otherwise. + */ + protected function useTorrent() { + return $this->matchPathRegex($this->getLocalPath(), $this->config->getTorrentPaths()); + } } diff --git a/tests/StreamWrapperTest.php b/tests/StreamWrapperTest.php index cc03de3..da7fe22 100644 --- a/tests/StreamWrapperTest.php +++ b/tests/StreamWrapperTest.php @@ -315,6 +315,7 @@ public function testBasename() { * Test that we throw an exception if a URI is not set. * * @expectedException \LogicException + * * @covers \Drupal\amazons3\StreamWrapper::getBasename */ public function testBasenameUriNotSet() { @@ -326,6 +327,7 @@ public function testBasenameUriNotSet() { * @covers \Drupal\amazons3\StreamWrapper::getExternalUrl * @covers \Drupal\amazons3\StreamWrapper::getContentDispositionAttachment * @covers \Drupal\amazons3\StreamWrapper::forceDownload + * @covers \Drupal\amazons3\StreamWrapper::matchPathRegex */ public function testSaveAs() { $config = StreamWrapperConfiguration::fromConfig([ @@ -391,4 +393,23 @@ public function testAttachmentSpace() { // https://s3.amazonaws.com/bucket.example.com/force-download/test%20with%20spaces.jpg?response-content-disposition=attachment%3B%20filename%3D%22test%20with%20spaces.jpg%22&AWSAccessKeyId=placeholder&Expires=1429987166&Signature=xEZpLFLnNAgIFbRuoP7VRbNUF%2BQ%3D $this->assertRegExp('!.*response-content-disposition=attachment%3B%20filename%3D%22test%20with%20spaces\.jpg.*!', $wrapper->getExternalUrl()); } + + /** + * Test that we can create torrent URLs. + * + * @covers \Drupal\amazons3\StreamWrapper::getExternalUrl + * @covers \Drupal\amazons3\StreamWrapper::useTorrent + */ + public function testTorrentPath() { + $config = StreamWrapperConfiguration::fromConfig([ + 'bucket' => 'bucket.example.com', + 'caching' => FALSE, + 'expiration' => 0, + 'torrentPaths' => array('torrents/.*') + ]); + + $wrapper = new StreamWrapper($config); + $wrapper->setUri('s3://bucket.example.com/torrents/test'); + $this->assertEquals('https://s3.amazonaws.com/bucket.example.com/torrents/test%3Ftorrent', $wrapper->getExternalUrl()); + } }