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

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. headerhash.cxx
  5. Abstract:
  6. Header hash goo
  7. Author:
  8. Bilal Alam (balam) 20-Feb-2000
  9. Environment:
  10. Win32 - User Mode
  11. Project:
  12. ULW3.DLL
  13. --*/
  14. #include "precomp.hxx"
  15. RESPONSE_HEADER_HASH *RESPONSE_HEADER_HASH::sm_pResponseHash;
  16. HEADER_RECORD RESPONSE_HEADER_HASH::sm_rgHeaders[] =
  17. {
  18. //
  19. // The only consumer of this data is W3_REQUEST::GetHeader
  20. // GetServerVariable is handled by SERVER_VARIABLE_HASH, so we do
  21. // not need to store the HTTP_'ed and capitalized names here
  22. //
  23. { HttpHeaderCacheControl , HEADER("Cache-Control") },
  24. { HttpHeaderConnection , HEADER("Connection") },
  25. { HttpHeaderDate , HEADER("Date") },
  26. { HttpHeaderKeepAlive , HEADER("Keep-Alive") },
  27. { HttpHeaderPragma , HEADER("Pragma") },
  28. { HttpHeaderTrailer , HEADER("Trailer") },
  29. { HttpHeaderTransferEncoding , HEADER("Transfer-Encoding") },
  30. { HttpHeaderUpgrade , HEADER("Upgrade") },
  31. { HttpHeaderVia , HEADER("Via") },
  32. { HttpHeaderWarning , HEADER("Warning") },
  33. { HttpHeaderAllow , HEADER("Allow") },
  34. { HttpHeaderContentLength , HEADER("Content-Length") },
  35. { HttpHeaderContentType , HEADER("Content-Type") },
  36. { HttpHeaderContentEncoding , HEADER("Content-Encoding") },
  37. { HttpHeaderContentLanguage , HEADER("Content-Language") },
  38. { HttpHeaderContentLocation , HEADER("Content-Location") },
  39. { HttpHeaderContentMd5 , HEADER("Content-MD5") },
  40. { HttpHeaderContentRange , HEADER("Content-Range") },
  41. { HttpHeaderExpires , HEADER("Expires") },
  42. { HttpHeaderLastModified , HEADER("Last-Modified") },
  43. { HttpHeaderAcceptRanges , HEADER("Accept-Ranges") },
  44. { HttpHeaderAge , HEADER("Age") },
  45. { HttpHeaderEtag , HEADER("ETag") },
  46. { HttpHeaderLocation , HEADER("Location") },
  47. { HttpHeaderProxyAuthenticate , HEADER("Proxy-Authenticate") },
  48. { HttpHeaderRetryAfter , HEADER("Retry-After") },
  49. // Set it to something which cannot be a header name, in effect
  50. // making Server an unknown header
  51. { HttpHeaderServer , HEADER("c:d\r\n") },
  52. // Set it to something which cannot be a header name, in effect
  53. // making Set-Cookie an unknown header
  54. { HttpHeaderSetCookie , HEADER("a:b\r\n") },
  55. { HttpHeaderVary , HEADER("Vary") },
  56. // Set it to something which cannot be a header name, in effect
  57. // making WWW-Authenticate an unknown header
  58. { HttpHeaderWwwAuthenticate , HEADER("b:c\r\n") }
  59. };
  60. HEADER_RECORD * * RESPONSE_HEADER_HASH::sm_ppSortedResponseHeaders = NULL;
  61. DWORD RESPONSE_HEADER_HASH::sm_cResponseHeaders =
  62. sizeof( RESPONSE_HEADER_HASH::sm_rgHeaders ) /
  63. sizeof( HEADER_RECORD );
  64. int _cdecl
  65. CompareResponseHeaderRecords(
  66. const void *pRecord1,
  67. const void *pRecord2 )
  68. /*++
  69. Routine Description:
  70. Comparison function for qsort
  71. Arguments:
  72. pRecord1
  73. pRecord2
  74. Return Value:
  75. <0 if Record1 < pRecord2
  76. =0 if Record1 == pRecord2
  77. >0 if Record1 > pRecord2
  78. --*/
  79. {
  80. return _stricmp( ( * (HEADER_RECORD **) pRecord1)->_pszName,
  81. ( * (HEADER_RECORD **) pRecord2)->_pszName );
  82. }
  83. int _cdecl
  84. CompareResponseHeaderRecordsForBSearch(
  85. const void *pKey,
  86. const void *pRecord )
  87. /*++
  88. Routine Description:
  89. Comparison function for qsort
  90. Arguments:
  91. pKey
  92. pRecord
  93. Return Value:
  94. <0 if Key < Record.Key
  95. =0 if Key == Record.Key
  96. >0 if Key > Record.Key
  97. --*/
  98. {
  99. return _stricmp( (CHAR *) (pKey),
  100. (*(HEADER_RECORD **) pRecord)->_pszName );
  101. }
  102. //static
  103. HRESULT
  104. RESPONSE_HEADER_HASH::Initialize(
  105. VOID
  106. )
  107. /*++
  108. Routine Description:
  109. Initialize global header hash table
  110. Arguments:
  111. None
  112. Return Value:
  113. HRESULT
  114. --*/
  115. {
  116. //
  117. // lkrhash used to be to translate header name to header index
  118. // RESPONSE_HEADER_HASH is array of constant number of elements
  119. // it is less expensive to sort it and then use bsearch to find the item
  120. //
  121. sm_ppSortedResponseHeaders =
  122. new HEADER_RECORD * [ sm_cResponseHeaders ];
  123. if ( sm_ppSortedResponseHeaders == NULL )
  124. {
  125. return HRESULT_FROM_WIN32( ERROR_OUTOFMEMORY );
  126. }
  127. for(DWORD i = 0; i < sm_cResponseHeaders; i++ )
  128. {
  129. sm_ppSortedResponseHeaders[i] = &sm_rgHeaders[i];
  130. }
  131. qsort((void*)sm_ppSortedResponseHeaders,
  132. sm_cResponseHeaders,
  133. sizeof( HEADER_RECORD *),
  134. CompareResponseHeaderRecords );
  135. return NO_ERROR;
  136. }
  137. //static
  138. VOID
  139. RESPONSE_HEADER_HASH::Terminate(
  140. VOID
  141. )
  142. /*++
  143. Routine Description:
  144. Global cleanup of header hash table
  145. Arguments:
  146. None
  147. Return Value:
  148. None
  149. --*/
  150. {
  151. if ( sm_ppSortedResponseHeaders != NULL )
  152. {
  153. delete [] sm_ppSortedResponseHeaders;
  154. }
  155. }
  156. //static
  157. ULONG
  158. RESPONSE_HEADER_HASH::GetIndex(
  159. CHAR * pszName
  160. )
  161. {
  162. HEADER_RECORD ** ppHdrRec =
  163. reinterpret_cast< HEADER_RECORD **>(
  164. bsearch( (void *) pszName,
  165. (void*)sm_ppSortedResponseHeaders,
  166. sm_cResponseHeaders,
  167. sizeof( HEADER_RECORD * ),
  168. CompareResponseHeaderRecordsForBSearch ) );
  169. if ( ppHdrRec != NULL )
  170. {
  171. return (*ppHdrRec)->_ulHeaderIndex;
  172. }
  173. else
  174. {
  175. return UNKNOWN_INDEX;
  176. }
  177. }