Componentes.Terceros.RemObj.../internal/5.0.23.613/1/RemObjects SDK for Delphi/Source/uROWebBrokerServer.pas
david 2824855ea7 - Modificación del paquete RemObjects_Core_D10 para que sea un paquete de runtime/designtime (antes era designtime sólo)
- 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
2007-09-10 14:06:19 +00:00

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.