Skip to content

Setting a config with ContentType during write operations #511

@challgren

Description

@challgren

So for Rackspace and Amazon S3 a ContentType/Content-Type is required when uploading a file, as the service doesn't automatically set a ContentType for objects that are uploaded. If the content type is not set correctly the uploaded file will not render in the browser correctly when the end user views the uploaded file.

Example upload a PDF and then view the Amazon S3 link. The default content type will be set to text/plain when it should be set to application/pdf in Chrome this would cause the PDF to not render with an error of unknown file type. On Rackspace Chrome would attempt to download the file instead of displaying as a application/pdf, as I no longer use Rackspace I am unable to provide what really happens.

The problem comes into play because we are using streams to write files and the S3 adapter does attempt to set the ContentType but because the supplied data is a stream its unable to call https://github.com/thephpleague/flysystem/blob/master/src/Util/MimeType.php#L182 and use finfo. I could do the below code again for S3 but I do know that Amazon S3 charges based on REQUESTs so this could become an "expensive" workaround.

When using the Rackspace Adapter I would have to

public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options)
    {
        if ($entity->isDirty('photo') && $this->adapter) {
            try {
                $obj = $this->adapter->getContainer()->getObject($entity->get('photo_dir') . $entity->get('photo'));
                $obj->saveMetadata(['Content-Type' => $options['content-type']], false);
            } catch (\Exception $exception) {
            }
        }
    }

to correct the content type. The Rackspace file adapter makes no attempt to automatically set the ContentType.

I did open an Issue with AWS S3 Flysystem https://github.com/thephpleague/flysystem-aws-s3-v3/issues/167 but they suggested manually setting the Config when writing the file. However the current implementations prevent that from being possible.

One possible solution is to write a CustomWriter for Amazon and Rackspace, or modify the DefaultWriter to finfo before the file is converted into a stream and supply the ContentType and Content-Type to the Config param when calling $flysystem->writeStream(). I do think that by including these additional Writers developers may assume that they don't need to configure an Flysystem Adapter. I do foresee many other developers having the same issues.

I'm open to discussion for the best possible solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions