View source
<?php
namespace Drupal\Tests\s3fs\Functional;
use Drupal\Tests\BrowserTestBase;
class S3fsUrlGenerationTest extends BrowserTestBase {
protected static $modules = [
's3fs',
];
protected $defaultTheme = 'stark';
protected $config;
protected function setUp() : void {
parent::setUp();
$this
->config('s3fs.settings')
->set('presigned_urls', "600|signreq/*\n300|shortsignttl/*")
->set('saveas', '.*saveas/*')
->set('torrents', '.*tordir/*')
->set('bucket', '513ec7bfc9ac489781a764057973d870')
->set('region', 'us-east-1')
->save();
$settings = [];
$settings['settings']['s3fs.access_key'] = (object) [
'value' => 'BogusAccessKey',
'required' => TRUE,
];
$settings['settings']['s3fs.secret_key'] = (object) [
'value' => 'BogusSecretKey',
'required' => TRUE,
];
$this
->writeSettings($settings);
}
public function testDefaultUriGeneration() {
$urlBase = 'http://513ec7bfc9ac489781a764057973d870.s3.amazonaws.com';
$this
->runTests($urlBase);
}
public function testHttpsDefaultUriGeneration() {
$urlBase = 'https://513ec7bfc9ac489781a764057973d870.s3.amazonaws.com';
$this
->config('s3fs.settings')
->set('use_https', TRUE)
->save();
$this
->runTests($urlBase);
}
public function testDefaultDifferentRegion() {
$urlBase = 'http://513ec7bfc9ac489781a764057973d870.s3.us-east-2.amazonaws.com';
$this
->config('s3fs.settings')
->set('region', 'us-east-2')
->save();
$this
->runTests($urlBase);
}
public function testCustomEndpointWithPortUriGeneration() {
$urlBase = 'http://513ec7bfc9ac489781a764057973d870.s3fslocalstack:4566';
$this
->config('s3fs.settings')
->set('use_customhost', TRUE)
->set('hostname', 'https://s3fslocalstack:4566')
->save();
$this
->runTests($urlBase);
}
public function testCustomHostname() {
$urlBase = 'http://test.example.org';
$this
->config('s3fs.settings')
->set('use_cname', TRUE)
->set('domain', 'test.example.org')
->save();
$this
->runTests($urlBase);
}
public function testCustomHostnameWithPort() {
$urlBase = 'http://test.example.org:8080';
$this
->config('s3fs.settings')
->set('use_cname', TRUE)
->set('domain', 'test.example.org:8080')
->save();
$this
->runTests($urlBase);
}
public function testHttpsCustomHostname() {
$urlBase = 'https://test.example.org';
$this
->config('s3fs.settings')
->set('use_https', TRUE)
->save();
$this
->config('s3fs.settings')
->set('use_cname', TRUE)
->set('domain', 'test.example.org')
->save();
$this
->runTests($urlBase);
}
public function testCustomHostnameDifferentRegion() {
$urlBase = 'http://test.example.org';
$this
->config('s3fs.settings')
->set('use_cname', TRUE)
->set('domain', 'test.example.org')
->set('region', 'us-east-2')
->save();
$this
->runTests($urlBase);
}
public function testPathBasedEndpoint() {
$urlBase = 'http://s3.amazonaws.com/513ec7bfc9ac489781a764057973d870';
$this
->config('s3fs.settings')
->set('use_path_style_endpoint', TRUE)
->save();
$this
->runTests($urlBase);
}
public function testPathBasedEndpointWithCustomHostname() {
$urlBase = 'http://test.example.org/513ec7bfc9ac489781a764057973d870';
$this
->config('s3fs.settings')
->set('use_path_style_endpoint', TRUE)
->set('use_cname', TRUE)
->set('domain', 'test.example.org')
->save();
$this
->runTests($urlBase);
}
public function testWithRootFolder() {
$urlBase = 'http://513ec7bfc9ac489781a764057973d870.s3.amazonaws.com/MyRootFolder';
$this
->config('s3fs.settings')
->set('root_folder', 'MyRootFolder')
->save();
$this
->runTests($urlBase);
}
protected function runTests(string $urlBase) {
$publicFile = 's3://public.txt';
$signedLongFile = 's3://signreq/signed.txt';
$signedShortFile = 's3://shortsignttl/shortsigned.txt';
$torrentWorksFile = 's3://tordir/thisworks.txt';
$torrentFail = 's3://signreq/tordir/thiswontwork.txt';
$forcedSaveFile = 's3://saveas/forcedsave.txt';
$forcedSavePresignFile = 's3://signreq/saveas/alsoforcesaved.txt';
$publicFileUri = file_create_url($publicFile);
$this
->assertEquals($urlBase . '/public.txt', $publicFileUri, 'Public request as expected');
$signedLongUri = file_create_url($signedLongFile);
$this
->assertStringContainsString($urlBase, $signedLongUri, "Signed request contains base url");
$this
->assertStringContainsString('X-Amz-Signature', $signedLongUri, 'Signed request contains a signature');
$this
->assertStringContainsString('X-Amz-SignedHeaders=host', $signedLongUri, 'Host is part of signed request');
$this
->assertStringContainsString('X-Amz-Expires=600', $signedLongUri, 'Signed for 600 Seconds');
$this
->assertStringContainsString('X-Amz-Expires=300', file_create_url($signedShortFile), 'Signed for 300 seconds');
$this
->assertEquals($urlBase . '/tordir/thisworks.txt?torrent', file_create_url($torrentWorksFile), 'Download via torrent');
$this
->assertStringNotContainsString('torrent', file_create_url($torrentFail), 'Signed URLS can not use torrent download');
$forcedSaveUri = file_create_url($forcedSaveFile);
$this
->assertStringContainsString('X-Amz-Signature', $forcedSaveUri, 'Forced save request contains a signature');
$this
->assertStringContainsString('response-content-disposition=attachment', $forcedSaveUri, 'Forced save includes content-disposition header');
$forcedSavePresignUri = file_create_url($forcedSavePresignFile);
$this
->assertStringContainsString('X-Amz-Signature', $forcedSavePresignUri, 'Forced Save on a presign contains a signature');
$this
->assertStringContainsString('response-content-disposition=attachment', $forcedSavePresignUri, 'Forced Save with forced presign still includes content-disposition');
}
public function testGetExternalUrlNone() {
$this
->runDomainRootTests('none', 's3://', 'test_root/');
$this
->runDomainRootTests('none', 'public://', 'test_root/test_public/');
}
public function testGetExternalUrlRoot() {
$this
->runDomainRootTests('root', 's3://', '');
$this
->runDomainRootTests('root', 'public://', 'test_public/');
}
public function testGetExternalUrlPublic() {
$this
->runDomainRootTests('public', 's3://', '');
$this
->runDomainRootTests('public', 'public://', '');
}
protected function runDomainRootTests($domainRoot, $scheme, $expected) {
$dummyFile = 'dummy.pdf';
$domain = 'test.example.org';
$this
->config('s3fs.settings')
->set('use_cname', TRUE)
->set('root_folder', 'test_root')
->set('public_folder', 'test_public')
->set('domain_root', $domainRoot)
->set('domain', $domain)
->save();
$streamWrapper = \Drupal::service('stream_wrapper.s3fs');
$streamWrapper
->setUri($scheme . $dummyFile);
$this
->assertEquals('http://' . $domain . '/' . $expected . $dummyFile, $streamWrapper
->getExternalUrl(), $domainRoot . ' domain_root as expected');
}
}