|
|
#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
|