|
|
/*++
Copyright (c) 1998-2002 Microsoft Corporation
Module Name:
parse.h
Abstract:
Contains all of the public definitions for the HTTP parsing code.
Author:
Henry Sanders (henrysa) 04-May-1998
Revision History:
Paul McDaniel (paulmcd) 14-Apr-1999
--*/
#ifndef _PARSE_H_
#define _PARSE_H_
//
// Constants
//
#define WILDCARD_SIZE (STRLEN_LIT("*/*") + sizeof(CHAR))
#define WILDCARD_SPACE '*/* '
#define WILDCARD_COMMA '*/*,'
//
// Size of Connection: header values
//
#define CONN_CLOSE_HDR "close"
#define CONN_CLOSE_HDR_LENGTH STRLEN_LIT(CONN_CLOSE_HDR)
#define CONN_KEEPALIVE_HDR "keep-alive"
#define CONN_KEEPALIVE_HDR_LENGTH STRLEN_LIT(CONN_KEEPALIVE_HDR)
#define CHUNKED_HDR "chunked"
#define CHUNKED_HDR_LENGTH STRLEN_LIT(CHUNKED_HDR)
#define MIN_VERSION_SIZE STRLEN_LIT("HTTP/1.1")
#define STATUS_CODE_LENGTH 3
#define HTTP_VERSION_11 "HTTP/1.1"
#define HTTP_VERSION_10 "HTTP/1.0"
#define HTTP_VERSION_OTHER "HTTP/"
#define VERSION_SIZE STRLEN_LIT(HTTP_VERSION_11)
#define VERSION_OTHER_SIZE STRLEN_LIT(HTTP_VERSION_OTHER)
#define MAX_KNOWN_VERB_LENGTH STRLEN_LIT("PROPPATCH") + sizeof(CHAR)
#define MAX_VERB_LENGTH 255
// "HTTP/1.x" backwards because of endianness
#define HTTP_11_VERSION 0x312e312f50545448ui64
#define HTTP_10_VERSION 0x302e312f50545448ui64
//
// These are backwards because of little endian.
//
#define HTTP_PREFIX 'PTTH'
#define HTTP_PREFIX_SIZE 4
#define HTTP_PREFIX_MASK 0xdfdfdfdf
C_ASSERT((HTTP_PREFIX & HTTP_PREFIX_MASK) == HTTP_PREFIX);
#define HTTP_PREFIX1 '\0//:'
#define HTTP_PREFIX1_SIZE 3
#define HTTP_PREFIX1_MASK 0x00ffffff
C_ASSERT((HTTP_PREFIX1 & HTTP_PREFIX1_MASK) == HTTP_PREFIX1);
#define HTTP_PREFIX2 '//:S'
#define HTTP_PREFIX2_SIZE 4
#define HTTP_PREFIX2_MASK 0xffffffdf
C_ASSERT((HTTP_PREFIX2 & HTTP_PREFIX2_MASK) == HTTP_PREFIX2);
#define MAX_HEADER_LONG_COUNT (3)
#define MAX_HEADER_LENGTH (MAX_HEADER_LONG_COUNT * sizeof(ULONGLONG))
#define NUMBER_HEADER_INDICES (26)
#define NUMBER_HEADER_HINT_INDICES (9)
//
// Default Server: header if none provided by the application.
//
#define DEFAULT_SERVER_HDR "Microsoft-HTTPAPI/1.0"
#define DEFAULT_SERVER_HDR_LENGTH STRLEN_LIT(DEFAULT_SERVER_HDR)
//
// One second in 100ns system time units. Used for generating
// Date: headers.
//
#define ONE_SECOND (10000000)
//
// 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. This is used for all known verbs that are 7 characters
// or less.
//
typedef struct _FAST_VERB_ENTRY { ULONGLONG RawVerbMask; union { UCHAR Char[sizeof(ULONGLONG)+1]; ULONGLONG LongLong; } RawVerb; ULONG RawVerbLength; HTTP_VERB TranslatedVerb;
} FAST_VERB_ENTRY, *PFAST_VERB_ENTRY;
//
// Macro for defining fast verb table entries. Note that we don't subtract 1
// from the various sizeof occurences because we'd just have to add it back
// in to account for the separating space.
//
#define CREATE_FAST_VERB_ENTRY(verb) \
{ \ (0xffffffffffffffffui64 >> ((8 - (sizeof(#verb))) * 8)), \ {#verb " "}, \ (sizeof(#verb)), \ HttpVerb##verb \ }
//
// Stucture of the all verb lookup table. This table holds all verbs
// that are too long to fit in the fast verb table.
//
typedef struct _LONG_VERB_ENTRY { ULONG RawVerbLength; UCHAR RawVerb[MAX_KNOWN_VERB_LENGTH]; HTTP_VERB TranslatedVerb;
} LONG_VERB_ENTRY, *PLONG_VERB_ENTRY;
//
// Macro for defining all long verb table entries.
//
#define CREATE_LONG_VERB_ENTRY(verb) \
{ sizeof(#verb) - 1, #verb, HttpVerb##verb }
//
// Header handler callback functions
//
typedef NTSTATUS (*PFN_SERVER_HEADER_HANDLER)( PUL_INTERNAL_REQUEST pRequest, PUCHAR pHeader, USHORT HeaderLength, HTTP_HEADER_ID HeaderID, ULONG * pBytesTaken );
typedef NTSTATUS (*PFN_CLIENT_HEADER_HANDLER)( PUC_HTTP_REQUEST pRequest, PUCHAR pHeader, ULONG HeaderLength, HTTP_HEADER_ID HeaderID );
//
// 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; BOOLEAN AutoGenerate; PFN_SERVER_HEADER_HANDLER pServerHandler; PFN_CLIENT_HEADER_HANDLER pClientHandler; LONG HintIndex;
} 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;
//
// Structure for a header hint index table entry.
//
typedef struct _HEADER_HINT_INDEX_ENTRY { PHEADER_MAP_ENTRY pHeaderMap; UCHAR c;
} HEADER_HINT_INDEX_ENTRY, *PHEADER_HINT_INDEX_ENTRY, **PPHEADER_HINT_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 UPCASE_MASK 0xDFDFDFDFDFDFDFDFui64
#define CREATE_HEADER_MASK(hlength, maskoffset) \
((hlength) > (maskoffset) ? UPCASE_MASK : \ (((maskoffset) - (hlength)) >= 8 ? 0 : \ (UPCASE_MASK >> ( ((maskoffset) - (hlength)) * 8ui64))))
//
// Macro for creating header map entries. The mask entries are created
// by the init code.
//
#define CREATE_HEADER_MAP_ENTRY(header, ID, auto, serverhandler, clienthandler, HintIndex)\
{ \ 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, \ auto, \ serverhandler, \ clienthandler, \ HintIndex \ }
//
// Parser states for parsing a chunk header extension.
//
typedef enum { CHStart, CHSeenCR, CHInChunkExtName, CHSeenChunkExtNameAndEquals, CHInChunkExtValToken, CHInChunkExtValQuotedString, CHSeenChunkExtValQuotedStringTerminator, CHSuccess, CHError } CH_PARSER_STATE, *PCH_PARSER_STATE;
//
// Parser states for parsing message header field content.
//
typedef enum { HFCStart, HFCSeenCR, HFCSeenLF, HFCSeenCRLF, HFCFolding, HFCInQuotedString } HFC_PARSER_STATE, *PHFC_PARSER_STATE;
//
// Parser states for parsing a quoted string.
//
typedef enum { QSInString, QSSeenBackSlash, QSSeenCR, QSSeenLF, QSSeenCRLF, QSFolding } QS_PARSER_STATE, *PQS_PARSER_STATE;
//
// External variables.
//
extern ULONG g_RequestHeaderMap[HttpHeaderMaximum]; extern ULONG g_ResponseHeaderMap[HttpHeaderMaximum];
extern HEADER_MAP_ENTRY g_RequestHeaderMapTable[]; extern HEADER_MAP_ENTRY g_ResponseHeaderMapTable[];
extern HEADER_INDEX_ENTRY g_RequestHeaderIndexTable[]; extern HEADER_INDEX_ENTRY g_ResponseHeaderIndexTable[];
extern HEADER_HINT_INDEX_ENTRY g_RequestHeaderHintIndexTable[];
//
// Function prototypes.
//
PUCHAR FindHexToken( IN PUCHAR pBuffer, IN ULONG BufferLength, OUT ULONG *TokenLength );
NTSTATUS InitializeParser( VOID );
ULONG UlpParseHttpVersion( PUCHAR pString, ULONG StringLength, PHTTP_VERSION pVersion );
NTSTATUS FindHeaderEndReadOnly( IN PUCHAR pHeader, IN ULONG HeaderLength, OUT PULONG pBytesTaken );
NTSTATUS FindHeaderEnd( IN PUCHAR pHeader, IN ULONG HeaderLength, OUT PULONG pBytesTaken );
NTSTATUS FindRequestHeaderEnd( IN PUL_INTERNAL_REQUEST pRequest, IN PUCHAR pHeader, IN ULONG HeaderLength, OUT PULONG pBytesTaken );
NTSTATUS FindChunkHeaderEnd( IN PUCHAR pHeader, IN ULONG HeaderLength, OUT PULONG pBytesTaken );
NTSTATUS ParseChunkLength( IN ULONG FirstChunkParsed, IN PUCHAR pBuffer, IN ULONG BufferLength, OUT PULONG pBytesTaken, OUT PULONGLONG pChunkLength );
NTSTATUS ParseQuotedString( IN PUCHAR pInput, IN ULONG InputLength, IN PUCHAR pOutput, OUT PULONG pBytesTaken );
#endif // _PARSE_H_
|