Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1863 lines
53 KiB

/*++
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_