Posting data and receiving a response for a SOAP client

Almost all of my developments were in desktop applications. I am currently using Delphi 2010, and I need to write a SOAP client to access the web service that California EDD supports for electronic billing. I refused the importer of Delphi WSDL because there were too many behind the curtain and I did not seem to be able to make any progress. I downloaded Fiddler2 and used this to see what I wrote on the Internet. I found this procedure for publication, and I feel like I'm leaving now.

//from StackOverflow Andreas Rejbrand 06/04/2012 procedure WebPostData(const UserAgent: string; const Server: string; const Resource: string; const Data: AnsiString); overload; var hInet: HINTERNET; hHTTP: HINTERNET; hReq: HINTERNET; const accept: packed array[0..1] of LPWSTR = (PChar('*/*'), nil); header: string = 'Content-Type: text/plain'; begin hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); try hHTTP := InternetConnect(hInet, PChar(Server), INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 1); try hReq := HttpOpenRequest(hHTTP, PChar('POST'), PChar(Resource), nil, nil, @accept, 0, 1); try if not HttpSendRequest(hReq, PChar(header), length(header), PChar(Data), length(Data)) then raise Exception.Create('HttpOpenRequest failed. ' + SysErrorMessage(GetLastError)); finally InternetCloseHandle(hReq); end; finally InternetCloseHandle(hHTTP); end; finally InternetCloseHandle(hInet); end; end; 

I changed the Content-Type because the original seemed never to return.

I call it this way:

 procedure TForm1.Button1Click(Sender: TObject); var sl: TStringList; s: String; begin sl := TStringList.Create; sl.LoadFromFile('C:\Documents and Settings\Jack\Desktop\My Reading\FSET Development\Ping.xml'); s := sl.Text; sl.Free; WebPostData('BNWebSvc', 'FSETTESTPROD.EDD.CA.GOV','fsetservice', s); end; 

In my browser there is a host (FSETTESTPROD.EDD.CA.GOV) and says that it is available. When I send a message, I get a 404 error, possibly because the web service name has been added. In Fiddler2, the output is as follows:

 POST http://FSETTESTPROD.EDD.CA.GOV/fsetservice HTTP/1.1 Accept: */* Content-Type: text/plain User-Agent: BNWebSvc Host: FSETTESTPROD.EDD.CA.GOV Content-Length: 2190 Pragma: no-cache Cookie: __utma=158387685.1851397844.1321382260.1321382260.1321382260.1; __utmz=158387685.1321382260.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=calif%20edd%20eft%20payroll%20processor%20batch%20processing <?xml version="1.0" encoding="utf-8"?> <log> <inputMessage utc="3/2/2007 10:45:44 PM" messageId="urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b"> <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>//edd.ca.gov/Ping</wsa:Action> <wsa:MessageID>urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b</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-0983e8c1-e822-4648-8066-33839f54a6a0"> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> <wsu:Expires>2007-03-02T22:50:41Z</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-0d55d82c-d16d-4c0e-826b-21bf7c805a0f"> <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>w6dgDz1DMzKntFsFdEcjhw==</wsse:Nonce> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <Ping xmlns="http://edd.ca.gov/"> </Ping> </soap:Body> </soap:Envelope> </processingStep> </inputMessage> </log> 

I will need to send this using HTTPS when it works, and I probably need to enable this to make it work.

Am I going in the right direction?

The procedure from Andreas did not indicate how to get the answer. How to get an answer?

+4
source share
2 answers

I think I'm moving forward. I changed WebPostData to a function and copied some code from another place to use SSL and return the result. Now it looks like this:

 function WebPostData(const UserAgent: string; const Server: string; const Resource: string; const Data: AnsiString): String; var hInet: HINTERNET; hHTTP: HINTERNET; hReq: HINTERNET; BufStream: TMemoryStream; BytesRead: Cardinal; aBuffer : Array[0..4096] of Char; flags : DWord; const accept: packed array[0..1] of LPWSTR = (PChar('*/*'), nil); header: string = 'Content-Type: text/plain'; begin hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); try hHTTP := InternetConnect(hInet, PChar(Server), INTERNET_DEFAULT_HTTPS_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 1); try flags := INTERNET_FLAG_SECURE or INTERNET_FLAG_KEEP_CONNECTION; hReq := HttpOpenRequest(hHTTP, PChar('POST'), PChar(Resource), nil, nil, @accept, flags, 1); try if not HttpSendRequest(hReq, PChar(header), length(header), PChar(Data), length(Data)) then begin raise Exception.Create('HttpOpenRequest failed. ' + SysErrorMessage(GetLastError)); end else begin BufStream := TMemoryStream.Create; try while InternetReadFile(hReq, @aBuffer, SizeOf(aBuffer), BytesRead) do begin if (BytesRead = 0) then Break; BufStream.Write(aBuffer, BytesRead); end; aBuffer[0] := #0; BufStream.Write(aBuffer, 1); Result := PChar(BufStream.Memory); finally BufStream.Free; end; end; finally InternetCloseHandle(hReq); end; finally InternetCloseHandle(hHTTP); end; finally InternetCloseHandle(hInet); end; end; 

And now I get two results in Fiddler, one successful and the other not.

Successful:

 CONNECT fsettestprod.edd.ca.gov:443 HTTP/1.0 User-Agent: BNWebSvc Host: FSETTESTPROD.EDD.CA.GOV:443 Content-Length: 0 Connection: Keep-Alive Pragma: no-cache A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below. Major Version: 3 Minor Version: 1 Random: 4F 28 1F 92 96 EA 2C 64 91 59 12 84 D1 F3 F8 ED BA 89 A5 44 94 D6 50 E0 CF 9B FA 12 5F 57 AD EB SessionID: empty Ciphers: [0004] SSL_RSA_WITH_RC4_128_MD5 [0005] SSL_RSA_WITH_RC4_128_SHA [000A] SSL_RSA_WITH_3DES_EDE_SHA [0009] SSL_RSA_WITH_DES_SHA [0064] TLS_RSA_EXPORT1024_WITH_RC4_56_SHA [0062] TLS_RSA_EXPORT1024_WITH_DES_SHA [0003] SSL_RSA_EXPORT_WITH_RC4_40_MD5 [0006] SSL_RSA_EXPORT_WITH_RC2_40_MD5 [0013] SSL_DHE_DSS_WITH_3DES_EDE_SHA [0012] SSL_DHE_DSS_WITH_DES_SHA [0063] TLS_DHE_DSS_EXPORT1024_WITH_DES_SHA 

And unsuccessful:

 POST https://FSETTESTPROD.EDD.CA.GOV/fsetservice HTTP/1.1 Accept: */* Content-Type: text/plain User-Agent: BNWebSvc Host: FSETTESTPROD.EDD.CA.GOV Content-Length: 2190 Connection: Keep-Alive Cache-Control: no-cache Cookie: __utma=158387685.1851397844.1321382260.1321382260.1321382260.1; __utmz=158387685.1321382260.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=calif%20edd%20eft%20payroll%20processor%20batch%20processing <?xml version="1.0" encoding="utf-8"?> <log> <inputMessage utc="3/2/2007 10:45:44 PM" messageId="urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b"> <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>//edd.ca.gov/Ping</wsa:Action> <wsa:MessageID>urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b</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-0983e8c1-e822-4648-8066-33839f54a6a0"> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> <wsu:Expires>2007-03-02T22:50:41Z</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-0d55d82c-d16d-4c0e-826b-21bf7c805a0f"> <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>w6dgDz1DMzKntFsFdEcjhw==</wsse:Nonce> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <Ping xmlns="http://edd.ca.gov/"> </Ping> </soap:Body> </soap:Envelope> </processingStep> </inputMessage> </log> 

I went through my code and watched Fiddler react. Both messages came when I crossed the HTTPSendRequest line. In a button-click event, I assign the results of the function to the recording control, but all I get is a bunch of squares indicating non-printable characters.

Does the result that I get shows that the process is good, but the content is bad?

Could this be a problem because you cannot access the WebService this way?

How can I decrypt the results or will it happen automatically when I receive the process correctly?

+1
source

Now I have done more research, bought a decent book on Web Services Teach Web Services (thanks, Nook root), and spoke briefly to someone at the agency whose web service I am trying to use. Therefore, I think that I have answers to the questions that I asked, and I will summarize them here if it will be useful for everyone who starts the same path. If you see that I have distorted something, and you can correct or improve it, I would appreciate it if you take the time to make your improvements.

In the graph showing that the web services are running over HTTP, this means that if you use a component that can request a website, you can probably also use it to create a web service client.

You should probably install Fiddler2 right away. The feedback you receive from him will be needed to make progress.

A WSDL file may be useful for building a web services client, but maybe not. My experience with the Delphi WSDL importer is that it does part-time work. The Wikipedia article on web services has a section on large web services that indicates that the WSDL file is not needed, but can help automate the design of the web service client. If this does not help, do not use it.

You do not need to use the HTTPRIO component to access the web service. You can use the WinInet module with some code, as shown above, which I plagiarized from some StackOverflow posts.

The schemas specified in the WSDL file must not exist in the specified locations. Technically, this is a URI, not a URL (identifiers, not locations).

Manually writing a web service client may be an acceptable alternative to automatic generation when automatic generation does not work. In addition, like many black box solutions, it only works when it works. When this does not work, there can be no other choice. In addition, you will learn more and be able to better control the output.

Sending your request using SSL seems automatic if you use the PostWebData procedure described above. A response is also included in this procedure.

Getting the two responses I received from the web service seems to indicate that my process is good, but my content is bad. Now I have to examine the actual SOAP envelope and provide acceptable data in order to proceed to the next step.

If the results are not decrypted when I complete this next step, I will have to do more research.

Hope this helps someone who is trying to find their way into web services.

0
source

Source: https://habr.com/ru/post/1393876/


All Articles