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.

399 lines
10 KiB

  1. /*++
  2. Copyright (c) 1998-2002 Microsoft Corporation
  3. Module Name:
  4. parse.h
  5. Abstract:
  6. Contains all of the public definitions for the HTTP parsing code.
  7. Author:
  8. Henry Sanders (henrysa) 04-May-1998
  9. Revision History:
  10. Paul McDaniel (paulmcd) 14-Apr-1999
  11. --*/
  12. #ifndef _PARSE_H_
  13. #define _PARSE_H_
  14. //
  15. // Constants
  16. //
  17. #define WILDCARD_SIZE (STRLEN_LIT("*/*") + sizeof(CHAR))
  18. #define WILDCARD_SPACE '*/* '
  19. #define WILDCARD_COMMA '*/*,'
  20. //
  21. // Size of Connection: header values
  22. //
  23. #define CONN_CLOSE_HDR "close"
  24. #define CONN_CLOSE_HDR_LENGTH STRLEN_LIT(CONN_CLOSE_HDR)
  25. #define CONN_KEEPALIVE_HDR "keep-alive"
  26. #define CONN_KEEPALIVE_HDR_LENGTH STRLEN_LIT(CONN_KEEPALIVE_HDR)
  27. #define CHUNKED_HDR "chunked"
  28. #define CHUNKED_HDR_LENGTH STRLEN_LIT(CHUNKED_HDR)
  29. #define MIN_VERSION_SIZE STRLEN_LIT("HTTP/1.1")
  30. #define STATUS_CODE_LENGTH 3
  31. #define HTTP_VERSION_11 "HTTP/1.1"
  32. #define HTTP_VERSION_10 "HTTP/1.0"
  33. #define HTTP_VERSION_OTHER "HTTP/"
  34. #define VERSION_SIZE STRLEN_LIT(HTTP_VERSION_11)
  35. #define VERSION_OTHER_SIZE STRLEN_LIT(HTTP_VERSION_OTHER)
  36. #define MAX_KNOWN_VERB_LENGTH STRLEN_LIT("PROPPATCH") + sizeof(CHAR)
  37. #define MAX_VERB_LENGTH 255
  38. // "HTTP/1.x" backwards because of endianness
  39. #define HTTP_11_VERSION 0x312e312f50545448ui64
  40. #define HTTP_10_VERSION 0x302e312f50545448ui64
  41. //
  42. // These are backwards because of little endian.
  43. //
  44. #define HTTP_PREFIX 'PTTH'
  45. #define HTTP_PREFIX_SIZE 4
  46. #define HTTP_PREFIX_MASK 0xdfdfdfdf
  47. C_ASSERT((HTTP_PREFIX & HTTP_PREFIX_MASK) == HTTP_PREFIX);
  48. #define HTTP_PREFIX1 '\0//:'
  49. #define HTTP_PREFIX1_SIZE 3
  50. #define HTTP_PREFIX1_MASK 0x00ffffff
  51. C_ASSERT((HTTP_PREFIX1 & HTTP_PREFIX1_MASK) == HTTP_PREFIX1);
  52. #define HTTP_PREFIX2 '//:S'
  53. #define HTTP_PREFIX2_SIZE 4
  54. #define HTTP_PREFIX2_MASK 0xffffffdf
  55. C_ASSERT((HTTP_PREFIX2 & HTTP_PREFIX2_MASK) == HTTP_PREFIX2);
  56. #define MAX_HEADER_LONG_COUNT (3)
  57. #define MAX_HEADER_LENGTH (MAX_HEADER_LONG_COUNT * sizeof(ULONGLONG))
  58. #define NUMBER_HEADER_INDICES (26)
  59. #define NUMBER_HEADER_HINT_INDICES (9)
  60. //
  61. // Default Server: header if none provided by the application.
  62. //
  63. #define DEFAULT_SERVER_HDR "Microsoft-HTTPAPI/1.0"
  64. #define DEFAULT_SERVER_HDR_LENGTH STRLEN_LIT(DEFAULT_SERVER_HDR)
  65. //
  66. // One second in 100ns system time units. Used for generating
  67. // Date: headers.
  68. //
  69. #define ONE_SECOND (10000000)
  70. //
  71. // Structure of the fast verb lookup table. The table consists of a series of
  72. // entries where each entry contains an HTTP verb represented as a ulonglong,
  73. // a mask to use for comparing that verb, the length of the verb, and the
  74. // translated id. This is used for all known verbs that are 7 characters
  75. // or less.
  76. //
  77. typedef struct _FAST_VERB_ENTRY
  78. {
  79. ULONGLONG RawVerbMask;
  80. union
  81. {
  82. UCHAR Char[sizeof(ULONGLONG)+1];
  83. ULONGLONG LongLong;
  84. } RawVerb;
  85. ULONG RawVerbLength;
  86. HTTP_VERB TranslatedVerb;
  87. } FAST_VERB_ENTRY, *PFAST_VERB_ENTRY;
  88. //
  89. // Macro for defining fast verb table entries. Note that we don't subtract 1
  90. // from the various sizeof occurences because we'd just have to add it back
  91. // in to account for the separating space.
  92. //
  93. #define CREATE_FAST_VERB_ENTRY(verb) \
  94. { \
  95. (0xffffffffffffffffui64 >> ((8 - (sizeof(#verb))) * 8)), \
  96. {#verb " "}, \
  97. (sizeof(#verb)), \
  98. HttpVerb##verb \
  99. }
  100. //
  101. // Stucture of the all verb lookup table. This table holds all verbs
  102. // that are too long to fit in the fast verb table.
  103. //
  104. typedef struct _LONG_VERB_ENTRY
  105. {
  106. ULONG RawVerbLength;
  107. UCHAR RawVerb[MAX_KNOWN_VERB_LENGTH];
  108. HTTP_VERB TranslatedVerb;
  109. } LONG_VERB_ENTRY, *PLONG_VERB_ENTRY;
  110. //
  111. // Macro for defining all long verb table entries.
  112. //
  113. #define CREATE_LONG_VERB_ENTRY(verb) \
  114. { sizeof(#verb) - 1, #verb, HttpVerb##verb }
  115. //
  116. // Header handler callback functions
  117. //
  118. typedef NTSTATUS (*PFN_SERVER_HEADER_HANDLER)(
  119. PUL_INTERNAL_REQUEST pRequest,
  120. PUCHAR pHeader,
  121. USHORT HeaderLength,
  122. HTTP_HEADER_ID HeaderID,
  123. ULONG * pBytesTaken
  124. );
  125. typedef NTSTATUS (*PFN_CLIENT_HEADER_HANDLER)(
  126. PUC_HTTP_REQUEST pRequest,
  127. PUCHAR pHeader,
  128. ULONG HeaderLength,
  129. HTTP_HEADER_ID HeaderID
  130. );
  131. //
  132. // Structure for a header map entry. Each header map entry contains a
  133. // verb and a series of masks to use in checking that verb.
  134. //
  135. typedef struct _HEADER_MAP_ENTRY
  136. {
  137. ULONG HeaderLength;
  138. ULONG ArrayCount;
  139. ULONG MinBytesNeeded;
  140. union
  141. {
  142. UCHAR HeaderChar[MAX_HEADER_LENGTH];
  143. ULONGLONG HeaderLong[MAX_HEADER_LONG_COUNT];
  144. } Header;
  145. ULONGLONG HeaderMask[MAX_HEADER_LONG_COUNT];
  146. UCHAR MixedCaseHeader[MAX_HEADER_LENGTH];
  147. HTTP_HEADER_ID HeaderID;
  148. BOOLEAN AutoGenerate;
  149. PFN_SERVER_HEADER_HANDLER pServerHandler;
  150. PFN_CLIENT_HEADER_HANDLER pClientHandler;
  151. LONG HintIndex;
  152. } HEADER_MAP_ENTRY, *PHEADER_MAP_ENTRY;
  153. //
  154. // Structure for a header index table entry.
  155. //
  156. typedef struct _HEADER_INDEX_ENTRY
  157. {
  158. PHEADER_MAP_ENTRY pHeaderMap;
  159. ULONG Count;
  160. } HEADER_INDEX_ENTRY, *PHEADER_INDEX_ENTRY;
  161. //
  162. // Structure for a header hint index table entry.
  163. //
  164. typedef struct _HEADER_HINT_INDEX_ENTRY
  165. {
  166. PHEADER_MAP_ENTRY pHeaderMap;
  167. UCHAR c;
  168. } HEADER_HINT_INDEX_ENTRY, *PHEADER_HINT_INDEX_ENTRY, **PPHEADER_HINT_INDEX_ENTRY;
  169. //
  170. // A (complex) macro to create a mask for a header map entry,
  171. // given the header length and the mask offset (in bytes). This
  172. // mask will need to be touched up for non-alphabetic characters.
  173. //
  174. #define UPCASE_MASK 0xDFDFDFDFDFDFDFDFui64
  175. #define CREATE_HEADER_MASK(hlength, maskoffset) \
  176. ((hlength) > (maskoffset) ? UPCASE_MASK : \
  177. (((maskoffset) - (hlength)) >= 8 ? 0 : \
  178. (UPCASE_MASK >> ( ((maskoffset) - (hlength)) * 8ui64))))
  179. //
  180. // Macro for creating header map entries. The mask entries are created
  181. // by the init code.
  182. //
  183. #define CREATE_HEADER_MAP_ENTRY(header, ID, auto, serverhandler, clienthandler, HintIndex)\
  184. { \
  185. sizeof(#header) - 1, \
  186. ((sizeof(#header) - 1) / 8) + \
  187. (((sizeof(#header) - 1) % 8) == 0 ? 0 : 1), \
  188. (((sizeof(#header) - 1) / 8) + \
  189. (((sizeof(#header) - 1) % 8) == 0 ? 0 : 1)) * 8, \
  190. { #header }, \
  191. { 0, 0, 0}, \
  192. { #header }, \
  193. ID, \
  194. auto, \
  195. serverhandler, \
  196. clienthandler, \
  197. HintIndex \
  198. }
  199. //
  200. // Parser states for parsing a chunk header extension.
  201. //
  202. typedef enum
  203. {
  204. CHStart,
  205. CHSeenCR,
  206. CHInChunkExtName,
  207. CHSeenChunkExtNameAndEquals,
  208. CHInChunkExtValToken,
  209. CHInChunkExtValQuotedString,
  210. CHSeenChunkExtValQuotedStringTerminator,
  211. CHSuccess,
  212. CHError
  213. } CH_PARSER_STATE, *PCH_PARSER_STATE;
  214. //
  215. // Parser states for parsing message header field content.
  216. //
  217. typedef enum
  218. {
  219. HFCStart,
  220. HFCSeenCR,
  221. HFCSeenLF,
  222. HFCSeenCRLF,
  223. HFCFolding,
  224. HFCInQuotedString
  225. } HFC_PARSER_STATE, *PHFC_PARSER_STATE;
  226. //
  227. // Parser states for parsing a quoted string.
  228. //
  229. typedef enum
  230. {
  231. QSInString,
  232. QSSeenBackSlash,
  233. QSSeenCR,
  234. QSSeenLF,
  235. QSSeenCRLF,
  236. QSFolding
  237. } QS_PARSER_STATE, *PQS_PARSER_STATE;
  238. //
  239. // External variables.
  240. //
  241. extern ULONG g_RequestHeaderMap[HttpHeaderMaximum];
  242. extern ULONG g_ResponseHeaderMap[HttpHeaderMaximum];
  243. extern HEADER_MAP_ENTRY g_RequestHeaderMapTable[];
  244. extern HEADER_MAP_ENTRY g_ResponseHeaderMapTable[];
  245. extern HEADER_INDEX_ENTRY g_RequestHeaderIndexTable[];
  246. extern HEADER_INDEX_ENTRY g_ResponseHeaderIndexTable[];
  247. extern HEADER_HINT_INDEX_ENTRY g_RequestHeaderHintIndexTable[];
  248. //
  249. // Function prototypes.
  250. //
  251. PUCHAR
  252. FindHexToken(
  253. IN PUCHAR pBuffer,
  254. IN ULONG BufferLength,
  255. OUT ULONG *TokenLength
  256. );
  257. NTSTATUS
  258. InitializeParser(
  259. VOID
  260. );
  261. ULONG
  262. UlpParseHttpVersion(
  263. PUCHAR pString,
  264. ULONG StringLength,
  265. PHTTP_VERSION pVersion
  266. );
  267. NTSTATUS
  268. FindHeaderEndReadOnly(
  269. IN PUCHAR pHeader,
  270. IN ULONG HeaderLength,
  271. OUT PULONG pBytesTaken
  272. );
  273. NTSTATUS
  274. FindHeaderEnd(
  275. IN PUCHAR pHeader,
  276. IN ULONG HeaderLength,
  277. OUT PULONG pBytesTaken
  278. );
  279. NTSTATUS
  280. FindRequestHeaderEnd(
  281. IN PUL_INTERNAL_REQUEST pRequest,
  282. IN PUCHAR pHeader,
  283. IN ULONG HeaderLength,
  284. OUT PULONG pBytesTaken
  285. );
  286. NTSTATUS
  287. FindChunkHeaderEnd(
  288. IN PUCHAR pHeader,
  289. IN ULONG HeaderLength,
  290. OUT PULONG pBytesTaken
  291. );
  292. NTSTATUS
  293. ParseChunkLength(
  294. IN ULONG FirstChunkParsed,
  295. IN PUCHAR pBuffer,
  296. IN ULONG BufferLength,
  297. OUT PULONG pBytesTaken,
  298. OUT PULONGLONG pChunkLength
  299. );
  300. NTSTATUS
  301. ParseQuotedString(
  302. IN PUCHAR pInput,
  303. IN ULONG InputLength,
  304. IN PUCHAR pOutput,
  305. OUT PULONG pBytesTaken
  306. );
  307. #endif // _PARSE_H_