====== 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