2012-04-26 19 views
6

Korzystanie następujące Delphi XE2 (Update 4) kod:błąd SignatureDoesNotMatch gdy Content-Type jest 'text/*' używając 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); 

zawsze pojawia się błąd przy wywołaniu UploadObject:

Nie powiodło się: HTTP/1.1 403 Forbidden - podpis żądania, który obliczamy, nie pasuje do podanego przez Ciebie podpisu. Sprawdź klucz i podpisz metodę: . (SignatureDoesNotMatch)

Dzieje się tak tylko wtedy, gdy typ zawartości ustawiony jest na "text/plain", "text/html" lub tekst cokolwiek. Używając dokładnie tego samego kodu, jeśli po prostu zmienisz typ zawartości na dowolny inny typ zawartości, np. "video/3gpp", a następnie działa zgodnie z oczekiwaniami i bez błędów. Rzeczywista treść przesłanego obiektu nie jest istotna i nie ma wpływu na błąd.

Przeszukałem kod Indy w Delphi, ale nie jestem pewien, dlaczego typ zawartości tekstu zawsze podaje ten błąd.

Wszelkie pomysły?

Odpowiedz

4

Jeśli dołączyć "; charset = ISO-8859-1" do napisu Content-Type, to działa:

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

Stepping poprzez kod widzę Content-Type jest zmieniany w TIdEntityHeaderInfo .SetHeaders (IdHTTPHeaderInfo.pas), która jest wywoływana z TIdHTTPProtocol.BuildAndSendRequest (IdHTTP.pas).

Ostatecznie wygląda na to, że TIdEntityHeaderInfo.SetContentType (IdHTTPHeaderInfo.pas) dołącza zestaw znaków do typu zawartości, jeśli jest "tekstowy" i nie ma go jeszcze. Nie należy zmieniać typu zawartości w tych sytuacjach, ponieważ typ zawartości jest częścią napisu, który ma zostać podpisany, więc zmiana go po podpisaniu powoduje, że podpis jest nieważny.

+0

Cieszę się, że udało się to naprawić samodzielnie. to dokładnie ten sam problem podczas próby aktualizacji tekstu/html. W tym czasie uciekłem się do "html" - ale potem Internet Explorer miał problemy z przeglądaniem plików. –

0

Miałem ten sam problem. Użyłem również strumienia aplikacji/oktetu jako typu zawartości, ale nadal miałem pewne problemy. Później odkryłem, że nazwy pojemników muszą być pisane małymi literami (w amerykańskim standardzie standardowym, Amazon pozwala na definiowanie segmentów z dużymi literami lub nazwami mieszanymi, ale te nie są dostępne przez HTTP API (w tym TAmazonStorageService). nie znaleziono wiadomości, nadal mam błąd 403 (nieuwierzytelniony użytkownik) Jednak zmieniłem nazwę na wszystkie małe litery, działało dobrze Mam nadzieję, że to pomaga