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
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;
|
|
}
|
|
}
|
|
|
|
|
|
|