flysystem-aws-s3-v3
flysystem-aws-s3-v3 copied to clipboard
Issues when specifying a 'root' path
- Laravel Version: 9.8
- PHP Version: 8.1.3
- flysystem-aws-s3-v3 Version: 3.0.13
Description:
I'm encountering this issue with Laravel, but their team directed me here. See Issue.
I'm using Digital Ocean Spaces to host website assets. If I specify a 'root' path in filesystems.php
for any DO disk, I run into issues retrieving the files. If I remove the 'root' key and write the folder path manually, I don't have any issues. Specifically, it looks like the end path character "/" is being converted to "%5C". Note, I only encountered this issue after upgrading from L8 to L9.
Here's how I'm generating the URL in my Blade:
<img src="{{ Storage::disk('vendor-logos')->url($vendor->image) }}" alt="{{ $vendor->name }}">
Here's the HTML that produces:
<img src="https://bwi.nyc3.digitaloceanspaces.com/vendor-logos%5Cb574d580c91d97b6b12155708ecc61a3c0779750" alt="BASF">
Note how the src
path above is missing a /
, right after the root location 'vendor-logos'. Any file I display like this gets prepended with a %5C
. I could be going in the wrong direction, but a quick Google search shows that 5c is the hex ASCII representation of "backslash".
Disk:
'vendor-logos' => [
'driver' => 's3',
'key' => env('DIGITALOCEAN_SPACES_KEY'),
'secret' => env('DIGITALOCEAN_SPACES_SECRET'),
'endpoint' => 'https://nyc3.digitaloceanspaces.com',
'region' => 'nyc',
'bucket' => 'bwi',
'root' => 'vendor-logos',
'visibility' => 'public',
],
Here's a snippet of my vendor
model's underlying table. The highlighted record is the one used in my example above.
Steps To Reproduce:
- Setup a disk in L9 that uses digital ocean spaces.
- Define a 'root' key in the filesystem config for that disk
- Make sure the asset in your digital ocean space is in the folder that corresponds to the 'root' path you specified in
filesystems.php
- Try to display the asset in a blade.
@bennettblack Hi, I don't believe this is a Flysystem issue. Flysystem does not expose the paths apart from listings which do not display this described behaviour.
@frankdejonge Thank you for looking into my inquiry. @driesvints is this ok to re-open?
@bennettblack in the meanwhile, have you tried debugging the call? See where the encoding actually happens?
@frankdejonge Well, now that I have, It appears that it's happening in aws\aws-sdk-php\src\functions.php @ serialize()
which utilizes some GuzzleHttp methods. Unfortunately there are some things going on there that are above my understanding. Doesn't seem to be Laravel or Flysystem though - sorry for the trouble.
Isn't the issue that you're trying to use the S3 driver with digitalocean? Don't you need a special digitalocean driver?
I don't think this is a Laravel issue. All we do is pass the root to the S3Adapter from Flysystem as the prefix. It then gets handled by flysystem as the adapter root.
@driesvints the docs say its compatible with the s3 filesystem
Hi, I have the same problem with Wasabi S3.
the backslash appears converted.
If you put the URL parameter and with the full endpoint it will work (or maybe it ignores it and just uses it).
It seems that the problem is when automatically generating the url.
See my Issue at laravel repo: https://github.com/laravel/framework/issues/42136
Thank you
Hi, same here but the problem occurs only on Windows platform. Same project on Ubuntu works fine.
Same problem here. RHEL8 and latest macos
If config has 'root' => '/'
its eats first letter of path
more related to laravel here
Adding in - I'm having same issue on Windows.
If I remove the root key then no issues. Otherwise the root gets a \ between root specified and file. That then gets encoded to %5C the HTML URL Encoding.
For what it's worth I traced it deeper.
Entry into the Flysystem package happens on the url method for me AwsS3V3Adapter.php class
The method checks if there is a url key in the config property, doesn't find it and then hits a getObjectUrl Method. In that there's a prefixpath method being called for the second parameter:
And that class(PathPrefixer.php) has a prefix private string that I think the file system over wrote to be '' on windows:
And then with Xdebug I can show that the prefix rendered with the expectred / as a \ but suspect that's a windows file system thing
@frankdejonge I have another issue related to "Extra slash" when i'm trying to get list of files with prefix that is not ending with '/' but is part of files naming i got empty list of files because of prefixer adding slash at the end of prefix $feedList = $storage->listContents($this->feedLocation . $this->feedNamePrefix);
Why it is trying to trim and write back this slash at all ?! my path is looks like "media/group/fileprefix_" and for example it should return files like "media/group/fileprefix_20220618.csv" in native AWS SDK it work this way

This happen on Windows system.
Add the 'directory_separator'
to your s3 block inside the filesystems config.
s3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
'root' => "your_root_path"
'directory_separator' => '/'
],
This solves the same problem on my side: PHP: 8.1.9 Laravel: 9.31.0 flysytem-aws-s3-v3: 3.5.0
Got this issue as well, when setting a s3 disk with a root "/", I cannot get the content of a file.
The URL used by curl is then completely wrong:
When removing the root "/" it seems to work.
This happen on Windows system. Add the
'directory_separator'
to your s3 block inside the filesystems config.s3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'throw' => false, 'root' => "your_root_path" 'directory_separator' => '/' ],
This solves the same problem on my side: PHP: 8.1.9 Laravel: 9.31.0 flysytem-aws-s3-v3: 3.5.0
Likewise. I believe this is the solution.