Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi SOAP-Request zusätzliche Felder hinzufügen (https://www.delphipraxis.net/150504-soap-request-zusaetzliche-felder-hinzufuegen.html)

Codewalker 19. Apr 2010 10:06


SOAP-Request zusätzliche Felder hinzufügen
 
Ich habe in Delphi eine WSDL importiert und nutze die daraus erstellte Unit um einen Webservice abzufragen. Das ganz läuft scheinbar über ein THTTPRio-Objekt. Jetzt möchte ich dem ausgehendem SOAP-Envelope eine Node hinzufügen. Weiß jemand, wie das mit THTTPRio oder den Delphi-Komponenten machbar ist?

mjustin 19. Apr 2010 12:59

Re: SOAP-Request zusätzliche Felder hinzufügen
 
Im SOAP Header oder im Body?

Für den HEader kann man die HTTPRio Komponente über (HTTPRio1 as ISoapHeaders) casten und dann einen Header-Node mit der Methode 'Send' anhängen. (siehe z.B. http://www.cnblogs.com/fuyingke/arch...05/230260.html)

Für den Body kann man zwar diverses hacken (angefangen mit der WSDL, man kann den generierten Source anpassen, oder den Request selber abfangen und manipulieren). Jedoch wird da eine WSDL bildlich gesprochen ein "Vertrag" ist der Server die hinzugefügten Inhalte sehr wahrscheinlich nicht verarbeiten.

Codewalker 22. Apr 2010 12:46

Re: SOAP-Request zusätzliche Felder hinzufügen
 
Also, ich habe das ganze jetzt mal versucht umzusetzen. Der Request sieht soweit in Ordnung aus, trotzdem kommt ein "401 Unauthorized". Evtl. sieht jemand meinen Fehler oder kann mir helfen ihn zu lösen. Ich fürchte, dass die Signatur falsch berechnet wird und es ein Unicode/Ansi-Problem ist, komme aber seit Stunden nicht weiter :pale:
Delphi-Quellcode:
  TAmazonAuth = class(TSoapHeader)
  private
    FAWSAccessKeyId: string;
    FTimestamp:     string;
    FSignature:     string;
  published
    property AWSAccessKeyId: string (* index (IS_REF) *) Read FAWSAccessKeyId Write FAWSAccessKeyId;
    property Timestamp: string Read FTimestamp Write FTimestamp;
    property Signature: string Read FSignature Write FSignature;
  end;

implementation

function emt_now: TDateTime;
var
  st: TSystemTime;
begin
  GetSystemTime(st);
  Result := SystemTimeToDateTime(st);
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  Headers: ISOAPHeaders;
  Hdr: TAmazonAuth;
  ctx: THMAC_Context;
  mac: THashDigest;
  phash: PHashDesc;
  AmazonString, AmazonTimestamp, AmazonSignature: ansistring;
  AWSPort: AWSECommerceServicePortType;
  body: ItemSearch;
  arr_request: Array_Of_ItemSearchRequest;
  aRequest: ItemSearchRequest;
  aResponse: ItemSearchResponse;
  i: integer;
  j: integer;
begin
  AWSPort := GetAWSECommerceServicePortType(False, '', RIO);

  RemClassRegistry.RegisterXSClass(TAmazonAuth, 'http://security.amazonaws.com/doc/2007-01-01/', 'TAmazonAuth');
  InvRegistry.RegisterHeaderClass(TypeInfo(AWSECommerceServicePortType), TAmazonAuth, 'Header', 'http://security.amazonaws.com/doc/2007-01-01/'); {and the header}

  Headers := RIO as ISOAPHeaders;
  Hdr := TAmazonAuth.Create;

  //Authentication
  AmazonTimestamp := FormatDateTime('yyyy"-"mm"-"dd"T"hh":"nn":"ss"Z"', emt_now);

  AmazonString := 'ItemSearch' + AmazonTimestamp;

  // Generate Request and Signature - Build Signature
  phash := FindHash_by_Name('SHA256');
  hmac_inits(ctx, phash, sAWSID);
  hmac_update(ctx, @AmazonString[1], Length(AmazonString));
  hmac_final(ctx, mac);
  AmazonSignature := Base64Str(@mac[1], sizeof(TSHA256Digest));

  Hdr.FSerializationOptions := [xoHolderClass, xoAttributeOnLastMember, xoSimpleTypeWrapper];
  Hdr.FAWSAccessKeyId := AWSID;
  Hdr.FTimestamp := AmazonTimestamp;
  Hdr.FSignature := AmazonSignature;
  Headers.Send(Hdr);

  body := ItemSearch.Create;
  body.AWSAccessKeyId := AWSID;

  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
      LiveLog.Lines.Add(aResponse.Items[i].Item[j].ItemAttributes.Title);
    end;
end;
LiveLog ist ein einfaches Memo in dem die Ergebnisse stehen sollen. Die Konstanten für die Schlüssel muss man natürlich noch ändern:
Delphi-Quellcode:
const
  AWSID    = 'Die AWS ID';
  sAWSID   = 'Die geheime AWS ID';


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz