====== Using Synapse In A Borland SOAP Client ====== From: Stig Johansen (stig.johansen@udvikling.it) Subject: Re: Cannot run two SOAP-threads ? Newsgroups: borland.public.kylix.internet.web Date: 2002-05-06 21:01:50 PST Jochen Staerk wrote: > i've got a problem that my kylix raises several errors up to sigservs > when i try to run two or more threads that create themselves httprios > and query a web service. the same code runs with windows! I had the some problems using soap clients in multithreaded environments. I have a working solution, allthough I am not sure whether it is the right solution: * In oxmldom.pas, the handling of GlobalOXDOM is not threadsafe. I changes the declaration to threadvar instead of var. * The indy components. In my project, when using small packets, the first request is ok, the second inserts extra crlf in the header, the third crashes. I dont have the time to debug indy, so I replaced it with Synapse. See: From my previous post: I downloaded the latest source, and made the following changes in SOAPHTTPTrans: Added: procedure SetupSyna(SynaHttp: THTTPSend); var ContentHeader, ActionHeader: string; Protocol, Host, path, Document, Port, Bookmark: string; begin if (soNoValueForEmptySOAPAction in FInvokeOptions) and (SoapAction = '') then ActionHeader := SHTTPSoapAction + ':' else if SoapAction = '""' then ActionHeader := SHTTPSoapAction + ': ""' else ActionHeader := SHTTPSoapAction + ': ' + '"' + FSoapAction + '"'; SynaHttp.Headers.Add(ActionHeader); SynaHTTP.MimeType := 'text/xml'; { do not localize } SynaHttp.Protocol := '1.0' ; end; {$IFDEF USE_SYNA} procedure PostData(Response: TStream); var SynaHTTP: THTTPSend; WireData: string; begin SynaHTTP := THTTPSend.Create; try SetupSyna(SynaHttp); WireData := UTF8Encode(DataMsg); SynaHTTP.Document.Write(Pointer(WireData)^, Length(WireData)); try SynaHTTP.HTTPMethod('POST', FURL); Response.CopyFrom(SynaHTTP.Document, 0); finally end; finally FreeAndNil(SynaHTTP); end; end; {$ENDIF} And the following change: {$IFDEF USE_INDY} InitURL(FURL); {$ENDIF} ===================== Delphi 7 =================== --- //[[tiberiua@yahoo.com|Tiberiu Ardeleanu]] 2009/03/30 13:32// Remember to include $(DELPHI)\Source\SOAP in your client project search path, so that these changes will be compiled into your application. Changes to do in SOAPHTTPTrans in order to use synapase: You should add synapse in the same way Indy is used. define USE_SYNA: {$IFDEF LINUX} //{$DEFINE USE_INDY} {$DEFINE USE_SYNA} {$ENDIF} {$IFDEF MSWINDOWS} //{$DEFINE USE_INDY} {$DEFINE USE_SYNA} {$ENDIF} in uses: uses ... , {$IFDEF USE_SYNA} HTTPSend, synautil; {$ELSE} {$IFDEF USE_INDY} ...; {$ELSE} ...; {$ENDIF} {$ENDIF} Search for USE_INDY and add {$IFNDEF USE_SYNA} as for {$IFNDEF USE_INDY} e.g: {$IFNDEF USE_SYNA} {$IFNDEF USE_INDY} ... ... {$ELSE} ... {$ENDIF} {$ENDIF} in THTTPReqResp.Execute add: {$IFDEF USE_SYNA} procedure SetupSyna(SynaHttp: THTTPSend); var Protocol, Host, Path, Port, Para, pUser, pPass: string; begin if FBindingType = btMIME then begin SynaHttp.MimeType := Format(ContentHeaderMIME, [FMimeBoundary]); SynaHttp.Headers.Add(MimeVersion); end else { Assume btSOAP } begin SynaHttp.MimeType := sTextXML; SynaHttp.Headers.Add(GetSOAPActionHeader); end; SynaHttp.UserName := FUserName; SynaHttp.Password := FPassword; if FProxy <> '' then begin ParseURL(FProxy, Protocol, pUser, pPass, Host, Port, Path, Para); SynaHttp.ProxyHost := Host; SynaHttp.ProxyPort := Port; SynaHttp.ProxyUser := pUser; SynaHttp.ProxyPass := pPass; end; SynaHttp.Protocol := '1.0'; SynaHttp.UserAgent := 'CustomSoap'; end; procedure PostData(const Request: TStream; Response: TStream); var SynaHTTP: THTTPSend; begin SynaHTTP := THTTPSend.Create; try SetupSyna(SynaHttp); Request.Position := 0; SynaHTTP.Document.LoadFromStream(Request); SynaHTTP.Document.Position := 0; if SynaHTTP.HTTPMethod('POST', FURL) then begin Response.CopyFrom(SynaHTTP.Document, 0); FContentType := SynaHTTP.Headers.Values[SContentType]; FMimeBoundary := GetMimeBoundaryFromType(FContentType); CheckContentType; end else raise ESOAPHTTPException.Create(SInvalidHTTPResponse); finally FreeAndNil(SynaHTTP); end; end; {$ENDIF} then change: {$IFDEF USE_INDY} PostData(Request, Response); {$ELSE} ... {$ENDIF} with {$IFDEF USE_SYNA} PostData(Request, Response); {$ELSE} {$IFDEF USE_INDY} PostData(Request, Response); {$ELSE} ... {$ENDIF} {$ENDIF} Enjoy