SignatureDoesNotMatch error when Content-type is "text / *" using TAmazonStorageService.UploadObject

Using the following Delphi XE2 code (Update 4):

var ConInfo: TAmazonConnectionInfo; RespInfo: TCloudResponseInfo; Service: TAmazonStorageService; Content: TBytes; Headers: TStringList; begin ConInfo:=TAmazonConnectionInfo.Create(self); ConInfo.AccountName:='YOUR ACCOUNT NAME'; ConInfo.AccountKey:='YOUR ACCOUNT KEY'; ConInfo.Protocol:='http'; Service:=TAmazonStorageService.Create(ConInfo); RespInfo:=TCloudResponseInfo.Create; SetLength(Content, 128); FillMemory(@Content[0], 128, Byte('x')); Headers:=TStringList.Create; Headers.Values['Content-type']:='text/plain'; if not Service.UploadObject('YOUR BUCKET', 'test.txt', Content, TRUE, nil, Headers, amzbaPrivate, RespInfo) then ShowMessage('Failed:' + RespInfo.StatusMessage); 

I always get an error when I call UploadObject:

Error: HTTP / 1.1 403 Forbidden. The signature we signed for the request does not match the signature you provided. Check your key and sign the method. (SignatureDoesNotMatch)

This only happens when the content type is set to text / plain, text / html, or text. Using exactly the same code, if you just change the content type to any other type of content, for example. 'video / 3gpp' then it works as expected and without errors. The actual contents of the downloaded object is not relevant and does not affect the receipt of an error or not.

I traced the Indy code in Delphi, but I am at a dead end why the type of text content always gives this error.

Any ideas?

+6
source share
2 answers

If you add "; charset = ISO-8859-1" to the Content-Type line, then it works:

 Headers.Values['Content-type']:='text/plain; charset=ISO-8859-1'; 

While executing the code, I see that the Content-Type changes to TIdEntityHeaderInfo.SetHeaders (IdHTTPHeaderInfo.pas), which is called from TIdHTTPProtocol.BuildAndSendRequest (IdHTTP.pas).

In the end, the problem seems to be that TIdEntityHeaderInfo.SetContentType (IdHTTPHeaderInfo.pas) adds a character set to the content type if it is β€œtext” and it does not already have it. He should not change the type of content in these situations, because the type of content is part of the line that must be signed, so changing it after signing makes the signature invalid.

+4
source

I had the same problem. I also used application / octet-stream as the content type, but still had some problems. Later I discovered that the bucket names should be lowercase (in the standard US region, Amazon allows you to define buckets with names in upper or mixed case, however these buckets are not available through the HTTP API (including TAmazonStorageService). I did not find the message, I still got an error 403 (failed user verification). However, I changed the name to all lowercase letters, it worked fine. I hope this helps.

0
source

Source: https://habr.com/ru/post/914195/


All Articles