|
|
#ifndef __SSI_REQUEST_HXX__
#define __SSI_REQUEST_HXX__
/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
ssi_request.hxx
Abstract:
This module contains the server side include processing code. We aim for support as specified by iis\spec\ssi.doc. The code is based on existing SSI support done in iis\svcs\w3\gateways\ssinc\ssinc.cxx.
Master STM file handler ( STM file may include other files )
Author:
Ming Lu (MingLu) 5-Apr-2000
Revision history Jaroslad Dec-2000 - modified to execute asynchronously
Jaroslad Apr-2001 - added VectorSend support, keepalive, split to multiple source files
--*/
class SSI_INCLUDE_FILE; class SSI_ELEMENT_LIST; class SSI_FILE;
/*++
class SSI_REQUEST Master structure for SSI request. Provides a "library" of utilities for use by higher level functions
Hierarchy:
SSI_REQUEST - SSI_INCLUDE_FILE - SSI_FILE - SSI_ELEMENT_LIST
--*/
class SSI_REQUEST { public: ~SSI_REQUEST();
VOID * operator new( size_t size ) { UNREFERENCED_PARAMETER( size ); // use ACACHE
DBG_ASSERT( size == sizeof( SSI_REQUEST ) ); DBG_ASSERT( sm_pachSsiRequests != NULL ); return sm_pachSsiRequests->Alloc(); } VOID operator delete( VOID * pSSIRequest ) { DBG_ASSERT( pSSIRequest != NULL ); DBG_ASSERT( sm_pachSsiRequests != NULL ); DBG_REQUIRE( sm_pachSsiRequests->Free( pSSIRequest ) ); }
static HRESULT InitializeGlobals( VOID ) /*++
Routine Description:
Global initialization routine for SSI_REQUEST
Arguments:
None Return Value:
HRESULT
--*/ { ALLOC_CACHE_CONFIGURATION acConfig; HKEY hKeyParam; DWORD dwType; DWORD nBytes; DWORD dwValue; DWORD err;
//
// Setup allocation lookaside
//
acConfig.nConcurrency = 1; acConfig.nThreshold = 100; acConfig.cbSize = sizeof( SSI_REQUEST );
DBG_ASSERT( sm_pachSsiRequests == NULL ); sm_pachSsiRequests = new ALLOC_CACHE_HANDLER( "SSI_REQUEST", &acConfig );
if ( sm_pachSsiRequests == NULL ) { return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); }
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, W3_PARAMETERS_KEY, 0, KEY_READ, &hKeyParam ) == NO_ERROR ) { nBytes = sizeof( dwValue ); err = RegQueryValueExA( hKeyParam, "SSIEnableCmdDirective", NULL, &dwType, ( LPBYTE )&dwValue, &nBytes );
if ( ( err == ERROR_SUCCESS ) && ( dwType == REG_DWORD ) ) { sm_fEnableCmdDirective = !!dwValue; }
RegCloseKey( hKeyParam ); } return NO_ERROR; }
static VOID TerminateGlobals( VOID ) /*++
Routine Description:
Terminate SSI_REQUEST globals
Arguments:
None Return Value:
None
--*/ { if ( sm_pachSsiRequests != NULL ) { delete sm_pachSsiRequests; sm_pachSsiRequests = NULL; } }
static HRESULT CreateInstance( IN EXTENSION_CONTROL_BLOCK * pECB, OUT SSI_REQUEST ** ppSsiRequest ); VOID SetCurrentIncludeFile( IN SSI_INCLUDE_FILE * pSIF ) { _pSIF = pSIF; //
// SSI_REQUEST takes ovnership
// of all the child SSI_INCLUDE_FILE instances
// That way sending the response data may be
// delayed at the very end of the SSI_REQUEST handling
//
AddToDelayedSIFDeleteList( pSIF ); }
EXTENSION_CONTROL_BLOCK * GetECB( VOID ) const { return _pECB; }
SSI_VECTOR_BUFFER& GetVectorBuffer( VOID ) { return _VectorBuffer; }
HANDLE GetUserToken( VOID ) { return _hUser; }
HRESULT SSISendError( IN DWORD dwMessageID, IN LPSTR apszParms[] );
BOOL SetUserErrorMessage( IN STRA * pstrUserMessage ) { if( FAILED ( _strUserMessage.Copy(*pstrUserMessage) ) ) { return FALSE; } return TRUE; }
BOOL IsExecDisabled( VOID ) { if ( !_fIsLoadedSsiExecDisabled ) { CHAR achSsiExecDisabled[ 2 ]; // to store "1" or "0"
DWORD cchSsiExecDisabled = sizeof ( achSsiExecDisabled ); //
// We use lame way to retrieve SsiExecDisabled
// There is internal variable that get's set
// based on metabase setting
//
if ( !_pECB->GetServerVariable( _pECB->ConnID, "SSI_EXEC_DISABLED", achSsiExecDisabled, &cchSsiExecDisabled ) ) { _fSsiExecDisabled = TRUE; // disable exec in the case of error
} else { _fSsiExecDisabled = ( strcmp( achSsiExecDisabled, "1" ) == 0 ) ? TRUE : FALSE; } _fIsLoadedSsiExecDisabled = TRUE; } return _fSsiExecDisabled; }
BOOL IsCmdDirectiveEnabled( VOID ) const { // Value is read from registry.
// There is no metabase equivalent
return sm_fEnableCmdDirective; } HRESULT SendCustomError( HSE_CUSTOM_ERROR_INFO * pCustomErrorInfo ); HRESULT SendDate( IN SYSTEMTIME *, IN STRA * );
HRESULT LookupVirtualRoot( IN WCHAR * pszVirtual, OUT STRU * pstrPhysical, IN DWORD dwAccess );
HRESULT DoWork( IN HRESULT hr, OUT BOOL * pfAsyncPending );
VOID AddToDelayedSIFDeleteList( SSI_INCLUDE_FILE * pSIF ) /*++
Routine Description:
SSI_REQUEST will keep all the child SSI_INCLUDE_FILE instances on the list and delete them at the end of it's execution when all the response data was sent to client The reason for the delayed delete is that SSINC will try to buffer the response whenever possible to minimize number of response sends To send the response at the very end of the request processing all the child SSI_INCLUDE_FILE instances must be present at the time of sending the response
Arguments:
None Return Value:
HRESULT
--*/ { InsertHeadList( &_DelayedSIFDeleteListHead, &pSIF->_DelayedDeleteListEntry ); };
static VOID WINAPI HseIoCompletion( IN EXTENSION_CONTROL_BLOCK * pECB, IN PVOID pContext, IN DWORD cbIO, IN DWORD dwError ); private: //
// private constructor
// use CreateInstance to instantiate the object
//
SSI_REQUEST( EXTENSION_CONTROL_BLOCK * pECB ); //
// Not implemented methods
// Declarations present to prevent compiler
// to generate default ones.
//
SSI_REQUEST(); SSI_REQUEST( const SSI_REQUEST& ); SSI_REQUEST& operator=( const SSI_REQUEST& );
HRESULT Initialize( VOID );
EXTENSION_CONTROL_BLOCK * _pECB; // file name of the SSI (physical path)
STRU _strFilename; // inline buffer for _strFilename
WCHAR _achFilename[ SSI_DEFAULT_PATH_SIZE + 1 ]; // URL of the SSI file requested
STRU _strURL; // inline buffer for _strURL
WCHAR _achURL[ SSI_DEFAULT_URL_SIZE + 1 ]; // error message text configured by SSI file
STRA _strUserMessage; // inline buffer for _struserMessage
CHAR _achUserMessage[ SSI_DEFAULT_USER_MESSAGE + 1 ]; // handle to the authenticated user
HANDLE _hUser; // flag if Exec is disabled
BOOL _fSsiExecDisabled; // flag if _fSsiExecDisabled was loaded already
BOOL _fIsLoadedSsiExecDisabled; // Current include file (multiple stm files may be nested)
SSI_INCLUDE_FILE * _pSIF; // Lookaside
static ALLOC_CACHE_HANDLER * sm_pachSsiRequests; // is CMD execution enabled ?
static BOOL sm_fEnableCmdDirective; // vector buffer - buffers data to be sent to client
// to ensure bettter performance (sending too many very short
// chunks of response data asynchronously is very ineficient
SSI_VECTOR_BUFFER _VectorBuffer; // List of all SSI_INCLUDE_FILE instances that are needed
// for the SSI_REQUEST processing
LIST_ENTRY _DelayedSIFDeleteListHead; };
#endif
|