You are here

public function S3fsStreamWrapper::getExternalUrl in S3 File System 7

Same name and namespace in other branches
  1. 7.3 S3fsStreamWrapper.inc \S3fsStreamWrapper::getExternalUrl()
  2. 7.2 S3fsStreamWrapper.inc \S3fsStreamWrapper::getExternalUrl()

Returns a web accessible URL for the resource.

The format of the returned URL will be different depending on how the S3 integration has been configured on the S3 File System admin page.

Return value

string Returns a string containing a web accessible URL for the resource.

Overrides DrupalStreamWrapperInterface::getExternalUrl

File

./S3fsStreamWrapper.inc, line 302
Drupal stream wrapper implementation for S3 File System.

Class

S3fsStreamWrapper
The stream wrapper class.

Code

public function getExternalUrl() {
  $this
    ->_debug("getExternalUri() called for {$this->uri}.");
  $s3_filename = $this
    ->_uri_to_s3_filename($this->uri);

  // Image styles support:
  // If an image derivative URL (e.g. styles/thumbnail/blah.jpg) is generated
  // and the file doesn't exist, provide a URL to s3fs's special version of
  // image_style_deliver(), which will create the derivative when that URL
  // gets requested.
  $path_parts = explode('/', $s3_filename);
  if ($path_parts[0] == 'styles') {
    if (!$this
      ->_s3fs_get_object($this->uri)) {

      // The style delivery path looks like: s3/files/styles/<style>/...
      // And $path_parts looks like array('styles', '<style>', ...), so
      // just add the extra parts to the beginning.
      array_unshift($path_parts, 's3', 'files');
      return url(implode('/', $path_parts), array(
        'absolute' => TRUE,
      ));
    }
  }

  // Set up the URL settings from the Settings page.
  $url_settings = array(
    'torrent' => FALSE,
    'presigned_url' => FALSE,
    'timeout' => 60,
    'forced_saveas' => FALSE,
    'api_args' => array(
      'Scheme' => !empty($this->config['use_https']) ? 'https' : 'http',
    ),
  );

  // Presigned URLs.
  foreach ($this->presignedURLs as $blob => $timeout) {

    // ^ is used as the delimeter because it's an illegal character in URLs.
    if (preg_match("^{$blob}^", $s3_filename)) {
      $url_settings['presigned_url'] = TRUE;
      $url_settings['timeout'] = $timeout;
      break;
    }
  }

  // Forced Save As.
  foreach ($this->saveas as $blob) {
    if (preg_match("^{$blob}^", $s3_filename)) {
      $filename = basename($s3_filename);
      $url_settings['api_args']['ResponseContentDisposition'] = "attachment; filename=\"{$filename}\"";
      $url_settings['forced_saveas'] = TRUE;
      break;
    }
  }

  // Throw a deprecation warning if any modules implement the old hook.
  // TODO: Remove this in April 2015, six months after the old hook was removed.
  if (module_implements('s3fs_url_info')) {
    trigger_error('hook_s3fs_url_info() is deprecated. Please use hook_s3fs_url_settings_alter() instead.', E_USER_DEPRECATED);
  }

  // Allow other modules to change the URL settings.
  drupal_alter('s3fs_url_settings', $url_settings, $s3_filename);
  if (empty($this->config['use_cname'])) {

    // We're not using a CNAME, so we ask S3 for the URL.
    $expires = NULL;
    if ($url_settings['presigned_url']) {
      $expires = "+{$url_settings['timeout']} seconds";
    }
    else {

      // Due to Amazon's security policies (see Request Parameters section @
      // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html),
      // only signed requests can use request parameters.
      // Thus, we must provide an expiry time for any URLs which specify
      // Response* API args. Currently, this only includes "Forced Save As".
      foreach ($url_settings['api_args'] as $key => $arg) {
        if (strpos($key, 'Response') === 0) {
          $expires = "+10 years";
          break;
        }
      }
    }
    $url = $this->s3
      ->getObjectUrl($this->config['bucket'], $s3_filename, $expires, $url_settings['api_args']);
  }
  else {

    // We are using a CNAME, so we need to manually construct the URL.
    $url = "{$this->domain}/{$s3_filename}";
  }

  // If this file is versioned, append the version number as a GET arg to
  // ensure that browser caches will be bypassed upon version changes.
  $meta = $this
    ->_read_cache($this->uri);
  if (!empty($meta['version'])) {
    $url .= (strpos($url, '?') === FALSE ? '?' : '&') . $meta['version'];
  }

  // Torrents can only be created for publicly-accessible files:
  // https://forums.aws.amazon.com/thread.jspa?threadID=140949
  // So Forced SaveAs and Presigned URLs cannot be served as torrents.
  if (!$url_settings['forced_saveas'] && !$url_settings['presigned_url']) {
    foreach ($this->torrents as $blob) {
      if (preg_match("^{$blob}^", $s3_filename)) {

        // You get a torrent URL by adding a "torrent" GET arg.
        $url .= (strpos($url, '?') === FALSE ? '?' : '&') . 'torrent';
        break;
      }
    }
  }
  return $url;
}