You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
419 lines
10 KiB
419 lines
10 KiB
#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
|
|
|