windows-nt/Source/XPSP1/NT/inetsrv/iis/iisrearc/iisplus/ulw3/w3request.hxx
2020-09-26 16:20:57 +08:00

742 lines
15 KiB
C++

#ifndef _W3REQUEST_HXX_
#define _W3REQUEST_HXX_
#define W3_REQUEST_SIGNATURE ((DWORD) 'QR3W')
#define W3_REQUEST_SIGNATURE_FREE ((DWORD) 'qr3w')
class W3_CONTEXT;
class W3_REQUEST
{
protected:
DWORD _dwSignature;
//
// We provide a friendly wrapper of the UL_HTTP_REQUEST from UL
//
HTTP_REQUEST * _pUlHttpRequest;
HTTP_UNKNOWN_HEADER * _pExtraUnknown;
//
// If a filter changes the URL, unknown verb, etc., we need a new buffer
// pointed into by UL_HTTP_REQUEST
//
CHUNK_BUFFER _HeaderBuffer;
//
// If we are going to insert entity body (child requests) then we'll
// need a HTTP_DATA_CHUNK to store the pointer
//
HTTP_DATA_CHUNK _InsertedEntityBodyChunk;
//
// Preloaded entity
//
BUFFER _buffEntityBodyPreload;
//
// Keep track of the "wire user" for this request
//
STRA _strRequestUserName;
//
// Keep track of original full URL of request (can be changed by filter)
//
WCHAR * _pszOriginalFullUrl;
DWORD _cchOriginalFullUrl;
static PHOSTENT sm_pHostEnt;
public:
W3_REQUEST()
: _dwSignature( W3_REQUEST_SIGNATURE ),
_pUlHttpRequest( NULL ),
_pExtraUnknown( NULL ),
_pszOriginalFullUrl( NULL ),
_cchOriginalFullUrl( 0 )
{
_InsertedEntityBodyChunk.DataChunkType = HttpDataChunkFromMemory;
}
virtual ~W3_REQUEST()
{
if ( _pExtraUnknown != NULL )
{
LocalFree( _pExtraUnknown );
_pExtraUnknown = NULL;
}
_dwSignature = W3_REQUEST_SIGNATURE_FREE;
}
VOID
SetHttpRequest(
HTTP_REQUEST * pRequest
)
{
_pUlHttpRequest = pRequest;
_pszOriginalFullUrl = pRequest->CookedUrl.pFullUrl;
_cchOriginalFullUrl = pRequest->CookedUrl.FullUrlLength / sizeof(WCHAR);
}
static
HRESULT
Initialize(
VOID
);
static
VOID
Terminate(
VOID
);
HRESULT
SetNewPreloadedEntityBody(
VOID * pvBuffer,
DWORD cbBuffer
);
HRESULT AppendEntityBody(
VOID * pvBuffer,
DWORD cbBuffer
);
HRESULT PreloadEntityBody(
W3_CONTEXT * pW3Context,
BOOL * pfComplete
);
HRESULT
PreloadCompletion(
W3_CONTEXT * pW3Context,
DWORD cbRead,
DWORD dwStatus,
BOOL * pfComplete
);
VOID
RemoveDav(
VOID
);
HRESULT
SetUrl(
STRU & strNewUrl,
BOOL fResetQueryString = TRUE
);
HRESULT
SetUrlA(
STRA & strNewUrl,
BOOL fResetQueryString = TRUE
);
HTTP_CONNECTION_ID
QueryConnectionId(
VOID
) const
{
return _pUlHttpRequest->ConnectionId;
}
BOOL
QueryMoreEntityBodyExists(
VOID
)
{
return _pUlHttpRequest->MoreEntityBodyExists;
}
HTTP_REQUEST_ID
QueryRequestId(
VOID
) const
{
return _pUlHttpRequest->RequestId;
}
DWORD
QuerySiteId(
VOID
) const
{
return (DWORD)(_pUlHttpRequest->UrlContext >> 32);
}
DWORD
QueryLocalAddress(
VOID
) const;
DWORD
QueryRemoteAddress(
VOID
) const;
USHORT
QueryLocalPort(
VOID
) const;
USHORT
QueryRemotePort(
VOID
) const;
BOOL
IsProxyRequest(
VOID
);
BOOL
IsChunkedRequest(
VOID
);
BOOL
IsLocalRequest(
VOID
) const;
BOOL
IsSecureRequest(
VOID
) const
{
DBG_ASSERT( _pUlHttpRequest != NULL );
return _pUlHttpRequest->pSslInfo != NULL;
}
HTTP_SSL_INFO *
QuerySslInfo(
VOID
) const
{
DBG_ASSERT( _pUlHttpRequest != NULL );
return _pUlHttpRequest->pSslInfo;
}
HTTP_SSL_CLIENT_CERT_INFO *
QueryClientCertInfo(
VOID
) const
{
DBG_ASSERT( _pUlHttpRequest != NULL );
if ( _pUlHttpRequest->pSslInfo != NULL )
{
return _pUlHttpRequest->pSslInfo->pClientCertInfo;
}
else
{
return NULL;
}
}
VOID
SetClientCertInfo(
HTTP_SSL_CLIENT_CERT_INFO * pClientCertInfo
)
{
DBG_ASSERT( pClientCertInfo != NULL );
DBG_ASSERT( _pUlHttpRequest != NULL );
DBG_ASSERT( _pUlHttpRequest->pSslInfo != NULL );
_pUlHttpRequest->pSslInfo->pClientCertInfo = pClientCertInfo;
}
HTTP_RAW_CONNECTION_ID
QueryRawConnectionId(
VOID
) const
{
DBG_ASSERT( _pUlHttpRequest != NULL );
return _pUlHttpRequest->RawConnectionId;
}
HRESULT
GetRawUrl(
STRA * pstrRawUrl
)
{
if ( pstrRawUrl == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
return pstrRawUrl->Copy( _pUlHttpRequest->pRawUrl,
_pUlHttpRequest->RawUrlLength );
}
HRESULT
GetOriginalFullUrl(
STRU * pstrFullUrl
)
{
if ( pstrFullUrl == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
return pstrFullUrl->Copy( _pszOriginalFullUrl, _cchOriginalFullUrl );
}
HRESULT
GetFullUrl(
STRU * pstrFullUrl
)
{
if ( pstrFullUrl == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
return pstrFullUrl->Copy( _pUlHttpRequest->CookedUrl.pFullUrl,
_pUlHttpRequest->CookedUrl.FullUrlLength / sizeof(WCHAR) );
}
HRESULT
GetAllHeaders(
STRA * pstrHeaders,
BOOL fISAPIStyle
);
BOOL
IsSuspectUrl(
VOID
);
HRESULT
GetUrl(
STRU * pstrUrl
)
{
if ( pstrUrl == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
return pstrUrl->Copy( _pUlHttpRequest->CookedUrl.pAbsPath,
_pUlHttpRequest->CookedUrl.AbsPathLength / sizeof(WCHAR) );
}
VOID
QueryUrl(
WCHAR ** ppszUrl,
USHORT * pcbUrl)
{
*ppszUrl = _pUlHttpRequest->CookedUrl.pAbsPath;
*pcbUrl = _pUlHttpRequest->CookedUrl.AbsPathLength;
}
HRESULT
GetHostAddr(
IN OUT STRU *pstrHostAddr
)
{
WCHAR * pchTail;
if ( pstrHostAddr == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
pchTail = wcspbrk( _pUlHttpRequest->CookedUrl.pHost, L":" );
if( !pchTail )
{
DBG_ASSERT( FALSE );
return E_FAIL;
}
else
{
return pstrHostAddr->Copy( _pUlHttpRequest->CookedUrl.pHost,
DIFF(pchTail - _pUlHttpRequest->CookedUrl.pHost) );
}
}
BOOL
QueryClientWantsDisconnect(
VOID
);
HRESULT
GetVerbString(
STRA * pstrVerb
);
VOID
QueryVerb(
CHAR ** ppszVerb,
USHORT * pcchVerb
);
HRESULT
GetVersionString(
STRA * pstrVersion
);
HRESULT
GetAuthType(
STRA * pstrAuthType
);
HRESULT
GetRequestUserName(
STRA * pstrUserName
)
{
if ( pstrUserName == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
return pstrUserName->Copy( _strRequestUserName );
}
HRESULT
SetRequestUserName(
STRA & strUserName
)
{
return _strRequestUserName.Copy( strUserName );
}
STRA *
QueryRequestUserName()
{
return &_strRequestUserName;
}
HTTP_VERSION
QueryVersion(
VOID
)
{
return _pUlHttpRequest->Version;
}
HRESULT
GetQueryString(
STRU * pstrQueryString
)
{
DBG_ASSERT ( pstrQueryString != NULL );
if ( _pUlHttpRequest->CookedUrl.QueryStringLength )
{
return pstrQueryString->Copy( _pUlHttpRequest->CookedUrl.pQueryString + 1,
_pUlHttpRequest->CookedUrl.QueryStringLength / sizeof(WCHAR) - 1 );
}
else
{
return pstrQueryString->Copy( L"", 0 );
}
}
HRESULT
GetQueryStringA(
STRA * pstrQueryString
)
{
DBG_ASSERT ( pstrQueryString != NULL );
if ( _pUlHttpRequest->CookedUrl.QueryStringLength )
{
return pstrQueryString->CopyWTruncate( _pUlHttpRequest->CookedUrl.pQueryString + 1);
}
else
{
return pstrQueryString->Copy( "", 0 );
}
}
HRESULT
SetVerb(
STRA & strVerb
);
HRESULT
SetVersion(
STRA & strVersion
);
HRESULT
BuildFullUrl(
STRA& strPath,
STRA * pstrRedirect,
BOOL fIncludeParameters = TRUE
);
HRESULT
BuildFullUrl(
STRU& strPath,
STRU * pstrRedirect,
BOOL fIncludeParameters = TRUE
);
HTTP_VERB
QueryVerbType(
VOID
) const
{
return _pUlHttpRequest->Verb;
}
VOID
SetVerbType(
HTTP_VERB NewVerb
)
{
_pUlHttpRequest->Verb = NewVerb;
}
CHAR *
GetHeader(
ULONG index,
USHORT * pcchLength = NULL
)
{
if (pcchLength)
{
*pcchLength = _pUlHttpRequest->Headers.pKnownHeaders[ index ].RawValueLength;
}
return _pUlHttpRequest->Headers.pKnownHeaders[ index ].pRawValue;
}
CHAR *
GetHeader(
CHAR * pszHeaderName
);
HRESULT
GetHeader(
STRA & strHeaderName,
STRA * pstrValue,
BOOL fIsUnknownHeader = FALSE
)
{
return GetHeader( strHeaderName.QueryStr(),
strHeaderName.QueryCCH(),
pstrValue,
fIsUnknownHeader );
}
HRESULT
GetHeader(
CHAR * pszHeaderName,
DWORD cchHeaderName,
STRA * pstrValue,
BOOL fIsUnknownHeader = FALSE
);
HRESULT
CloneRequest(
DWORD dwCloneFlags,
W3_REQUEST ** ppRequest
);
HRESULT
DeleteHeader(
CHAR * pszHeaderName
);
HRESULT
SetHeader(
STRA & strHeaderName,
STRA & strHeaderValue,
BOOL fAppend = FALSE
);
HRESULT
SetHeadersByStream(
CHAR * pszHeaderStream
);
CHAR *
QueryRawUrl(
USHORT *pcchUrl
) const
{
*pcchUrl = _pUlHttpRequest->RawUrlLength;
return _pUlHttpRequest->pRawUrl;
}
LPVOID
QueryEntityBody(
VOID
)
{
if ( _pUlHttpRequest->EntityChunkCount == 0 )
{
return NULL;
}
//
// we only expect one memory type chunk
//
DBG_ASSERT( _pUlHttpRequest->EntityChunkCount == 1 );
DBG_ASSERT( _pUlHttpRequest->pEntityChunks[0].DataChunkType == HttpDataChunkFromMemory );
return _pUlHttpRequest->pEntityChunks[0].FromMemory.pBuffer;
}
DWORD
QueryAvailableBytes(
VOID
)
{
if ( _pUlHttpRequest->EntityChunkCount == 0 )
{
return 0;
}
//
// we only expect one memory type chunk
//
DBG_ASSERT( _pUlHttpRequest->EntityChunkCount == 1 );
DBG_ASSERT( _pUlHttpRequest->pEntityChunks[0].DataChunkType == HttpDataChunkFromMemory );
return _pUlHttpRequest->pEntityChunks[0].FromMemory.BufferLength;
}
private:
HRESULT
BuildISAPIHeaderLine(
CHAR * pszHeaderName,
DWORD cchHeaderName,
CHAR * pszHeaderValue,
DWORD cchHeaderValue,
STRA * pstrHeaderLine
);
HRESULT
BuildRawHeaderLine(
CHAR * pszHeaderName,
DWORD cchHeaderName,
CHAR * pszHeaderValue,
DWORD cchHeaderValue,
STRA * pstrHeaderLine
);
};
//
// Cloned request used for executing child requests
//
#define W3_REQUEST_CLONE_BASICS 0x01
#define W3_REQUEST_CLONE_HEADERS 0x02
#define W3_REQUEST_CLONE_ENTITY 0x04
#define W3_REQUEST_CLONE_NO_PRECONDITION 0x08
#define W3_REQUEST_CLONE_NO_DAV 0x10
class W3_CLONE_REQUEST : public W3_REQUEST
{
public:
W3_CLONE_REQUEST()
{
_pUlHttpRequest = &_ulHttpRequest;
}
virtual ~W3_CLONE_REQUEST()
{
}
HRESULT
CopyMinimum(
HTTP_REQUEST * pRequestToClone
);
HRESULT
CopyHeaders(
HTTP_REQUEST * pRequestToClone
);
HRESULT
CopyBasics(
HTTP_REQUEST * pRequestToClone
);
HRESULT
CopyEntity(
HTTP_REQUEST * pRequestToClone
);
VOID
RemoveConditionals(
VOID
);
VOID *
operator new(
size_t size
)
{
DBG_ASSERT( size == sizeof( W3_CLONE_REQUEST ) );
DBG_ASSERT( sm_pachCloneRequests != NULL );
return sm_pachCloneRequests->Alloc();
}
VOID
operator delete(
VOID * pCloneRequest
)
{
DBG_ASSERT( pCloneRequest != NULL );
DBG_ASSERT( sm_pachCloneRequests != NULL );
DBG_REQUIRE( sm_pachCloneRequests->Free( pCloneRequest ) );
}
static
HRESULT
Initialize(
VOID
);
static
VOID
Terminate(
VOID
);
private:
HTTP_REQUEST _ulHttpRequest;
//
// Lookaside for main contexts
//
static ALLOC_CACHE_HANDLER * sm_pachCloneRequests;
};
HRESULT
UlCleanAndCopyUrl(
IN PUCHAR pSource,
IN ULONG SourceLength,
OUT PULONG pBytesCopied,
IN OUT PWSTR pDestination,
OUT PWSTR * ppQueryString
);
#endif