Отладка передачи SOAP


Я пытаюсь сделать доказательство концептуального потребления веб-сервиса с помощью Delphi 2010 и Indy. Мой код на данный момент таков:

procedure TForm1.Log(const sEvent, sMsg: String);
const sPrior: String = '';
begin
  if sEvent <> sPrior then begin
    mTraffic.Lines.Append('');
    mTraffic.Lines.Append(Format('%s: %s', [sEvent, FormatDateTime('mm/dd/yyyy hh:nn:ss.zzz', Now)]));
    mTraffic.Lines.Append('--------------------------------------------------------------------------------');
    sPrior := sEvent;
  end;
  mTraffic.Lines.Append(sMsg);
  Application.ProcessMessages;
end;

function TForm1.BuildRequest: String;
const MINPERDAY = 1440;
var slRequest: TStringList;
    sFileName: String;
    sID: String;
    sGUID: String;
    oDoc: TNativeXML;
    oNode: TXmlNode;
    uNow: _SystemTime;
    dtNow: TDateTime;
    sNow: String;
    sNonce: String;
    oIdmd5: TIdHashMessageDigest5;
begin
  sFileName := 'Send.xml';
  slRequest := TStringList.Create;
  oIdmd5 := TIdHashMessageDigest5.Create;
  oDoc := TNativeXML.Create;
  try
    oDoc.LoadFromFile(sFileName);
    SetAttrib(oDoc, 'inputMessage', 'utc', FormatDateTime('m/d/yyyy hh:mm:ss am/pm', Now));
    sGUID := 'urn:uuid' + MyCreateUUID;
    SetAttrib(oDoc, 'inputMessage', 'messageId', sGUID);
    SetNode(oDoc, 'wsa:messageId', sGUID);
    Windows.GetSystemTime(uNow);
    dtNow := SysUtils.SystemTimeToDateTime(uNow);
    sNow := FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"', dtNow);
    sNonce := oIdmd5.HashStringAsHex(sNow + 'Jack' + 'Test' + 'Salt');
    SetNodes(oDoc, 'wsu:Created', FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"', dtNow));
    SetNode(oDoc, 'wsu:Expires', FormatDateTime('yyyy-mm-dd"T"hh:mm:ss"Z"', dtNow + 5 /MINPERDAY));
    SetNode(oDoc, 'wsse:Nonce', sNonce);
    SetNode(oDoc, 'ElectronicPostmark', FormatDateTime('yyyy-mm-dd"T"hh:mm:ss.zz-8.00', dtNow));
    SetNode(oDoc, 'wsse:Username', '#MyUserName#');
    SetNode(oDoc, 'wsse:Password', '#MyPassword#');
    oDoc.XmlFormat := xfReadable;
    Result := oDoc.WriteToString;
  finally
    slRequest.Free;
    oIdmd5.Free;
    oDoc.Free;
  end;

end;

function TForm1.SSLPost(const url: String; sRequest: String): String;
var lHTTP: TIdHTTP;
    lIOHandler: TIdSSLIOHandlerSocketOpenSSL;
    lIDLogDebug: TIdLogDebug;
    ss: TStringStream;
begin
  lHTTP := TIdHTTP.Create(nil);
  lIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  lIDLogDebug := TIdLogDebug.Create(nil);
  ss := TStringStream.Create;
  try
    ss.WriteString(sRequest);
    ss.Position := 0;
    lIOHandler.SSLOptions.Method := sslvSSLv3;
    lIOHandler.OnStatusInfo := IdSSLIOHandlerSocketOpenSSL1StatusInfo;
    lHTTP.IOHandler := lIOHandler;
    lIdLogDebug.OnSend := IdLogDebug1Send;
    lIDLogDebug.OnReceive := IdLogDebug1Receive;
    lIDLogDebug.Active := True;
    lHTTP.Intercept := lIdLogDebug;
    try
      lHTTP.Request.CustomHeaders.Add('SOAPAction: "http://edd.ca.gov/SendTransmission"');
      Result := lHTTP.Post(url, ss);
    except
      On e: Exception do begin
        Result := e.Message + #13#10 + '**No Response**';
      end;
    end;
  finally
    lHTTP.Free;
    lIOHandler.Free;
    lIdLogDebug.Free;
    ss.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var sResponse: String;
begin
  sResponse := SSLPost('https://FSETTESTPROD.EDD.CA.GOV', BuildRequest);
  Log('Response', sResponse);
end;

Примечание: я особенно не уверен в этой строке непосредственно перед постом

lHTTP.Request.CustomHeaders.Add('SOAPAction: "http://edd.ca.gov/SendTransmission"'); 

Согласно документации веб-службы, я должен получить либо успех ACK1, либо ошибку ACK1 с объяснением. Вот результат, который я получаю в этот момент:

    SSL: 02/28/2012 16:33:55.609
    --------------------------------------------------------------------------------
    SSL status: "before/connect initialization"
    SSL status: "before/connect initialization"
    SSL status: "SSLv3 write client hello A"
    SSL status: "SSLv3 read server hello A"
    SSL status: "SSLv3 read server certificate A"
    SSL status: "SSLv3 read server done A"
    SSL status: "SSLv3 write client key exchange A"
    SSL status: "SSLv3 write change cipher spec A"
    SSL status: "SSLv3 write finished A"
    SSL status: "SSLv3 flush data"
    SSL status: "SSLv3 read finished A"
    SSL status: "SSL negotiation finished successfully"
    SSL status: "SSL negotiation finished successfully"
    Cipher: name = RC4-MD5; description = RC4-MD5                 SSLv3 Kx=RSA      Au=RSA  Enc=RC4(128)  Mac=MD5 
    ; bits = 128; version = TLSv1/SSLv3; 

    Send: 02/28/2012 16:33:55.859
    --------------------------------------------------------------------------------
    POST / HTTP/1.0
    Content-Length: 3130
    SOAPAction: "http://edd.ca.gov/SendTransmission"
    Host: FSETTESTPROD.EDD.CA.GOV
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding: identity
    User-Agent: Mozilla/3.0 (compatible; Indy Library)


    <?xml version="1.0" encoding="utf-8"?>
    <log>
      <inputMessage utc="2/28/2012 04:32:28 pm" messageId="urn:uuid{4A995507-9E23-49C3-A17C-19C30693C6C1}">
        <processingStep description="Unprocessed message">
          <soap:Envelope xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <soap:Header>
              <wsa:Action>http://edd.ca.gov/Sendtransmission</wsa:Action>
              <wsa:MessageID>urn:uuid{4A995507-9E23-49C3-A17C-19C30693C6C1}</wsa:MessageID>
              <wsa:ReplyTo>
                <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
              </wsa:ReplyTo>
              <wsa:To>http://localhost:3031/EDD.DMRC.FSET.WebServices/FsetService.asmx</wsa:To>
              <wsse:Security soap:mustUnderstand="1">
                <wsu:Timestamp wsu:Id="Timestamp-db31b09e-9283-4ff1-9a57-5b97971328d4">
                  <wsu:Created>2012-02-29T00:32:28Z</wsu:Created>
                  <wsu:Expires>2012-02-29T00:37:28Z</wsu:Expires>
                </wsu:Timestamp>
                <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-0ac2cf06-b8da-46c8-9314-8081144b09d5">
                  <wsse:Username>#MyUserName#</wsse:Username>
                  <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">#MyPassword#</wsse:Password>
                  <wsse:Nonce>0D78327F3F671183149EEC5907A6A5F6</wsse:Nonce>
                  <wsu:Created>2012-02-29T00:32:28Z</wsu:Created>
                </wsse:UsernameToken>
              </wsse:Security>
            </soap:Header>
            <soap:Body>
              <SendTransmission xmlns="http://edd.ca.gov/">
                <SendTransmissionRequest xmlns="http://www.irs.gov/a2a/mef/MeFTransmitterServiceWse.xsd">
                  <transmissionDataList>
                    <Count>1</Count>
                    <transmissionData>
                      <transmissionId>123456789</transmissionId>
                      <ElectronicPostmark>2012-02-29T00:32:28.750-8.00</ElectronicPostmark>
                    </transmissionData>
                  </transmissionDataList>
                </SendTransmissionRequest>
                <fileBytes>UEsDBBQAAAAIAAaJUzYwks2W0QYAAD2IAAALAAAAREU2</fileBytes>
              </SendTransmission>
            </soap:Body>
          </soap:Envelope>
        </processingStep>
      </inputMessage>
    </log>

Receive: 02/28/2012 16:33:56.234
--------------------------------------------------------------------------------
HTTP/1.1 200 OK
Connection: close
Date: Wed, 29 Feb 2012 00:33:51 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Content-Length: 195
Content-Type: text/html
Set-Cookie: ASPSESSIONIDCQSQQDSS=BPLHDJLCKCLDKBDMLBNJOMHP; path=/
Cache-control: private

<html>
<head>
<title>This location has been marked as available</title>
</head>
<body>
<h1>AVAILABLE</h1>
This IP address has been assigned to EDD FSET User Test web site.
</body>
</html>

Response: 02/28/2012 16:33:56.281
--------------------------------------------------------------------------------
<html>
<head>
<title>This location has been marked as available</title>
</head>
<body>
<h1>AVAILABLE</h1>
This IP address has been assigned to EDD FSET User Test web site.
</body>
</html>

Я был в телефонном и электронном контакте с агентством, которое поддерживает веб-службу (California EDD). Они заинтересованы в том, чтобы как можно больше людей приняли эту технологию и сократили объем бумаги, которую им приходится обрабатывать, но у них нет глубоких знаний о системе, потому что она была создана внешним поставщиком.

Я скачал SOAPUI, чтобы попытаться лучше понять сервис и устранить любые ошибки, которые могут быть вызваны моей реализацией и возможным неправильным использованием библиотеки Indy. Я не знаю, как использовать SOAPUI для этой цели. Инструкции, похоже, не касаются моей ситуации. Если я загружаю WSDL в программу и пытаюсь протестировать одну из функций, я получаю результат, что тест завершен со статусом [завершено], и я не знаю, что с этим делать.

Я был бы признателен за любую помощь в моей маленькой проблеме.
1 5

1 ответ:

SoapUI-это путь, чтобы увидеть, как все должно работать. Используй Рио.Onbeforeexecute и AfterExecute события для проверки XML, который вы отправляете и получаете. Сравните их с тем, что SoapUI посылает и получает. Игнорируйте различия в пространствах имен, которые не должны иметь значения. В идеале, вы должны иметь возможность взять XML, выходящий из события OnBeforeExecute (сохранить поток в текстовый файл или журнал), вставить в SoapUI, (щелкните правой кнопкой мыши, чтобы очистить / переформатировать в SoapUI) и посмотреть, имеет ли XML смысл, и посмотрите, что произойдет, когда вы представите это.

Если окажется, что ваш XML близок к работе,но требуется "настройка", вы можете отредактировать XML в событии OnBeforeExecute с помощью StringReplace и т. д., и "исправить" XML, чтобы он работал.