Ошибка SignatureDoesNotMatch, когда тип содержимого - "text/*" с использованием TAmazonStorageService.UploadObject
Используя следующий код Delphi XE2 (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);
Я всегда получаю ошибку при вызове UploadObject:
Failed: HTTP / 1.1 403 Forbidden-вычисленная нами сигнатура запроса не соответствует предоставленной вами подписи. Проверьте ваш ключ и подпись метод. (SignatureDoesNotMatch)
Это происходит только в том случае, если для типа содержимого задано значение "text/plain", "text/html" или "text anything". Используя точно такой же код, если вы просто измените тип контента на любой другой тип контента, например "video/3gpp", тогда он работает как ожидалось и без ошибок. Фактическое содержимое загружаемого объекта не имеет отношения к делу и не влияет на получение ошибки или нет.
Я проследил инди-код в Delphi, но я в тупике, почему тип текстового контента всегда выдает эту ошибку.
Есть идеи?
2 ответа:
Если вы добавляете "; charset=ISO-8859-1 " к строке типа содержимого, то это работает:
Headers.Values['Content-type']:='text/plain; charset=ISO-8859-1';
Проходя через код, я вижу, что тип контента изменяется в TIdEntityHeaderInfo.SetHeaders (IdHTTPHeaderInfo.pas), который называется от TIdHTTPProtocol.BuildAndSendRequest (IdHTTP.первенство).
В конечном счете, похоже, что проблема заключается в том, что TIdEntityHeaderInfo.SetContentType (IdHTTPHeaderInfo.pas) - это добавление набора символов к типу контента, если это "текст", а это не так. уже есть один. В таких ситуациях не следует изменять тип содержимого, так как тип содержимого является частью подписываемой строки, поэтому его изменение после подписания делает подпись недействительной.
У меня была та же самая проблема. Я также использовал application / octet-stream в качестве типа контента, но все еще имел некоторые проблемы. Позже я обнаружил, что имена ведер должны быть в нижнем регистре (в стандартном регионе США Amazon позволяет определять ведра с именами прописных или смешанных регистров; однако эти ведра недоступны через HTTP API (включая TAmazonStorageService). Вместо сообщения "не найдено" я получил сообщение об ошибке 403 (не прошедший проверку подлинности пользователь). Правда, один я поменял название на всех в нижнем регистре он работал отлично. Надеюсь, это поможет