283 lines
6.8 KiB
C
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_
|
||
|
|