Leaked source code of windows server 2003
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.
 
 
 
 
 
 

232 lines
5.8 KiB

/*++
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;
}
}