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.

880 lines
28 KiB

  1. /*++
  2. Copyright (c) 2001-2002 Microsoft Corporation
  3. Module Name:
  4. HttpCmn.h
  5. Abstract:
  6. Declare general routines that appear on both sides of the
  7. HTTP blood-brain barrier (i.e., in both http.sys and httpapi.dll),
  8. but are not exported.
  9. Author:
  10. George V. Reilly (GeorgeRe) 11-Dec-2001
  11. Revision History:
  12. --*/
  13. #ifndef _HTTPCMN_H_
  14. #define _HTTPCMN_H_
  15. #include <tuneprefix.h>
  16. #define PREFAST_ASSUME(cond, reason) PREFIX_ASSUME(cond, reason)
  17. #define PREFAST_NOT_REACHED(reason) PREFIX_NOT_REACHED(reason)
  18. #if KERNEL_PRIV
  19. # define HttpCmnDebugBreak() DbgBreakPoint()
  20. # define HttpCmnDebugBreakOnError() UlDbgBreakOnError(__FILE__, __LINE__)
  21. #else // !KERNEL_PRIV => usermode code
  22. VOID
  23. __cdecl
  24. HttpCmnDbgPrint(
  25. IN PCH Format,
  26. ...
  27. );
  28. VOID
  29. HttpCmnDbgAssert(
  30. PCSTR pszAssert,
  31. PCSTR pszFilename,
  32. ULONG LineNumber
  33. );
  34. NTSTATUS
  35. HttpCmnDbgStatus(
  36. NTSTATUS Status,
  37. PCSTR pszFilename,
  38. ULONG LineNumber
  39. );
  40. VOID
  41. HttpCmnDbgBreakOnError(
  42. PCSTR pszFilename,
  43. ULONG LineNumber
  44. );
  45. # define HttpCmnDebugBreak() DebugBreak()
  46. # define HttpCmnDebugBreakOnError() \
  47. HttpCmnDbgBreakOnError(__FILE__, __LINE__)
  48. # define WriteGlobalStringLog HttpCmnDbgPrint
  49. #if HTTPAPI
  50. # define PAGED_CODE() NOP_FUNCTION
  51. typedef enum _POOL_TYPE {
  52. NonPagedPool,
  53. PagedPool
  54. } POOL_TYPE;
  55. #endif // HTTPAPI
  56. #endif // !KERNEL_PRIV
  57. #if DBG
  58. //
  59. // Debug spew control.
  60. // If you change or add a flag, please update the FlagTable
  61. // in ..\util\tul.c.
  62. //
  63. #define UL_DEBUG_OPEN_CLOSE 0x0000000000000001ui64
  64. #define UL_DEBUG_SEND_RESPONSE 0x0000000000000002ui64
  65. #define UL_DEBUG_SEND_BUFFER 0x0000000000000004ui64
  66. #define UL_DEBUG_TDI 0x0000000000000008ui64
  67. #define UL_DEBUG_FILE_CACHE 0x0000000000000010ui64
  68. #define UL_DEBUG_CONFIG_GROUP_FNC 0x0000000000000020ui64
  69. #define UL_DEBUG_CONFIG_GROUP_TREE 0x0000000000000040ui64
  70. #define UL_DEBUG_REFCOUNT 0x0000000000000080ui64
  71. #define UL_DEBUG_HTTP_IO 0x0000000000000100ui64
  72. #define UL_DEBUG_ROUTING 0x0000000000000200ui64
  73. #define UL_DEBUG_URI_CACHE 0x0000000000000400ui64
  74. #define UL_DEBUG_PARSER 0x0000000000000800ui64
  75. #define UL_DEBUG_SITE 0x0000000000001000ui64
  76. #define UL_DEBUG_WORK_ITEM 0x0000000000002000ui64
  77. #define UL_DEBUG_FILTER 0x0000000000004000ui64
  78. #define UL_DEBUG_LOGGING 0x0000000000008000ui64
  79. #define UL_DEBUG_TC 0x0000000000010000ui64
  80. #define UL_DEBUG_OPAQUE_ID 0x0000000000020000ui64
  81. #define UL_DEBUG_PERF_COUNTERS 0x0000000000040000ui64
  82. #define UL_DEBUG_URL_ACL 0x0000000000080000ui64
  83. #define UL_DEBUG_TIMEOUTS 0x0000000000100000ui64
  84. #define UL_DEBUG_LIMITS 0x0000000000200000ui64
  85. #define UL_DEBUG_LARGE_MEM 0x0000000000400000ui64
  86. #define UL_DEBUG_IOCTL 0x0000000000800000ui64
  87. #define UL_DEBUG_LOGBYTES 0x0000000001000000ui64
  88. #define UL_DEBUG_ETW 0x0000000002000000ui64
  89. #define UL_DEBUG_AUTH_CACHE 0x0000000004000000ui64
  90. #define UL_DEBUG_SERVINFO 0x0000000008000000ui64
  91. #define UL_DEBUG_BINARY_LOGGING 0x0000000010000000ui64
  92. #define UL_DEBUG_TDI_STATS 0x0000000020000000ui64
  93. #define UL_DEBUG_UL_ERROR 0x0000000040000000ui64
  94. #define UL_DEBUG_VERBOSE 0x0000000080000000ui64
  95. #define UL_DEBUG_ERROR_LOGGING 0x0000000100000000ui64
  96. #define UL_DEBUG_LOG_UTIL 0x0000000200000000ui64
  97. #undef IF_DEBUG
  98. #define IF_DEBUG(a) \
  99. if ( ((UL_DEBUG_ ## a) & g_UlDebug) != 0 )
  100. #define IF_DEBUG2EITHER(a, b) \
  101. if ( (((UL_DEBUG_ ## a) | (UL_DEBUG_ ## b)) & g_UlDebug) != 0 )
  102. #define IF_DEBUG2BOTH(a, b) \
  103. if ( (((UL_DEBUG_ ## a) | (UL_DEBUG_ ## b)) & g_UlDebug) \
  104. == ((UL_DEBUG_ ## a) | (UL_DEBUG_ ## b)) )
  105. //
  106. // Tracing.
  107. //
  108. extern ULONGLONG g_UlDebug;
  109. // Do NOT call UlTrace(%S, %ws, %ls, %wZ, %wc, %lc, or %C)
  110. // while a spinlock is held. The RtlUnicodeToMultiByte routines are
  111. // pageable and you may bugcheck.
  112. # define UlTrace(a, _b_) \
  113. do \
  114. { \
  115. IF_DEBUG(##a) \
  116. { \
  117. WriteGlobalStringLog _b_ ; \
  118. } \
  119. } while (0, 0)
  120. # define UlTrace2Either(a1, a2, _b_) \
  121. do \
  122. { \
  123. IF_DEBUG2EITHER(##a1, ##a2) \
  124. { \
  125. WriteGlobalStringLog _b_ ; \
  126. } \
  127. } while (0, 0)
  128. # define UlTrace2Both(a1, a2, _b_) \
  129. do \
  130. { \
  131. IF_DEBUG2BOTH(##a1, ##a2) \
  132. { \
  133. WriteGlobalStringLog _b_ ; \
  134. } \
  135. } while (0, 0)
  136. # define UlTraceVerbose(a, _b_) UlTrace2Both(a, VERBOSE, _b_)
  137. # define UlTraceError(a, _b_) \
  138. do \
  139. { \
  140. IF_DEBUG2EITHER(##a, ##UL_ERROR) \
  141. { \
  142. WriteGlobalStringLog _b_ ; \
  143. HttpCmnDebugBreakOnError(); \
  144. } \
  145. } while (0, 0)
  146. VOID
  147. HttpFillBuffer(
  148. PUCHAR pBuffer,
  149. SIZE_T BufferLength
  150. );
  151. # define HTTP_FILL_BUFFER(pBuffer, BufferLength) \
  152. HttpFillBuffer((PUCHAR) pBuffer, BufferLength)
  153. # if !KERNEL_PRIV
  154. # define RETURN(status) \
  155. return HttpCmnDbgStatus((status), __FILE__, __LINE__)
  156. # undef ASSERT
  157. # define ASSERT(x) \
  158. ((void) ((x) || (HttpCmnDbgAssert(#x, __FILE__, __LINE__), 0) ))
  159. # endif // !KERNEL_PRIV
  160. #else // !DBG
  161. # undef IF_DEBUG
  162. # define IF_DEBUG(a) if (FALSE)
  163. # define IF_DEBUG2EITHER(a, b) if (FALSE)
  164. # define IF_DEBUG2BOTH(a, b) if (FALSE)
  165. # define UlTrace(a, _b_) NOP_FUNCTION
  166. # define UlTrace2Either(a1, a2, _b_) NOP_FUNCTION
  167. # define UlTrace2Both(a1, a2, _b_) NOP_FUNCTION
  168. # define UlTrace3Any(a1, a2, a3, _b_) NOP_FUNCTION
  169. # define UlTrace3All(a1, a2, a3, _b_) NOP_FUNCTION
  170. # define UlTraceVerbose(a, _b_) NOP_FUNCTION
  171. # define UlTraceError(a, _b_) NOP_FUNCTION
  172. # define HTTP_FILL_BUFFER(pBuffer, BufferLength) NOP_FUNCTION
  173. # if !KERNEL_PRIV
  174. # define RETURN(status) return (status)
  175. # undef ASSERT
  176. # define ASSERT(x) NOP_FUNCTION
  177. # endif // !KERNEL_PRIV
  178. #endif // !DBG
  179. PCSTR
  180. HttpStatusToString(
  181. NTSTATUS Status
  182. );
  183. typedef const UCHAR* PCUCHAR;
  184. typedef const VOID* PCVOID;
  185. VOID
  186. HttpCmnInitializeHttpCharsTable(
  187. BOOLEAN EnableDBCS
  188. );
  189. char*
  190. strnchr(
  191. const char* string,
  192. char c,
  193. size_t count
  194. );
  195. wchar_t*
  196. wcsnchr(
  197. const wchar_t* string,
  198. wint_t c,
  199. size_t count
  200. );
  201. // 2^16-1 + '\0'
  202. #define MAX_USHORT_STR ((ULONG) sizeof("65535"))
  203. // 2^32-1 + '\0'
  204. #define MAX_ULONG_STR ((ULONG) sizeof("4294967295"))
  205. // 2^64-1 + '\0'
  206. #define MAX_ULONGLONG_STR ((ULONG) sizeof("18446744073709551615"))
  207. NTSTATUS
  208. HttpStringToULongLong(
  209. IN BOOLEAN IsUnicode,
  210. IN PCVOID pString,
  211. IN SIZE_T StringLength,
  212. IN BOOLEAN LeadingZerosAllowed,
  213. IN ULONG Base,
  214. OUT PVOID* ppTerminator,
  215. OUT PULONGLONG pValue
  216. );
  217. __inline
  218. NTSTATUS
  219. HttpAnsiStringToULongLong(
  220. IN PCUCHAR pString,
  221. IN SIZE_T StringLength,
  222. IN BOOLEAN LeadingZerosAllowed,
  223. IN ULONG Base,
  224. OUT PUCHAR* ppTerminator,
  225. OUT PULONGLONG pValue
  226. )
  227. {
  228. return HttpStringToULongLong(
  229. FALSE,
  230. pString,
  231. StringLength,
  232. LeadingZerosAllowed,
  233. Base,
  234. (PVOID*) ppTerminator,
  235. pValue
  236. );
  237. }
  238. __inline
  239. NTSTATUS
  240. HttpWideStringToULongLong(
  241. IN PCWSTR pString,
  242. IN SIZE_T StringLength,
  243. IN BOOLEAN LeadingZerosAllowed,
  244. IN ULONG Base,
  245. OUT PWSTR* ppTerminator,
  246. OUT PULONGLONG pValue
  247. )
  248. {
  249. return HttpStringToULongLong(
  250. TRUE,
  251. pString,
  252. StringLength,
  253. LeadingZerosAllowed,
  254. Base,
  255. (PVOID*) ppTerminator,
  256. pValue
  257. );
  258. }
  259. NTSTATUS
  260. HttpStringToULong(
  261. IN BOOLEAN IsUnicode,
  262. IN PCVOID pString,
  263. IN SIZE_T StringLength,
  264. IN BOOLEAN LeadingZerosAllowed,
  265. IN ULONG Base,
  266. OUT PVOID* ppTerminator,
  267. OUT PULONG pValue
  268. );
  269. __inline
  270. NTSTATUS
  271. HttpAnsiStringToULong(
  272. IN PCUCHAR pString,
  273. IN SIZE_T StringLength,
  274. IN BOOLEAN LeadingZerosAllowed,
  275. IN ULONG Base,
  276. OUT PUCHAR* ppTerminator,
  277. OUT PULONG pValue
  278. )
  279. {
  280. return HttpStringToULong(
  281. FALSE,
  282. pString,
  283. StringLength,
  284. LeadingZerosAllowed,
  285. Base,
  286. (PVOID*) ppTerminator,
  287. pValue
  288. );
  289. }
  290. __inline
  291. NTSTATUS
  292. HttpWideStringToULong(
  293. IN PCWSTR pString,
  294. IN SIZE_T StringLength,
  295. IN BOOLEAN LeadingZerosAllowed,
  296. IN ULONG Base,
  297. OUT PWSTR* ppTerminator,
  298. OUT PULONG pValue
  299. )
  300. {
  301. return HttpStringToULong(
  302. TRUE,
  303. pString,
  304. StringLength,
  305. LeadingZerosAllowed,
  306. Base,
  307. (PVOID*) ppTerminator,
  308. pValue
  309. );
  310. }
  311. NTSTATUS
  312. HttpStringToUShort(
  313. IN BOOLEAN IsUnicode,
  314. IN PCVOID pString,
  315. IN SIZE_T StringLength,
  316. IN BOOLEAN LeadingZerosAllowed,
  317. IN ULONG Base,
  318. OUT PVOID* ppTerminator,
  319. OUT PUSHORT pValue
  320. );
  321. __inline
  322. NTSTATUS
  323. HttpAnsiStringToUShort(
  324. IN PCUCHAR pString,
  325. IN SIZE_T StringLength,
  326. IN BOOLEAN LeadingZerosAllowed,
  327. IN ULONG Base,
  328. OUT PUCHAR* ppTerminator,
  329. OUT PUSHORT pValue
  330. )
  331. {
  332. return HttpStringToUShort(
  333. FALSE,
  334. pString,
  335. StringLength,
  336. LeadingZerosAllowed,
  337. Base,
  338. (PVOID*) ppTerminator,
  339. pValue
  340. );
  341. }
  342. __inline
  343. NTSTATUS
  344. HttpWideStringToUShort(
  345. IN PCWSTR pString,
  346. IN SIZE_T StringLength,
  347. IN BOOLEAN LeadingZerosAllowed,
  348. IN ULONG Base,
  349. OUT PWSTR* ppTerminator,
  350. OUT PUSHORT pValue
  351. )
  352. {
  353. return HttpStringToUShort(
  354. TRUE,
  355. pString,
  356. StringLength,
  357. LeadingZerosAllowed,
  358. Base,
  359. (PVOID*) ppTerminator,
  360. pValue
  361. );
  362. }
  363. //
  364. // ASCII constants
  365. //
  366. #define HT 0x09 // aka TAB
  367. #define LF 0x0A // aka NL, New Line
  368. #define VT 0x0B // Vertical TAB
  369. #define FF 0x0C // Form Feed
  370. #define CR 0x0D // Carriage Return
  371. #define SP 0x20 // Space
  372. #define DOUBLE_QUOTE 0x22 // "
  373. #define PERCENT 0x25 // %
  374. #define STAR 0x2A // *
  375. #define HYPHEN 0x2D // - aka Minus aka Dash
  376. #define DOT 0x2E // . aka Period aka Full Stop
  377. #define FORWARD_SLASH 0x2F // /
  378. #define ZERO 0x30 // 0
  379. #define COLON 0x3A // :
  380. #define SEMI_COLON 0x3B // ;
  381. #define EQUALS 0x3D // =
  382. #define QUESTION_MARK 0x3F // ? aka Query
  383. #define LEFT_BRACKET 0x5B // [ aka Left Square Bracket
  384. #define BACK_SLASH 0x5C // \ aka Whack
  385. #define RIGHT_BRACKET 0x5D // ] aka Right Square Bracket
  386. // Fast toupper() and tolower() macros that work for [A-Z] and [a-z] only
  387. #if DBG
  388. # define UPCASE_CHAR(c) \
  389. ( (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z')) \
  390. ? ((UCHAR) ((c) & 0xdf)) \
  391. : (ASSERT(! "non-alpha UPCASE_CHAR"), 0) )
  392. # define LOCASE_CHAR(c) \
  393. ( (('A' <= (c) && (c) <= 'Z') || ('a' <= (c) && (c) <= 'z')) \
  394. ? ((UCHAR) ((c) | 0x20)) \
  395. : (ASSERT(! "non-alpha LOCASE_CHAR"), 0) )
  396. #else // !DBG
  397. # define UPCASE_CHAR(c) ((UCHAR) ((c) & 0xdf))
  398. # define LOCASE_CHAR(c) ((UCHAR) ((c) | 0x20))
  399. #endif // !DBG
  400. //
  401. // Character classes for HTTP header and URL parsing.
  402. // For header parsing, the definitions are taken from RFC 2616, "HTTP/1.1"
  403. // For URL parsing, the definitions are from RFC 2396, "URI Generic Syntax"
  404. // and RFC 2732, "IPv6 Literals in URLs".
  405. //
  406. // Per RFC 2616, section 2.2, "Basic Rules":
  407. // OCTET = <any 8-bit sequence of data>
  408. // CHAR = <any US-ASCII character (octets 0 - 127)>
  409. // TEXT = <any OCTET except CTLs, but including LWS>
  410. // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
  411. #define HTTP_CTL_SET \
  412. "\x00" "\x01" "\x02" "\x03" "\x04" "\x05" "\x06" "\x07" \
  413. "\x08" "\x09" "\x0A" "\x0B" "\x0C" "\x0D" "\x0E" "\x0F" \
  414. "\x10" "\x11" "\x12" "\x13" "\x14" "\x15" "\x16" "\x17" \
  415. "\x18" "\x19" "\x1A" "\x1B" "\x1C" "\x1D" "\x1E" "\x1F" \
  416. "\x7F"
  417. // In the Unicode ISO-10646 character set, these are also control chars
  418. #define UNICODE_C1_SET \
  419. "\x80" "\x81" "\x82" "\x83" "\x84" "\x85" "\x86" "\x87" \
  420. "\x88" "\x89" "\x8A" "\x8B" "\x8C" "\x8D" "\x8E" "\x8F" \
  421. "\x90" "\x91" "\x92" "\x93" "\x94" "\x95" "\x96" "\x97" \
  422. "\x98" "\x99" "\x9A" "\x9B" "\x9C" "\x9D" "\x9E" "\x9F"
  423. // UPALPHA = <any US-ASCII uppercase letter "A".."Z">
  424. #define HTTP_UPALPHA_SET \
  425. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  426. // LOALPHA = <any US-ASCII lowercase letter "a".."z">
  427. #define HTTP_LOALPHA_SET \
  428. "abcdefghijklmnopqrstuvwxyz"
  429. // ALPHA = (UPALPHA | LOALPHA)
  430. #define HTTP_ALPHA_SET \
  431. HTTP_UPALPHA_SET HTTP_LOALPHA_SET
  432. // DIGIT = <any US-ASCII digit "0".."9">
  433. #define HTTP_DIGITS_SET \
  434. "0123456789"
  435. // ALPHANUM = (ALPHA | DIGIT)
  436. #define HTTP_ALPHANUM_SET \
  437. HTTP_ALPHA_SET HTTP_DIGITS_SET
  438. // HEX = (DIGIT | "A".."F" | "a".."f")
  439. #define HTTP_HEX_SET \
  440. HTTP_DIGITS_SET "ABCDEF" "abcdef"
  441. // SP = US-ASCII 32, the space character
  442. #define HTTP_SPACE_SET \
  443. "\x20"
  444. // LWS = (SP | HT) -- Linear White Space
  445. // Note: Folding is handled specially
  446. #define HTTP_LWS_SET \
  447. HTTP_SPACE_SET "\t"
  448. // separators = characters that delimit tokens in HTTP headers
  449. // token = 1*<any 7-bit CHAR except CTLs or separators>
  450. #define HTTP_SEPARATORS_SET \
  451. "(" ")" "<" ">" "@" \
  452. "," ";" ":" "\"" "\\" \
  453. "/" "[" "]" "?" "=" \
  454. "{" "}" HTTP_LWS_SET
  455. // Whitespace tokens: (CR | LF | SP | HT)
  456. #define HTTP_WS_TOKEN_SET \
  457. "\r" "\n" HTTP_LWS_SET
  458. // IsWhite : (CTL | SP)
  459. // this is used by the logger, not the parser.
  460. // Removed the "\xA0", it will break foreign
  461. // language multibyte utf8 sequences.
  462. #define HTTP_ISWHITE_SET \
  463. HTTP_CTL_SET HTTP_SPACE_SET
  464. //
  465. // Now the URL character classes from RFC 2396, as modified by RFC 2732.
  466. //
  467. // Limited set of punctuation marks that can appear literally in URLs
  468. #define URL_MARK_SET \
  469. "-" "_" "." "!" "~" "*" "'" "(" ")"
  470. // Alphanumerics and marks can always appear literally in URLs
  471. #define URL_UNRESERVED_SET \
  472. HTTP_ALPHANUM_SET URL_MARK_SET
  473. // RFC2396 describes these characters as `unwise' "because gateways and
  474. // other transport agents are known to sometimes modify such characters,
  475. // or they are used as delimiters".
  476. //
  477. // Note: RFC2732 removed "[" and "]" from the 'unwise' set and added
  478. // them to the 'reserved' set, so that IPv6 literals could be
  479. // expressed in URLs.
  480. #define URL_UNWISE_SET \
  481. "{" "}" "|" "\\" "^" "`"
  482. // These characters have special meanings if they appear unescaped in a URI
  483. #define URL_RESERVED_SET \
  484. ";" "/" "?" ":" "@" "&" "=" "+" \
  485. "$" "," "[" "]"
  486. // The delimiters are excluded from URLs because they typically delimit URLs
  487. // when they appear in other contexts.
  488. #define URL_DELIMS_SET \
  489. "<" ">" "#" "%" "\""
  490. // BACK_SLASH, FORWARD_SLASH, PERCENT, DOT, and QUESTION_MARK are
  491. // the "dirty" chars. These are used to determine if the host or URL
  492. // are clean to take the fast path in converting them to Unicode.
  493. // The delimiters are also considered dirty, to simplify the fast path.
  494. // All octets above the US-ASCII range (i.e., >= 128) are also considered dirty
  495. #define URL_DIRTY_SET \
  496. "\\" "/" "." "?" URL_DELIMS_SET
  497. // These characters are not valid in the abspath part of a URL after it has
  498. // been canonicalized to Unicode. CODEWORK: What about '%' (double escaping)?
  499. // According to MSDN, invalid characters in file and directory names are
  500. // < > : " / \ |
  501. // CODEWORK: temporarily removed ":". Do this smarter.
  502. #define URL_INVALID_SET \
  503. HTTP_CTL_SET UNICODE_C1_SET
  504. // Valid characters in hostnames are letters, digits, and hyphens, per RFC 1034
  505. // We also allow underscores.
  506. #define URL_HOSTNAME_LABEL_LDH_SET \
  507. HTTP_ALPHANUM_SET "-" "_"
  508. // Characters that are illegal in an NT computer name, as taken from
  509. // NetValidateName(): %sdxroot%\ds\netapi\netlib\nameval.c and
  510. // %sdxroot%\public\internal\base\inc\validc.h
  511. // " / \ [ ] : | < > + = ; , ? * and CTL chars
  512. // Also added " " (SP) and "%" to this list
  513. #define URL_ILLEGAL_COMPUTERNAME_SET \
  514. "\"" "/" "\\" "[" "]" ":" "|" " " "%" \
  515. "<" ">" "+" "=" ";" "," "?" "*" \
  516. HTTP_CTL_SET
  517. //
  518. // Bit flags in HttpChars[]
  519. //
  520. extern ULONG HttpChars[256];
  521. #define HTTP_CHAR (1 << 0x00)
  522. #define HTTP_UPCASE (1 << 0x01)
  523. #define HTTP_LOCASE (1 << 0x02)
  524. #define HTTP_ALPHA (HTTP_UPCASE | HTTP_LOCASE)
  525. #define HTTP_DIGIT (1 << 0x03)
  526. #define HTTP_ALPHANUM (HTTP_ALPHA | HTTP_DIGIT)
  527. #define HTTP_CTL (1 << 0x04)
  528. #define HTTP_LWS (1 << 0x05)
  529. #define HTTP_HEX (1 << 0x06)
  530. #define HTTP_SEPARATOR (1 << 0x07)
  531. #define HTTP_TOKEN (1 << 0x08)
  532. #define HTTP_WS_TOKEN (1 << 0x09)
  533. #define HTTP_ISWHITE (1 << 0x0A)
  534. #define HTTP_PRINT (1 << 0x0B)
  535. #define HTTP_TEXT (1 << 0x0C)
  536. #define HTTP_DBCS_LEAD_BYTE (1 << 0x0D)
  537. #define URL_DIRTY (1 << 0x0E)
  538. #define URL_LEGAL (1 << 0x0F)
  539. #define URL_TOKEN (HTTP_ALPHA | HTTP_DIGIT | URL_LEGAL)
  540. #define URL_HOSTNAME_LABEL (1 << 0x10)
  541. #define URL_INVALID (1 << 0x11)
  542. #define URL_ILLEGAL_COMPUTERNAME (1 << 0x12)
  543. // Use bits 31,30 in HttpChars[] to perform table lookup in URI canonicalizer
  544. #define HTTP_CHAR_SHIFT (0x1E)
  545. #define HTTP_CHAR_SLASH (1 << HTTP_CHAR_SHIFT)
  546. #define HTTP_CHAR_DOT (2 << HTTP_CHAR_SHIFT)
  547. #define HTTP_CHAR_QM_HASH (3 << HTTP_CHAR_SHIFT)
  548. //
  549. // These character type macros are safe for 8-bit data only.
  550. // We cast the argument to a UCHAR, so you'll never overflow, but you'll
  551. // get nonsense if you pass in an arbitrary Unicode character. For Unicode
  552. // characters, only the first 128 values (the US-ASCII range) make sense.
  553. //
  554. #define IS_CHAR_TYPE(c, mask) (HttpChars[(UCHAR)(c)] & (mask))
  555. // CHAR = <any US-ASCII character (octets 0 - 127)>
  556. #define IS_HTTP_CHAR(c) IS_CHAR_TYPE(c, HTTP_CHAR)
  557. // HTTP_UPALPHA_SET = <any US-ASCII uppercase letter "A".."Z">
  558. #define IS_HTTP_UPCASE(c) IS_CHAR_TYPE(c, HTTP_UPCASE)
  559. // HTTP_LOALPHA_SET = <any US-ASCII lowercase letter "a".."z">
  560. #define IS_HTTP_LOCASE(c) IS_CHAR_TYPE(c, HTTP_LOCASE)
  561. // HTTP_ALPHA_SET = <"A".."Z", "a".."z">
  562. #define IS_HTTP_ALPHA(c) IS_CHAR_TYPE(c, HTTP_ALPHA)
  563. // HTTP_DIGITS_SET = <any US-ASCII digit "0".."9">
  564. #define IS_HTTP_DIGIT(c) IS_CHAR_TYPE(c, HTTP_DIGIT)
  565. // HTTP_ALPHANUM_SET = <"A".."Z", "a".."z", "0".."9">
  566. #define IS_HTTP_ALPHANUM(c) IS_CHAR_TYPE(c, HTTP_ALPHANUM)
  567. // HTTP_CTL_SET = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
  568. #define IS_HTTP_CTL(c) IS_CHAR_TYPE(c, HTTP_CTL)
  569. // HTTP_LWS_SET = (SP | HT) -- Linear White Space
  570. #define IS_HTTP_LWS(c) IS_CHAR_TYPE(c, HTTP_LWS)
  571. // HTTP_HEX_SET = <"0".."9", "A".."F", "a".."f">
  572. #define IS_HTTP_HEX(c) IS_CHAR_TYPE(c, HTTP_HEX)
  573. // HTTP_SEPARATORS_SET = ( ) < > @ , ; : " \ / [ ] ? = { } SP HT
  574. #define IS_HTTP_SEPARATOR(c) IS_CHAR_TYPE(c, HTTP_SEPARATOR)
  575. // token = 1*<any 7-bit CHAR except CTLs or separators>
  576. // ! # $ % & ' * + - . 0..9 A..Z ^ _ ` a..z | ~
  577. #define IS_HTTP_TOKEN(c) IS_CHAR_TYPE(c, HTTP_TOKEN)
  578. // HTTP_WS_TOKEN_SET = (CR | LF | SP | HT)
  579. #define IS_HTTP_WS_TOKEN(c) IS_CHAR_TYPE(c, HTTP_WS_TOKEN)
  580. // HTTP_ISWHITE_SET = (CTL | SP)
  581. #define IS_HTTP_WHITE(c) IS_CHAR_TYPE(c, HTTP_ISWHITE)
  582. // PRINT = <any OCTET except CTLs, but including SP and HT>
  583. #define IS_HTTP_PRINT(c) IS_CHAR_TYPE(c, HTTP_PRINT)
  584. // TEXT = <any OCTET except CTLs, but including SP, HT, CR, and LF>
  585. #define IS_HTTP_TEXT(c) IS_CHAR_TYPE(c, HTTP_TEXT)
  586. // DBCS lead bytes
  587. #define IS_DBCS_LEAD_BYTE(c) IS_CHAR_TYPE(c, HTTP_DBCS_LEAD_BYTE)
  588. // URL_DIRTY_SET = \ / % . ? | URL_DELIMS_SET
  589. #define IS_URL_DIRTY(c) IS_CHAR_TYPE(c, URL_DIRTY)
  590. // URL_TOKEN_SET = (HTTP_ALPHA_SET | HTTP_DIGITS_SET | URL_MARK_SET
  591. // | URL_RESERVED_SET| URL_UNWISE_SET | % )
  592. #define IS_URL_TOKEN(c) IS_CHAR_TYPE(c, URL_TOKEN)
  593. // URL_HOSTNAME_LABEL_LDH_SET = (HTTP_ALPHANUM_SET | - | _ )
  594. #define IS_URL_HOSTNAME_LABEL(c) IS_CHAR_TYPE(c, URL_HOSTNAME_LABEL)
  595. // URL_INVALID_SET = (HTTP_CTL_SET | UNICODE_C1_SET)
  596. #define IS_URL_INVALID(c) IS_CHAR_TYPE(c, URL_INVALID)
  597. // URL_ILLEGAL_COMPUTERNAME_SET =
  598. // " / \ [ ] : | < > + = ; , ? * and HTTP_CTL_SET
  599. #define IS_URL_ILLEGAL_COMPUTERNAME(c) IS_CHAR_TYPE(c, URL_ILLEGAL_COMPUTERNAME)
  600. #define ASCII_MAX 0x007f
  601. #define ANSI_HIGH_MIN 0x0080
  602. #define ANSI_HIGH_MAX 0x00ff
  603. #define IS_ASCII(c) ((unsigned) (c) <= ASCII_MAX)
  604. #define IS_ANSI(c) ((unsigned) (c) <= ANSI_HIGH_MAX)
  605. #define IS_HIGH_ANSI(c) \
  606. (ANSI_HIGH_MIN <= (unsigned) (c) && (unsigned) (c) <= ANSI_HIGH_MAX)
  607. //
  608. // Other lookup tables
  609. //
  610. extern WCHAR FastPopChars[256];
  611. extern WCHAR DummyPopChars[256];
  612. extern WCHAR FastUpcaseChars[256];
  613. extern WCHAR AnsiToUnicodeMap[256];
  614. //
  615. // Length of string literals in chars; e.g., WSCLEN_LIT(L"https://")
  616. // Must NOT be used with char* pointers.
  617. //
  618. #define STRLEN_LIT(sz) ((USHORT) (sizeof(sz) - sizeof(CHAR)))
  619. #define WCSLEN_LIT_BYTES(wsz) ((USHORT) (sizeof(wsz) - sizeof(WCHAR)))
  620. #define WCSLEN_LIT(wsz) ((USHORT) (WCSLEN_LIT_BYTES(wsz) / sizeof(WCHAR)))
  621. //
  622. // Calculate the dimension of an array.
  623. //
  624. #define DIMENSION(x) ( sizeof(x) / sizeof(x[0]) )
  625. //
  626. // nice MIN/MAX macros
  627. //
  628. #define MIN(a,b) ( ((a) > (b)) ? (b) : (a) )
  629. #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
  630. //
  631. // These definitions allow for a trailing NUL in a counted string,
  632. // such as a UNICODE_STRING, a HTTP_COOKED_URL, or a HTTP_KNOWN_HEADER.
  633. //
  634. #define UNICODE_STRING_MAX_WCHAR_LEN 0x7FFE
  635. #define UNICODE_STRING_MAX_BYTE_LEN (UNICODE_STRING_MAX_WCHAR_LEN*sizeof(WCHAR))
  636. #define ANSI_STRING_MAX_CHAR_LEN 0xFFFE
  637. //
  638. // Cache line requirement.
  639. //
  640. #ifdef _WIN64
  641. # define UL_CACHE_LINE 64
  642. #else
  643. # define UL_CACHE_LINE 32
  644. #endif
  645. //
  646. // The DIFF macro should be used around an expression involving pointer
  647. // subtraction. The expression passed to DIFF is cast to a ULONG type.
  648. // This is safe because we never handle buffers bigger than 4GB,
  649. // even on Win64, and we guarantee that the argument is non-negative.
  650. // DIFF_USHORT is the obvious USHORT variant.
  651. //
  652. #define DIFF(x) ((ULONG)(x))
  653. #define DIFF_USHORT(x) ((USHORT)(x))
  654. #define DIFF_ULONGPTR(x) ((ULONG_PTR)(x))
  655. // 2^16-1 = 65535 = 5 chars = 5 bytes
  656. #define MAX_PORT_LENGTH 5
  657. // Max size of numeric form of IPv6 address (in chars)
  658. // �1234:6789:1234:6789:1234:6789:123.123.123.123� + '\0'
  659. #define INET6_RAWADDRSTRLEN 46
  660. // Maximum length of an IPv6 scoped address (in chars)
  661. // INET6_RAWADDRSTRLEN + "%1234567890"
  662. #define MAX_IP_ADDR_STRING_LEN (INET6_RAWADDRSTRLEN + 11)
  663. // Maximum length of an IPv6 scoped address (in chars)
  664. // "[" + INET6_RAWADDRSTRLEN + "%1234567890" + "]"
  665. #define MAX_IP_ADDR_PLUS_BRACKETS_STRING_LEN (MAX_IP_ADDR_STRING_LEN + 2)
  666. // Maximum length of an IPv6 scoped address and port (in chars)
  667. // "[" + MAX_IP_ADDR_STRING_LEN + ":65535]"
  668. #define MAX_IP_ADDR_AND_PORT_STRING_LEN (MAX_IP_ADDR_STRING_LEN + 8)
  669. VOID
  670. HttpCmnInitAllocator(
  671. VOID
  672. );
  673. VOID
  674. HttpCmnTermAllocator(
  675. VOID
  676. );
  677. PVOID
  678. HttpCmnAllocate(
  679. IN POOL_TYPE PoolType,
  680. IN SIZE_T NumBytes,
  681. IN ULONG PoolTag,
  682. IN PCSTR pFileName,
  683. IN USHORT LineNumber);
  684. VOID
  685. HttpCmnFree(
  686. IN PVOID pMem,
  687. IN ULONG PoolTag,
  688. IN PCSTR pFileName,
  689. IN USHORT LineNumber);
  690. #define HTTPP_ALLOC(PoolType, NumBytes, PoolTag) \
  691. HttpCmnAllocate((PoolType), (NumBytes), (PoolTag), __FILE__, __LINE__)
  692. #define HTTPP_FREE(pMem, PoolTag) \
  693. HttpCmnFree((pMem), (PoolTag), __FILE__, __LINE__)
  694. #endif // _HTTPCMN_H_