2012-04-26 35 views
6

使用下面的德爾福XE2(更新4)代碼:SignatureDoesNotMatch錯誤「文/ *」使用TAmazonStorageService.UploadObject

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得到一個錯誤:

失敗:HTTP/1.1 403禁止 - 我們計算的請求籤名 與您提供的簽名不匹配。檢查您的密鑰並簽署 方法。 (SignatureDoesNotMatch)

這僅當內容類型被設置爲「文本/純」,文本/ html「,或文本什麼事情發生。使用完全相同的代碼,如果您只是將內容類型更改爲任何其他內容類型,例如'video/3gpp',那麼它按預期工作,沒有錯誤。被上傳對象的實際內容是不相關的,並且與獲取錯誤沒有關係。

我已經追蹤了Delphi中的Indy代碼,但我很難理解爲什麼文本內容類型總是會出現這個錯誤。

任何想法?

回答

4

如果追加 「;字符集= ISO-8859-1」 的內容類型的字符串,然後它的工作原理:

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

通過代碼步進我看到的Content-Type在TIdEntityHeaderInfo正在改變.SetHeaders(IdHTTPHeaderInfo.pas)從TIdHTTPProtocol.BuildAndSendRequest(IdHTTP.pas)中調用。

最終,它看起來像問題是TIdEntityHeaderInfo.SetContentType(IdHTTPHeaderInfo.pas)將字符集附加到內容類型,如果它是'文本'並且它還沒有。它不應該在這些情況下更改內容類型,因爲內容類型是要簽名的字符串的一部分,所以在簽名後更改它會使簽名無效。

+0

很高興您能夠自己解決它。當嘗試上傳文本/ html時,這個問題完全相同。當時我使用的只是「html」 - 但隨後Internet Explorer在查看文件時遇到問題。感謝分享!!!!! – 2014-03-11 23:48:49

0

我有同樣的問題。我還使用application/octet-stream作爲內容類型,但仍有一些麻煩。之後,我發現存儲桶名稱必須小寫(在美國標準區域中,亞馬遜允許使用大寫或混合大小寫名稱來定義存儲區;但是,這些存儲區不能通過HTTP API(包括TAmazonStorageService)訪問。沒有找到消息,我仍然有403錯誤(未經身份驗證的用戶)。 但是,我將名稱更改爲全部小寫,它工作正常。 希望它有幫助

相關問題