Einzelnen Beitrag anzeigen

MikeSP2

Registriert seit: 10. Aug 2010
10 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#3

AW: Amazon Webservice

  Alt 13. Aug 2010, 08:09
Hallo Codewalker,

ich habs probiert wie du gesagt hast mit dem Delphi import und nun sind die Unbekannten Funktionen etc. weg. Leider Sträubt sich Amazon wehement gegen meine Anfrage.
Hier einmal mein Code:
Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, InvokeRegistry, Rio, SOAPHTTPClient, AWSECommerceService, StdCtrls,
  himXML, DECUtil, DECCipher, DECHash, DECFmt,HMAC, Hash, SHA256, mem_util;

const
  AWSID = 'gelöscht';
  sAWSID = 'gelöscht';
  sACCES_ID = 'gelöscht';

type
  TForm1 = class(TForm)


    Button1: TButton;
    HTTPRIO1: THTTPRIO;
    Memo1: TMemo;

    procedure Button1Click(Sender: TObject);
    procedure HTTPRIO1BeforeExecute(const MethodName: string;
      SOAPRequest: TStream);
  private
    function GenerateCurrentTimeStamp: string;
    function GenerateHMACSignature(Text, key: ansistring): ansistring;
    function concat(c: Char; l: Integer): String;
    function SimpleCryptString(const S, Key: string): string;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var
 AWSPort: AWSECommerceServicePortType;
  AmazonPort: AWSECommerceServicePortType;
  body: ItemSearch;
  arr_request: Array_Of_ItemSearchRequest;
  aRequest: ItemSearchRequest;
  aResponse: ItemSearchResponse;
  i: Integer;
  j: Integer;
begin
   AWSPort := GetAWSECommerceServicePortType(False,'',HTTPRIO1);
   body := ItemSearch.Create;
   body.AWSAccessKeyId := AWSID;
   body.SubscriptionId := sACCES_ID;
   body.AssociateTag := sACCES_ID;

    aRequest := ItemSearchrequest.Create;
    aRequest.SearchIndex := 'Video';
    aRequest.Title := 'Matrix';

    SetLength(arr_request, 1);
    arr_request[0] := aRequest;
    body.Request := arr_request;

    aResponse := AWSPort.ItemSearch(body);
    for i := 0 to Length(aResponse.Items) - 1 do
      for j := 0 to Length(aResponse.Items[i].Item) - 1 do
      begin
        Memo1.Lines.Add(aResponse.Items[i].Item[j].ItemAttributes.Title);
      end;
end;

function TForm1.GenerateCurrentTimeStamp(): string;
var
 TimeStamp: string;
 y,mon,d,h,m,s,ms: Word;
begin
 DecodeDate(Now,y,mon,d);
 DecodeTime(Now,h,m,s,ms);
// 2009-02-16T17:39:51.000Z
 Result := Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.000Z',[y,mon,d,h,m,s]);
end;

function TForm1.concat(c: Char; l: Integer): String;
var
  I: Integer;
begin
 Result := '';
 for I := 0 to l-1 do
   Result := '0' + Result;
end;

function TForm1.SimpleCryptString(const S, Key: string): string;
var
  i, j: Integer;
  C: Byte;
  P: PByte;
begin
  SetLength(Result, Length(S));
  P := PByte(Result);

  j := 1;
  for i := 1 to Length(S) do
  begin
    C := Ord(S[i]);

    C := C xor Ord(Key[j]);
    P^ := C;
    Inc(P);
    Inc(j);
    if j > Length(Key) then
      j := 1;
  end;
end;

function TForm1.GenerateHMACSignature(Text, key: ansistring): ansistring;
var
   ctx: THMAC_Context;
   phash: PHashDesc;
   mac: THashDigest;
begin
   phash := FindHash_by_Name('SHA256');
   if phash = nil then begin
      {Action for 'Hash function not found/registered.'}
      exit;
   end;
   hmac_init(ctx, phash, @key[1], length(key));
   hmac_update(ctx, @Text[1], length(Text));
   hmac_final(ctx, mac);
   // Result := HexStr(@mac, sizeof(mac));
        Result := Base64Str(@mac, sizeof(TSHA256Digest));
end;

procedure TForm1.HTTPRIO1BeforeExecute(const MethodName: string;
  SOAPRequest: TStream);
var
 XML: TXMLFile;
 Node: TXMLNode;
 S: ansistring;
begin
 SOAPRequest.Seek(0,0);
 XML := TXMLFile.Create(Self,false);
 xml.LoadFromStream(SOAPRequest);
 Node := XML.RootNode.Node['SOAP-ENV:Body'].Node['ItemSearch'];
 Node.AddNode('Timestamp').Text := GenerateCurrentTimeStamp;
 Node.AddNode('Action').Text := 'ItemSearch';
 Node.AddNode('Signature').Text_Base64w := GenerateHMACSignature('ItemSearch',Node.Node['Timestamp'].Text);
 SOAPRequest.Seek(0,0);
 xml.SaveToStream(SOAPRequest);
 xml.SaveToXML(S);
 Memo1.Text := S;
 Application.Processmessages;
end;
Die Soap-Meldung:
Delphi-Quellcode:
<?xml version="1.0" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Body>
    <ItemSearch xmlns="http://webservices.amazon.com/AWSECommerceService/2010-06-01">
      <AWSAccessKeyId>gelöscht</AWSAccessKeyId>
      <SubscriptionId>gelöscht</SubscriptionId>
      <AssociateTag>gelöscht</AssociateTag>
      <Request>
        <SearchIndex>Video</SearchIndex>
        <Title>Matrix</Title>
      </Request>
      <Timestamp>2010-08-13T07:57:35.000Z</Timestamp>
      <Action>ItemSearch</Action>
      <Signature>ZgBGADUAaQB4ADEAdABnAFAAMQBzAHIAQgBsAGYATw BSAGMAVgBaAGgAUQBYAGgAQwA4AHQATwBiADEAOA BlAEsATwAxADYAaABHAFcAZgBGAFEAOAA9AA==</Signature>
    </ItemSearch>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Danach bricht die Anwendung mit: "Ein XML-Dokument muss ein Element der Oberen Ebne enthalten."
ab. Was mir logisch erscheint da ich ja keine antwort bekomme von Amazon.
Wie bekomme ich denn das umgesetzt was nru schreibt:

In den TSOAPHeader:
Delphi-Quellcode:
    // sAWSID = Secret Key
    AmazonTimestamp := FormatDateTime('yyyy"-"mm"-"dd"T"hh":"nn":00Z"', emt_now);
    AmazonString := 'ItemSearch' + AmazonTimestamp;
    AmazonSignature := GenerateHMACSignature( AmazonString, sAWSID );
Ich denke daran liegt es das es nicht klappt.
Gruß
MikeSp

Geändert von Matze (13. Aug 2010 um 08:55 Uhr) Grund: Leerzeichen in <Signature>-Zeile eingefügt, damit bei geringerer Bildschirmauflösung kein horizontaler Scrollbalken erscheint
  Mit Zitat antworten Zitat