- Recompilación en Delphi10 de todos los paquetes de RO para generar las DCU's en Lib\D10 - Recompilación en Delphi10 de todos los paquetes de DA para generar las DCU's en Lib\D10 git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@9 b6239004-a887-0f4b-9937-50029ccdca16
456 lines
14 KiB
ObjectPascal
456 lines
14 KiB
ObjectPascal
unit uROWebBrokerServer;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ RemObjects SDK Library - Core Library }
|
|
{ }
|
|
{ compiler: Delphi 5 and up, Kylix 2 and up }
|
|
{ platform: Win32, Linux }
|
|
{ }
|
|
{ (c)opyright RemObjects Software. all rights reserved. }
|
|
{ }
|
|
{ Using this code requires a valid license of the RemObjects SDK }
|
|
{ which can be obtained at http://www.remobjects.com. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$I RemObjects.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF REMOBJECTS_TRIAL}uROTrial,{$ENDIF}
|
|
Classes, HTTPApp, uROClientIntf, uROServer;
|
|
|
|
type
|
|
{ TROWebBrokerServer }
|
|
TROWebBrokerServer = class(TROServer, IROTransport, IROTCPTransport, IROHTTPTransport)
|
|
private
|
|
fUserBeforeDispatch : THTTPMethodEvent;
|
|
fActions : TWebActionItems;
|
|
|
|
fActive : boolean;
|
|
fTransportIntf : IROHTTPTransport;
|
|
|
|
fRequest : TWebRequest;
|
|
fResponse : TWebResponse;
|
|
fSendExceptionsAs500: boolean;
|
|
fOverridePathInfo : string;
|
|
fServeInfoPage: Boolean;
|
|
fServeRodl: Boolean;
|
|
|
|
function ReadRequestStream(aRequest : TWebRequest): TStream;
|
|
function GetRequest: TWebRequest;
|
|
function GetResponse: TWebResponse;
|
|
function IsWebModuleAction(const aPathInfo: string) : boolean;
|
|
|
|
protected
|
|
procedure ReplaceBeforeDispatch(aOwner : TComponent; aNewHandler : THTTPMethodEvent); virtual;
|
|
|
|
function GetDispatchersClass : TROMessageDispatchersClass; override;
|
|
|
|
procedure Loaded; override;
|
|
procedure IntSetActive(const Value: boolean); override;
|
|
function IntGetActive : boolean; override;
|
|
|
|
{ IROTransport }
|
|
function GetTransportObject : TObject;
|
|
|
|
{ IROTCPTransport }
|
|
function GetClientAddress : string;
|
|
|
|
{ IROHTTPTransport }
|
|
procedure SetHeaders(const aName, aValue : string);
|
|
function GetHeaders(const aName : string) : string;
|
|
function GetContentType : string;
|
|
procedure SetContentType(const aValue : string);
|
|
function GetUserAgent : string;
|
|
procedure SetUserAgent(const aValue : string);
|
|
function GetTargetURL : string;
|
|
procedure SetTargetURL(const aValue : string);
|
|
function GetPathInfo : string;
|
|
procedure SetPathInfo (const aValue : string);
|
|
function GetLocation : string;
|
|
function GetQueryString : string;
|
|
|
|
public
|
|
constructor Create(aOwner : TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
property Request : TWebRequest read GetRequest;
|
|
property Response : TWebResponse read GetResponse;
|
|
|
|
published
|
|
procedure IntOnBeforeDispatch(Sender: TObject;
|
|
Request: TWebRequest;
|
|
Response: TWebResponse; var Handled: Boolean); virtual;
|
|
property SendExceptionsAs500: boolean read fSendExceptionsAs500 write fSendExceptionsAs500 default true;
|
|
property ServeInfoPage : Boolean read fServeInfoPage write fServeInfoPage default true;
|
|
property ServeRodl : Boolean read fServeRodl write fServeRodl default true;
|
|
property OnGetRODLReader;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses TypInfo, uRORes, uROHTTPTools, SysUtils, uROHTTPDispatch, uROServerIntf,
|
|
uROClient, uROHtmlServerInfo, uRODL;
|
|
|
|
type
|
|
// See TROWebBrokerServer.Loaded This is for EWF support.
|
|
IInterfaceComponentReference = interface
|
|
['{E28B1858-EC86-4559-8FCD-6B4F824151ED}']
|
|
function GetComponent: TComponent;
|
|
end;
|
|
|
|
{ TROWebBrokerServer }
|
|
|
|
constructor TROWebBrokerServer.Create(aOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
|
|
fActive := TRUE;
|
|
fActions := NIL;
|
|
fServeInfoPage := true;
|
|
fServeRodl := true;
|
|
fSendExceptionsAs500 := true;
|
|
Supports(Self, IROTransport, fTransportIntf);
|
|
end;
|
|
|
|
destructor TROWebBrokerServer.Destroy;
|
|
begin
|
|
fTransportIntf := NIL;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.Loaded;
|
|
var dispatchactions : IUnknown;
|
|
icref : IInterfaceComponentReference;
|
|
begin
|
|
inherited;
|
|
|
|
if not (csDesigning in ComponentState) then begin
|
|
ReplaceBeforeDispatch(Owner, IntOnBeforeDispatch);
|
|
|
|
if Owner is TWebModule
|
|
then fActions := TWebActionItems(GetObjectProp(Owner, 'Actions'))
|
|
else try
|
|
{ This is for EWF. I don't want to set a dependency to the EWF units.
|
|
This component has to stay WebBroker and EWF neutral since, in the end, we are
|
|
dealing with web broker actions. This solves the problem. }
|
|
|
|
{$IFDEF DELPHI6UP}
|
|
if IsPublishedProp(Owner, 'DispatchActions')
|
|
then dispatchactions := GetInterfaceProp(Owner, 'DispatchActions')
|
|
else Exit;
|
|
{$ENDIF DELPHI6UP}
|
|
|
|
if (dispatchactions<>NIL) then begin
|
|
if Supports(dispatchactions, IInterfaceComponentReference, icref) then begin
|
|
fActions := TWebActionItems(GetObjectProp(icref.GetComponent, 'Actions'));
|
|
end;
|
|
end;
|
|
except
|
|
//ToDo: do we really want to catch this exception and display a DIAOG??
|
|
on E:Exception do begin
|
|
//showmessage(e.message);
|
|
fActions := NIL;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TROWebBrokerServer.IntGetActive: boolean;
|
|
begin
|
|
result := fActive;
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.IntSetActive(const Value: boolean);
|
|
begin
|
|
fActive := Value;
|
|
end;
|
|
|
|
function TROWebBrokerServer.ReadRequestStream(aRequest : TWebRequest): TStream;
|
|
var s, t : string;
|
|
i : integer;
|
|
begin
|
|
s := aRequest.Content;
|
|
i := aRequest.ContentLength-Length(Request.Content);
|
|
|
|
while (i>0) do begin
|
|
t := aRequest.ReadString(I);
|
|
s := S+T;
|
|
i := i-Length(t);
|
|
end;
|
|
|
|
result := TStringStream.Create(s);
|
|
end;
|
|
|
|
function TROWebBrokerServer.IsWebModuleAction(const aPathInfo: string) : boolean;
|
|
var i : integer;
|
|
begin
|
|
result := FALSE;
|
|
if (fActions=NIL) then Exit;
|
|
|
|
for i := 0 to (fActions.Count-1) do
|
|
if (CompareText(fActions[i].PathInfo, aPathInfo)=0) then begin
|
|
result := TRUE;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.IntOnBeforeDispatch(Sender: TObject;
|
|
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
|
|
var requeststream : TStream;
|
|
responsestream : TStringStream;
|
|
root, sub: string;
|
|
disp: TROHTTPDispatcher;
|
|
lIgnore: TROResponseOptions;
|
|
format: TDataFormat;
|
|
info: IRONamedModuleInfo;
|
|
ok : boolean;
|
|
lRodl: TRODLLibrary;
|
|
begin
|
|
requeststream := NIL;
|
|
responsestream := NIL;
|
|
|
|
fRequest := Request;
|
|
fResponse := Response;
|
|
|
|
// Executes the user's event handler
|
|
if Assigned(fUserBeforeDispatch)
|
|
then fUserBeforeDispatch(Sender, Request, Response, Handled);
|
|
|
|
// Processes the message if not handled already
|
|
if not Handled and not IsWebModuleAction(Request.PathInfo) then begin
|
|
try
|
|
responsestream := TStringStream.Create('');
|
|
requeststream := ReadRequestStream(Request);
|
|
|
|
root := request.PathInfo;
|
|
if (root <> '') and (root[1] = '/') then delete(root, 1,1);
|
|
if pos('/', root) > 0 then
|
|
begin
|
|
sub := copy(root, pos('/', root)+1, maxint);
|
|
root := '/' + copy(root, 1, pos('/', root) - 1);
|
|
end else
|
|
begin
|
|
root := '/' + root;
|
|
sub := '';
|
|
end;
|
|
|
|
disp := TROHTTPMessageDispatchers(Dispatchers).GetDispatcherByPath(root) as TROHTTPDispatcher;
|
|
|
|
if disp <> nil then
|
|
begin
|
|
if (requeststream.Size = 0) then begin
|
|
ok := fServeRodl;
|
|
if ok then
|
|
ok := IntDispatchMessage(disp, fTransportIntf, requeststream, responsestream, lIgnore)
|
|
else
|
|
responsestream.WriteString('<font size="7">500 Invalid Path</font><br />'+err_CannotFindMessageDispatcher);
|
|
end else if (sub = '') then
|
|
ok := IntDispatchMessage(disp, fTransportIntf, requeststream, responsestream, lIgnore)
|
|
else if (CompareText(sub, 'rodl') = 0) and fServeRodl then
|
|
begin
|
|
if copy(disp.PathInfo, 1, 1) = '/' then fTransportIntf.PathInfo := disp.PathInfo else fTransportIntf.PathInfo := '/'+disp.PathInfo;
|
|
GetRodl(responsestream, fTransportIntf, format, GetRODLReader);
|
|
ok := true;
|
|
end else if Supports(disp.Message, IRONamedModuleInfo, info) and (CompareText(info.ModuleInfoName, sub) = 0) and fServeRodl then
|
|
begin
|
|
if copy(disp.PathInfo, 1, 1) = '/' then fTransportIntf.PathInfo := disp.PathInfo else fTransportIntf.PathInfo := '/'+disp.PathInfo;
|
|
info.GetModuleInfo(responsestream, fTransportIntf, format);
|
|
ok := true;
|
|
end else
|
|
begin
|
|
ok := IntDispatchMessage(disp, fTransportIntf, requeststream, responsestream, lIgnore)
|
|
end;
|
|
end else if (CompareText(root, '/rodl') = 0) and (sub = '') and fServeRodl then
|
|
begin
|
|
GetRodl(responsestream, fTransportIntf, format, GetRODLReader);
|
|
ok := true;
|
|
end else if fServeInfoPage and (CompareText(root, '/doc') = 0) then
|
|
begin
|
|
if sub = 'css' then
|
|
begin
|
|
responsestream.Writestring(GetRodlCss);
|
|
Response.ContentType := 'text/css';
|
|
ok := true;
|
|
end else
|
|
if sub = 'xslt' then
|
|
begin
|
|
responsestream.WriteString(GetRodlStyleSheet);
|
|
Response.ContentType := 'text/xml';
|
|
ok := true;
|
|
end else if sub = '' then
|
|
begin
|
|
lRodl := GetRodlLibrary(GetRODLReader);
|
|
try
|
|
Response.ContentType := 'text/xml';
|
|
responsestream.WriteString(GetRodlWithStyleSheet(lRodl, fRequest.ScriptName + '/doc/xslt'));
|
|
finally
|
|
lRodl.Free;
|
|
end;
|
|
ok := true;
|
|
end else
|
|
begin
|
|
responsestream.WriteString('<font size="7">500 Invalid Path</font><br />'+err_CannotFindMessageDispatcher);
|
|
ok := false;
|
|
end;
|
|
end else if fServeInfoPage and (CompareStr(root, '/favicon.ico') = 0) then
|
|
begin
|
|
GetRodlFavIcon(responsestream);
|
|
Response.ContentType := 'image/x-icon';
|
|
ok := true;
|
|
end else if fServeInfoPage and (root = '/') then
|
|
begin
|
|
lrodl := GetRodlLibrary(GetRODLReader);
|
|
try
|
|
responsestream.WriteString(GetRodlServerInfo(fRequest.ScriptName, lRodl, Dispatchers));
|
|
finally
|
|
lRodl.Free;
|
|
end;
|
|
ok := true;
|
|
end else
|
|
begin
|
|
responsestream.WriteString('<font size="7">500 Invalid Path</font><br />'+err_CannotFindMessageDispatcher);
|
|
ok := false;
|
|
end;
|
|
|
|
if ok or not fSendExceptionsAs500 then
|
|
Response.StatusCode := HTTP_OK
|
|
else
|
|
Response.StatusCode := HTTP_FAILED;
|
|
|
|
finally
|
|
requeststream.Free;
|
|
Handled := TRUE;
|
|
|
|
responsestream.Position := 0;
|
|
Response.ContentStream := responsestream;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetRequest: TWebRequest;
|
|
begin
|
|
result := fRequest;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetResponse: TWebResponse;
|
|
begin
|
|
result := fResponse;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetClientAddress: string;
|
|
begin
|
|
result := fRequest.RemoteAddr;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetContentType: string;
|
|
begin
|
|
result := Response.ContentType
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetHeaders(const aName: string): string;
|
|
begin
|
|
Result := Request.GetFieldByName(aName);
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetTargetURL: string;
|
|
begin
|
|
result := ''
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetTransportObject: TObject;
|
|
begin
|
|
result := Self;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetUserAgent: string;
|
|
begin
|
|
result := str_ProductName
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.SetContentType(const aValue: string);
|
|
begin
|
|
Response.ContentType := aValue
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.SetHeaders(const aName, aValue: string);
|
|
begin
|
|
SetHeaderValue(Response.CustomHeaders, aName, aValue);
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.SetPathInfo(const aValue: string);
|
|
begin
|
|
fOverridePathInfo := aValue;
|
|
// ignore?
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.SetTargetURL(const aValue: string);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.SetUserAgent(const aValue: string);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TROWebBrokerServer.ReplaceBeforeDispatch(aOwner: TComponent;
|
|
aNewHandler: THTTPMethodEvent);
|
|
// Do not change the sequance of these names. It's important for EWF.
|
|
const EventHandlerNames : array[0..1] of string = ('OnBeforeDispatch', 'BeforeDispatch');
|
|
var pinfo : PPropInfo;
|
|
i : integer;
|
|
myevent : THTTPMethodEvent;
|
|
mtd,
|
|
mtd2 : TMethod;
|
|
s : string;
|
|
begin
|
|
for i := 0 to High(EventHandlerNames) do begin
|
|
s := EventHandlerNames[i];
|
|
pinfo := GetPropInfo(Owner, s);
|
|
|
|
if (pinfo<>NIL) then begin
|
|
myevent := IntOnBeforeDispatch;
|
|
mtd := TMethod(myevent); // <--- I have to pass through a local variable. Cannot type caet directly... Go figure!
|
|
|
|
mtd2 := GetMethodProp(Owner, pinfo);
|
|
SetMethodProp(Owner, pinfo, mtd);
|
|
|
|
TMethod(fUserBeforeDispatch) := mtd2;
|
|
Exit;
|
|
end;
|
|
end;
|
|
//TWebModule(aOwner).BeforeDispatch := aNewHandler;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetPathInfo: string;
|
|
begin
|
|
if fOverridePathInfo <> '' then
|
|
result := fOverridePathInfo
|
|
else
|
|
result := Request.PathInfo
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetDispatchersClass: TROMessageDispatchersClass;
|
|
begin
|
|
result := TROHTTPMessageDispatchers;
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetLocation: string;
|
|
begin
|
|
result := 'http://'+fRequest.Host+fRequest.URL
|
|
end;
|
|
|
|
function TROWebBrokerServer.GetQueryString: string;
|
|
begin
|
|
result := fRequest.Query
|
|
end;
|
|
|
|
initialization
|
|
RegisterServerClass(TROWebBrokerServer);
|
|
finalization
|
|
UnregisterServerClass(TROWebBrokerServer);
|
|
end.
|