/*++

Copyright (c) 1998-2001 Microsoft Corporation

Module Name:

    httpdef.h

Abstract:

    This module contains basic HTTP protocol stack type definitions
    shared between the user- and kernel-mode components.

Author:

    Keith Moore (keithmo)       29-Jul-1998

Revision History:

    Paul McDaniel (paulmcd)     15-Mar-1999

        Added new response flags.

    Chun Ye (chunye)            27-Sep-2000

        Renamed UL_* to HTTP_*.

--*/


#ifndef _HTTPDEF_H_
#define _HTTPDEF_H_


#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus


//
// Forward references.
//

typedef struct _HTTP_RESPONSE *PHTTP_RESPONSE;
typedef struct _HTTP_DATA_CHUNK *PHTTP_DATA_CHUNK;
typedef struct _HTTP_SSL_INFO *PHTTP_SSL_INFO;


//
// Generic option flags. These apply to control channels and application
// pools.
//
// HTTP_OPTION_OVERLAPPED - Opens the object for asynchronous I/O.
//
// HTTP_OPTION_CONTROLLER - Opens the object that doesn't read data.
//

#define HTTP_OPTION_OVERLAPPED                      0x00000001
#define HTTP_OPTION_CONTROLLER                      0x00000002
#define HTTP_OPTION_VALID                           0x00000003

//
// Flags for HttpReceiveHttpRequest().
//
// HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY - Specifies that the caller would like
// any available entity body to be copied along with the protocol headers
//

#define HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY         0x00000001
#define HTTP_RECEIVE_REQUEST_FLAG_FLUSH_BODY        0x00000002
#define HTTP_RECEIVE_REQUEST_FLAG_VALID             0x00000003


//
// Flags for HttpSendHttpResponse() and HttpSendEntityBody().
//
// HTTP_SEND_RESPONSE_FLAG_DISCONNECT - Specifies that the network connection
// should be disconnected immediately after sending the response, overriding
// the HTTP protocol's persistent connection features.
//
// HTTP_SEND_RESPONSE_FLAG_MORE_DATA - Specifies that additional entity body
// data will be sent by the caller.
//
// HTTP_SEND_REPONSE_RAW_HEADER - Specifies that a caller of
// HttpSendEntityBody is intentionally omitting a call to
// HttpSendHttpResponse in order to bypass normal header processing. The
// actual HTTP header will be generated by the application and sent
// as entity body. This flag should be passed on the first call to
// HttpSendEntityBody, and not after.
//

#define HTTP_SEND_RESPONSE_FLAG_DISCONNECT          0x00000001
#define HTTP_SEND_RESPONSE_FLAG_MORE_DATA           0x00000002
#define HTTP_SEND_RESPONSE_FLAG_RAW_HEADER          0x00000004
#define HTTP_SEND_RESPONSE_FLAG_VALID               0x00000007


//
// Flags for HttpFlushResponseCache().
//
// HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE - Flushes the specified URL and all
// heirarchally related sub-URLs from the response cache.
//

#define HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE          0x00000001
#define HTTP_FLUSH_RESPONSE_FLAG_VALID              0x00000001


//
// Flags for HttpReceiveClientCertificate
//
// HTTP_RECEIVE_CLIENT_CERT_FLAG_MAP - Maps the client certificate to a token.
//

#define HTTP_RECEIVE_CLIENT_CERT_FLAG_MAP           0x00000001
#define HTTP_RECEIVE_CLIENT_CERT_FLAG_VALID         0x00000001


//
// Opaque identifiers for various kernel objects.
//

typedef ULONGLONG HTTP_OPAQUE_ID, *PHTTP_OPAQUE_ID;

typedef HTTP_OPAQUE_ID HTTP_REQUEST_ID, *PHTTP_REQUEST_ID;
typedef HTTP_OPAQUE_ID HTTP_CONNECTION_ID, *PHTTP_CONNECTION_ID;
typedef HTTP_OPAQUE_ID HTTP_CONFIG_GROUP_ID, *PHTTP_CONFIG_GROUP_ID;
typedef HTTP_OPAQUE_ID HTTP_RAW_CONNECTION_ID, *PHTTP_RAW_CONNECTION_ID;

#define HTTP_NULL_ID            0
#define HTTP_IS_NULL_ID(pid)    (*(pid) == 0)
#define HTTP_SET_NULL_ID(pid)   (*(pid) = 0)


//
// An opaque context for URLs in an configuration group.
//

typedef ULONGLONG HTTP_URL_CONTEXT;

//
// Network QOS stuff.
//

typedef ULONG HTTP_BANDWIDTH_LIMIT, *PHTTP_BANDWIDTH_LIMIT;
typedef ULONG HTTP_CONNECTION_LIMIT, *PHTTP_CONNECTION_LIMIT;


//
// Distinguished value for bandwidth and connection limits indicating
// "no limit".
//

#define HTTP_LIMIT_INFINITE   (ULONG)-1L


//
// Enabled states. Used for configuration groups and the control channel.
//

typedef enum _HTTP_ENABLED_STATE
{
    HttpEnabledStateActive,
    HttpEnabledStateInactive,

    HttpEnabledStateMaximum

} HTTP_ENABLED_STATE, *PHTTP_ENABLED_STATE;

//
// UTF8 Logging
//

typedef BOOLEAN HTTP_CONTROL_CHANNEL_UTF8_LOGGING, *PHTTP_CONTROL_CHANNEL_UTF8_LOGGING;

//
// Control channel query/set information classes used for the
// HttpQueryControlChannelInformation() and HttpSetControlChannelInformation()
// APIs.
//

typedef enum _HTTP_CONTROL_CHANNEL_INFORMATION_CLASS
{
    //
    // Query/set the master state.
    //
    // pControlChannelInformation points to a HTTP_ENABLED_STATE enum.
    //

    HttpControlChannelStateInformation,

    //
    // Query/set the default network bandwidth limit.
    //
    // pControlChannelInformation points to a HTTP_BANDWIDTH_LIMIT value.
    //

    HttpControlChannelBandwidthInformation,

    //
    // Query/set the default network connections limit.
    //
    // pControlChannelInformation points to a HTTP_CONNECTION_LIMIT value.
    //

    HttpControlChannelConnectionInformation,

    //
    // Set the HTTP response to be sent with either HTTP has been deactivated
    // or in critically bad situations in which it is impossible to even
    // determine which process should receive the request.
    //
    // pControlChannelInformation points to a HTTP_AUTO_RESPONSE structure.
    //
    // Note this cannot be queried.
    //

    HttpControlChannelAutoResponseInformation,

    //
    // Set the handle used to communicate with the Filter/SSL process.
    //
    // Note this cannot be queried.
    //

    HttpControlChannelFilterInformation,

    //
    // Set the global Connection Timeout information
    //
    // pControlChannelInformation points to a HTTP_CONTROL_CHANNEL_TIMEOUT_LIMIT structure.
    //

    HttpControlChannelTimeoutInformation,

    //
    // Set the UTF8 Logging property for all sites
    //
    // pControlChannelInformation points to a HTTP_CONTROL_CHANNEL_UTF8_LOGGING structure.
    //
    
    HttpControlChannelUTF8Logging,

    HttpControlChannelMaximumInformation

} HTTP_CONTROL_CHANNEL_INFORMATION_CLASS, *PHTTP_CONTROL_CHANNEL_INFORMATION_CLASS;

//
// Default control channel property values.
//

#define HTTP_CONTROL_CHANNEL_STATE_DEFAULT              HttpEnabledStateInactive
#define HTTP_CONTROL_CHANNEL_MAX_BANDWIDTH_DEFAULT      HTTP_LIMIT_INFINITE
#define HTTP_CONTROL_CHANNEL_MAX_CONNECTIONS_DEFAULT    HTTP_LIMIT_INFINITE
#define HTTP_CONTROL_CHANNEL_AUTO_RESPONSE_DEFAULT      NULL

// 
// Connection Timeout Limits structure for HttpControlChannelTimeoutInformation
//
typedef struct _HTTP_CONTROL_CHANNEL_TIMEOUT_LIMIT 
{
    ULONG   ConnectionTimeout;  // Seconds
    ULONG   HeaderWaitTimeout;  // Seconds
    ULONG   MinFileKbSec;       // Bytes/Seconds
} HTTP_CONTROL_CHANNEL_TIMEOUT_LIMIT, *PHTTP_CONTROL_CHANNEL_TIMEOUT_LIMIT;


//
// Application pool query/set information classes used for the
// HttpQueryAppPoolInformation() and HttpSetAppPoolInforamtion()
// APIs.
//

typedef enum _HTTP_APP_POOL_INFORMATION_CLASS
{
    //
    // Query/set the maximum number of processes for the specified
    // application group. This value is typically 1 in the normal case
    // and greater than 1 for Web Gardens.
    //
    // pAppPoolInformation points to a ULONG containing the maximum
    // number of processes.
    //
    // NOTE: not used.

    HttpAppPoolDemandStartInformation,

    //
    // Clears the demand start flag. This is part of the demand start
    // handshake protocol used between the user- and kernel-mode
    // components.
    //
    // pAppPoolInformation is unused.
    //
    // NOTE: not used.

    HttpAppPoolDemandStartFlagInformation,

    //
    // Query/set the maximum number of queued new requests on
    // the application pool.
    //
    // pAppPoolInformation points to a LONG containing the maximum
    // number of queued requests.
    //

    HttpAppPoolQueueLengthInformation,

    //
    // Query/set the active state of the application pool.
    //
    // pAppPoolInformation points to a HTTP_ENABLED_STATE enum.
    //

    HttpAppPoolStateInformation,

    HttpAppPoolMaximumInformation

} HTTP_APP_POOL_INFORMATION_CLASS, *PHTTP_APP_POOL_INFORMATION_CLASS;


//
// Configuration group query/set information classes use for the
// HttpQueryConfigGroupInformation() and HttpSetConfigGroupInformation()
// APIs.
//

typedef enum _HTTP_CONFIG_GROUP_INFORMATION_CLASS
{
    //
    // Query/set the current state of the configuration group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_STATE structure
    // that receives the current state.
    //

    HttpConfigGroupStateInformation,

    //
    // Query/set the maximum network bandwidth allowed for the configuration
    // group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_MAX_BANDWIDTH
    // structure specifying the maximum bytes per second allowed for the
    // contiainer.
    //

    HttpConfigGroupBandwidthInformation,

    //
    // Query/set the maximum network connections allowed for the
    // configuration group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_MAX_CONNECTIONS
    // structure containing the maximum number of network connections
    // allowed for the container.
    //

    HttpConfigGroupConnectionInformation,

    //
    // Set the response to be sent when the configuration group is
    // in a nonresponsive state.
    //
    // pConfigGroupInformation points to a HTTP_AUTO_RESPONSE
    // structure.
    //
    // Note this cannot be queried.
    //

    HttpConfigGroupAutoResponseInformation,

    //
    // Set the application pool associated with the configuration
    // group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_APP_POOL
    // structure containing the HANDLE of the application pool to
    // associate.
    //

    HttpConfigGroupAppPoolInformation,

    //
    // Set the cache size associated with the configuration
    // group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_APP_POOL
    // structure containing the HANDLE of the application pool to
    // associate.
    //

    HttpConfigGroupCacheSizeInformation,

    //
    // Set the security descriptor associated with the configuration
    // group. This security descriptor is used to control the
    // creation of transient URL registrations beneath the
    // configuration group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_SECURITY
    // structure.
    //
    // Note this cannot be queried.
    //

    HttpConfigGroupSecurityInformation,

    //
    // Set the logging related config settings.
    // This allows WAS to supply logging config as a config group
    // setting group.
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_LOGGING
    // structure.
    //
    // Note this cannot be queried.
    //

    HttpConfigGroupLogInformation,

    //
    // Set this information only on the root config object for the
    // site.  
    //
    // pConfigGroupInformation points to a HTTP_CONFIG_GROUP_SITE
    // structure.
    //

    HttpConfigGroupSiteInformation,

    //
    // Set this information only on the root config object for the
    // site.
    //
    // pConfigGroupInformation points to a DWORD that contains 
    // the ConnectionTimeout value (in seconds)
    //

    HttpConfigGroupConnectionTimeoutInformation,

#if DBG

    //
    // Private for dev testing only.
    //

    HttpConfigGroupGetUrlInfo,
    HttpConfigGroupFreeUrlInfo,
    HttpConfigGroupUrlStaleTest,

    //
    // End private dev testing only.
    //

#endif

    HttpConfigGroupMaximumInformation

} HTTP_CONFIG_GROUP_INFORMATION_CLASS, *PHTTP_CONFIG_GROUP_INFORMATION_CLASS;


//
// Generic configuration group property flags. Each structure defining a
// property value must contain an element of this type.
//

typedef struct _HTTP_PROPERTY_FLAGS
{
    ULONG_PTR Present:1;

} HTTP_PROPERTY_FLAGS, *PHTTP_PROPERTY_FLAGS;


//
// Individual property values.
//

typedef struct _HTTP_CONFIG_GROUP_STATE
{
    HTTP_PROPERTY_FLAGS Flags;
    HTTP_ENABLED_STATE State;

} HTTP_CONFIG_GROUP_STATE, *PHTTP_CONFIG_GROUP_STATE;


typedef struct _HTTP_CONFIG_GROUP_MAX_BANDWIDTH
{
    HTTP_PROPERTY_FLAGS Flags;
    HTTP_BANDWIDTH_LIMIT MaxBandwidth;

} HTTP_CONFIG_GROUP_MAX_BANDWIDTH, *PHTTP_CONFIG_GROUP_MAX_BANDWIDTH;


typedef struct _HTTP_CONFIG_GROUP_MAX_CONNECTIONS
{
    HTTP_PROPERTY_FLAGS Flags;
    HTTP_CONNECTION_LIMIT MaxConnections;

} HTTP_CONFIG_GROUP_MAX_CONNECTIONS, *PHTTP_CONFIG_GROUP_MAX_CONNECTIONS;


typedef struct _HTTP_AUTO_RESPONSE
{
    HTTP_PROPERTY_FLAGS Flags;
    PHTTP_RESPONSE pResponse;
    ULONG EntityChunkCount;
    PHTTP_DATA_CHUNK pEntityChunks;

} HTTP_AUTO_RESPONSE, *PHTTP_AUTO_RESPONSE;


typedef struct _HTTP_CONTROL_CHANNEL_FILTER
{
    HTTP_PROPERTY_FLAGS Flags;
    HANDLE FilterHandle;
    BOOLEAN FilterOnlySsl;

} HTTP_CONTROL_CHANNEL_FILTER, *PHTTP_CONTROL_CHANNEL_FILTER;


typedef struct _HTTP_CONFIG_GROUP_APP_POOL
{
    HTTP_PROPERTY_FLAGS Flags;
    HANDLE AppPoolHandle;

} HTTP_CONFIG_GROUP_APP_POOL, *PHTTP_CONFIG_GROUP_APP_POOL;


typedef struct _HTTP_CONFIG_GROUP_CACHE_SIZE
{
    HTTP_PROPERTY_FLAGS Flags;
    ULONG CacheSize;

} HTTP_CONFIG_GROUP_CACHE_SIZE, *PHTTP_CONFIG_GROUP_CACHE_SIZE;


typedef struct _HTTP_CONFIG_GROUP_SECURITY
{
    HTTP_PROPERTY_FLAGS Flags;
    PSECURITY_DESCRIPTOR pSecurityDescriptor;

} HTTP_CONFIG_GROUP_SECURITY, *PHTTP_CONFIG_GROUP_SECURITY;


typedef enum _HTTP_LOGGING_TYPE
{
    HttpLoggingTypeW3C,
    HttpLoggingTypeIIS,
    HttpLoggingTypeNCSA,

    HttpLoggingTypeMaximum

} HTTP_LOGGING_TYPE, *PHTTP_LOGGING_TYPE;


typedef enum _HTTP_LOGGING_PERIOD
{
    HttpLoggingPeriodMaxSize = 0,
    HttpLoggingPeriodDaily   = 1,
    HttpLoggingPeriodWeekly  = 2,
    HttpLoggingPeriodMonthly = 3,
    HttpLoggingPeriodHourly  = 4,

    HttpLoggingPeriodMaximum

} HTTP_LOGGING_PERIOD, *PHTTP_LOGGING_PERIOD;


typedef struct _HTTP_CONFIG_GROUP_LOGGING
{
    //
    // To indicate if this property exist or not
    // in the config group
    //

    HTTP_PROPERTY_FLAGS Flags;

    //
    // This is field?s counterpart in the metabase is
    // LogType
    //

    BOOLEAN LoggingEnabled;

    //
    // Indicates the Logging Format
    //

    HTTP_LOGGING_TYPE LogFormat;

    //
    // Indicates the exact directory where the log file
    // will be written to for a site.
    //

    UNICODE_STRING LogFileDir;

    //
    // HTTP does not keep the site name information.
    // WAS should pass down this. E.g. "W3SVC1"
    //

    UNICODE_STRING SiteName;

    //
    // Log Period in terms of
    // 0 = MAX SIZE, 1 = DAILY, 2 = WEEKLY,
    // 3 = MONTHLY,  4 = HOURLY
    //

    ULONG LogPeriod;

    //
    // Indicates the max size,in bytes,after which the
    // log file should be rotated. A value of -1
    // (HTTP_LIMIT_INFINITE) indicates unlimited size.
    //

    ULONG LogFileTruncateSize;

    //
    // A bit mask indicating which fields to log when
    // LogFormat is set to W3C Extended
    //

    ULONG LogExtFileFlags;

    //
    // If this has been set then we recycle log files
    // based on the local time for this site. Default
    // should be FALSE.
    //
    
    BOOLEAN LocaltimeRollover;

} HTTP_CONFIG_GROUP_LOGGING, *PHTTP_CONFIG_GROUP_LOGGING;


// 
// HTTP_CONFIG_GROUP_SITE
// 

typedef struct _HTTP_CONFIG_GROUP_SITE
{
	ULONG   SiteId;
	
} HTTP_CONFIG_GROUP_SITE, *PHTTP_CONFIG_GROUP_SITE;

//
// This structure holds all the necessary Logging Info,
// And pushed down by User (Worker Process) with
// Sendresponse or SendEntityBody Ioctls.
//

typedef struct _HTTP_LOG_FIELDS_DATA
{
    USHORT UserNameLength;
    USHORT UriStemLength;
    USHORT ClientIpLength;
    USHORT ServerNameLength;
    USHORT ServiceNameLength;
    USHORT ServerIpLength;
    USHORT MethodLength;
    USHORT UriQueryLength;
    USHORT HostLength;
    USHORT UserAgentLength;
    USHORT CookieLength;
    USHORT ReferrerLength;

    PWSTR UserName;
    PWSTR UriStem;
    PSTR ClientIp;
    PSTR ServerName;
    PSTR ServiceName;
    PSTR ServerIp;
    PSTR Method;
    PSTR UriQuery;
    PSTR Host;
    PSTR UserAgent;
    PSTR Cookie;
    PSTR Referrer;

    ULONG ServerPort;

    ULONG ProtocolStatus;
    ULONG Win32Status;

} HTTP_LOG_FIELDS_DATA, *PHTTP_LOG_FIELDS_DATA;


#if DBG

//
// Private for dev testing only.
//

typedef struct _HTTP_CONFIG_GROUP_DBG_URL_INFO
{
    UNICODE_STRING Url;                     // IN
    HTTP_ENABLED_STATE CurrentState;        // OUT
    HTTP_BANDWIDTH_LIMIT MaxBandwidth;      // OUT
    HTTP_CONNECTION_LIMIT MaxConnections;   // OUT
    HTTP_URL_CONTEXT UrlContext;            // OUT
    PVOID pReserved;                        // OUT
    BOOLEAN Stale;                          // OUT

} HTTP_CONFIG_GROUP_DBG_URL_INFO, *PHTTP_CONFIG_GROUP_DBG_URL_INFO;

//
// End private dev testing only.
//

#endif


//
// This structure defines a file byte range.
//
// If the StartingOffset field is HTTP_BYTE_RANGE_TO_EOF (see below) then
// the last Length bytes of the file are sent.
//
// If the Length field is HTTP_BYTE_RANGE_TO_EOF then the remainder of the
// file (everything after StartingOffset) is sent.
//

typedef struct _HTTP_BYTE_RANGE
{
    LARGE_INTEGER StartingOffset;
    LARGE_INTEGER Length;

} HTTP_BYTE_RANGE, *PHTTP_BYTE_RANGE;

#define HTTP_BYTE_RANGE_TO_EOF ((ULONGLONG)-1)


//
// The type for version numbers.
//

typedef struct _HTTP_VERSION
{
    USHORT MajorVersion;
    USHORT MinorVersion;

} HTTP_VERSION, *PHTTP_VERSION;


//
// Some useful macros for version manipulation.
//

#define HTTP_VERSION_UNKNOWN    { 0, 0 }
#define HTTP_VERSION_0_9        { 0, 9 }
#define HTTP_VERSION_1_0        { 1, 0 }
#define HTTP_VERSION_1_1        { 1, 1 }

#define HTTP_SET_VERSION(version, major, minor)             \
{                                                           \
    (version).MajorVersion = (major);                       \
    (version).MinorVersion = (minor);                       \
}

#define HTTP_EQUAL_VERSION(version, major, minor)           \
    ((version).MajorVersion == (major) &&                   \
     (version).MinorVersion == (minor))

#define HTTP_GREATER_VERSION(version, major, minor)         \
    ((version).MajorVersion > (major) ||                    \
     ((version).MajorVersion == (major) &&                  \
      (version).MinorVersion > (minor)))

#define HTTP_LESS_VERSION(version, major, minor)            \
    ((version).MajorVersion < (major) ||                    \
     ((version).MajorVersion == (major) &&                  \
      (version).MinorVersion < (minor)))

#define HTTP_NOT_EQUAL_VERSION(version, major, minor)       \
    (!HTTP_EQUAL_VERSION(version, major, minor))

#define HTTP_GREATER_EQUAL_VERSION(version, major, minor)   \
    (!HTTP_LESS_VERSION(version, major, minor))

#define HTTP_LESS_EQUAL_VERSION(version, major, minor)      \
    (!HTTP_GREATER_VERSION(version, major, minor))


//
// The enum type for HTTP verbs.
//

typedef enum _HTTP_VERB
{
    HttpVerbUnparsed,
    HttpVerbUnknown,
    HttpVerbInvalid,
    HttpVerbOPTIONS,
    HttpVerbGET,
    HttpVerbHEAD,
    HttpVerbPOST,
    HttpVerbPUT,
    HttpVerbDELETE,
    HttpVerbTRACE,
    HttpVerbCONNECT,
    HttpVerbTRACK,              // used by wolf-pack for a non-logged trace
    HttpVerbMOVE,
    HttpVerbCOPY,
    HttpVerbPROPFIND,
    HttpVerbPROPPATCH,
    HttpVerbMKCOL,
    HttpVerbLOCK,
    HttpVerbUNLOCK,
    HttpVerbSEARCH,

    HttpVerbMaximum

} HTTP_VERB, *PHTTP_VERB;


//
// Symbols for all HTTP/1.1 headers and other tokens.  Notice request +
// response values overlap.  Make sure you know which type of header array
// you are indexing.
//
// These values are used as offsets into arrays and as token values in
// HTTP_KNOWN_HEADER.
//

typedef enum _HTTP_HEADER_ID
{

    HttpHeaderCacheControl          = 0,    // general-header [section 4.5]
    HttpHeaderConnection            ,       // general-header [section 4.5]
    HttpHeaderDate                  ,       // general-header [section 4.5]
    HttpHeaderKeepAlive             ,       // general-header [not in rfc]
    HttpHeaderPragma                ,       // general-header [section 4.5]
    HttpHeaderTrailer               ,       // general-header [section 4.5]
    HttpHeaderTransferEncoding      ,       // general-header [section 4.5]
    HttpHeaderUpgrade               ,       // general-header [section 4.5]
    HttpHeaderVia                   ,       // general-header [section 4.5]
    HttpHeaderWarning               = 9,    // general-header [section 4.5]

    HttpHeaderAllow                 = 10,   // entity-header  [section 7.1]
    HttpHeaderContentLength         ,       // entity-header  [section 7.1]
    HttpHeaderContentType           ,       // entity-header  [section 7.1]
    HttpHeaderContentEncoding       ,       // entity-header  [section 7.1]
    HttpHeaderContentLanguage       ,       // entity-header  [section 7.1]
    HttpHeaderContentLocation       ,       // entity-header  [section 7.1]
    HttpHeaderContentMd5            ,       // entity-header  [section 7.1]
    HttpHeaderContentRange          ,       // entity-header  [section 7.1]
    HttpHeaderExpires               ,       // entity-header  [section 7.1]
    HttpHeaderLastModified          = 19,   // entity-header  [section 7.1]

    HttpHeaderAccept                = 20,   // request-header [section 5.3]
    HttpHeaderAcceptCharset         ,       // request-header [section 5.3]
    HttpHeaderAcceptEncoding        ,       // request-header [section 5.3]
    HttpHeaderAcceptLanguage        ,       // request-header [section 5.3]
    HttpHeaderAuthorization         ,       // request-header [section 5.3]
    HttpHeaderCookie                ,       // request-header [not in rfc]  // 25 
    HttpHeaderExpect                ,       // request-header [section 5.3]
    HttpHeaderFrom                  ,       // request-header [section 5.3]
    HttpHeaderHost                  ,       // request-header [section 5.3]
    HttpHeaderIfMatch               ,       // request-header [section 5.3]
    HttpHeaderIfModifiedSince       ,       // request-header [section 5.3] // 30
    HttpHeaderIfNoneMatch           ,       // request-header [section 5.3]
    HttpHeaderIfRange               ,       // request-header [section 5.3]
    HttpHeaderIfUnmodifiedSince     ,       // request-header [section 5.3]
    HttpHeaderMaxForwards           ,       // request-header [section 5.3]
    HttpHeaderProxyAuthorization    ,       // request-header [section 5.3] // 35
    HttpHeaderReferer               ,       // request-header [section 5.3]
    HttpHeaderRange                 ,       // request-header [section 5.3]
    HttpHeaderTe                    ,       // request-header [section 5.3]
    HttpHeaderTranslate             ,       // request-header [webDAV, not in rfc 2518]
    HttpHeaderUserAgent             = 40,   // request-header [section 5.3] // 40

    HttpHeaderRequestMaximum        = 41,

    HttpHeaderAcceptRanges          = 20,   // response-header [section 6.2]
    HttpHeaderAge                   ,       // response-header [section 6.2]
    HttpHeaderEtag                  ,       // response-header [section 6.2]
    HttpHeaderLocation              ,       // response-header [section 6.2]
    HttpHeaderProxyAuthenticate     ,       // response-header [section 6.2]
    HttpHeaderRetryAfter            ,       // response-header [section 6.2]
    HttpHeaderServer                ,       // response-header [section 6.2]
    HttpHeaderSetCookie             ,       // response-header [not in rfc]
    HttpHeaderVary                  ,       // response-header [section 6.2]
    HttpHeaderWwwAuthenticate       = 29,   // response-header [section 6.2]

    HttpHeaderResponseMaximum       = 30,

    HttpHeaderMaximum               = 41
    
} HTTP_HEADER_ID, *PHTTP_HEADER_ID;


//
// Structure defining format of known header.
//

typedef struct _HTTP_KNOWN_HEADER
{
    //
    // raw value
    //

    USHORT RawValueLength;              // in bytes not including the NULL
    PSTR pRawValue;

} HTTP_KNOWN_HEADER, *PHTTP_KNOWN_HEADER;


//
// Structure defining format of unknown header.
//

typedef struct _HTTP_UNKNOWN_HEADER
{
    USHORT NameLength;                  // in bytes not including the NULL
    USHORT RawValueLength;              // in bytes not including the NULL

    //
    // The header name (minus the ':' character)
    //

    PSTR pName;

    //
    // The header value
    //

    PSTR pRawValue;

} HTTP_UNKNOWN_HEADER, *PHTTP_UNKNOWN_HEADER;


//
// This enum defines a data source for a particular chunk of data.
//

typedef enum _HTTP_DATA_CHUNK_TYPE
{
    HttpDataChunkFromMemory,
    HttpDataChunkFromFileName,
    HttpDataChunkFromFileHandle,

    HttpDataChunkMaximum

} HTTP_DATA_CHUNK_TYPE, *PHTTP_DATA_CHUNK_TYPE;


//
// This structure describes an individual data chunk.
//

typedef struct _HTTP_DATA_CHUNK
{
    //
    // The type of this data chunk.
    //

    HTTP_DATA_CHUNK_TYPE DataChunkType;

    //
    // The data chunk structures, one per supported data chunk type.
    //

    union
    {
        //
        // From memory data chunk.
        //

        struct
        {
            PVOID pBuffer;
            ULONG BufferLength;

        } FromMemory;

        //
        // From filename data chunk.
        //

        struct
        {
            HTTP_BYTE_RANGE ByteRange;

            USHORT FileNameLength;      // in bytes not including the NULL
            PCWSTR pFileName;

        } FromFileName;

        //
        // From file handle data chunk.
        //

        struct
        {
            HTTP_BYTE_RANGE ByteRange;
            HANDLE FileHandle;

        } FromFileHandle;

    };

} HTTP_DATA_CHUNK, *PHTTP_DATA_CHUNK;


//
// The enum type for HTTP request reasons.
//

typedef enum _HTTP_REQUEST_REASON
{
    HttpReasonResponseCacheMiss,
    HttpReasonFileHandleCacheMiss,
    HttpReasonCachePolicy,
    HttpReasonCacheSecurity,
    HttpReasonClientDisconnect,

    HttpReasonMaximum

} HTTP_REQUEST_REASON, *PHTTP_REQUEST_REASON;


//
// Structure defining format of request headers.
//

typedef struct _HTTP_REQUEST_HEADERS
{
    //
    // The array of unknown HTTP headers and the number of
    // entries in the array.
    //

    ULONG UnknownHeaderCount;

    PHTTP_UNKNOWN_HEADER pUnknownHeaders;

    //
    // Known headers.
    //

    HTTP_KNOWN_HEADER pKnownHeaders[HttpHeaderRequestMaximum];

} HTTP_REQUEST_HEADERS, *PHTTP_REQUEST_HEADERS;


//
// Structure defining format of request headers.
//

typedef struct _HTTP_RESPONSE_HEADERS
{
    //
    // The array of unknown HTTP headers and the number of
    // entries in the array.
    //

    ULONG UnknownHeaderCount;

    PHTTP_UNKNOWN_HEADER pUnknownHeaders;

    //
    // Known headers.
    //

    HTTP_KNOWN_HEADER pKnownHeaders[HttpHeaderResponseMaximum];

} HTTP_RESPONSE_HEADERS, *PHTTP_RESPONSE_HEADERS;


//
// Network address definitions.
//

#define HTTP_NETWORK_ADDRESS_TYPE_IPV4      0

typedef struct _HTTP_NETWORK_ADDRESS_IPV4
{
    ULONG IpAddress;
    USHORT Port;
    USHORT Spare;   // for alignment

} HTTP_NETWORK_ADDRESS_IPV4, *PHTTP_NETWORK_ADDRESS_IPV4;


//
// Structure defining format of transport address.
//

typedef struct _HTTP_TRANSPORT_ADDRESS
{
    USHORT RemoteAddressLength; // sizeof(HTTP_NETWORK_ADDRESS_xxx)
    USHORT RemoteAddressType;   // HTTP_NETWORK_ADDRESS_TYPE_xxx

    USHORT LocalAddressLength;  // sizeof(HTTP_NETWORK_ADDRESS_xxx)
    USHORT LocalAddressType;    // HTTP_NETWORK_ADDRESS_TYPE_xxx

    PVOID pRemoteAddress;       // points to a HTTP_NETWORK_ADDRESS_xxx
    PVOID pLocalAddress;        // points to a HTTP_NETWORK_ADDRESS_xxx

} HTTP_TRANSPORT_ADDRESS, *PHTTP_TRANSPORT_ADDRESS;


//
// Structure defining format of cooked URL.
//

typedef struct _HTTP_COOKED_URL
{
    //
    // Pointers overlap and point into pFullUrl.  NULL if not present.
    //

    USHORT FullUrlLength;       // in bytes not including the NULL
    USHORT HostLength;          // in bytes not including the NULL
    USHORT AbsPathLength;       // in bytes not including the NULL
    USHORT QueryStringLength;   // in bytes not including the NULL

    PWSTR pFullUrl;             // points to "http://...."
    PWSTR pHost;                // points to the first char in the hostname
    PWSTR pAbsPath;             // Points to the 3rd '/' char
    PWSTR pQueryString;         // Points to the 1st '?' char

} HTTP_COOKED_URL, *PHTTP_COOKED_URL;


//
// The structure of an HTTP request.
//

typedef struct _HTTP_REQUEST
{
    //
    // An opaque request identifier. These values are used by the driver
    // to correlate outgoing responses with incoming requests.
    //

    HTTP_CONNECTION_ID ConnectionId;
    HTTP_REQUEST_ID RequestId;

    //
    // The context associated with the URL prefix.
    //

    HTTP_URL_CONTEXT UrlContext;

    //
    // The HTTP version number.
    //

    HTTP_VERSION Version;

    //
    // The request verb.
    //

    HTTP_VERB Verb;

    //
    // An indication of the reason the request was issued to/from user-mode.
    //

    HTTP_REQUEST_REASON Reason;

    //
    // The pointer and length of the verb string if the Verb field is
    // HttpVerbUnknown.
    //

    //
    // The pointer and length of the raw URL.
    //

    USHORT UnknownVerbLength;           // in bytes not including the NULL
    USHORT RawUrlLength;                // in bytes not including the NULL

    PSTR pUnknownVerb;
    PSTR pRawUrl;

    //
    // The pointers and length of the canonicalized URL and parts.
    //

    HTTP_COOKED_URL CookedUrl;

    //
    // Transport addresses for the connection.
    //

    HTTP_TRANSPORT_ADDRESS Address;

    //
    // The request headers.
    //

    HTTP_REQUEST_HEADERS Headers;

    //
    // The total number of bytes received from network for this request.
    //

    ULONGLONG BytesReceived;

    //
    // 1 if there is more entity body to be read or written for this request.
    // 0 if there is no entity body or all of the entity body was copied into
    // pEntityChunks.
    //

    ULONG MoreEntityBodyExists:1;

    //
    // The pointer and length of any copied entity body.  Entity body is only
    // copied if HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY is passed to receive.
    //

    ULONG EntityChunkCount;
    PHTTP_DATA_CHUNK pEntityChunks;

    //
    // SSL connection information.
    //

    HTTP_RAW_CONNECTION_ID RawConnectionId;
    PHTTP_SSL_INFO pSslInfo;

} HTTP_REQUEST, *PHTTP_REQUEST;


//
// This structure describes an HTTP response.
//

typedef struct _HTTP_RESPONSE
{
    //
    // Response flags (see HTTP_RESPONSE_FLAG_* definitions below).
    //

    USHORT Flags;

    //
    // The raw HTTP version number.  Used by client side API only.
    //

    HTTP_VERSION Version;

    //
    // The HTTP status code (e.g. 200).
    //

    USHORT StatusCode;

    //
    // The HTTP reason (e.g. "OK") .  This is a unicode string for convenience,
    // but MUST not contain non-ascii characters.
    //

    ULONG ReasonLength;                 // in bytes not including the NULL
    PSTR pReason;

    //
    // The response headers.
    //

    HTTP_RESPONSE_HEADERS Headers;

    //
    // 1 if there is more entity body to be read or written for this response.
    // 0 if there is no entity body or all of the entity body was copied into
    // pEntityChunks.
    //

    ULONG MoreEntityBodyExists:1;

    //
    // The pointer and length of any entity body.
    //

    ULONG EntityChunkCount;
    PHTTP_DATA_CHUNK pEntityChunks;

} HTTP_RESPONSE, *PHTTP_RESPONSE;


//
// Flags for HTTP_RESPONSE_FLAGS.
//
// HTTP_RESPONSE_FLAG_CALC_CONTENT_LENGTH - The content length is
// calculated by summing the length of all entity body data chunks.
//
// HTTP_RESPONSE_FLAG_CALC_ETAG - An entity tag is calculated for
// the reponse based on the memory and file data chunks representing the
// entity data.
//
// HTTP_RESPONSE_FLAG_CALC_LAST_MODIFIED - The last modified time is
// calculated by examining the file data chunks within the entity body.
//

#define HTTP_RESPONSE_FLAG_CALC_CONTENT_LENGTH      0x00000001
#define HTTP_RESPONSE_FLAG_CALC_ETAG                0x00000002
#define HTTP_RESPONSE_FLAG_CALC_LAST_MODIFIED       0x00000004
#define HTTP_RESPONSE_FLAG_VALID                    0x00000007


//
// Cache control.
//

//
// This enum defines the available cache policies.
//

typedef enum _HTTP_CACHE_POLICY_TYPE
{
    HttpCachePolicyNocache,
    HttpCachePolicyUserInvalidates,
    HttpCachePolicyTimeToLive,

    HttpCachePolicyMaximum

} HTTP_CACHE_POLICY_TYPE, *PHTTP_CACHE_POLICY_TYPE;


//
//  o Only cache GET's + HEAD's.
//  o Don't cache if VARY is present.
//

typedef struct _HTTP_CACHE_POLICY
{
    HTTP_CACHE_POLICY_TYPE Policy;
    ULONG SecondsToLive;

} HTTP_CACHE_POLICY, *PHTTP_CACHE_POLICY;


//
// Filters and SSL.
//

//
// Data associated with raw transport connections.
//

typedef struct _HTTP_RAW_CONNECTION_INFO
{
    //
    // Connection ID.
    //

    HTTP_RAW_CONNECTION_ID ConnectionId;

    //
    // Transport address info.
    //

    HTTP_TRANSPORT_ADDRESS Address;

    //
    // Used by client APIs only
    //

    ULONG ServerNameLength;     // Length of server name (in bytes)
    PWSTR pServerName;          // Name of remote server

    //
    // Initial data.
    //

    ULONG InitialDataSize;      // size of initial data
    PVOID pInitialData;         // pointer to initial data

} HTTP_RAW_CONNECTION_INFO, *PHTTP_RAW_CONNECTION_INFO;


//
// Client certificate information.
//

typedef struct _HTTP_SSL_CLIENT_CERT_INFO
{
    ULONG CertFlags;
    ULONG CertEncodedSize;
    PUCHAR pCertEncoded;
    HANDLE Token;
    ULONG CertDeniedByMapper:1;

} HTTP_SSL_CLIENT_CERT_INFO, *PHTTP_SSL_CLIENT_CERT_INFO;


//
// Data computed during SSL handshake.
//

typedef struct _HTTP_SSL_INFO
{
    USHORT ServerCertKeySize;
    USHORT ConnectionKeySize;
    ULONG ServerCertIssuerSize;
    ULONG ServerCertSubjectSize;

    PSTR pServerCertIssuer;
    PSTR pServerCertSubject;

    PHTTP_SSL_CLIENT_CERT_INFO pClientCertInfo;

} HTTP_SSL_INFO, *PHTTP_SSL_INFO;


//
// For transfers between filters and upper levels.
//

typedef enum _HTTP_FILTER_BUFFER_TYPE
{
    HttpFilterBufferHttpStream,             // both directions
    HttpFilterBufferSslInitInfo,            // filter -> app
    HttpFilterBufferSslClientCert,          // filter -> app
    HttpFilterBufferSslClientCertAndMap,    // filter -> app
    HttpFilterBufferSslRenegotiate,         // app -> filter
    HttpFilterBufferSslRenegotiateAndMap,   // app -> filter
    HttpFilterBufferCloseConnection,        // app -> filter

    HttpFilterBufferMaximum

} HTTP_FILTER_BUFFER_TYPE;


//
// The buffer transferred between filters and upper levels.
//

typedef struct _HTTP_FILTER_BUFFER
{
    HTTP_FILTER_BUFFER_TYPE BufferType;

    ULONG BufferSize;
    PUCHAR pBuffer;

    ULONGLONG Reserved;

} HTTP_FILTER_BUFFER, *PHTTP_FILTER_BUFFER;


//
// Counter Group.
//

//
// Counter property description.
//

typedef struct _HTTP_PROP_DESC
{
    ULONG Size;
    ULONG Offset;
    BOOLEAN WPZeros;

} HTTP_PROP_DESC, *PHTTP_PROP_DESC;


//
// This enum defines the available couter groups.
//

typedef enum _HTTP_COUNTER_GROUP
{
    HttpCounterGroupSite,
    HttpCounterGroupGlobal,

    HttpCounterGroupMaximum

} HTTP_COUNTER_GROUP;


//
// This enum defines the type of global couters.
//

typedef enum _HTTP_GLOBAL_COUNTER_ID
{
    HttpGlobalCounterCurrentUrisCached,
    HttpGlobalCounterTotalUrisCached,
    HttpGlobalCounterUriCacheHits,
    HttpGlobalCounterUriCacheMisses,
    HttpGlobalCounterUriCacheFlushes,
    HttpGlobalCounterTotalFlushedUris,

    HttpGlobalCounterMaximum

} HTTP_GLOBAL_COUNTER_ID;


//
// Global couters.
//

typedef struct _HTTP_GLOBAL_COUNTERS
{
    ULONG CurrentUrisCached;
    ULONG TotalUrisCached;
    ULONG UriCacheHits;
    ULONG UriCacheMisses;
    ULONG UriCacheFlushes;
    ULONG TotalFlushedUris;

} HTTP_GLOBAL_COUNTERS, *PHTTP_GLOBAL_COUNTERS;


//
// This enum defines the type of site couters.
//

typedef enum _HTTP_SITE_COUNTER_ID
{
    HttpSiteCounterBytesSent,
    HttpSiteCounterBytesReceived,
    HttpSiteCounterBytesTransfered,
    HttpSiteCounterCurrentConns,
    HttpSiteCounterMaxConnections,
    HttpSiteCounterConnAttempts,
    HttpSiteCounterGetReqs,
    HttpSiteCounterHeadReqs,
    HttpSiteCounterAllReqs,
    HttpSiteCounterMeasuredIoBandwidthUsage,
    HttpSiteCounterCurrentBlockedBandwidthBytes,
    HttpSiteCounterTotalBlockedBandwidthBytes,

    HttpSiteCounterMaximum

} HTTP_SITE_COUNTER_ID;


//
// Site couters.
//

typedef struct _HTTP_SITE_COUNTERS
{
    ULONG SiteId;
    ULONGLONG BytesSent;
    ULONGLONG BytesReceived;
    ULONGLONG BytesTransfered;
    ULONG CurrentConns;
    ULONG MaxConnections;
    ULONG ConnAttempts;
    ULONG GetReqs;
    ULONG HeadReqs;
    ULONG AllReqs;
    ULONG MeasuredIoBandwidthUsage;
    ULONG CurrentBlockedBandwidthBytes;
    ULONG TotalBlockedBandwidthBytes;

} HTTP_SITE_COUNTERS, *PHTTP_SITE_COUNTERS;


#ifdef __cplusplus
}   // extern "C"
#endif  // __cplusplus


#endif  // _HTTPDEF_H_

