2007-05-05 19:05:01 +00:00
{
This file is part of the Web Service Toolkit
Copyright ( c) 2 0 0 6 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.
}
2007-07-13 22:33:55 +00:00
{$INCLUDE wst_global.inc}
{$IFDEF FPC}
//{$UNDEF INDY_9}
//{$DEFINE INDY_10}
{$ELSE}
//{$UNDEF INDY_10}
//{$DEFINE INDY_9}
{$ENDIF}
2007-05-05 19:05:01 +00:00
2007-07-13 22:33:55 +00:00
unit indy_http_server;
2007-05-05 19:05:01 +00:00
interface
uses
Classes, SysUtils,
IdCustomHTTPServer,
2007-07-13 22:33:55 +00:00
IdHTTPServer,
{$IFDEF INDY_10}
IdContext,
{$ENDIF}
{$IFDEF INDY_9}
IdTCPServer,
{$ENDIF}
IdSocketHandle;
2007-05-05 19:05:01 +00:00
2007-07-13 22:33:55 +00:00
{$INCLUDE wst.inc}
{$INCLUDE wst_delphi.inc}
2007-05-05 19:05:01 +00:00
type
{ TwstWebApplication }
TwstWebApplication = class( TObject)
private
FHTTPServerObject: TIdHTTPServer;
FRootAddress : string ;
private
function GenerateWSDLTable( ) : string ;
procedure ProcessWSDLRequest(
2007-07-13 22:33:55 +00:00
{$IFDEF INDY_10}
2007-05-05 19:05:01 +00:00
AContext : TIdContext;
2007-07-13 22:33:55 +00:00
{$ENDIF}
2007-05-05 19:05:01 +00:00
ARequestInfo : TIdHTTPRequestInfo;
AResponseInfo : TIdHTTPResponseInfo;
var APath : string
) ;
procedure ProcessServiceRequest(
2007-07-13 22:33:55 +00:00
{$IFDEF INDY_10}
2007-05-05 19:05:01 +00:00
AContext : TIdContext;
2007-07-13 22:33:55 +00:00
{$ENDIF}
2007-05-05 19:05:01 +00:00
ARequestInfo : TIdHTTPRequestInfo;
AResponseInfo : TIdHTTPResponseInfo;
var APath : string
) ;
private
procedure Handler_CommandGet(
2007-07-13 22:33:55 +00:00
{$IFDEF INDY_10}
2007-05-05 19:05:01 +00:00
AContext : TIdContext;
2007-07-13 22:33:55 +00:00
{$ENDIF}
{$IFDEF INDY_9}
AThread: TIdPeerThread;
{$ENDIF}
2007-05-05 19:05:01 +00:00
ARequestInfo : TIdHTTPRequestInfo;
AResponseInfo : TIdHTTPResponseInfo
) ;
public
2007-07-13 22:33:55 +00:00
constructor Create(
const AServerIpAddress : string = '127.0.0.1' ;
const AListningPort : Integer = 8 0 0 0 ;
const ADefaultClientPort : Integer = 2 5 0 0 0 ;
const AServerSoftware : string = 'Web Service Toolkit Application'
) ;
2007-05-05 19:05:01 +00:00
destructor Destroy( ) ; override ;
procedure Display( const AMsg : string ) ;
2007-07-13 22:33:55 +00:00
procedure Start( ) ;
procedure Stop( ) ;
2007-05-05 19:05:01 +00:00
end ;
implementation
uses base_service_intf,
server_service_intf, server_service_imputils,
2007-06-28 23:33:38 +00:00
server_service_soap, server_binary_formatter, server_service_xmlrpc,
2007-07-13 22:33:55 +00:00
metadata_repository, metadata_wsdl,
{$IFNDEF FPC}
ActiveX, XMLDoc, XMLIntf, xmldom, wst_delphi_xml,
{$ELSE}
DOM, XMLWrite, wst_fpc_xml,
{$ENDIF}
2007-05-05 19:05:01 +00:00
metadata_service, metadata_service_binder, metadata_service_imp,
user_service_intf, user_service_intf_binder, user_service_intf_imp;
2007-07-13 22:33:55 +00:00
{$IFNDEF FPC}
type
TwstIndy9Thread = class( TIdPeerThread)
protected
procedure AfterExecute; override ;
procedure BeforeExecute; override ;
end ;
{ TwstIndy9Thread }
procedure TwstIndy9Thread. AfterExecute;
begin
CoUninitialize( ) ;
inherited ;
end ;
procedure TwstIndy9Thread. BeforeExecute;
begin
inherited ;
CoInitialize( nil ) ;
end ;
{$ENDIF}
2007-05-05 19:05:01 +00:00
const
sSEPARATOR = '/' ;
sSERVICES_PREFIXE = 'services' ;
sWSDL = 'WSDL' ;
function ExtractNextPathElement( var AFullPath : string ) : string ;
var
i : SizeInt;
begin
Result : = '' ;
if ( Length( AFullPath) > 0 ) then begin
while ( Length( AFullPath) > 0 ) and ( AFullPath[ 1 ] = sSEPARATOR ) do begin
Delete( AFullPath, 1 , 1 ) ;
end ;
i : = Pos( sSEPARATOR, AFullPath) ;
if ( i < 1 ) then begin
Result : = AFullPath;
AFullPath : = '' ;
end else begin
Result : = Copy( AFullPath, 1 , Pred( i) ) ;
Delete( AFullPath, 1 , i) ;
end ;
end ;
end ;
function GetWSDL( const ARepName, ARootAddress: shortstring ) : string ;
var
strm : TMemoryStream;
rep : PServiceRepository;
doc : TXMLDocument;
i : SizeInt;
s : string ;
begin
Result : = '' ;
rep : = nil ;
doc : = Nil ;
i : = GetModuleMetadataMngr( ) . IndexOfName( ARepName) ;
if ( i < 0 ) then
Exit;
strm : = TMemoryStream. Create( ) ;
try
s : = GetModuleMetadataMngr( ) . GetRepositoryName( i) ;
GetModuleMetadataMngr( ) . LoadRepositoryName( s, ARootAddress, rep) ;
//if ( GetModuleMetadataMngr().LoadRepositoryName(s,rep) > 0 ) then
//rep^.namespace := 'urn:wst';
strm. Clear( ) ;
2007-07-13 22:33:55 +00:00
doc : = CreateDoc( ) ;
2007-05-05 19:05:01 +00:00
GenerateWSDL( rep, doc) ;
WriteXMLFile( doc, strm) ;
i : = strm. Size;
if ( i > 0 ) then begin
SetLength( Result , i) ;
Move( strm. memory^ , Result [ 1 ] , i) ;
end ;
finally
2007-07-13 22:33:55 +00:00
ReleaseDomNode( doc) ;
2007-05-05 19:05:01 +00:00
strm. Free( ) ;
GetModuleMetadataMngr( ) . ClearRepository( rep) ;
end ;
end ;
{ TwstWebApplication }
function TwstWebApplication. GenerateWSDLTable( ) : string ;
var
r : IModuleMetadataMngr;
i : Integer ;
begin
r : = GetModuleMetadataMngr( ) ;
Result : = '<html>' +
'<head>' +
'<title>' +
'The Web Service Toolkit generated Metadata table' +
'</title>' +
'<body>' +
'<p BGCOLOR="#DDEEFF"><FONT FACE="Arial" COLOR="#0000A0" SIZE="+2">The following repositories has available. Click on the link to view the corresponding WSDL.</FONT></p>' +
'<table width="100%">' +
'<tr>' ;
for i : = 0 to Pred( r. GetCount( ) ) do
Result : = Result + '<td align="center">' +
Format( '<a href="%s">' , [ sSEPARATOR+ sSERVICES_PREFIXE+ sSEPARATOR+ sWSDL+ sSEPARATOR+ r. GetRepositoryName( i) ] ) +
r. GetRepositoryName( i) +
'</a>' +
'</td>' ;
Result : = Result +
'</tr>' +
'</table>' +
'</body>' +
'</head>' +
'</html>' ;
end ;
procedure TwstWebApplication. ProcessWSDLRequest(
2007-07-13 22:33:55 +00:00
{$IFDEF INDY_10}
2007-05-05 19:05:01 +00:00
AContext : TIdContext;
2007-07-13 22:33:55 +00:00
{$ENDIF}
2007-05-05 19:05:01 +00:00
ARequestInfo : TIdHTTPRequestInfo;
AResponseInfo : TIdHTTPResponseInfo;
var APath : string
) ;
var
locRepName, strBuff : string ;
i : Integer ;
begin
locRepName : = ExtractNextPathElement( APath) ;
if AnsiSameText( sWSDL, locRepName) then
locRepName : = ExtractNextPathElement( APath) ;
strBuff : = GetWSDL( locRepName, FRootAddress) ;
i : = Length( strBuff) ;
if ( i > 0 ) then begin
AResponseInfo. ContentType : = 'text/xml' ;
if not Assigned( AResponseInfo. ContentStream) then
AResponseInfo. ContentStream : = TMemoryStream. Create( ) ;
AResponseInfo. ContentStream. Write( strBuff[ 1 ] , i) ;
Exit;
end ;
AResponseInfo. ContentText : = GenerateWSDLTable( ) ;
AResponseInfo. ContentType : = 'text/html' ;
end ;
procedure TwstWebApplication. ProcessServiceRequest(
2007-07-13 22:33:55 +00:00
{$IFDEF INDY_10}
2007-05-05 19:05:01 +00:00
AContext : TIdContext;
2007-07-13 22:33:55 +00:00
{$ENDIF}
2007-05-05 19:05:01 +00:00
ARequestInfo : TIdHTTPRequestInfo;
AResponseInfo : TIdHTTPResponseInfo;
var APath : string
) ;
var
2007-06-28 23:33:38 +00:00
trgt, ctntyp, frmt : string ;
2007-05-05 19:05:01 +00:00
rqst : IRequestBuffer;
2007-07-13 22:33:55 +00:00
inStream : {$IFDEF FPC} TMemoryStream{$ELSE} TStringStream{$ENDIF} ;
2007-05-05 19:05:01 +00:00
begin
trgt : = ExtractNextPathElement( APath) ;
if AnsiSameText( sWSDL, trgt) then begin
2007-07-13 22:33:55 +00:00
ProcessWSDLRequest( {$IFDEF INDY_10} AContext, {$ENDIF} ARequestInfo, AResponseInfo, APath) ;
2007-05-05 19:05:01 +00:00
Exit;
end ;
inStream : = nil ;
try
try
2007-07-13 22:33:55 +00:00
inStream : = {$IFDEF FPC} TMemoryStream. Create( ) ; {$ELSE} TStringStream. Create( ARequestInfo. FormParams) ; {$ENDIF}
2007-05-05 19:05:01 +00:00
AResponseInfo. ContentStream : = TMemoryStream. Create( ) ;
ctntyp : = ARequestInfo. ContentType;
2007-07-13 22:33:55 +00:00
{$IFDEF FPC}
2007-05-05 19:05:01 +00:00
inStream. CopyFrom( ARequestInfo. PostStream, 0 ) ;
2007-07-13 22:33:55 +00:00
{$ENDIF}
2007-05-05 19:05:01 +00:00
inStream. Position : = 0 ;
AResponseInfo. ContentType : = ctntyp;
2007-06-28 23:33:38 +00:00
frmt : = Trim( ARequestInfo. Params. Values[ 'format' ] ) ;
rqst : = TRequestBuffer. Create( trgt, ctntyp, inStream, AResponseInfo. ContentStream, frmt) ;
2007-05-05 19:05:01 +00:00
HandleServiceRequest( rqst) ;
finally
inStream. Free( ) ;
end ;
except
on e : Exception do begin
Display( 'ProcessData()>> Exception = ' + e. Message ) ;
raise ;
end ;
end ;
end ;
procedure TwstWebApplication. Handler_CommandGet(
2007-07-13 22:33:55 +00:00
{$IFDEF INDY_10}
AContext : TIdContext;
{$ENDIF}
{$IFDEF INDY_9}
AThread: TIdPeerThread;
{$ENDIF}
2007-05-05 19:05:01 +00:00
ARequestInfo : TIdHTTPRequestInfo;
AResponseInfo : TIdHTTPResponseInfo
) ;
var
locPath, locPathPart, s : string ;
j : SizeInt;
begin
if Assigned( ARequestInfo. PostStream) and ( ARequestInfo. PostStream. Size > 0 ) then begin
j : = ARequestInfo. PostStream. Size;
SetLength( s, j) ;
ARequestInfo. PostStream. Read( s[ 1 ] , j) ;
Display( '----------- QUERY ----------------------' ) ;
Display( s) ;
end ;
locPath : = ARequestInfo. Document;
locPathPart : = ExtractNextPathElement( locPath) ;
if AnsiSameText( sSERVICES_PREFIXE, locPathPart) then begin
2007-07-13 22:33:55 +00:00
ProcessServiceRequest( {$IFDEF INDY_10} AContext, {$ENDIF} ARequestInfo, AResponseInfo, locPath) ;
2007-05-05 19:05:01 +00:00
if Assigned( AResponseInfo. ContentStream) and ( AResponseInfo. ContentStream. Size > 0 ) then begin
j : = AResponseInfo. ContentStream. Size;
SetLength( s, j) ;
AResponseInfo. ContentStream. Position : = 0 ;
AResponseInfo. ContentStream. Read( s[ 1 ] , j) ;
Display( '--------- RESPONSE ------------------------' ) ;
Display( s) ;
end ;
Exit;
end ;
2007-07-13 22:33:55 +00:00
ProcessWSDLRequest( {$IFDEF INDY_10} AContext, {$ENDIF} ARequestInfo, AResponseInfo, locPath) ;
2007-05-05 19:05:01 +00:00
end ;
2007-07-13 22:33:55 +00:00
constructor TwstWebApplication. Create(
const AServerIpAddress : string ;
const AListningPort : Integer ;
const ADefaultClientPort : Integer ;
const AServerSoftware : string
) ;
2007-05-05 19:05:01 +00:00
var
b : TIdSocketHandle;
begin
inherited Create( ) ;
2007-07-13 22:33:55 +00:00
FHTTPServerObject : = TIdHTTPServer. Create( {$IFNDEF INDY_10} nil {$ENDIF} ) ;
{$IFNDEF FPC}
FHTTPServerObject. ThreadClass : = TwstIndy9Thread;
{$ENDIF}
2007-05-05 19:05:01 +00:00
b : = FHTTPServerObject. Bindings. Add( ) ;
2007-07-13 22:33:55 +00:00
b. IP : = AServerIpAddress;
b. port : = AListningPort;
FRootAddress : = Format( 'http://%s:%d/' , [ AServerIpAddress, AListningPort] ) ;
FHTTPServerObject. DefaultPort : = ADefaultClientPort;
FHTTPServerObject. ServerSoftware : = AServerSoftware;
2007-05-05 19:05:01 +00:00
FHTTPServerObject. Active : = True ;
2007-07-13 22:33:55 +00:00
FHTTPServerObject. OnCommandGet : = {$IFDEF FPC} @ {$ENDIF} Handler_CommandGet;
2007-05-05 19:05:01 +00:00
end ;
destructor TwstWebApplication. Destroy( ) ;
begin
FreeAndNil( FHTTPServerObject) ;
inherited Destroy( ) ;
end ;
procedure TwstWebApplication. Display( const AMsg: string ) ;
begin
2007-07-13 22:33:55 +00:00
//WriteLn(AMsg);
end ;
procedure TwstWebApplication. Start( ) ;
begin
if not FHTTPServerObject. Active then
FHTTPServerObject. Active : = True ;
end ;
procedure TwstWebApplication. Stop( ) ;
begin
if FHTTPServerObject. Active then
FHTTPServerObject. Active : = False ;
2007-05-05 19:05:01 +00:00
end ;
initialization
RegisterStdTypes( ) ;
Server_service_RegisterBinaryFormat( ) ;
Server_service_RegisterSoapFormat( ) ;
2007-06-28 23:33:38 +00:00
Server_service_RegisterXmlRpcFormat( ) ;
2007-07-13 22:33:55 +00:00
2007-05-05 19:05:01 +00:00
RegisterUserServiceImplementationFactory( ) ;
2007-06-28 23:33:38 +00:00
Server_service_RegisterUserServiceService( ) ;
2007-05-05 19:05:01 +00:00
Register_user_service_intf_ServiceMetadata( ) ;
2007-07-13 22:33:55 +00:00
2007-05-05 19:05:01 +00:00
RegisterWSTMetadataServiceImplementationFactory( ) ;
2007-06-28 23:33:38 +00:00
Server_service_RegisterWSTMetadataServiceService( ) ;
2007-07-13 22:33:55 +00:00
2007-05-05 19:05:01 +00:00
end .