Using the following Delphi XE2 (update 4) code:
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 on the call to UploadObject:
Failed:HTTP/1.1 403 Forbidden - The request signature we calculated does not match the signature you provided. Check your key and signing method. (SignatureDoesNotMatch)
This only happens when the Content-type is set to 'text/plain', 'text/html', or text anything. Using exactly the same code, if you just change the content-type to any other content-type, e.g. 'video/3gpp', then it works as expected and without error. The actual content of the object being uploaded isn't relevant and has no bearing on getting the error or not.
I've traced through the Indy code in Delphi, but I'm stumped as to why the text content type always gives this error.
Any ideas?
If you append "; charset=ISO-8859-1" to the Content-Type string, then it works:
Headers.Values['Content-type']:='text/plain; charset=ISO-8859-1';
Stepping through the code I see the Content-Type is being changed in TIdEntityHeaderInfo.SetHeaders (IdHTTPHeaderInfo.pas) which is called from TIdHTTPProtocol.BuildAndSendRequest (IdHTTP.pas).
Ultimately, it looks like the problem is that TIdEntityHeaderInfo.SetContentType (IdHTTPHeaderInfo.pas) is appending a character set to the content type if it is 'text' and it doesn't already have one. It shouldn't be changing the content type in these situations because the content type is part of the string to be signed, so changing it after the signing makes the signature invalid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With