Welkom bij Bandhosting.nl,
hosting en webdevelopment.

Avoid ListObjects: Invalid query parameter(s): [encoding-type] errors when using S3 with Google Cloud Storage

When using the Amazon S3 client PHP library with Google Cloud Storage, you'll run into the following error:

Stack trace
Aws\S3\Exception\S3Exception: Uncaught exception 'Aws\S3\Exception\S3Exception' with message 'Error executing "ListObjects" on "https://XXXX.storage.googleapis.com/?prefix=xxxxx%2F&max-keys=1&encoding-type=url"; AWS HTTP error: Client error: `GET https://nostradamus-storage.storage.googleapis.com/?prefix=files%2Fintern.koeckers.nl%2Fmailer%2F2018%2F07%2F2254.1532521119-1807530koeckersseizoenskaartproef1.pdf%2F&max-keys=1&encoding-type=url` resulted in a `400 Bad Request` response: <?xml version='1.0' encoding='UTF-8'?><Error><Code>InvalidArgument</Code><Message>Invalid argument.</Message><Details>In (truncated...) InvalidArgument (client): Invalid argument. - <?xml version='1.0' encoding='UTF-8'?><Error><Code>InvalidArgument</Code><Message>Invalid argument.</Message><Details>Invalid query parameter(s): [encoding-type]</Details></Error>' in /var/www/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php:191
in Aws\WrappedHttpHandler::parseError called at /var/www/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php (100)

This is caused because the encoding-type argument is not implemented by Google on their S3 API (https://stackoverflow.com/questions/47264520/unable-to-listobjects-from-gcs-bucket)

This is set by the S3 Client itself and not really easy to configure. A fix for the error above is relatively easy fortunately by creating a middleware that removes the header:

use Aws\Middleware;

$client = new S3Client([
    'credentials' => [
        'key' => 'XXXX',
        'secret' => 'YYYY'
    ],
    'region' => 'europe',
    'endpoint' => 'https://storage.googleapis.com',
    'version' => 'latest'
]);

$middleware = Middleware::tap(function ($command, $request = null) {
     unset($command['EncodingType']);
});

$client->getHandlerList()->appendInit($middleware, 'encode-type-interceptor');

This will remove the header that's set in the S3Client class and make it's generated request compatible with Google Cloud Storage