
+Fix server side SOAP headers reading. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@533 8e941d3f-bd1b-0410-a28a-d453659cc2b4
235 lines
5.8 KiB
ObjectPascal
235 lines
5.8 KiB
ObjectPascal
{
|
|
This file is part of the Web Service Toolkit
|
|
Copyright (c) 2006 by Inoussa OUEDRAOGO
|
|
|
|
This file is provide under modified LGPL licence
|
|
( the files COPYING.modifiedLGPL and COPYING.LGPL).
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
}
|
|
{$INCLUDE wst_global.inc}
|
|
unit xmlrpc_formatter;
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, TypInfo,
|
|
{$IFNDEF FPC}xmldom, wst_delphi_xml{$ELSE}DOM{$ENDIF},
|
|
base_service_intf, service_intf, imp_utils, base_xmlrpc_formatter;
|
|
|
|
{$INCLUDE wst.inc}
|
|
{$INCLUDE wst_delphi.inc}
|
|
|
|
type
|
|
|
|
|
|
{ TXmlRpcFormatter }
|
|
{$M+}
|
|
TXmlRpcFormatter = class(TXmlRpcBaseFormatter,IFormatterClient)
|
|
private
|
|
FCallProcedureName : string;
|
|
FCallTarget : String;
|
|
public
|
|
procedure BeginCall(
|
|
const AProcName,
|
|
ATarget : string;
|
|
ACallContext : ICallContext
|
|
);
|
|
procedure EndCall();
|
|
procedure BeginCallRead(ACallContext : ICallContext);
|
|
|
|
function GetCallProcedureName():String;
|
|
function GetCallTarget():String;
|
|
end;
|
|
|
|
{ TXmlRpcCallMaker }
|
|
|
|
TXmlRpcCallMaker = class(TSimpleFactoryItem,ICallMaker)
|
|
private
|
|
FPropMngr : IPropertyManager;
|
|
FUniqueAddress: Boolean;
|
|
public
|
|
constructor Create();override;
|
|
destructor Destroy();override;
|
|
function GetPropertyManager():IPropertyManager;
|
|
procedure MakeCall(
|
|
ASerializer : IFormatterClient;
|
|
ATransport : ITransport
|
|
);
|
|
published
|
|
property UniqueAddress : Boolean read FUniqueAddress Write FUniqueAddress;
|
|
end;
|
|
{$M-}
|
|
|
|
implementation
|
|
{$IFDEF FPC}uses wst_fpc_xml;{$ENDIF}
|
|
|
|
{ TXmlRpcFormatter }
|
|
|
|
procedure TXmlRpcFormatter.BeginCall(
|
|
const AProcName,
|
|
ATarget : string;
|
|
ACallContext : ICallContext
|
|
);
|
|
var
|
|
mthdNode, mthNameNode, prmsNode : TDOMNode;
|
|
doc : TXMLDocument;
|
|
begin
|
|
Clear();
|
|
doc := Self.GetXmlDoc();
|
|
|
|
FCallTarget := ATarget;
|
|
FCallProcedureName := AProcName;
|
|
|
|
// methodCall
|
|
mthdNode := doc.CreateElement(sMETHOD_CALL);
|
|
doc.AppendChild(mthdNode);
|
|
|
|
//methodName
|
|
mthNameNode := doc.CreateElement(sMETHOD_NAME);
|
|
mthdNode.AppendChild(mthNameNode);
|
|
mthNameNode.AppendChild(doc.CreateTextNode(FCallProcedureName));
|
|
|
|
//params
|
|
prmsNode := doc.CreateElement(sPARAMS);
|
|
mthdNode.AppendChild(prmsNode);
|
|
PushStackParams(prmsNode);
|
|
end;
|
|
|
|
procedure TXmlRpcFormatter.EndCall();
|
|
begin
|
|
EndScope();
|
|
end;
|
|
|
|
procedure TXmlRpcFormatter.BeginCallRead(ACallContext : ICallContext);
|
|
var
|
|
callNode : TDOMElement;
|
|
prmsNode, faultNode, tmpNode : TDOMNode;
|
|
doc : TXMLDocument;
|
|
errCode : Integer;
|
|
eltName, errMsg : string;
|
|
excpt_Obj : EXmlRpcException;
|
|
begin
|
|
ClearStack();
|
|
doc := GetXmlDoc();
|
|
callNode := doc.DocumentElement;
|
|
if not SameText(sMETHOD_RESPONSE,callNode.NodeName) then
|
|
Error('XML root node must be "%s".',[sMETHOD_RESPONSE]);
|
|
|
|
prmsNode := FindNode(callNode,sPARAMS);
|
|
if ( prmsNode <> nil ) then begin
|
|
PushStackParams(prmsNode);
|
|
end else begin
|
|
faultNode := FindNode(callNode,sFAULT);
|
|
if ( faultNode = nil ) then begin
|
|
raise EServiceException.CreateFmt('Invalid XmlRPC response message, "%s" or "%s" are not present.',[sPARAMS,sFAULT]);
|
|
end;
|
|
tmpNode := FindNode(faultNode,sVALUE);
|
|
if ( tmpNode = nil ) then begin
|
|
raise EServiceException.CreateFmt('Invalid XmlRPC fault response message, "%s" is not present.',[sVALUE]);
|
|
end;
|
|
tmpNode := FindNode(tmpNode,XmlRpcDataTypeNames[xdtStruct]);
|
|
if ( tmpNode = nil ) then begin
|
|
raise EServiceException.CreateFmt('Invalid XmlRPC fault response message, "%s" is not present.',[XmlRpcDataTypeNames[xdtStruct]]);
|
|
end;
|
|
PushStack(tmpNode);
|
|
eltName := sFAULT_CODE;
|
|
errCode := 0;
|
|
Get(TypeInfo(Integer),eltName,errCode) ;
|
|
eltName := sFAULT_STRING;
|
|
errMsg := '';
|
|
Get(TypeInfo(string),eltName,errMsg);
|
|
excpt_Obj := EXmlRpcException.Create('');
|
|
excpt_Obj.FaultCode := IntToStr(errCode);
|
|
excpt_Obj.FaultString := errMsg; ;
|
|
excpt_Obj.Message := Format(
|
|
'Service exception :%s Code = "%s"%s Message = "%s"',
|
|
[LineEnding,excpt_Obj.FaultCode,LineEnding,excpt_Obj.FaultString]
|
|
);
|
|
raise excpt_Obj;
|
|
end;
|
|
end;
|
|
|
|
function TXmlRpcFormatter.GetCallProcedureName(): String;
|
|
begin
|
|
Result := FCallProcedureName;
|
|
end;
|
|
|
|
function TXmlRpcFormatter.GetCallTarget(): String;
|
|
begin
|
|
Result := FCallTarget;
|
|
end;
|
|
|
|
{ TXmlRpcCallMaker }
|
|
|
|
constructor TXmlRpcCallMaker.Create();
|
|
begin
|
|
FUniqueAddress := True;
|
|
FPropMngr := TPublishedPropertyManager.Create(Self);
|
|
end;
|
|
|
|
destructor TXmlRpcCallMaker.Destroy();
|
|
begin
|
|
FPropMngr := Nil;
|
|
inherited Destroy();
|
|
end;
|
|
|
|
function TXmlRpcCallMaker.GetPropertyManager(): IPropertyManager;
|
|
begin
|
|
Result := FPropMngr;
|
|
end;
|
|
|
|
procedure TXmlRpcCallMaker.MakeCall(
|
|
ASerializer : IFormatterClient;
|
|
ATransport : ITransport
|
|
);
|
|
var
|
|
rqt, rsps : TMemoryStream;
|
|
propMngr : IPropertyManager;
|
|
begin
|
|
Assert(Assigned(ASerializer));
|
|
Assert(Assigned(ATransport));
|
|
propMngr := ATransport.GetPropertyManager();
|
|
propMngr.SetProperty(
|
|
sCONTENT_TYPE,
|
|
ASerializer.GetPropertyManager().GetProperty(sCONTENT_TYPE)
|
|
);
|
|
propMngr.SetProperty(
|
|
sFORMAT,
|
|
sPROTOCOL_NAME
|
|
);
|
|
rsps := nil;
|
|
rqt := TMemoryStream.Create();
|
|
try
|
|
rsps := TMemoryStream.Create();
|
|
ASerializer.SaveToStream(rqt);
|
|
rqt.Position := 0;
|
|
ATransport.SendAndReceive(rqt,rsps);
|
|
rqt.Clear();
|
|
rsps.Position := 0;
|
|
ASerializer.Clear();
|
|
ASerializer.LoadFromStream(rsps);
|
|
finally
|
|
rsps.Free();
|
|
rqt.Free();
|
|
end;
|
|
end;
|
|
|
|
procedure RegisterXmlRpcProtocol();
|
|
begin
|
|
RegisterStdTypes();
|
|
GetFormaterRegistry().Register(
|
|
sPROTOCOL_NAME,
|
|
TSimpleItemFactory.Create(TXmlRpcFormatter) as IItemFactory,
|
|
TSimpleItemFactory.Create(TXmlRpcCallMaker) as IItemFactory
|
|
);
|
|
end;
|
|
|
|
Initialization
|
|
RegisterXmlRpcProtocol();
|
|
|
|
end.
|