thephpleague / flysystem

Abstraction for local and remote filesystems
https://flysystem.thephpleague.com
MIT License
13.37k stars 827 forks source link

AWS S3 Adapter: retrieve mime type from file content #1781

Open miloslavkostir opened 7 months ago

miloslavkostir commented 7 months ago

Feature Request

Q A
Adapter Name AwsS3V3Adapter

Some services don't support Content-Type as a request parameter for PutObject e.g. Dell PowerScale OneFS see OneFS S3 API doc Table 21. OneFS S3 PutObject API request parameters On the other hand, some developers may prefer retrieving mime type from file content in the function AwsS3V3Adapter::mimeType() instead of getting it from HeadObject

What about creating (an optional) feature for retrieving content type from file content? Something like this:

$mimetype = $this->mimeTypeDetector->detectMimeTypeFromBuffer(fread($this->readStream($path), 1024));

Ideally I could the function enable/disable in the options.

miloslavkostir commented 7 months ago

Like this https://github.com/miloslavkostir/flysystem/commit/229437159c4b0b0d91f849a83e1e8fcd304398de

jgivoni commented 2 months ago

The problem is that the mimetype (ContentType) is not stored as metadata on the object (file). If you "solve" it by reading from the file content after the file is stored, you are going to read from the file every time any time you need it which is not great for performance. In fact, with your implementation, the adapter will read from the file content for any retrieval of any metadata (even if it's just asking for the filesize) and if you do a listContent, it will also read from all the files listed.

All in all, I think a better solution is to write a wrapper adapter that can wrap any filesystem adapter that doesn't persist mimetype internally. That wrapper can then take two other adapters, one for storing the actual file and most of the metadata, and another for storing any missing metadata in a special metadata file. The two do not even have to be pointing to the same storage pool.

Think of it as something that could be needed for any adapter, not only some S3 providers. In fact, LocalFilesystemAdapter also do not store the mimetype as metadata (and doesn't return it unless you call mimetype() explicitly), so the solution could also be an advantage here.

miloslavkostir commented 1 month ago

There was a caching in v1. It would solve the problem of performance. Why the caching was removed from v2?