You are here

function _minisite_install_stage_file_proxy_fetch in Mini site 8

Fetch file from the specified URI using stage_file_proxy fetcher.

This is a shortened version of \Drupal\stage_file_proxy\EventSubscriber\ProxySubscriber::checkFileOrigin.

Unfortunately, it is not possible to use functionality of stage_file_proxy transparently within update hooks (send request from the update hook to the same server) as they can be ran via CLI, in which case it is possible that the request may not reach the website (for example, if PHP runs in a Docker container separate to the web-server and the internal name of the web-server is not the same as site's external URI).

It is also not possible to simply craft a stub request and pass it to the stage_file_proxy's ProxySubscriber::checkFileOrigin method, since the method uses 'exit' to perform a redirect (the logic is not separated from the request stack handling), which will terminate the process itself.

The only viable solution is to use stage_file_proxy's fetcher manager with additionally added logic taken from ProxySubscriber::checkFileOrigin method.

Parameters

string $url: Absolute URL to the file to download. Absolute is required in order to check that this is not an origin server.

Return value

bool TRUE if file was downloaded, FALSE otherwise.

See also

\Drupal\stage_file_proxy\EventSubscriber\ProxySubscriber::checkFileOrigin

1 call to _minisite_install_stage_file_proxy_fetch()
minisite_update_8002 in ./minisite.install
Re-saves all Minisite instances to populate the database with asset links.

File

./minisite.install, line 334
Contains install and update functions for Minisite.

Code

function _minisite_install_stage_file_proxy_fetch($url) {
  $config = \Drupal::configFactory()
    ->get('stage_file_proxy.settings');

  // Get the origin server.
  $server = $config
    ->get('origin');

  // Quit if no origin given.
  if (!$server) {
    return FALSE;
  }
  $request = Request::create($url);

  // Quit if we are the origin, ignore http(s).
  $current_host = $request
    ->getHost();
  if (preg_replace('#^[a-z]*://#u', '', $server) === $current_host) {
    return FALSE;
  }
  $fetch_manager = \Drupal::getContainer()
    ->get('stage_file_proxy.fetch_manager');
  $file_dir = $fetch_manager
    ->filePublicPath();
  $request_path = $request
    ->getPathInfo();
  $request_path = mb_substr($request_path, 1);
  if (strpos($request_path, '' . $file_dir) !== 0) {
    return FALSE;
  }

  // Note if the origin server files location is different. This
  // must be the exact path for the remote site's public file
  // system path, and defaults to the local public file system path.
  $remote_file_dir = trim($config
    ->get('origin_dir'));
  if (!$remote_file_dir) {
    $remote_file_dir = $file_dir;
  }
  $request_path = rawurldecode($request_path);
  $relative_path = mb_substr($request_path, mb_strlen($file_dir) + 1);
  $options = [
    'verify' => $config
      ->get('verify'),
  ];
  return $fetch_manager
    ->fetch($server, $remote_file_dir, $relative_path, $options);
}