Отладка передачи 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 ответ:
SoapUI-это путь, чтобы увидеть, как все должно работать. Используй Рио.Onbeforeexecute и AfterExecute события для проверки XML, который вы отправляете и получаете. Сравните их с тем, что SoapUI посылает и получает. Игнорируйте различия в пространствах имен, которые не должны иметь значения. В идеале, вы должны иметь возможность взять XML, выходящий из события OnBeforeExecute (сохранить поток в текстовый файл или журнал), вставить в SoapUI, (щелкните правой кнопкой мыши, чтобы очистить / переформатировать в SoapUI) и посмотреть, имеет ли XML смысл, и посмотрите, что произойдет, когда вы представите это.
Если окажется, что ваш XML близок к работе,но требуется "настройка", вы можете отредактировать XML в событии OnBeforeExecute с помощью StringReplace и т. д., и "исправить" XML, чтобы он работал.