windows-nt/Source/XPSP1/NT/inetsrv/iis/iisrearc/ulrtl/parsep.h
2020-09-26 16:20:57 +08:00

283 lines
6.8 KiB
C

/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
parsep.h
Abstract:
Contains all of the kernel mode HTTP parsing code.
Author:
Henry Sanders (henrysa) 04-May-1998
Revision History:
--*/
#ifndef _PARSEP_H_
#define _PARSEP_H_
#define MIN_VERSION_SIZE (sizeof("HTTP/1.1") - 1)
#define MAX_VERB_LENGTH (sizeof("PROPPATCH"))
#define HTTP_11_VERSION 0x312e312f50545448
#define HTTP_10_VERSION 0x302e312f50545448
#define UPCASE_MASK ((ULONGLONG)0xdfdfdfdfdfdfdfdf)
#define MAX_HEADER_LONG_COUNT 3
#define MAX_HEADER_LENGTH (MAX_HEADER_LONG_COUNT * sizeof(ULONGLONG))
#define NUMBER_HEADER_INDICIES 26
//
// Default Server: header if none provided by the application.
//
#define DEFAULT_SERVER_HDR "Microsoft-IIS/UL"
#define DEFAULT_SERVER_HDR_LENGTH (sizeof(DEFAULT_SERVER_HDR) - sizeof(CHAR))
//
// Size of a Date: value if we need to generate it ourselves.
//
#define DATE_HDR_LENGTH (sizeof("Thu, 26 Aug 1999 17:14:02 GMT") - sizeof(CHAR))
//
// Size of Connection: header values
//
#define CONN_CLOSE_HDR "close"
#define CONN_CLOSE_HDR_LENGTH (sizeof(CONN_CLOSE_HDR) - sizeof(CHAR))
#define CONN_KEEPALIVE_HDR "keep-alive"
#define CONN_KEEPALIVE_HDR_LENGTH (sizeof(CONN_KEEPALIVE_HDR) - sizeof(CHAR))
//
// These are backwards because of little endian.
//
#define HTTP_PREFIX 'PTTH'
#define HTTP_PREFIX_SIZE 4
#define HTTP_PREFIX_MASK 0xdfdfdfdf
#define HTTP_PREFIX1 '\0//:'
#define HTTP_PREFIX1_SIZE 3
#define HTTP_PREFIX1_MASK 0x00ffffff
#define HTTP_PREFIX2 '//:S'
#define HTTP_PREFIX2_SIZE 4
#define HTTP_PREFIX2_MASK 0xffffffdf
typedef NTSTATUS (*PFN_HEADER_HANDLER)(
PUL_INTERNAL_REQUEST pRequest,
PUCHAR pHttpRequest,
ULONG HttpRequestLength,
HTTP_HEADER_ID HeaderID,
ULONG * pBytesTaken
);
//
// Structure of the fast verb lookup table. The table consists of a series of
// entries where each entry contains an HTTP verb represented as a ulonglong,
// a mask to use for comparing that verb, the length of the verb and the
// translated id.
//
typedef struct _FAST_VERB_ENTRY
{
union
{
UCHAR Char[sizeof(ULONGLONG)+1];
ULONGLONG LongLong;
} RawVerb;
ULONGLONG RawVerbMask;
ULONG RawVerbLength;
HTTP_VERB TranslatedVerb;
} FAST_VERB_ENTRY, *PFAST_VERB_ENTRY;
//
// Stucture of the all verb lookup table. This table holds all verbs that
// we understand, including those that are too long to fit in the fast
// verb table.
//
typedef struct _LONG_VERB_ENTRY
{
ULONG RawVerbLength;
UCHAR RawVerb[MAX_VERB_LENGTH];
HTTP_VERB TranslatedVerb;
} LONG_VERB_ENTRY, *PLONG_VERB_ENTRY;
//
// Structure for a header map entry. Each header map entry contains a
// verb and a series of masks to use in checking that verb.
//
typedef struct _HEADER_MAP_ENTRY
{
ULONG HeaderLength;
ULONG ArrayCount;
ULONG MinBytesNeeded;
union
{
UCHAR HeaderChar[MAX_HEADER_LENGTH];
ULONGLONG HeaderLong[MAX_HEADER_LONG_COUNT];
} Header;
ULONGLONG HeaderMask[MAX_HEADER_LONG_COUNT];
UCHAR MixedCaseHeader[MAX_HEADER_LENGTH];
HTTP_HEADER_ID HeaderID;
PFN_HEADER_HANDLER pHandler;
} HEADER_MAP_ENTRY, *PHEADER_MAP_ENTRY;
//
// Structure for a header index table entry.
//
typedef struct _HEADER_INDEX_ENTRY
{
PHEADER_MAP_ENTRY pHeaderMap;
ULONG Count;
} HEADER_INDEX_ENTRY, *PHEADER_INDEX_ENTRY;
//
// A (complex) macro to create a mask for a header map entry,
// given the header length and the mask offset (in bytes). This
// mask will need to be touched up for non-alphabetic characters.
//
#define CREATE_HEADER_MASK(hlength, maskoffset) \
((hlength) > (maskoffset) ? UPCASE_MASK : \
(((maskoffset) - (hlength)) >= 8 ? 0 : \
(UPCASE_MASK >> ( ((maskoffset) - (hlength)) * (ULONGLONG)8))))
//
// Macro for creating header map entries. The mask entries are created
// by the init code.
//
#define CREATE_HEADER_MAP_ENTRY(header, ID, handler) { \
\
sizeof(#header) - 1, \
((sizeof(#header) - 1) / 8) + \
(((sizeof(#header) - 1) % 8) == 0 ? 0 : 1), \
(((sizeof(#header) - 1) / 8) + \
(((sizeof(#header) - 1) % 8) == 0 ? 0 : 1)) * 8, \
{ #header }, \
{ 0, 0, 0}, \
{ #header }, \
ID, \
handler, \
}
//
// Macro for defining fast verb table entries. Note that we don't subtrace 1
// from the various sizeof occurences because we'd just have to add it back
// in to account for the seperating space.
//
#define CREATE_FAST_VERB_ENTRY(verb) { {#verb " "}, \
(0xffffffffffffffff >> \
((8 - (sizeof(#verb))) * 8)), \
(sizeof(#verb)), HttpVerb##verb }
//
// Macro for defining all verb table entries.
//
#define CREATE_LONG_VERB_ENTRY(verb) { sizeof(#verb) - 1, \
#verb,\
HttpVerb##verb }
#define IS_UTF8_TRAILBYTE(ch) (((ch) & 0xc0) == 0x80)
NTSTATUS
CheckForAbsoluteUrl(
IN PUL_INTERNAL_REQUEST pRequest,
IN PUCHAR pURL,
IN ULONG URLLength,
IN PUCHAR * pHostPtr,
IN ULONG * BytesTaken
);
NTSTATUS
LookupVerb(
IN PUL_INTERNAL_REQUEST pRequest,
IN PUCHAR pHttpRequest,
IN ULONG HttpRequestLength,
OUT ULONG * pBytesTaken
);
NTSTATUS
ParseHeader(
IN PUL_INTERNAL_REQUEST pRequest,
IN PUCHAR pHttpRequest,
IN ULONG HttpRequestLength,
OUT ULONG * pBytesTaken
);
NTSTATUS
LookupHeader(
IN PUL_INTERNAL_REQUEST pRequest,
IN PUCHAR pHttpRequest,
IN ULONG HttpRequestLength,
IN PHEADER_MAP_ENTRY pCurrentHeaderMap,
IN ULONG HeaderMapCount,
OUT ULONG * pBytesTaken
);
typedef enum _URL_PART
{
Scheme,
HostName,
AbsPath,
QueryString
} URL_PART;
NTSTATUS
UlpCleanAndCopyUrl(
IN URL_PART UrlPart,
IN OUT PWSTR pDestination,
IN PUCHAR pSource,
IN ULONG SourceLength,
OUT PULONG pBytesCopied,
OUT PWSTR * ppQueryString OPTIONAL,
OUT PULONG pUrlHash
);
// Call this only after the entire request has been parsed
//
NTSTATUS
UlpCookUrl(
IN PUL_INTERNAL_REQUEST pRequest
);
#endif // _PARSEP_H_