|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name :
basereq.hxx Abstract:
This file declares the class for http base request, that is used by the w3 information service.
Author:
Murali R. Krishnan ( MuraliK ) 16-Oct-1995
Environment:
Win32 -- User Mode
Project:
W3 Server DLL
Revision History: Murali R. Krishnan (MuraliK) 22-Jan-1996 make impersonation/revert function virtual
--*/
# ifndef _BASEREQ_HXX_
# define _BASEREQ_HXX_
/************************************************************
* Include Headers ************************************************************/
# include "string.hxx"
# include "httphdr.hxx"
# include "tssec.hxx"
# include "w3type.hxx"
# include "filter.hxx"
# include "redirect.hxx"
extern BOOL ReadEntireFile( CHAR *pszFileName, TSVC_CACHE &Cache, HANDLE User, BUFFER *pBuf, DWORD *pdwBytesRead );
// Forward References
class CLIENT_CONN; class HTTP_FILTER; class HTTP_FILTER_DLL; class W3_SERVER_INSTANCE;
/************************************************************
* Symbolic Constants ************************************************************/
//
// HTTP Server response status codes
//
#define HT_OK 200
#define HT_CREATED 201
//#define HT_ACCEPTED 202
//#define HT_PARTIAL 203
#define HT_NO_CONTENT 204
#define HT_RANGE 206
//#define HT_MULT_CHOICE 300
#define HT_MOVED 301
#define HT_REDIRECT 302
#define HT_REDIRECT_METHOD 303
#define HT_NOT_MODIFIED 304
#define HT_BAD_REQUEST 400
#define HT_DENIED 401
//#define HT_PAYMENT_REQ 402
#define HT_FORBIDDEN 403
#define HT_NOT_FOUND 404
#define HT_METHOD_NOT_ALLOWED 405
#define HT_NONE_ACCEPTABLE 406
#define HT_PROXY_AUTH_REQ 407
//#define HT_REQUEST_TIMEOUT 408
//#define HT_CONFLICT 409
//#define HT_GONE 410
#define HT_LENGTH_REQUIRED 411
#define HT_PRECOND_FAILED 412
#define HT_URL_TOO_LONG 414
#define HT_RANGE_NOT_SATISFIABLE 416
#define HT_SERVER_ERROR 500
#define HT_NOT_SUPPORTED 501
#define HT_BAD_GATEWAY 502
#define HT_SVC_UNAVAILABLE 503
#define HT_GATEWAY_TIMOUT 504
//
// Special invalid HTTP response code used to indicate a request should not
// be logged
//
#define HT_DONT_LOG 000
//
// The versioning string for responses
//
#define HTTP_VERSION_STR PSZ_HTTP_VERSION_STR
//
// Flags for network communications over this request
//
#define IO_FLAG_ASYNC 0x00000010 // Call is async
#define IO_FLAG_SYNC 0x00000020 // Call is synchronous
#define IO_FLAG_SEND 0x00000040 // Call is a send
#define IO_FLAG_RECV 0x00000080 // Call is a recv
#define IO_FLAG_NO_FILTER 0x00000100 // Don't go through filters
#define IO_FLAG_AND_RECV 0x00000400 // Add recv operation to IO
#define IO_FLAG_NO_RECV 0x00000800 // Don't do auto-recv after TransmitFile
#define IO_FLAG_NO_DELAY 0x00001000 // Disable Nagling on the socket
// Flags for header generation
#define HTTPH_SEND_GLOBAL_EXPIRE 0x00000001
#define HTTPH_NO_DATE 0x00000002
#define HTTPH_NO_CONNECTION 0x00000004
#define HTTPH_NO_CUSTOM 0x00000008
#define MIN_BUFFER_SIZE_FOR_HEADERS 384
#define MAX_CUSTOM_ERROR_FILE_SIZE (48 * 1024)
#define MD_AUTH_ALL (MD_AUTH_ANONYMOUS|MD_AUTH_BASIC|MD_AUTH_MD5|MD_AUTH_MAPBASIC)
#define MAX_CERT_FIELD_SIZE 4096
#define MAX_ALLOW_SIZE (sizeof("Allow: OPTIONS, TRACE, PUT, DELETE, HEAD, GET\r\n") - 1)
#define MAX_URI_LENGTH 255
//
// Back trace configuration
//
#define MAX_BACKTRACE_FRAMES 10
/************************************************************
* Type Definitions ************************************************************/
enum HTTP_VERB { HTV_GET = 0, HTV_HEAD, HTV_TRACE, HTV_PUT, HTV_DELETE, HTV_TRACECK, HTV_POST, HTV_OPTIONS, HTV_UNKNOWN };
//
// Class of a custom error entry.
//
class CUSTOM_ERROR_ENTRY { public:
CUSTOM_ERROR_ENTRY( DWORD dwErr, DWORD dwSubError, BOOL bWildcard, CHAR *pszPath, BOOL bFileError ) { m_dwErr = dwErr; m_dwSubError = dwSubError; m_bIsFileError = bFileError; m_bIsWildcard = bWildcard;
if (bFileError) { m_pszNames.ErrorFileName = pszPath; } else { m_pszNames.ErrorURL = pszPath; } }
~CUSTOM_ERROR_ENTRY( VOID ) { CHAR *pszTemp;
if (m_bIsFileError) { pszTemp = m_pszNames.ErrorFileName; } else { pszTemp = m_pszNames.ErrorURL; }
if (pszTemp != NULL) { TCP_FREE(pszTemp); } }
BOOL IsFileError( VOID ) { return m_bIsFileError; }
CHAR *QueryErrorFileName( VOID ) { return m_pszNames.ErrorFileName; }
CHAR *QueryErrorURL( VOID ) { return m_pszNames.ErrorURL; }
DWORD QueryError( VOID ) { return m_dwErr; }
DWORD QuerySubError( VOID ) { return m_dwSubError; }
DWORD QueryWildcard( VOID ) { return m_bIsWildcard; }
LIST_ENTRY _ListEntry;
private: BOOL m_bIsFileError; BOOL m_bIsWildcard; DWORD m_dwErr; DWORD m_dwSubError; union { CHAR *ErrorFileName; CHAR *ErrorURL;
} m_pszNames; };
typedef CUSTOM_ERROR_ENTRY *PCUSTOM_ERROR_ENTRY;
//
// The structure of the server's pre-digested meta data.
//
#define W3MD_CREATE_PROCESS_AS_USER 0x00000001
#define W3MD_CREATE_PROCESS_NEW_CONSOLE 0x00000002
#define EXPIRE_MODE_NONE 0
#define EXPIRE_MODE_STATIC 1
#define EXPIRE_MODE_DYNAMIC 2
#define EXPIRE_MODE_OFF 3
class W3_METADATA : public COMMON_METADATA {
public:
//
// Hmmm, since most of these values aren't getting initialized, if
// somebody went and deleted all the metadata items from the tree, then
// bad things could happen. We should initialize with defaults things
// that might mess us
//
W3_METADATA(VOID) : m_dwAuthentication ( MD_AUTH_ANONYMOUS ), m_dwAuthenticationPersistence( MD_AUTH_SINGLEREQUESTIFPROXY ), m_fAnyExtAllowedOnReadDir( FALSE ), m_pRBlob ( NULL ), m_dwFooterLength ( 0 ), m_pszFooter ( NULL ), m_bFooterEnabled ( TRUE ), m_bHaveNoCache ( FALSE ), m_bHaveMaxAge ( FALSE ), m_bSSIExecDisabled ( FALSE ), m_dwCGIScriptTimeout ( DEFAULT_SCRIPT_TIMEOUT ), m_csecPoolIDCTimeout ( 0 ), m_dwCreateProcessFlags( W3MD_CREATE_PROCESS_AS_USER ), m_fAllowKeepAlives ( TRUE ), m_fCacheISAPIApps ( TRUE ), m_fDoReverseDns ( FALSE ), m_dwExpireMaxLength ( 0 ), m_dwExpireMode ( EXPIRE_MODE_NONE ), m_pWildcardMapping ( NULL ), m_dwNotifyExAuth ( 0 ), m_pszCCPointer ( NULL ), m_dwUploadReadAhead (DEFAULT_W3_UPLOAD_READ_AHEAD), m_dwPutReadSize (8192), #if defined(CAL_ENABLED)
m_dwCalHnd ( INVALID_CAL_EXEMPT_HANDLE ), #endif
m_dwDirBrowseFlags ( MD_DIRBROW_LOADDEFAULT ), m_fJobCGIEnabled ( FALSE ), m_fIgnoreTranslate ( FALSE ), m_fUseDigestSSP ( FALSE ), m_dwMaxExtLen (0) { InitializeListHead( &m_ExtMapHead ); InitializeListHead( &m_CustomErrorHead );
memset( m_apszNTProviders, 0, sizeof(m_apszNTProviders) );
if ( g_fIsWindows95 ) { m_dwCreateProcessFlags &= ~W3MD_CREATE_PROCESS_AS_USER; }
}
~W3_METADATA(VOID) { DWORD i = 0;
DestroyCustomErrorTable(); TerminateExtMap();
if (m_pRBlob != NULL ) { delete m_pRBlob; m_pRBlob = NULL; }
while ( m_apszNTProviders[i] ) { TCP_FREE( m_apszNTProviders[i++] ); }
#if defined(CAL_ENABLED)
if ( m_dwCalHnd != INVALID_CAL_EXEMPT_HANDLE ) { CalExemptRelease( m_dwCalHnd ); } #endif
}
BOOL HandlePrivateProperty( LPSTR pszURL, PIIS_SERVER_INSTANCE pInstance, METADATA_GETALL_INTERNAL_RECORD *pMDRecord, LPVOID pDataPointer, BUFFER *pBuffer, DWORD *pdwBytesUsed, PMETADATA_ERROR_INFO pMDErrorInfo );
BOOL FinishPrivateProperties( BUFFER *pBuffer, DWORD dwBytesUsed, BOOL bSucceeded );
//
// Query Methods
//
STR * QueryDefaultDocs( VOID ) { return &m_strDefaultDocs; }
STR * QueryHeaders( VOID ) { return &m_strHeaders; }
BUFFER * QueryMimeMap( VOID ) { return &m_bufMimeMap; }
DWORD QueryAuthentication( VOID ) const { return m_dwAuthentication; }
DWORD QueryAuthenticationPersistence( VOID ) const { return m_dwAuthenticationPersistence; }
DWORD QueryScriptTimeout( VOID ) const { return m_dwCGIScriptTimeout; }
DWORD QueryDirBrowseFlags( VOID ) const { return m_dwDirBrowseFlags; }
BOOL LookupExtMap( IN const CHAR * pchExt, IN BOOL fNoWildcards, OUT STR * pstrGatewayImage, OUT GATEWAY_TYPE * pGatewayType, OUT DWORD * pcchExt, OUT BOOL * pfImageInURL, OUT BOOL * pfVerbExcluded, OUT DWORD * pdwFlags, IN const CHAR *pszVerb, IN enum HTTP_VERB Verb, IN OUT PVOID * ppvExtMapInfo );
PTCP_AUTHENT_INFO QueryAuthentInfo(VOID) const { return (const PTCP_AUTHENT_INFO) &m_TCPAuthentInfo; }
BOOL BuildProviderList( CHAR *pszProviders );
BOOL CheckSSPPackage( IN LPCSTR pszAuthString );
PCHAR QueryRealm(VOID) const { return (m_strRealm.IsEmpty() ? NULL : m_strRealm.QueryStr()); }
DWORD QueryCreateProcessAsUser(VOID) const { return (m_dwCreateProcessFlags & W3MD_CREATE_PROCESS_AS_USER); }
DWORD QueryCreateProcessNewConsole(VOID) const { return (m_dwCreateProcessFlags & W3MD_CREATE_PROCESS_NEW_CONSOLE); }
BOOL QueryAnyExtAllowedOnReadDir() const { return m_fAnyExtAllowedOnReadDir; }
PREDIRECTION_BLOB QueryRedirectionBlob(VOID) const { return m_pRBlob; }
dllexp PCUSTOM_ERROR_ENTRY LookupCustomError( DWORD dwErr, DWORD dwSubError ) { LIST_ENTRY *pEntry; PCUSTOM_ERROR_ENTRY pCustomErrorItem; PCUSTOM_ERROR_ENTRY pCustomErrorWildcard = NULL;
for ( pEntry = m_CustomErrorHead.Flink; pEntry != &m_CustomErrorHead; pEntry = pEntry->Flink ) { pCustomErrorItem = CONTAINING_RECORD( pEntry, CUSTOM_ERROR_ENTRY, _ListEntry );
if ( pCustomErrorItem->QueryError() == dwErr ) { if ( pCustomErrorItem->QuerySubError() == dwSubError ) { return pCustomErrorItem; } else if ( pCustomErrorItem->QueryWildcard() ) { pCustomErrorWildcard = pCustomErrorItem; } } }
return pCustomErrorWildcard;
}
DWORD QueryFooterLength(VOID) const { return m_dwFooterLength; }
CHAR *QueryFooter(VOID) const { return m_pszFooter; }
BOOL FooterEnabled(VOID) const { return m_bFooterEnabled; }
BOOL SSIExecDisabled(VOID) const { return m_bSSIExecDisabled; }
DWORD QueryPoolIDCTimeout( VOID ) const { return m_csecPoolIDCTimeout; }
const LPSTR * QueryNTProviders( VOID ) const { return m_apszNTProviders; }
BOOL QueryKeepAlives( VOID ) const { return m_fAllowKeepAlives; }
BOOL QueryCacheISAPIApps( VOID ) const { return m_fCacheISAPIApps; }
BOOL QueryDoReverseDns(VOID) const { return m_fDoReverseDns; }
DWORD QueryExpireMaxLength(VOID) const { return m_dwExpireMaxLength;}
DWORD QueryExpireDelta(VOID) const { return m_dwExpireDelta;}
DWORD QueryExpireMode(VOID) const { return m_dwExpireMode;}
LPSTR QueryExpireHeader(VOID) const { return m_strExpireHeader.QueryStr();}
DWORD QueryExpireHeaderLength(VOID) const { return m_strExpireHeader.QueryCCH();}
LARGE_INTEGER QueryExpireTime(VOID) const { return m_liExpireTime;}
PVOID QueryWildcardMapping(VOID) const { return m_pWildcardMapping; }
DWORD QueryNotifyExAuth(VOID) const { return m_dwNotifyExAuth; }
BOOL QueryConfigNoCache(VOID) const { return m_bHaveNoCache; }
BOOL QueryHaveMaxAge(VOID) const { return m_bHaveMaxAge; }
LPSTR QueryCacheControlHeader(VOID) const { return m_strCacheControlHeader.QueryStr(); }
DWORD QueryCacheControlHeaderLength(VOID) const { return m_strCacheControlHeader.QueryCB(); }
STR * QueryRedirectHeaders( VOID ) { return &m_strRedirectHeaders; }
DWORD QueryUploadReadAhead(VOID) const { return m_dwUploadReadAhead; }
DWORD QueryPutReadSize(VOID) const { return m_dwPutReadSize; }
BOOL QueryJobCGIEnabled() { return m_fJobCGIEnabled; }
BOOL QueryIgnoreTranslate() const { return m_fIgnoreTranslate; }
BOOL QueryUseDigestSSP() const { return m_fUseDigestSSP; }
//
// Set Methods
//
BOOL SetAnonUserName(PCHAR AnonUserName) { return m_TCPAuthentInfo.strAnonUserName.Copy( AnonUserName ); }
BOOL SetAnonUserPassword(PCHAR AnonUserPassword) { return m_TCPAuthentInfo.strAnonUserPassword.Copy( AnonUserPassword ); }
BOOL SetDefaultLogonDomain(PCHAR DefLogonDom) { return m_TCPAuthentInfo.strDefaultLogonDomain.Copy( DefLogonDom ); }
VOID SetLogonMethod(DWORD dwLogonMethod) { m_TCPAuthentInfo.dwLogonMethod = dwLogonMethod; }
VOID SetUseAnonSubAuth( BOOL fUseAnonSubAuth ) { m_TCPAuthentInfo.fDontUseAnonSubAuth = !fUseAnonSubAuth; }
VOID SetAuthentication( DWORD dwFlags ) { if (g_fIsWindows95) { dwFlags &= INET_INFO_AUTH_W95_MASK; } m_dwAuthentication = dwFlags; }
VOID SetAuthenticationPersistence( DWORD dwFlags ) { m_dwAuthenticationPersistence = dwFlags; }
VOID SetCGIScriptTimeout( DWORD dwScriptTimeout ) { m_dwCGIScriptTimeout = dwScriptTimeout; }
VOID SetDirBrowseFlags( DWORD dwDirBrowseFlags ) { m_dwDirBrowseFlags = dwDirBrowseFlags; }
BOOL BuildExtMap(CHAR *pszExtMapString);
BOOL SetRealm(PCHAR pszRealm) { return m_strRealm.Copy( pszRealm ); }
VOID SetCreateProcessAsUser(BOOL fValue) { if ( fValue ) { if ( !g_fIsWindows95 ) { m_dwCreateProcessFlags |= W3MD_CREATE_PROCESS_AS_USER; } } else { m_dwCreateProcessFlags &= ~W3MD_CREATE_PROCESS_AS_USER; } }
VOID SetCreateProcessNewConsole(BOOL fValue) { if ( fValue ) { m_dwCreateProcessFlags |= W3MD_CREATE_PROCESS_NEW_CONSOLE; } else { m_dwCreateProcessFlags &= ~W3MD_CREATE_PROCESS_NEW_CONSOLE; } }
BOOL SetRedirectionBlob( STR & strSource, STR & strDestination ) { //
// If the redirection is nullified, don't allocate a blob
// and just return success.
//
if ( *( strDestination.QueryStr() ) == '!' ) { return TRUE; } m_pRBlob = new REDIRECTION_BLOB( strSource, strDestination ); if (m_pRBlob == NULL) { return FALSE; } return m_pRBlob->IsValid(); }
BOOL BuildCustomErrorTable( CHAR *pszErrorList, PMETADATA_ERROR_INFO pMDErrorInfo );
VOID DestroyCustomErrorTable( VOID );
BOOL ReadCustomFooter( CHAR *pszFooterString, TSVC_CACHE &Cache, HANDLE User, PMETADATA_ERROR_INFO pMDErrorInfo );
VOID SetFooter(DWORD dwLength, CHAR *pszFooter) { m_dwFooterLength = dwLength; m_pszFooter = pszFooter; }
VOID SetFooterEnabled(BOOL bEnabled) { m_bFooterEnabled = bEnabled; }
VOID SetSSIExecDisabled( BOOL bDisabled ) { m_bSSIExecDisabled = bDisabled; }
VOID SetPoolIDCTimeout( DWORD csecPoolIDCTimeout ) { m_csecPoolIDCTimeout = csecPoolIDCTimeout; }
VOID SetAllowKeepAlives( BOOL fAllowKeepAlives ) { m_fAllowKeepAlives = fAllowKeepAlives; }
VOID SetCacheISAPIApps( BOOL fCacheISAPIApps ) { m_fCacheISAPIApps = fCacheISAPIApps; }
BOOL SetExpire( CHAR* pszExpire, PMETADATA_ERROR_INFO pMDErrorInfo );
VOID SetWildcardMapping(PVOID pMapping) { m_pWildcardMapping = pMapping; }
VOID SetConfigNoCache(VOID) { m_bHaveNoCache = TRUE; }
VOID SetHaveMaxAge(VOID) { m_bHaveMaxAge = TRUE; }
VOID ClearConfigNoCache(VOID) { m_bHaveNoCache = FALSE; }
VOID ClearHaveMaxAge(VOID) { m_bHaveMaxAge = FALSE; }
BOOL SetCCHeader( BOOL bNoCache, BOOL bMaxAge, DWORD dwMaxAge );
VOID SetUploadReadAhead(DWORD dwUploadSize) { m_dwUploadReadAhead = dwUploadSize; }
VOID SetPutReadSize(DWORD dwSize) { m_dwPutReadSize = dwSize; }
//
// Disable job objects on IIS5.1, original code would read the
// property from metabase
//
VOID SetJobCGIEnabled( BOOL f ) { m_fJobCGIEnabled = FALSE; }
VOID SetIgnoreTranslate( BOOL f ) { m_fIgnoreTranslate = f; }
VOID SetUseDigestSSP( BOOL f ) { m_fUseDigestSSP = f; }
private: VOID TerminateExtMap( VOID ); TCP_AUTHENT_INFO m_TCPAuthentInfo; STR m_strDefaultDocs; STR m_strHeaders; BUFFER m_bufMimeMap; STR m_strRealm; DWORD m_dwAuthentication; DWORD m_dwAuthenticationPersistence; DWORD m_dwCGIScriptTimeout; DWORD m_dwDirBrowseFlags; DWORD m_dwCreateProcessFlags; LIST_ENTRY m_ExtMapHead; LIST_ENTRY m_CustomErrorHead; PREDIRECTION_BLOB m_pRBlob; DWORD m_dwFooterLength; CHAR *m_pszFooter; BUFFER m_bufFooter;
BOOL m_fAnyExtAllowedOnReadDir:1; BOOL m_bFooterEnabled:1; BOOL m_bHaveNoCache:1; BOOL m_bHaveMaxAge:1;
BOOL m_bSSIExecDisabled:1; BOOL m_fAllowKeepAlives:1; BOOL m_fCacheISAPIApps:1; BOOL m_fDoReverseDns:1;
DWORD m_csecPoolIDCTimeout; LPSTR m_apszNTProviders[MAX_SSPI_PROVIDERS]; STR m_strExpireHeader; STR m_strCacheControlHeader; DWORD m_dwExpireMaxLength; DWORD m_dwExpireMode; DWORD m_dwExpireDelta; LARGE_INTEGER m_liExpireTime; PVOID m_pWildcardMapping; DWORD m_dwNotifyExAuth; LPSTR m_pszCCPointer; STR m_strRedirectHeaders; DWORD m_dwUploadReadAhead; DWORD m_dwPutReadSize; BOOL m_fJobCGIEnabled; #if defined(CAL_ENABLED)
DWORD m_dwCalHnd; #endif
DWORD m_dwMaxExtLen; BOOL m_fIgnoreTranslate; BOOL m_fUseDigestSSP; };
typedef W3_METADATA *PW3_METADATA;
typedef struct _W3_METADATA_INFO {
DWORD dwMaxAge;
} W3_METADATA_INFO, *PW3_METADATA_INFO;
//
// Various states the HTTP Request goes through
//
enum HTR_STATE { //
// We're still gathering the client request header
//
HTR_READING_CLIENT_REQUEST = 0,
//
// The client is supplying some gateway data, deal with it
//
HTR_READING_GATEWAY_DATA,
//
// We need to take apart the client request and figure out what they
// want
//
HTR_PARSE,
//
// We're executing the verb or handing the request off to a gateway
//
HTR_DOVERB,
//
// The ISAPI application has submitted async IO operation
//
HTR_GATEWAY_ASYNC_IO,
//
// The client requested a file so send them the file
//
HTR_SEND_FILE,
//
// The proxy server is forwarding the request on to the remote server
//
HTR_PROXY_SENDING_REQUEST,
//
// The proxy server is waiting for a response from the remote server
//
HTR_PROXY_READING_RESPONSE,
//
// We're processing a CGI request so we need to ignore any IO
// completions that may occur as the CGIThread forwards the
// program's output
//
HTR_CGI,
//
// Processing a range request
//
HTR_RANGE,
//
// resume processing with clear text logon
//
HTR_RESTART_REQUEST,
//
// We're in the process of writing data from a client PUT request to
// disk
//
HTR_WRITING_FILE,
//
// We're renegotiating a certificate with the client
//
HTR_CERT_RENEGOTIATE, //
// We're reading the entity body before doing redirect
//
HTR_REDIRECT,
//
// We're reading the entity body before sending access denial
//
HTR_ACCESS_DENIED,
//
// We've completely handled the client's request
//
HTR_DONE };
enum CHUNK_STATE { READ_CHUNK_SIZE = 0, READ_CHUNK_PARAMS, READ_CHUNK, READ_CHUNK_FOOTER, READ_CHUNK_CRLF, READ_CHUNK_DONE };
#if 0 // This routine is no longer used /SAB
#define IS_WRITE_VERB(__verb__) ( (__verb__) == HTV_PUT || \
(__verb__) == HTV_DELETE) #endif 0
#define CHUNK_READ_SIZE 80 // Important to keep this small, to
// avoid getting two chunks into the
// same buffer in one read.
#define CRLF_SIZE 2
#define SSLNEGO_MAP 0x00000001
/*******************************************************************
CLASS: HTTP_REQ_BASE
SYNOPSIS: Basic HTTP request object
HISTORY: Johnl 24-Aug-1994 Created
********************************************************************/
class HTTP_REQ_BASE { public:
//
// Constructor/Destructor
//
HTTP_REQ_BASE( CLIENT_CONN * pClientConn, PVOID pvInitialBuff, DWORD cbInitialBuff );
virtual ~HTTP_REQ_BASE( VOID );
//
// This is the work entry point that is driven by the completion of the
// async IO.
//
virtual BOOL DoWork( BOOL * pfFinished ) = 0;
//
// Parses the client's HTTP request
//
virtual BOOL Parse( const CHAR* pchRequest, DWORD cbData, DWORD * pcbExtraData, BOOL * pfHandled, BOOL * pfFinished ) = 0;
// Following function can be overridden by individual derived object.
virtual dllexp BOOL GetInfo( const TCHAR * pszValName, STR * pstr, BOOL * pfFound = NULL ) { if ( pfFound ) { *pfFound = FALSE; }
return (TRUE); }
//
// Kicks off the read for a client request header
//
BOOL StartNewRequest( PVOID pvInitialBuff, DWORD cbInitialBuff, BOOL fFirst, BOOL *pfDoAgain);
BOOL OnFillClientReq( BOOL * pfCompleteRequest, BOOL * pfFinished, BOOL * pfHandled );
BOOL OnCompleteRequest( TCHAR * pchRequest, DWORD cbData, BOOL * pfFinished, BOOL * pfHandled );
BOOL OnRestartRequest( TCHAR * pchRequest, DWORD cbData, BOOL * pfFinished, BOOL * pfHandled);
BOOL HandleCertRenegotiation( BOOL * pfFinished, BOOL * pfHandled, DWORD cbData );
BOOL DenyAccess( BOOL * pfFinished, BOOL * pfDisconnected );
BOOL VrootAccessCheck( PW3_METADATA pMetaData, DWORD dwDesiredAccess );
BOOL DoChange( LPBOOL );
BOOL UnWrapRequest( BOOL * pfCompleteRequest, BOOL * pfFinished, BOOL * pfHandled );
//
// Attempts to logon with the user information gleaned from the Parse
// we just did
//
BOOL LogonUser( BOOL * pfFinished );
BOOL LogonAsSystem( VOID ); //
// Common header parsing functions.
//
BOOL OnContentLength ( CHAR * pszValue ); BOOL OnIfModifiedSince( CHAR * pszValue ); BOOL OnIfUnmodifiedSince( CHAR * pszValue ); BOOL OnIfMatch( CHAR * pszValue ); BOOL OnIfNoneMatch( CHAR * pszValue ); BOOL OnIfRange( CHAR * pszValue ); BOOL OnUnlessModifiedSince( CHAR * pszValue ); BOOL ProcessAuthorization ( CHAR * pszValue ); BOOL OnProxyAuthorization ( CHAR * pszValue ); BOOL OnHost ( CHAR * pszValue ); BOOL OnRange ( CHAR * pszValue );
//BOOL OnAuthorization ( CHAR * pszValue );
BOOL ParseAuthorization( CHAR * pszValue );
//
// Builds and optionally sends an HTTP server response back to the client
//
static BOOL BuildStatusLine( BUFFER * pstrResp, DWORD dwHTTPError, DWORD dwError2, LPSTR pszError2 = NULL, STR *pstrErrorStr = NULL );
//
// Builds a complete HTTP reply with extended explanation text
//
static BOOL BuildExtendedStatus( STR * pstrResp, DWORD dwHTTPError, DWORD dwError2 = NO_ERROR, DWORD dwExplanation = 0, LPSTR pszError2 = NULL );
//
// Sets the http status code and win32 error that should be used for
// this request when it gets written to the logfile
//
VOID SetLogStatus( DWORD LogHttpResponse, DWORD LogWinError ) { _dwLogHttpResponse = LogHttpResponse; _dwLogWinError = LogWinError; }
DWORD QueryLogHttpResponse( VOID ) const { return _dwLogHttpResponse; }
DWORD QueryLogWinError( VOID ) const { return _dwLogWinError; }
//
// Builds a server header for responding back to the client
//
BOOL BuildBaseResponseHeader( BUFFER * pbufResponse, BOOL * pfFinished, STR * pstrStatus = NULL, // Full status string
DWORD dwOptions = 0 );
BOOL BuildHttpHeader( OUT BOOL * pfFinished, IN CHAR * pchStatus = NULL, IN CHAR * pchAdditionalHeaders = NULL, IN DWORD dwOptions = 0);
dllexp BOOL SendHeader( IN CHAR * pchStatus OPTIONAL, IN CHAR * pchAdditionalHeaders OPTIONAL, IN DWORD IOFlags, OUT BOOL * pfFinished, IN DWORD dwOptions = 0, IN BOOL fWriteHeader = TRUE );
BOOL SendHeader( IN CHAR * pchHeaders, IN DWORD cbHeaders, IN DWORD IOFlags, OUT BOOL * pfFinished );
//
// Builds a 301 or 302 URL Moved message
//
dllexp BOOL BuildURLMovedResponse( BUFFER * pbufResp, STR * pstrURL, DWORD dwServerCode, BOOL fIncludeParams = FALSE );
dllexp BOOL WriteLogRecord( VOID );
BOOL AppendLogParameter( CHAR * pszParam );
//
// Sends an access denied message with the forms of authorization
// we support
//
BOOL SendAuthNeededResp( BOOL * pfFinished );
BOOL SetUserNameAndPassword( TCHAR * pszUserName, TCHAR * pszPassword ) { return _strUserName.Copy( pszUserName ) && _strPassword.Copy( pszPassword ); }
STR * QueryDenialHeaders( VOID ) { return &_strDenialHdrs; }
STR * QueryAdditionalRespHeaders( VOID ) { return &_strRespHdrs; }
DWORD QueryAuthentication( VOID ) const { return _pMetaData->QueryAuthentication(); }
DWORD QueryNotifyExAuth( VOID ) const { return _pMetaData->QueryNotifyExAuth(); }
DWORD QueryDirBrowseFlags( VOID ) const { return _pMetaData->QueryDirBrowseFlags(); }
BOOL IsIpDnsAccessCheckPresent( VOID ) const { return _pMetaData->IsIpDnsAccessCheckPresent(); }
PW3_METADATA QueryMetaData( VOID ) const { return _pMetaData; } //
// Retrieves various bits of request information
//
enum HTR_STATE QueryState( VOID ) const { return _htrState; }
BOOL IsKeepConnSet( VOID ) const { return _fKeepConn; }
BOOL IsProcessByteRange( VOID ) const { return _fProcessByteRange; }
BOOL IsAuthenticationRequested( VOID ) const { return _fAuthenticationRequested; }
BOOL IsAuthenticated( VOID ) const { return !_strUserName.IsEmpty(); }
DWORD IsChunked( VOID ) const { return _fChunked; }
VOID SetChunked( VOID ) { _fChunked = TRUE; }
VOID ClearChunked( VOID ) { _fChunked = FALSE; }
VOID SetKeepConn( BOOL fKeepConn ) { _fKeepConn = fKeepConn; }
VOID SetAuthenticationRequested( BOOL fAuthenticationRequested ) { _fAuthenticationRequested = fAuthenticationRequested; }
BOOL IsLoggedOn( VOID ) const { return _fLoggedOn; }
BOOL IsClearTextPassword( VOID ) const { return _fClearTextPass; };
BOOL IsNTLMImpersonation( VOID ) const { return !_fClearTextPass && !_fAnonymous && !UseVrAccessToken(); }
BOOL IsSecurePort( VOID ) const { return _fSecurePort; }
BOOL IsProxyRequest( VOID ) const { return _fProxyRequest; }
VOID SetProxyRequest( BOOL fIsProxyRequest ) { _fProxyRequest = fIsProxyRequest; }
BOOL IsClientProxy( VOID );
CLIENT_CONN * QueryClientConn( VOID ) const { return _pClientConn; }
W3_SERVER_INSTANCE * QueryW3Instance( VOID ) const { return _pW3Instance; }
W3_SERVER_INSTANCE * QueryW3InstanceAggressively( VOID ) const;
VOID SetW3Instance( IN W3_SERVER_INSTANCE* pInstance ) { DBG_ASSERT(_pW3Instance == NULL); _pW3Instance = pInstance; }
W3_SERVER_STATISTICS * QueryW3StatsObj( VOID ) const { return _pW3Stats; }
VOID SetW3StatsObj( IN LPW3_SERVER_STATISTICS pW3Stats ) { _pW3Stats = pW3Stats; }
BOOL IsPointNine( VOID ) const { return (_VersionMajor < 1); }
BOOL IsAtLeastOneOne( VOID ) const { return ((_VersionMajor == 1 && _VersionMinor >= 1) || (_VersionMajor >= 2)); }
BOOL IsOneOne( VOID ) const { return ((_VersionMajor == 1) && (_VersionMinor == 1)); }
BOOL IsAuthenticating( VOID ) const { return _fAuthenticating; }
DWORD QueryClientContentLength( VOID ) const { return _cbContentLength; }
DWORD QueryTotalRequestLength( VOID ) const { return _cbContentLength + _cbClientRequest; }
BYTE * QueryClientRequest( VOID ) const { return (BYTE *) _bufClientRequest.QueryPtr(); }
BUFFER * QueryClientReqBuff( VOID ) { return &_bufClientRequest; }
CHAR * QueryURL( VOID ) const { return _strURL.QueryStr(); }
CHAR * QueryURLParams( VOID ) const { return _strURLParams.QueryStr(); }
HTTP_HEADERS * QueryHeaderList( VOID ) { return &_HeaderList; }
BUFFER * QueryRespBuf( VOID ) { return &_bufServerResp; }
CHAR * QueryRespBufPtr( VOID ) { return (CHAR *) _bufServerResp.QueryPtr(); }
DWORD QueryRespBufCB( VOID ) { return strlen( (CHAR *)_bufServerResp.QueryPtr()); }
VOID SetDeniedFlags( DWORD dwDeniedFlags ) { _Filter.SetDeniedFlags( dwDeniedFlags ); }
CHAR * QueryHostAddr( VOID );
//
// If the client supplied additional data in their request, we store
// the byte count and data here.
//
DWORD QueryEntityBodyCB( VOID ) const { return _cbEntityBody; }
DWORD QueryTotalEntityBodyCB( VOID ) const { return _cbTotalEntityBody; }
VOID AddTotalEntityBodyCB( DWORD cbAdditionalEntityBody ) { _cbTotalEntityBody += cbAdditionalEntityBody; }
BYTE * QueryEntityBody( VOID ) const { return (BYTE *) _bufClientRequest.QueryPtr() + _cbClientRequest; }
BOOL ReadMoreEntityBody(DWORD cbOffset, DWORD cbSize);
BOOL ReadEntityBody( BOOL *pfDone, BOOL fFirstRead = FALSE, DWORD dwMaxAmountToRead = 0, BOOL *pfDisconnected = NULL );
BOOL DecodeChunkedBytes( LPBYTE lpBuffer, LPDWORD pnBytes );
BOOL IsChunkedReadComplete( ) { return ( _ChunkState == READ_CHUNK_DONE ); }
//
// IO Status stuff
//
VOID SetLastCompletionStatus( DWORD BytesWritten, DWORD CompletionStatus ) { _cbBytesWritten = BytesWritten; _status = CompletionStatus;
//
// Do accounting for async sends so that the total bytes matches
// the number actually sent to they client.
//
// TODO: If the client disconnects then the io completion may
// complete with an error even the data was successfully sent.
// This appears to be an issue with TCP, but requires further
// investigation. (taylorw)
//
if ( _fAsyncSendPosted ) { _cbBytesSent += BytesWritten; _fAsyncSendPosted = FALSE; } }
DWORD QueryIOStatus( VOID ) const { return _status; }
DWORD QueryBytesWritten( VOID ) const { return _cbBytesWritten; }
DWORD QueryBytesReceived( VOID ) const { return _cbBytesReceived; }
//
// Impersonation related stuff
//
BOOL UseVrAccessToken() const { return _pMetaData->QueryVrAccessToken() && (!_pMetaData->QueryVrPassThrough() || !_tcpauth.IsForwardable()); }
BOOL ImpersonateUser( VOID ) { return (!UseVrAccessToken() ? _tcpauth.Impersonate() : _pMetaData->ImpersonateVrAccessToken() ); }
VOID RevertUser( VOID ) { (!UseVrAccessToken() ? _tcpauth.RevertToSelf(): ::RevertToSelf() ); }
HANDLE QueryPrimaryToken( HANDLE * phDelete );
HANDLE QueryImpersonationHandle( BOOL fUnused = FALSE ) { return (UseVrAccessToken() ? _pMetaData->QueryVrAccessToken() : _tcpauth.QueryImpersonationToken() ); }
HANDLE QueryUserImpersonationHandle( VOID ) { return _tcpauth.QueryImpersonationToken(); }
HANDLE QueryVrootImpersonateHandle(VOID) const { return UseVrAccessToken() ? _pMetaData->QueryVrAccessToken() : NULL; }
TCP_AUTHENT * QueryAuthenticationObj( VOID ) { return &_tcpauth; }
BOOL IsValid( VOID ) const { return _fValid; }
//
// Forwards request to the client connection object
//
VOID Disconnect( DWORD htResp = 0, DWORD dwError2 = NO_ERROR, BOOL fShutdown= FALSE, LPBOOL pfFinished = NULL );
dllexp BOOL ReadFile( LPVOID lpBuffer, DWORD nBytesToRead, DWORD * pcbBytesRead, // Only for sync reads
DWORD dwFlags = IO_FLAG_ASYNC );
dllexp BOOL WriteFile( LPVOID lpBuffer, DWORD nBytesToRead, DWORD * pcbBytesWritten, // Only for sync writes
DWORD dwFlags = IO_FLAG_ASYNC );
dllexp BOOL TestConnection( VOID );
BOOL TransmitFile( TS_OPEN_FILE_INFO * pOpenFile, HANDLE hFile, DWORD Offset, DWORD BytesToWrite, DWORD dwFlags = IO_FLAG_ASYNC, PVOID pHead = NULL, DWORD HeadLength = 0, PVOID pTail = NULL, DWORD TailLength = 0);
BOOL TransmitFileTs( TS_OPEN_FILE_INFO * pOpenFile, DWORD Offset, DWORD BytesToWrite, DWORD dwFlags = IO_FLAG_ASYNC, PVOID pHead = NULL, DWORD HeadLength = 0, PVOID pTail = NULL, DWORD TailLength = 0);
BOOL SyncWsaSend( WSABUF * rgWsaBuffers, DWORD cWsaBuffers, LPDWORD pcbWritten );
BOOL PostCompletionStatus( DWORD cbBytesTransferred );
DWORD Reference( VOID ); DWORD Dereference( VOID ); DWORD QueryRefCount( VOID );
//
// Reset is called at the beginning of every request
//
virtual BOOL Reset( BOOL fResetPipelineInfo ); virtual VOID ReleaseCacheInfo( VOID );
//
// Called to reset Authentication status
//
BOOL ResetAuth( BOOL fSessionTerminated = TRUE );
// added these methods for exposing them to the Server extension processor
dllexp const STR & QueryContentTypeStr( void) const { return ( _strContentType); } dllexp const STR & QueryMethodStr( void) const { return ( _strMethod); }
dllexp const STR & QueryURLStr(void) const { return ( _strURL); }
dllexp const STR & QueryPhysicalPathStr( void) const { return ( _strPhysicalPath); }
dllexp const LPSTR QueryExpireHeader( void ) const { return ( _pMetaData->QueryExpireHeader() ); }
//
// Called at the beginning and end of a TCP session
//
VOID InitializeSession( CLIENT_CONN * pConn, PVOID pvInitialBuff, DWORD cbInitialBuff );
virtual VOID EndOfRequest( VOID ) = 0; virtual VOID SessionTerminated( VOID );
//
// Generally when the state is set to HTR_DONE
//
VOID SetState( enum HTR_STATE htrstate, DWORD dwLogHttpResponse = HT_DONT_LOG, DWORD dwLogWinError = NO_ERROR ) { _htrState = htrstate; _dwLogHttpResponse = dwLogHttpResponse; _dwLogWinError = dwLogWinError; }
BOOL SetCertificateInfo( PHTTP_FILTER_CERTIFICATE_INFO pData, CtxtHandle* pCtxt, HANDLE hImpersonationToken, HTTP_FILTER_DLL* pFilter );
BOOL CheckValidSSPILogin( VOID );
BOOL NotifyRequestSecurityContextClose( CtxtHandle *pH ) { return _pAuthFilter ? _Filter.NotifyRequestSecurityContextClose( _pAuthFilter, pH ) : TRUE; }
dllexp BOOL CheckForBasicAuthenticationHeader( LPSTR pszHeaders );
BOOL IsAnonymous( VOID ) const { return _fAnonymous; }
HTTP_FILTER * QueryFilter( VOID ) { return &_Filter; }
BOOL CheckCustomError(BUFFER *pBuf, DWORD dwErr, DWORD dwSubError, BOOL *pfFinished, DWORD *pdwMsgSize, BOOL bCheckURL = TRUE);
VOID SetNoCache( VOID ) { _bForceNoCache = 1; }
VOID ClearNoCache( VOID ) { _bForceNoCache = 0; }
DWORD QueryNoCache( VOID) { return _bForceNoCache; }
VOID SetSendVary( VOID ) { _bSendVary = 1; }
VOID ClearSendVary( VOID ) { _bSendVary = 0; }
VOID ToggleSendCL( VOID ) { _bSendContentLocation ^= 1; }
VOID SetSendCL( VOID ) { _bSendContentLocation = 1; }
VOID ClearSendCL( VOID ) { _bSendContentLocation = 0; }
BOOL IsCGIRequest( VOID ) const { return _GatewayType == GATEWAY_CGI; }
//
// The request looks like a gateway request (but may just be a poorly named
// directory)
//
BOOL IsProbablyGatewayRequest( VOID ) const { return (_GatewayType & GT_GATEWAY_REQUEST); }
enum HTTP_VERB QueryVerb( VOID ) const { return _verb; }
virtual DWORD BuildAllowHeader(CHAR *pszURL, CHAR *pszTail) = 0;
//
// Set the time for start of processing
//
VOID SetRequestStartTime( VOID ) { if (!_fStartTimeValid) { _msStartRequest= GetCurrentTime(); _fStartTimeValid= TRUE;}} HANDLE GetFileHandle( TS_OPEN_FILE_INFO * pOpenFile ) { HANDLE hHandle = INVALID_HANDLE_VALUE; if ( pOpenFile ) { if ( ImpersonateUser() ) { hHandle = pOpenFile->QueryFileHandle(); RevertUser(); } } return hHandle; }
VOID IncrementBytesSeenByRawReadFilter( DWORD cbBytesSeen ) { _cbOldData += cbBytesSeen; } protected:
//
// Breaks out the simple authorization info
//
BOOL ExtractClearNameAndPswd( CHAR * pch, STR * pstrUserName, STR * pstrPassword, BOOL fUUEncoded );
//
// Appends the forms of authentication the server supports to the
// server response string
//
BOOL AppendAuthenticationHdrs( STR * pstrAuthHdrs, BOOL * pfFinished );
//
// Data members
//
//
// Points to connection object we are communicating on
//
CLIENT_CONN * _pClientConn;
// Meta data info for this request.
PW3_METADATA _pMetaData;
// URI related info (file and metadata) for this request.
PW3_URI_INFO _pURIInfo;
//
// Points to the w3 instance
//
W3_SERVER_INSTANCE * _pW3Instance;
//
// Points to server instance's statistics object.
//
W3_SERVER_STATISTICS * _pW3Stats;
//
// Action the client is requesting
//
enum HTTP_VERB _verb;
//
// Statistics trackers
//
DWORD _cFilesSent; DWORD _cFilesReceived; DWORD _cbBytesSent; // Total for this request
DWORD _cbBytesReceived;
DWORD _cbTotalBytesSent; // Total for all requests using this
DWORD _cbTotalBytesReceived; // object
//
// Flags
//
BOOL _fValid:1; // TRUE if this object constructed successfully
BOOL _fKeepConn:1; // Pragma: Keep-connection was specified
BOOL _fAuthenticationRequested:1; // request client authentication
BOOL _fLoggedOn:1; // A user was successfully logged on
BOOL _fAnonymous:1; // The user is using the Anonymous user token
BOOL _fSecurePort; // This request is coming over an encrypted port
BOOL _fMappedAcct:1; // The user is using a mapped account
BOOL _fClearTextPass:1; // The user supplied a clear text password
BOOL _fAuthenticating:1; // We're in an NT authentication conversation
BOOL _fBasicRealm:1; // TRUE if realm specified
BOOL _fAuthSystem:1; BOOL _fAuthCert:1; BOOL _fInvalidAccessToken:1;
BOOL _fAsyncSendPosted:1; // TRUE when we send data to the client asychronously
BOOL _fChunked:1; // TRUE iff the entity body is in the chunked
// transfer-encoding
BOOL _fDiscNoError:1; // TRUE if we're to disconnect w/o an error.
BOOL _fNoDisconnectOnError:1; // TRUE if we're not to disconnect on an early error.
BOOL _fProxyRequest:1; // This is request is a proxy request
// Accept range variables
BOOL _fAcceptRange:1; // TRUE if the referenced file accept byte ranges
BOOL _fProcessByteRange:1; // TRUE while processing a byte range request
BOOL _fUnsatisfiableByteRange:1; // TRUE if an unsatisfiable byte range was encountered
BOOL _fMimeMultipart:1; // TRUE if generating a MIME multipart message
BOOL _fIfModifier:1; // TRUE if we've seen an If-Match, etc.
BOOL _fHaveContentLength:1;// Set to TRUE if we've seen a content length
// on this requests.
BOOL _fLogRecordWritten:1; // TRUE if we've written a log record
DWORD _iRangeIdx; // index in strRange string
DWORD _dwRgNxOffset; // next range offset
DWORD _dwRgNxSizeToSend; // next range size
DWORD _cbMimeMultipart; // length of a MIME multipart message body
//
// The state of the HTTP request
//
enum HTR_STATE _htrState;
enum GATEWAY_TYPE _GatewayType; // BGI vs CGI vs BAT
//
// List of raw headers passed by client
//
HTTP_HEADERS _HeaderList;
//
// Client protocol version information
//
BYTE _VersionMajor; BYTE _VersionMinor;
//
// If the client is passing data to a gateway, they will specify
// the length and type in a Content-length/type header that is stored
// here
//
STR _strContentType; UINT _cbContentLength;
//
// The URL the client is requesting
//
STR _strURL; // Just the URL
STR _strURLPathInfo; // Combined URL and script path info
STR _strURLParams; // Just the params (w/o '?')
STR _strLogParams; // Copy of _strURLParams for logging
STR _strPathInfo; // Additional script path info
STR _strRawURL; // Combined URL and params
STR _strOriginalURL; // URL before being passed to filters
//
// Various other pieces of data in the HTTP request we care about
//
STR _strMethod; // GET, HEAD, POST etc.
STR _strAuthType; // "user", "kerberos", "nt" etc.
STR _strAuthInfo; // Current SSP authorization blob
STR _strUserName; // The user name (empty if Guest)
STR _strPassword; // Temporarily holds the password
STR _strUnmappedUserName; // User before filter mappings
STR _strUnmappedPassword; // Password before filter mappings
STR _strPhysicalPath; // Physical path of URL (maybe empty)
STR _strUnmappedPhysicalPath; // unmapped Physical path of URL (maybe empty)
STR _strRespHdrs; // Optional headers from filters
STR _strDenialHdrs; // Optional headers from filters
// to add if request is denied
STR _strHostAddr; // Host address as a domain name
STR _strRange;
BOOL _fAuthTypeDigest; // is auth type Digest/NT-Digest
LARGE_INTEGER _liModifiedSince; // Contains If-Modified-Since time
LARGE_INTEGER _liUnlessModifiedSince; // Contains Unless-Modified-Since time
LARGE_INTEGER _liUnmodifiedSince; // Contains If-Unmodified-Since time
DWORD _dwExpireInDay; // # of days before pwd expiration
// or 0x7fffffff if n/a
DWORD _dwModifiedSinceLength; // Length parameter passed in with IMS.
BOOL _bProcessingCustomError:1; // TRUE if we're processing a custom error.
BOOL _bForceNoCache:1; // Set to TRUE if must force no-cache.
BOOL _bSendContentLocation:1; // Set to TRUE if we need to send C-L:
BOOL _bSendVary:1; // Set to TRUE if we need to send Vary: *.
//
// Encapsulates authentication and impersonation code
//
BOOL _fSingleRequestAuth:1; TCP_AUTHENT _tcpauth;
//
// Used to calculate the time of this request
//
BOOL _fStartTimeValid:1; DWORD _msStartRequest;
//
// Filter context information
//
HTTP_FILTER _Filter; HTTP_FILTER_DLL * _pAuthFilter;
//
// Contains the HTTP client request buffer
// _cbClientRequest indicates the number of bytes in the HTTP request
// (excluding gateway data)
// _cbOldData - Number of bytes in buffer raw read filters have already
// seen
// _cbEntityBody - Number of bytes of entity body currently in buffer
// _cbTotalEntityBody - Number of bytes expected in entity body.
// _cbChunkHeader - Number of bytes in chunk header processed.
// _cbChunkBytesRead - Number of bytes in the current transfer-encoded
// chunk we've read.
// _cbExtraData - Number of 'extra' bytes in buffer.
// _pchExtraData - Pointer to start of 'extra' bytes.
//
BUFFER _bufClientRequest; DWORD _cbClientRequest; DWORD _cbOldData; DWORD _cbEntityBody; DWORD _cbTotalEntityBody; DWORD _cbChunkHeader; DWORD _cbChunkBytesRead; DWORD _cbExtraData; CHAR *_pchExtraData;
//
// Contains the server response buffer, generally only used for response
// headers
//
BUFFER _bufServerResp;
//
// Stores the results of the last IO request
//
APIERR _status; DWORD _cbBytesWritten; DWORD _cbRestartBytesWritten; DWORD _dwRenegotiated; DWORD _dwSslNegoFlags; AC_RESULT _acIpAccess; BOOL _fNeedDnsCheck;
//
// Stores the request codes to write to the request log
//
DWORD _dwLogHttpResponse; DWORD _dwLogWinError;
// Information used for decoding chunked requests.
enum CHUNK_STATE _ChunkState; DWORD _dwChunkSize; // reset value is -1 => chunk size not sent.
BYTE _CRCount; BYTE _LFCount;
BUFFER _bufLastAnonAcctDesc; DWORD _cbLastAnonAcctDesc;
#if defined(CAL_ENABLED)
LPVOID m_pCalAuthCtxt; LPVOID m_pCalSslCtxt; #endif
VOID * m_ppvFrames[ MAX_BACKTRACE_FRAMES ]; };
#define CERT_NEGO_SUCCESS 1
#define CERT_NEGO_FAILURE 2
//
// Macro to check for both normal and localhost access
//
#define IS_ACCESS_ALLOWED(op) ( \
((GetFilePerms() & VROOT_MASK_## op) != 0) && \ (((GetFilePerms() & VROOT_MASK_NO_REMOTE_## op) == 0) || \ IsIPAddressLocal( \ QueryClientConn()->QueryLocalIPAddress(), \ QueryClientConn()->QueryRemoteIPAddress()) ) )
#define IS_ACCESS_ALLOWED2(_pExec, op) ( \
((_pExec->_pMetaData->QueryAccessPerms() & VROOT_MASK_## op) != 0) && \ (((_pExec->_pMetaData->QueryAccessPerms() & VROOT_MASK_NO_REMOTE_## op) == 0) || \ IsIPAddressLocal( \ QueryClientConn()->QueryLocalIPAddress(), \ QueryClientConn()->QueryRemoteIPAddress()) ) )
# endif // _BASEREQ_HXX_
|