diff --git a/.changes/nextrelease/chore-sort-presigned-headers.json b/.changes/nextrelease/chore-sort-presigned-headers.json new file mode 100644 index 0000000000..a99b91be64 --- /dev/null +++ b/.changes/nextrelease/chore-sort-presigned-headers.json @@ -0,0 +1,7 @@ +[ + { + "type": "enhancement", + "category": "", + "description": "Sorts presigned headers alphabetically." + } +] \ No newline at end of file diff --git a/src/Signature/SignatureV4.php b/src/Signature/SignatureV4.php index a7b9212215..48eb6b9f02 100644 --- a/src/Signature/SignatureV4.php +++ b/src/Signature/SignatureV4.php @@ -155,6 +155,9 @@ private function getPresignHeaders(array $headers) $presignHeaders[] = $lName; } } + + sort($presignHeaders); + return $presignHeaders; } diff --git a/tests/Signature/SignatureV4Test.php b/tests/Signature/SignatureV4Test.php index a101eb8619..07931b1cc7 100644 --- a/tests/Signature/SignatureV4Test.php +++ b/tests/Signature/SignatureV4Test.php @@ -304,7 +304,7 @@ public function testPresignSpecificHeaders() 'x-amz-content-sha256' => 'abc', ]); $presigned = $sig->presign($req, $creds, '+5 minutes'); - $this->assertStringContainsString(urlencode('host;x-amz-foo;content-md5;x-amz-meta-foo'), (string)$presigned->getUri()); + $this->assertStringContainsString(urlencode('content-md5;host;x-amz-foo;x-amz-meta-foo'), (string)$presigned->getUri()); } public function testPresignBlacklistedHeaders() @@ -613,4 +613,23 @@ public function testRemovesIllegalV4aHeadersBeforeSigning() $this->assertEquals($value, $req->getHeaderLine($key)); } } + + public function testSortHeadersAlphabetically() + { + $signature = new SignatureV4('foo', 'bar'); + $credentials = new Credentials('a', 'b'); + $headers = [ + 'z-header-1' => 'foo', + 'x-header-2' => 'bar', + 'b-header-3' => 'baz', + 'a-header-3' => 'baz', + 'r-header-4' => 'bar', + ]; + $req = new Request('PUT', 'http://foo.com', $headers); + $presigned = $signature->presign($req, $credentials, '+5 minutes'); + $this->assertStringContainsString( + urlencode('a-header-3;b-header-3;host;r-header-4;x-header-2;z-header-1'), + (string)$presigned->getUri() + ); + } }