|
|
/*++
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_
|