|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name : headerhash.cxx
Abstract: Header hash goo Author: Bilal Alam (balam) 20-Feb-2000
Environment: Win32 - User Mode
Project: ULW3.DLL --*/
#include "precomp.hxx"
RESPONSE_HEADER_HASH *RESPONSE_HEADER_HASH::sm_pResponseHash;
HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] = { //
// The only consumer of this data is W3_REQUEST::GetHeader
// GetServerVariable is handled by SERVER_VARIABLE_HASH, so we do
// not need to store the HTTP_'ed and capitalized names here
//
{ HttpHeaderCacheControl , HEADER("Cache-Control") }, { HttpHeaderConnection , HEADER("Connection") }, { HttpHeaderDate , HEADER("Date") }, { HttpHeaderKeepAlive , HEADER("Keep-Alive") }, { HttpHeaderPragma , HEADER("Pragma") }, { HttpHeaderTrailer , HEADER("Trailer") }, { HttpHeaderTransferEncoding , HEADER("Transfer-Encoding") }, { HttpHeaderUpgrade , HEADER("Upgrade") }, { HttpHeaderVia , HEADER("Via") }, { HttpHeaderWarning , HEADER("Warning") }, { HttpHeaderAllow , HEADER("Allow") }, { HttpHeaderContentLength , HEADER("Content-Length") }, { HttpHeaderContentType , HEADER("Content-Type") }, { HttpHeaderContentEncoding , HEADER("Content-Encoding") }, { HttpHeaderContentLanguage , HEADER("Content-Language") }, { HttpHeaderContentLocation , HEADER("Content-Location") }, { HttpHeaderContentMd5 , HEADER("Content-MD5") }, { HttpHeaderContentRange , HEADER("Content-Range") }, { HttpHeaderExpires , HEADER("Expires") }, { HttpHeaderLastModified , HEADER("Last-Modified") }, { HttpHeaderAcceptRanges , HEADER("Accept-Ranges") }, { HttpHeaderAge , HEADER("Age") }, { HttpHeaderEtag , HEADER("ETag") }, { HttpHeaderLocation , HEADER("Location") }, { HttpHeaderProxyAuthenticate , HEADER("Proxy-Authenticate") }, { HttpHeaderRetryAfter , HEADER("Retry-After") }, // Set it to something which cannot be a header name, in effect
// making Server an unknown header
{ HttpHeaderServer , HEADER("c:d\r\n") }, // Set it to something which cannot be a header name, in effect
// making Set-Cookie an unknown header
{ HttpHeaderSetCookie , HEADER("a:b\r\n") }, { HttpHeaderVary , HEADER("Vary") }, // Set it to something which cannot be a header name, in effect
// making WWW-Authenticate an unknown header
{ HttpHeaderWwwAuthenticate , HEADER("b:c\r\n") } };
HEADER_RECORD * * RESPONSE_HEADER_HASH::sm_ppSortedResponseHeaders = NULL; DWORD RESPONSE_HEADER_HASH::sm_cResponseHeaders = sizeof( RESPONSE_HEADER_HASH::sm_rgHeaders ) / sizeof( HEADER_RECORD );
int _cdecl CompareResponseHeaderRecords( const void *pRecord1, const void *pRecord2 ) /*++
Routine Description:
Comparison function for qsort
Arguments:
pRecord1 pRecord2
Return Value:
<0 if Record1 < pRecord2 =0 if Record1 == pRecord2 >0 if Record1 > pRecord2 --*/ { return _stricmp( ( * (HEADER_RECORD **) pRecord1)->_pszName, ( * (HEADER_RECORD **) pRecord2)->_pszName ); }
int _cdecl CompareResponseHeaderRecordsForBSearch( const void *pKey, const void *pRecord ) /*++
Routine Description:
Comparison function for qsort
Arguments:
pKey pRecord
Return Value:
<0 if Key < Record.Key =0 if Key == Record.Key >0 if Key > Record.Key --*/ { return _stricmp( (CHAR *) (pKey), (*(HEADER_RECORD **) pRecord)->_pszName ); }
//static
HRESULT RESPONSE_HEADER_HASH::Initialize( VOID ) /*++
Routine Description:
Initialize global header hash table
Arguments:
None
Return Value:
HRESULT
--*/ { //
// lkrhash used to be to translate header name to header index
// RESPONSE_HEADER_HASH is array of constant number of elements
// it is less expensive to sort it and then use bsearch to find the item
//
sm_ppSortedResponseHeaders = new HEADER_RECORD * [ sm_cResponseHeaders ]; if ( sm_ppSortedResponseHeaders == NULL ) { return HRESULT_FROM_WIN32( ERROR_OUTOFMEMORY ); } for(DWORD i = 0; i < sm_cResponseHeaders; i++ ) { sm_ppSortedResponseHeaders[i] = &sm_rgHeaders[i]; } qsort((void*)sm_ppSortedResponseHeaders, sm_cResponseHeaders, sizeof( HEADER_RECORD *), CompareResponseHeaderRecords );
return NO_ERROR; }
//static
VOID RESPONSE_HEADER_HASH::Terminate( VOID ) /*++
Routine Description:
Global cleanup of header hash table
Arguments:
None
Return Value:
None
--*/ { if ( sm_ppSortedResponseHeaders != NULL ) { delete [] sm_ppSortedResponseHeaders; } }
//static
ULONG RESPONSE_HEADER_HASH::GetIndex( CHAR * pszName ) { HEADER_RECORD ** ppHdrRec = reinterpret_cast< HEADER_RECORD **>( bsearch( (void *) pszName, (void*)sm_ppSortedResponseHeaders, sm_cResponseHeaders, sizeof( HEADER_RECORD * ), CompareResponseHeaderRecordsForBSearch ) );
if ( ppHdrRec != NULL ) { return (*ppHdrRec)->_ulHeaderIndex; } else { return UNKNOWN_INDEX; } }
|