聚势成锋 發表於 2020-6-12 10:19:00

DELPHI如何封装http.sys

<p>DELPHI如何封装http.sys</p>
<p>http.sys是windows操作系统内核级实现的支持高并发的http通讯协议,是为了https而开发。</p>
<p>思路:windows操作系统将HTTP.SYS通讯协议封装在httpapi.dll动态库里面。任何开发语言通过加载此动态库,即可调用它里面的函数。当然DELPHI也不例外。</p>
<p>封装非常简单,下面贴出tms sparkle如何封装http.sys的代码:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">unit Sparkle.HttpSys.Api;

{$I Sparkle.Inc}
{$SCOPEDENUMS OFF}

interface

{$IFDEF MSWINDOWS}

uses
Winapi.Windows, Winapi.WinSock, System.SysUtils;

{$MinEnumSize 4}
{$Align 8}

const
HTTP_INITIALIZE_SERVER = $00000001;
HTTP_INITIALIZE_CONFIG = $00000002;

type
HTTP_SERVER_PROPERTY = (
    HttpServerAuthenticationProperty,
    HttpServerLoggingProperty,
    HttpServerQosProperty,
    HttpServerTimeoutsProperty,
    HttpServerQueueLengthProperty,
    HttpServerStateProperty,
    HttpServer503VerbosityProperty,
    HttpServerBindingProperty,
    HttpServerExtendedAuthenticationProperty,
    HttpServerListenEndpointProperty,
    HttpServerChannelBindProperty,
    HttpServerProtectionLevelProperty
);

const
HTTP_MAX_SERVER_QUEUE_LENGTH = $7FFFFFFF;
HTTP_MIN_SERVER_QUEUE_LENGTH = 1;

type
HTTP_PROPERTY_FLAGS = ULONG;
PHTTP_PROPERTY_FLAGS = ^HTTP_PROPERTY_FLAGS;

const
HTTP_PROPERTY_FLAG_NONE = $00000000;
HTTP_PROPERTY_FLAG_PRESENT = $00000001;

type
HTTP_ENABLED_STATE = (
    HttpEnabledStateActive,
    HttpEnabledStateInactive
);

HTTP_STATE_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    State: HTTP_ENABLED_STATE;
end;
PHTTP_STATE_INFO = ^HTTP_STATE_INFO;

HTTP_503_RESPONSE_VERBOSITY = (
    Http503ResponseVerbosityBasic,
    Http503ResponseVerbosityLimited,
    Http503ResponseVerbosityFull
);

HTTP_QOS_SETTING_TYPE = (
    HttpQosSettingTypeBandwidth,
    HttpQosSettingTypeConnectionLimit,
    HttpQosSettingTypeFlowRate
);

HTTP_QOS_SETTING_INFO = record
    QosType: HTTP_QOS_SETTING_TYPE;
    QosSetting: PVOID;
end;
PHTTP_QOS_SETTING_INFO = ^HTTP_QOS_SETTING_INFO;

HTTP_CONNECTION_LIMIT_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    MaxConnections: ULONG;
end;
PHTTP_CONNECTION_LIMIT_INFO = ^HTTP_CONNECTION_LIMIT_INFO;

HTTP_BANDWIDTH_LIMIT_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    MaxBandwidth: ULONG;
end;
PHTTP_BANDWIDTH_LIMIT_INFO = ^HTTP_BANDWIDTH_LIMIT_INFO;

HTTP_FLOWRATE_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    MaxBandwidth: ULONG;
    MaxPeakBandwidth: ULONG;
    BurstSize: ULONG;
end;
PHTTP_FLOWRATE_INFO = ^HTTP_FLOWRATE_INFO;

const
HTTP_MIN_ALLOWED_BANDWIDTH_THROTTLING_RATE = ULONG(1024);
HTTP_LIMIT_INFINITE = ULONG(-1);

type
HTTP_SERVICE_CONFIG_TIMEOUT_KEY = (
    IdleConnectionTimeout = 0,
    HeaderWaitTimeout
);

HTTP_SERVICE_CONFIG_TIMEOUT_PARAM = USHORT;
PHTTP_SERVICE_CONFIG_TIMEOUT_PARAM = ^HTTP_SERVICE_CONFIG_TIMEOUT_PARAM;

HTTP_SERVICE_CONFIG_TIMEOUT_SET = record
    KeyDesc: HTTP_SERVICE_CONFIG_TIMEOUT_KEY;
    ParamDesc: HTTP_SERVICE_CONFIG_TIMEOUT_PARAM;
end;
PHTTP_SERVICE_CONFIG_TIMEOUT_SET = ^HTTP_SERVICE_CONFIG_TIMEOUT_SET;

HTTP_TIMEOUT_LIMIT_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    EntityBody: USHORT;
    DrainEntityBody: USHORT;
    RequestQueue: USHORT;
    IdleConnection: USHORT;
    HeaderWait: USHORT;
    MinSendRate: ULONG;
end;
PHTTP_TIMEOUT_LIMIT_INFO = ^HTTP_TIMEOUT_LIMIT_INFO;

HTTP_LISTEN_ENDPOINT_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    EnableSharing: Boolean;
end;
PHTTP_LISTEN_ENDPOINT_INFO = ^HTTP_LISTEN_ENDPOINT_INFO;

HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS = record
    DomainNameLength: USHORT;
    DomainName: PWideChar;
    RealmLength: USHORT;
    Realm: PWideChar;
end;
PHTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS = ^HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS;

HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS = record
    RealmLength: USHORT;
    Realm: PWideChar;
end;
PHTTP_SERVER_AUTHENTICATION_BASIC_PARAMS = ^HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS;

const
HTTP_AUTH_ENABLE_BASIC = $00000001;
HTTP_AUTH_ENABLE_DIGEST = $00000002;
HTTP_AUTH_ENABLE_NTLM = $00000004;
HTTP_AUTH_ENABLE_NEGOTIATE = $00000008;
HTTP_AUTH_ENABLE_KERBEROS = $00000010;
HTTP_AUTH_ENABLE_ALL = $0000001F;

HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING = $01;
HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL = $02;

type
HTTP_SERVER_AUTHENTICATION_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    AuthSchemes: ULONG;
    ReceiveMutualAuth: BOOLEAN;
    ReceiveContextHandle: BOOLEAN;
    DisableNTLMCredentialCaching: BOOLEAN;
    ExFlags: UCHAR;
    DigestParams: HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS;
    BasicParams: HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS;
end;
PHTTP_SERVER_AUTHENTICATION_INFO = ^HTTP_SERVER_AUTHENTICATION_INFO;

HTTP_SERVICE_BINDING_TYPE = (
    HttpServiceBindingTypeNone = 0,
    HttpServiceBindingTypeW,
    HttpServiceBindingTypeA
);

HTTP_SERVICE_BINDING_BASE = record
    _Type: HTTP_SERVICE_BINDING_TYPE;
end;
PHTTP_SERVICE_BINDING_BASE = ^HTTP_SERVICE_BINDING_BASE;
PPHTTP_SERVICE_BINDING_BASE = ^PHTTP_SERVICE_BINDING_BASE;

HTTP_SERVICE_BINDING_A = record
    Base: HTTP_SERVICE_BINDING_BASE;
    Buffer: PAnsiChar;
    BufferSize: ULONG;
end;
PHTTP_SERVICE_BINDING_A = ^HTTP_SERVICE_BINDING_A;

HTTP_SERVICE_BINDING_W = record
    Base: HTTP_SERVICE_BINDING_BASE;
    Buffer: PWCHAR;
    BufferSize: ULONG;
end;
PHTTP_SERVICE_BINDING_W = ^HTTP_SERVICE_BINDING_W;

HTTP_AUTHENTICATION_HARDENING_LEVELS = (
    HttpAuthenticationHardeningLegacy = 0,
    HttpAuthenticationHardeningMedium,
    HttpAuthenticationHardeningStrict
);

const
HTTP_CHANNEL_BIND_PROXY = $1;
HTTP_CHANNEL_BIND_PROXY_COHOSTING = $20;
HTTP_CHANNEL_BIND_NO_SERVICE_NAME_CHECK = $2;
HTTP_CHANNEL_BIND_DOTLESS_SERVICE = $4;
HTTP_CHANNEL_BIND_SECURE_CHANNEL_TOKEN = $8;
HTTP_CHANNEL_BIND_CLIENT_SERVICE = $10;

type
HTTP_CHANNEL_BIND_INFO = record
    Hardening: HTTP_AUTHENTICATION_HARDENING_LEVELS;
    Flags: ULONG;
    ServiceNames: PPHTTP_SERVICE_BINDING_BASE;
    NumberOfServiceNames: ULONG;
end;
PHTTP_CHANNEL_BIND_INFO = ^HTTP_CHANNEL_BIND_INFO;

HTTP_REQUEST_CHANNEL_BIND_STATUS = record
    ServiceName: PHTTP_SERVICE_BINDING_BASE;
    ChannelToken: PUCHAR;
    ChannelTokenSize: ULONG;
    Flags: ULONG;
end;
PHTTP_REQUEST_CHANNEL_BIND_STATUS = ^HTTP_REQUEST_CHANNEL_BIND_STATUS;

const
HTTP_LOG_FIELD_DATE = $00000001;
HTTP_LOG_FIELD_TIME = $00000002;
HTTP_LOG_FIELD_CLIENT_IP = $00000004;
HTTP_LOG_FIELD_USER_NAME = $00000008;
HTTP_LOG_FIELD_SITE_NAME = $00000010;
HTTP_LOG_FIELD_COMPUTER_NAME = $00000020;
HTTP_LOG_FIELD_SERVER_IP = $00000040;
HTTP_LOG_FIELD_METHOD = $00000080;
HTTP_LOG_FIELD_URI_STEM = $00000100;
HTTP_LOG_FIELD_URI_QUERY = $00000200;
HTTP_LOG_FIELD_STATUS = $00000400;
HTTP_LOG_FIELD_WIN32_STATUS = $00000800;
HTTP_LOG_FIELD_BYTES_SENT = $00001000;
HTTP_LOG_FIELD_BYTES_RECV = $00002000;
HTTP_LOG_FIELD_TIME_TAKEN = $00004000;
HTTP_LOG_FIELD_SERVER_PORT = $00008000;
HTTP_LOG_FIELD_USER_AGENT = $00010000;
HTTP_LOG_FIELD_COOKIE = $00020000;
HTTP_LOG_FIELD_REFERER = $00040000;
HTTP_LOG_FIELD_VERSION = $00080000;
HTTP_LOG_FIELD_HOST = $00100000;
HTTP_LOG_FIELD_SUB_STATUS = $00200000;

HTTP_LOG_FIELD_CLIENT_PORT = $00400000;
HTTP_LOG_FIELD_URI = $00800000;
HTTP_LOG_FIELD_SITE_ID = $01000000;
HTTP_LOG_FIELD_REASON = $02000000;
HTTP_LOG_FIELD_QUEUE_NAME = $04000000;

type
HTTP_LOGGING_TYPE = (
    HttpLoggingTypeW3C,
    HttpLoggingTypeIIS,
    HttpLoggingTypeNCSA,
    HttpLoggingTypeRaw
);

HTTP_LOGGING_ROLLOVER_TYPE = (
    HttpLoggingRolloverSize,
    HttpLoggingRolloverDaily,
    HttpLoggingRolloverWeekly,
    HttpLoggingRolloverMonthly,
    HttpLoggingRolloverHourly
);

const
HTTP_MIN_ALLOWED_LOG_FILE_ROLLOVER_SIZE = ULONG(1* 1024* 1024);

HTTP_LOGGING_FLAG_LOCAL_TIME_ROLLOVER = $00000001;
HTTP_LOGGING_FLAG_USE_UTF8_CONVERSION = $00000002;
HTTP_LOGGING_FLAG_LOG_ERRORS_ONLY = $00000004;
HTTP_LOGGING_FLAG_LOG_SUCCESS_ONLY = $00000008;

type
HTTP_LOGGING_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    LoggingFlags: ULONG;
    SoftwareName: PWideChar;
    SoftwareNameLength: USHORT;
    DirectoryNameLength: USHORT;
    DirectoryName: PWideChar;
    Format: HTTP_LOGGING_TYPE;
    Fields: ULONG;
    pExtFields: PVOID;
    NumOfExtFields: USHORT;
    MaxRecordSize: USHORT;
    RolloverType: HTTP_LOGGING_ROLLOVER_TYPE;
    RolloverSize: ULONG;
    pSecurityDescriptor: PSECURITY_DESCRIPTOR;
end;
PHTTP_LOGGING_INFO = ^HTTP_LOGGING_INFO;

HTTP_BINDING_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    RequestQueueHandle: THandle;
end;
PHTTP_BINDING_INFO = ^HTTP_BINDING_INFO;

HTTP_PROTECTION_LEVEL_TYPE = (
    HttpProtectionLevelUnrestricted,
    HttpProtectionLevelEdgeRestricted,
    HttpProtectionLevelRestricted
);

HTTP_PROTECTION_LEVEL_INFO = record
    Flags: HTTP_PROPERTY_FLAGS;
    Level: HTTP_PROTECTION_LEVEL_TYPE;
end;
PHTTP_PROTECTION_LEVEL_INFO = ^HTTP_PROTECTION_LEVEL_INFO;

const
HTTP_CREATE_REQUEST_QUEUE_FLAG_OPEN_EXISTING = $00000001;
HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER = $00000002;

HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY = $00000001;
HTTP_RECEIVE_REQUEST_FLAG_FLUSH_BODY = $00000002;

HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER = $00000001;

HTTP_SEND_RESPONSE_FLAG_DISCONNECT = $00000001;
HTTP_SEND_RESPONSE_FLAG_MORE_DATA = $00000002;
HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA = $00000004;
HTTP_SEND_RESPONSE_FLAG_ENABLE_NAGLING = $00000008;
HTTP_SEND_RESPONSE_FLAG_PROCESS_RANGES = $00000020;

HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE = $00000001;

type
HTTP_OPAQUE_ID = ULONGLONG;
PHTTP_OPAQUE_ID = ^HTTP_OPAQUE_ID;

HTTP_REQUEST_ID = HTTP_OPAQUE_ID;
PHTTP_REQUEST_ID = ^HTTP_REQUEST_ID;

HTTP_CONNECTION_ID = HTTP_OPAQUE_ID;
PHTTP_CONNECTION_ID = ^HTTP_CONNECTION_ID;

HTTP_RAW_CONNECTION_ID = HTTP_OPAQUE_ID;
PHTTP_RAW_CONNECTION_ID = ^HTTP_RAW_CONNECTION_ID;

HTTP_URL_GROUP_ID = HTTP_OPAQUE_ID;
PHTTP_URL_GROUP_ID = ^HTTP_URL_GROUP_ID;

HTTP_SERVER_SESSION_ID = HTTP_OPAQUE_ID;
PHTTP_SERVER_SESSION_ID = ^HTTP_SERVER_SESSION_ID;

const
HTTP_NULL_ID = ULONG(0);
HTTP_BYTE_RANGE_TO_EOF = ULONGLONG(-1);

type
HTTP_BYTE_RANGE = record
    StartingOffset: ULARGE_INTEGER;
    Length: ULARGE_INTEGER;
end;
PHTTP_BYTE_RANGE = ^HTTP_BYTE_RANGE;

HTTP_VERSION = record
    MajorVersion: USHORT;
    MinorVersion: USHORT;
end;
PHTTP_VERSION = ^HTTP_VERSION;

const
HTTP_VERSION_UNKNOWN: HTTP_VERSION = (MajorVersion: 0; MinorVersion: 0);
HTTP_VERSION_0_9: HTTP_VERSION = (MajorVersion: 0; MinorVersion: 9);
HTTP_VERSION_1_0: HTTP_VERSION = (MajorVersion: 1; MinorVersion: 0);
HTTP_VERSION_1_1: HTTP_VERSION = (MajorVersion: 1; MinorVersion: 1);

type
HTTP_VERB = (
    HttpVerbUnparsed,
    HttpVerbUnknown,
    HttpVerbInvalid,
    HttpVerbOPTIONS,
    HttpVerbGET,
    HttpVerbHEAD,
    HttpVerbPOST,
    HttpVerbPUT,
    HttpVerbDELETE,
    HttpVerbTRACE,
    HttpVerbCONNECT,
    HttpVerbTRACK,
    HttpVerbMOVE,
    HttpVerbCOPY,
    HttpVerbPROPFIND,
    HttpVerbPROPPATCH,
    HttpVerbMKCOL,
    HttpVerbLOCK,
    HttpVerbUNLOCK,
    HttpVerbSEARCH,
    HttpVerbMaximum
);

HTTP_HEADER_ID = (
    HttpHeaderCacheControl          = 0,    // general-header
    HttpHeaderConnection            = 1,    // general-header
    HttpHeaderDate                  = 2,    // general-header
    HttpHeaderKeepAlive             = 3,    // general-header
    HttpHeaderPragma                = 4,    // general-header
    HttpHeaderTrailer               = 5,    // general-header
    HttpHeaderTransferEncoding      = 6,    // general-header
    HttpHeaderUpgrade               = 7,    // general-header
    HttpHeaderVia                   = 8,    // general-header
    HttpHeaderWarning               = 9,    // general-header

    HttpHeaderAllow               = 10,   // entity-header
    HttpHeaderContentLength         = 11,   // entity-header
    HttpHeaderContentType         = 12,   // entity-header
    HttpHeaderContentEncoding       = 13,   // entity-header
    HttpHeaderContentLanguage       = 14,   // entity-header
    HttpHeaderContentLocation       = 15,   // entity-header
    HttpHeaderContentMd5            = 16,   // entity-header
    HttpHeaderContentRange          = 17,   // entity-header
    HttpHeaderExpires               = 18,   // entity-header
    HttpHeaderLastModified          = 19,   // entity-header

    HttpHeaderAccept                = 20,   // request-header
    HttpHeaderAcceptCharset         = 21,   // request-header
    HttpHeaderAcceptEncoding      = 22,   // request-header
    HttpHeaderAcceptLanguage      = 23,   // request-header
    HttpHeaderAuthorization         = 24,   // request-header
    HttpHeaderCookie                = 25,   // request-header
    HttpHeaderExpect                = 26,   // request-header
    HttpHeaderFrom                  = 27,   // request-header
    HttpHeaderHost                  = 28,   // request-header
    HttpHeaderIfMatch               = 29,   // request-header

    HttpHeaderIfModifiedSince       = 30,   // request-header
    HttpHeaderIfNoneMatch         = 31,   // request-header
    HttpHeaderIfRange               = 32,   // request-header
    HttpHeaderIfUnmodifiedSince   = 33,   // request-header
    HttpHeaderMaxForwards         = 34,   // request-header
    HttpHeaderProxyAuthorization    = 35,   // request-header
    HttpHeaderReferer               = 36,   // request-header
    HttpHeaderRange               = 37,   // request-header
    HttpHeaderTe                  = 38,   // request-header
    HttpHeaderTranslate             = 39,   // request-header
    HttpHeaderUserAgent             = 40,   // request-header
    HttpHeaderRequestMaximum      = 41,

    // Response Headers
    HttpHeaderAcceptRanges          = 20,   // response-header
    HttpHeaderAge                   = 21,   // response-header
    HttpHeaderEtag                  = 22,   // response-header
    HttpHeaderLocation            = 23,   // response-header
    HttpHeaderProxyAuthenticate   = 24,   // response-header
    HttpHeaderRetryAfter            = 25,   // response-header
    HttpHeaderServer                = 26,   // response-header
    HttpHeaderSetCookie             = 27,   // response-header
    HttpHeaderVary                  = 28,   // response-header
    HttpHeaderWwwAuthenticate       = 29,   // response-header
    HttpHeaderResponseMaximum       = 30,

    HttpHeaderMaximum               = 41
);

HTTP_KNOWN_HEADER = record
    RawValueLength: USHORT;
    pRawValue: PAnsiChar;
end;
PHTTP_KNOWN_HEADER = ^HTTP_KNOWN_HEADER;

HTTP_UNKNOWN_HEADER = record
    NameLength: USHORT;
    RawValueLength: USHORT;
    pName: PAnsiChar;
    pRawValue: PAnsiChar;
end;
PHTTP_UNKNOWN_HEADER = ^HTTP_UNKNOWN_HEADER;

HTTP_LOG_DATA_TYPE = (
    HttpLogDataTypeFields
);

HTTP_LOG_DATA = record
    _Type: HTTP_LOG_DATA_TYPE;
end;
PHTTP_LOG_DATA = ^HTTP_LOG_DATA;

HTTP_LOG_FIELDS_DATA = record
    Base: HTTP_LOG_DATA;
    UserNameLength: USHORT;
    UriStemLength: USHORT;
    ClientIpLength: USHORT;
    ServerNameLength: USHORT;
    ServiceNameLength: USHORT;
    ServerIpLength: USHORT;
    MethodLength: USHORT;
    UriQueryLength: USHORT;
    HostLength: USHORT;
    UserAgentLength: USHORT;
    CookieLength: USHORT;
    ReferrerLength: USHORT;
    UserName: PWCHAR;
    UriStem: PWCHAR;
    ClientIp: PAnsiChar;
    ServerName: PAnsiChar;
    ServiceName: PAnsiChar;
    ServerIp: PAnsiChar;
    Method: PAnsiChar;
    UriQuery: PAnsiChar;
    Host: PAnsiChar;
    UserAgent: PAnsiChar;
    Cookie: PAnsiChar;
    Referrer: PAnsiChar;
    ServerPort: USHORT;
    ProtocolStatus: USHORT;
    Win32Status: ULONG;
    MethodNum: HTTP_VERB;
    SubStatus: USHORT;
end;
PHTTP_LOG_FIELDS_DATA = ^HTTP_LOG_FIELDS_DATA;

HTTP_DATA_CHUNK_TYPE = (
    HttpDataChunkFromMemory,
    HttpDataChunkFromFileHandle,
    HttpDataChunkFromFragmentCache,
    HttpDataChunkFromFragmentCacheEx,
    HttpDataChunkMaximum
);

HTTP_DATA_CHUNK = record
    DataChunkType: HTTP_DATA_CHUNK_TYPE;
    case HTTP_DATA_CHUNK_TYPE of
      HttpDataChunkFromMemory: (
      pBuffer: PVOID;
      BufferLength: ULONG;
      );
      HttpDataChunkFromFileHandle: (
      ByteRange: HTTP_BYTE_RANGE;
                          FileHandle: THandle;
      );
      HttpDataChunkFromFragmentCache: (
      FragmentNameLength: USHORT;
      pFragmentName: PWideChar;
      );
      HttpDataChunkFromFragmentCacheEx: (
      ByteRangeEx: HTTP_BYTE_RANGE;
      pFragmentNameEx: PWideChar;
      );
end;
PHTTP_DATA_CHUNK = ^HTTP_DATA_CHUNK;

HTTP_REQUEST_HEADERS = record
    UnknownHeaderCount: USHORT;
    pUnknownHeaders: PHTTP_UNKNOWN_HEADER;
    TrailerCount: USHORT;
    pTrailers: PHTTP_UNKNOWN_HEADER;
    KnownHeaders: array of HTTP_KNOWN_HEADER;
end;
PHTTP_REQUEST_HEADERS = ^HTTP_REQUEST_HEADERS;

HTTP_RESPONSE_HEADERS = record
    UnknownHeaderCount: USHORT;
    pUnknownHeaders: PHTTP_UNKNOWN_HEADER;
    TrailerCount: USHORT;
    pTrailers: PHTTP_UNKNOWN_HEADER;
    KnownHeaders: Array of HTTP_KNOWN_HEADER;
end;
PHTTP_RESPONSE_HEADERS = ^HTTP_RESPONSE_HEADERS;

HTTP_TRANSPORT_ADDRESS = record
    pRemoteAddress: PSOCKADDR;
    pLocalAddress: PSOCKADDR;
end;
PHTTP_TRANSPORT_ADDRESS = ^HTTP_TRANSPORT_ADDRESS;

HTTP_COOKED_URL = record
    FullUrlLength: USHORT;
    HostLength: USHORT;
    AbsPathLength: USHORT;
    QueryStringLength: USHORT;
    pFullUrl: PWideChar;
    pHost: PWideChar;
    pAbsPath: PWideChar;
    pQueryString: PWideChar;
end;
PHTTP_COOKED_URL = ^HTTP_COOKED_URL;

HTTP_URL_CONTEXT = ULONGLONG;

const
HTTP_URL_FLAG_REMOVE_ALL = $00000001;

type
HTTP_AUTH_STATUS = (
    HttpAuthStatusSuccess,
    HttpAuthStatusNotAuthenticated,
    HttpAuthStatusFailure
);

HTTP_REQUEST_AUTH_TYPE = (
    HttpRequestAuthTypeNone = 0,
    HttpRequestAuthTypeBasic,
    HttpRequestAuthTypeDigest,
    HttpRequestAuthTypeNTLM,
    HttpRequestAuthTypeNegotiate,
    HttpRequestAuthTypeKerberos
);

HTTP_SSL_CLIENT_CERT_INFO = record
    CertFlags: ULONG;
    CertEncodedSize: ULONG;
    pCertEncoded: PUCHAR;
    Token: THandle;
    CertDeniedByMapper: BOOLEAN;
end;
PHTTP_SSL_CLIENT_CERT_INFO = ^HTTP_SSL_CLIENT_CERT_INFO;

const
HTTP_RECEIVE_SECURE_CHANNEL_TOKEN = $1;

type
HTTP_SSL_INFO = record
    ServerCertKeySize: USHORT;
    ConnectionKeySize: USHORT;
    ServerCertIssuerSize: ULONG;
    ServerCertSubjectSize: ULONG;
    pServerCertIssuer: PAnsiChar;
    pServerCertSubject: PAnsiChar;
    pClientCertInfo: PHTTP_SSL_CLIENT_CERT_INFO;
    SslClientCertNegotiated: ULONG;
end;
PHTTP_SSL_INFO = ^HTTP_SSL_INFO;

HTTP_REQUEST_INFO_TYPE = (
    HttpRequestInfoTypeAuth,
    HttpRequestInfoTypeChannelBind
);

HTTP_REQUEST_INFO = record
    InfoType: HTTP_REQUEST_INFO_TYPE;
    InfoLength: ULONG;
    pInfo: PVOID;
end;
PHTTP_REQUEST_INFO = ^HTTP_REQUEST_INFO;

SECURITY_STATUS = LongInt;

const
HTTP_REQUEST_AUTH_FLAG_TOKEN_FOR_CACHED_CRED = $00000001;

type
HTTP_REQUEST_AUTH_INFO = record
    AuthStatus: HTTP_AUTH_STATUS;
    SecStatus: SECURITY_STATUS;
    Flags: ULONG;
    AuthType: HTTP_REQUEST_AUTH_TYPE;
    AccessToken: THandle;
    ContextAttributes: ULONG;
    PackedContextLength: ULONG;
    PackedContextType: ULONG;
    PackedContext: PVOID;
    MutualAuthDataLength: ULONG;
    pMutualAuthData: PChar;
    PackageNameLength: USHORT;
    pPackageName: PWideChar;
end;
PHTTP_REQUEST_AUTH_INFO = ^HTTP_REQUEST_AUTH_INFO;

HTTP_REQUEST_V2 = record
    Flags: ULONG;
    ConnectionId: HTTP_CONNECTION_ID;
    RequestId: HTTP_REQUEST_ID;
    UrlContext: HTTP_URL_CONTEXT;
    Version: HTTP_VERSION;
    Verb: HTTP_VERB;
    UnknownVerbLength: USHORT;
    RawUrlLength: USHORT;
    pUnknownVerb: PAnsiChar;
    pRawUrl: PAnsiChar;
    CookedUrl: HTTP_COOKED_URL;
    Address: HTTP_TRANSPORT_ADDRESS;
    Headers: HTTP_REQUEST_HEADERS;
    BytesReceived: ULONGLONG;
    EntityChunkCount: USHORT;
    pEntityChunks: PHTTP_DATA_CHUNK;
    RawConnectionId: HTTP_RAW_CONNECTION_ID;
    pSslInfo: PHTTP_SSL_INFO;
    Dummy1: DWORD;
    RequestInfoCount: USHORT;
    pRequestInfo: PHTTP_REQUEST_INFO;
end;
PHTTP_REQUEST_V2 = ^HTTP_REQUEST_V2;

HTTP_REQUEST = HTTP_REQUEST_V2;
PHTTP_REQUEST = ^HTTP_REQUEST;

const
HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS = $00000001;
HTTP_REQUEST_FLAG_IP_ROUTED = $00000002;

const
HTTP_RESPONSE_FLAG_MULTIPLE_ENCODINGS_AVAILABLE = $00000001;

type
HTTP_RESPONSE_INFO_TYPE = (
    HttpResponseInfoTypeMultipleKnownHeaders,
    HttpResponseInfoTypeAuthenticationProperty,
    HttpResponseInfoTypeQoSProperty,
    HttpResponseInfoTypeChannelBind
);

HTTP_RESPONSE_INFO = record
    _Type: HTTP_RESPONSE_INFO_TYPE;
    Length: ULONG;
    pInfo: PVOID;
end;
PHTTP_RESPONSE_INFO = ^HTTP_RESPONSE_INFO;

const
HTTP_RESPONSE_INFO_FLAGS_PRESERVE_ORDER = $00000001;

type
HTTP_MULTIPLE_KNOWN_HEADERS = record
    HeaderId: HTTP_HEADER_ID;
    Flags: ULONG;
    KnownHeaderCount: USHORT;
    KnownHeaders: PHTTP_KNOWN_HEADER;
end;
PHTTP_MULTIPLE_KNOWN_HEADERS = ^HTTP_MULTIPLE_KNOWN_HEADERS;

HTTP_RESPONSE_V2 = record
    Flags: ULONG;
    Version: HTTP_VERSION;
    StatusCode: USHORT;
    ReasonLength: USHORT;
    pReason: PAnsiChar;
    Headers: HTTP_RESPONSE_HEADERS;
    EntityChunkCount: USHORT;
    pEntityChunks: PHTTP_DATA_CHUNK;
    ResponseInfoCount: USHORT;
    pResponseInfo: PHTTP_RESPONSE_INFO;
end;
PHTTP_RESPONSE_V2 = ^HTTP_RESPONSE_V2;

HTTP_RESPONSE = HTTP_RESPONSE_V2;
PHTTP_RESPONSE = ^HTTP_RESPONSE;

HTTPAPI_VERSION = record
    HttpApiMajorVersion: USHORT;
    HttpApiMinorVersion: USHORT;
end;
PHTTPAPI_VERSION = ^HTTPAPI_VERSION;

const
HTTPAPI_VERSION_1: HTTPAPI_VERSION = (HttpApiMajorVersion: 1; HttpApiMinorVersion: 0);
HTTPAPI_VERSION_2: HTTPAPI_VERSION = (HttpApiMajorVersion: 2; HttpApiMinorVersion: 0);

type
HTTP_CACHE_POLICY_TYPE = (
    HttpCachePolicyNocache,
    HttpCachePolicyUserInvalidates,
    HttpCachePolicyTimeToLive,
    HttpCachePolicyMaximum
);

HTTP_CACHE_POLICY = record
    Policy: HTTP_CACHE_POLICY_TYPE;
    SecondsToLive: ULONG;
end;
PHTTP_CACHE_POLICY = ^HTTP_CACHE_POLICY;

HTTP_SERVICE_CONFIG_ID = (
    HttpServiceConfigIPListenList,
    HttpServiceConfigSSLCertInfo,
    HttpServiceConfigUrlAclInfo,
    HttpServiceConfigTimeout,
    HttpServiceConfigCache,
    HttpServiceConfigMax
);

HTTP_SERVICE_CONFIG_QUERY_TYPE = (
    HttpServiceConfigQueryExact,
    HttpServiceConfigQueryNext,
    HttpServiceConfigQueryMax
);

HTTP_SERVICE_CONFIG_SSL_KEY = record
    pIpPort: PSOCKADDR;
end;
PHTTP_SERVICE_CONFIG_SSL_KEY = ^HTTP_SERVICE_CONFIG_SSL_KEY;

HTTP_SERVICE_CONFIG_SSL_PARAM = record
    SslHashLength: ULONG;
    pSslHash: PVOID;
    AppId: TGUID;
    pSslCertStoreName: PWideChar;
    DefaultCertCheckMode: LongInt;
    DefaultRevocationFreshnessTime: LongInt;
    DefaultRevocationUrlRetrievalTimeout: LongInt;
    pDefaultSslCtlIdentifier: PWideChar;
    pDefaultSslCtlStoreName: PWideChar;
    DefaultFlags: LongInt;
end;
PHTTP_SERVICE_CONFIG_SSL_PARAM = ^HTTP_SERVICE_CONFIG_SSL_PARAM;

const
HTTP_SERVICE_CONFIG_SSL_FLAG_USE_DS_MAPPER = $00000001;
HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT = $00000002;
HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER = $00000004;

type
HTTP_SERVICE_CONFIG_SSL_SET = record
    KeyDesc: HTTP_SERVICE_CONFIG_SSL_KEY;
    ParamDesc: HTTP_SERVICE_CONFIG_SSL_PARAM;
end;
PHTTP_SERVICE_CONFIG_SSL_SET = ^HTTP_SERVICE_CONFIG_SSL_SET;

HTTP_SERVICE_CONFIG_SSL_QUERY = record
    QueryDesc: HTTP_SERVICE_CONFIG_QUERY_TYPE;
    KeyDesc: HTTP_SERVICE_CONFIG_SSL_KEY;
    dwToken: LongInt;
end {_HTTP_SERVICE_CONFIG_SSL_QUERY};
PHTTP_SERVICE_CONFIG_SSL_QUERY = ^HTTP_SERVICE_CONFIG_SSL_QUERY;

HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM = record
    AddrLength: USHORT;
    pAddress: PSOCKADDR;
end;
PHTTP_SERVICE_CONFIG_IP_LISTEN_PARAM = ^HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM;

//HTTP_SERVICE_CONFIG_IP_LISTEN_QUERY = record
//    AddrCount: ULONG;
//    AddrList: Array of SOCKADDR_STORAGE;
//end;
//PHTTP_SERVICE_CONFIG_IP_LISTEN_QUERY = ^HTTP_SERVICE_CONFIG_IP_LISTEN_QUERY;

HTTP_SERVICE_CONFIG_URLACL_KEY = record
    pUrlPrefix: PWideChar;
end;
PHTTP_SERVICE_CONFIG_URLACL_KEY = ^HTTP_SERVICE_CONFIG_URLACL_KEY;

HTTP_SERVICE_CONFIG_URLACL_PARAM = record
    pStringSecurityDescriptor: PWideChar;
end;
PHTTP_SERVICE_CONFIG_URLACL_PARAM = ^HTTP_SERVICE_CONFIG_URLACL_PARAM;

HTTP_SERVICE_CONFIG_URLACL_SET = record
    KeyDesc: HTTP_SERVICE_CONFIG_URLACL_KEY;
    ParamDesc: HTTP_SERVICE_CONFIG_URLACL_PARAM;
end;
PHTTP_SERVICE_CONFIG_URLACL_SET = ^HTTP_SERVICE_CONFIG_URLACL_SET;

HTTP_SERVICE_CONFIG_URLACL_QUERY = record
    QueryDesc: HTTP_SERVICE_CONFIG_QUERY_TYPE;
    KeyDesc: HTTP_SERVICE_CONFIG_URLACL_KEY;
    dwToken: LongInt;
end;
PHTTP_SERVICE_CONFIG_URLACL_QUERY = ^HTTP_SERVICE_CONFIG_URLACL_QUERY;

HTTP_SERVICE_CONFIG_CACHE_KEY = (
    MaxCacheResponseSize = 0,
    CacheRangeChunkSize
);

HTTP_SERVICE_CONFIG_CACHE_PARAM = ULONG;
PHTTP_SERVICE_CONFIG_CACHE_PARAM = ^HTTP_SERVICE_CONFIG_CACHE_PARAM;

HTTP_SERVICE_CONFIG_CACHE_SET = record
    KeyDesc: HTTP_SERVICE_CONFIG_CACHE_KEY;
    ParamDesc: HTTP_SERVICE_CONFIG_CACHE_PARAM;
end {HTTP_SERVICE_CONFIG_CACHE_SET};
PHTTP_SERVICE_CONFIG_CACHE_SET = ^HTTP_SERVICE_CONFIG_CACHE_SET;

// Specific Types (not present in original http.h)

const
HttpVerbNames: array of string = (
    '',               //HttpVerbUnparsed,
    '',               //HttpVerbUnknown,
    '',               //HttpVerbInvalid,
    'OPTIONS',          //HttpVerbOPTIONS,
    'GET',            //HttpVerbGET,
    'HEAD',             //HttpVerbHEAD,
    'POST',             //HttpVerbPOST,
    'PUT',            //HttpVerbPUT,
    'DELETE',         //HttpVerbDELETE,
    'TRACE',            //HttpVerbTRACE,
    'CONNECT',          //HttpVerbCONNECT,
    'TRACK',            //HttpVerbTRACK,
    'MOVE',             //HttpVerbMOVE,
    'COPY',             //HttpVerbCOPY,
    'PROPFIND',         //HttpVerbPROPFIND,
    'PROPPATCH',      //HttpVerbPROPPATCH,
    'MKCOL',            //HttpVerbMKCOL,
    'LOCK',             //HttpVerbLOCK,
    'UNLOCK',         //HttpVerbUNLOCK,
    'SEARCH',         //HttpVerbSEARCH,
    ''                  //HttpVerbMaximum
);

HttpRequestHeaderNames: array of string = (
    'cache-control',            //HttpHeaderCacheControl
    'connection',               //HttpHeaderConnection
    'date',                     //HttpHeaderDate
    'keep-alive',               //HttpHeaderKeepAlive
    'pragma',                   //HttpHeaderPragma
    'trailer',                  //HttpHeaderTrailer
    'transfer-encoding',      //HttpHeaderTransferEncoding
    'upgrade',                  //HttpHeaderUpgrade
    'via',                      //HttpHeaderVia
    'warning',                  //HttpHeaderWarning
    'allow',                  //HttpHeaderAllow
    'content-length',         //HttpHeaderContentLength
    'content-type',             //HttpHeaderContentType
    'content-encoding',         //HttpHeaderContentEncoding
    'content-language',         //HttpHeaderContentLanguage
    'content-location',         //HttpHeaderContentLocation
    'content-md5',            //HttpHeaderContentMd5
    'content-range',            //HttpHeaderContentRange
    'expires',                  //HttpHeaderExpires
    'last-modified',            //HttpHeaderLastModified
    'accept',                   //HttpHeaderAccept
    'accept-charset',         //HttpHeaderAcceptCharset
    'accept-encoding',          //HttpHeaderAcceptEncoding
    'accept-language',          //HttpHeaderAcceptLanguage
    'authorization',            //HttpHeaderAuthorization
    'cookie',                   //HttpHeaderCookie
    'expect',                   //HttpHeaderExpect
    'from',                     //HttpHeaderFrom
    'host',                     //HttpHeaderHost
    'if-match',               //HttpHeaderIfMatch
    'if-modified-since',      //HttpHeaderIfModifiedSince
    'if-none-match',            //HttpHeaderIfNoneMatch
    'if-range',               //HttpHeaderIfRange
    'if-unmodified-since',      //HttpHeaderIfUnmodifiedSince
    'max-forwards',             //HttpHeaderMaxForwards
    'proxy-authorization',      //HttpHeaderProxyAuthorization
    'referer',                  //HttpHeaderReferer
    'range',                  //HttpHeaderRange
    'te',                     //HttpHeaderTe
    'translate',                //HttpHeaderTranslate
    'user-agent',               //HttpHeaderUserAgent
    ''                        //HttpHeaderRequestMaximum
);

HttpResponseHeaderNames: array of string = (
    'cache-control',            //HttpHeaderCacheControl
    'connection',               //HttpHeaderConnection
    'date',                     //HttpHeaderDate
    'keep-alive',               //HttpHeaderKeepAlive
    'pragma',                   //HttpHeaderPragma
    'trailer',                  //HttpHeaderTrailer
    'transfer-encoding',      //HttpHeaderTransferEncoding
    'upgrade',                  //HttpHeaderUpgrade
    'via',                      //HttpHeaderVia
    'warning',                  //HttpHeaderWarning
    'allow',                  //HttpHeaderAllow
    'content-length',         //HttpHeaderContentLength
    'content-type',             //HttpHeaderContentType
    'content-encoding',         //HttpHeaderContentEncoding
    'content-language',         //HttpHeaderContentLanguage
    'content-location',         //HttpHeaderContentLocation
    'content-md5',            //HttpHeaderContentMd5
    'content-range',            //HttpHeaderContentRange
    'expires',                  //HttpHeaderExpires
    'last-modified',            //HttpHeaderLastModified
    'accept-ranges',            //HttpHeaderAcceptRanges
    'age',                      //HttpHeaderAge
    'etag',                     //HttpHeaderEtag
    'location',               //HttpHeaderLocation
    'proxy-authenticate',       //HttpHeaderProxyAuthenticate
    'retry-after',            //HttpHeaderRetryAfter
    'server',                   //HttpHeaderServer
    'set-cookie',               //HttpHeaderSetCookie
    'vary',                     //HttpHeaderVary
    'www-authenticate',         //HttpHeaderWwwAuthenticate
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    ''                        //HttpHeaderMaximum
);

var
HttpInitialize: function(Version: HTTPAPI_VERSION; Flags: ULONG; pReserved: PVOID = nil): HRESULT; stdcall;
HttpTerminate: function(Flags: ULONG; pReserved: PVOID = nil): HRESULT; stdcall;
HttpCreateHttpHandle: function(var pReqQueueHandle: THandle; Reserved: ULONG = 0): HRESULT; stdcall;
HttpCreateRequestQueue: function(Version: HTTPAPI_VERSION; pName: PWideChar; pSecurityAttributes: PSecurityAttributes;
    Flags: ULONG; var pReqQueueHandle: THandle): HRESULT; stdcall;
HttpCloseRequestQueue: function(ReqQueueHandle: THandle): HRESULT; stdcall;
HttpSetRequestQueueProperty: function(Handle: THandle; Property_: HTTP_SERVER_PROPERTY; pPropertyInformation: PVOID;
    PropertyInformationLength: ULONG; Reserved: ULONG = 0; pReserved: PVOID = nil): HRESULT; stdcall;
HttpQueryRequestQueueProperty: function(Handle: THandle; Property_: HTTP_SERVER_PROPERTY; pPropertyInformation: PVOID;
    PropertyInformationLength: ULONG; Reserved: ULONG; var pReturnLength: ULONG; pReserved: PVOID = nil): HRESULT; stdcall;
HttpShutdownRequestQueue: function(ReqQueueHandle: THandle): HRESULT; stdcall;
HttpReceiveClientCertificate: function(ReqQueueHandle: THandle; ConnectionId: HTTP_CONNECTION_ID; Flags: ULONG;
    var pSslClientCertInfo: HTTP_SSL_CLIENT_CERT_INFO; SslClientCertInfoSize: ULONG; var pBytesReceived: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpCreateServerSession: function(Version: HTTPAPI_VERSION; var pServerSessionId: HTTP_SERVER_SESSION_ID; Reserved: ULONG = 0): HRESULT; stdcall;
HttpCloseServerSession: function(ServerSessionId: HTTP_SERVER_SESSION_ID): HRESULT; stdcall;

//HttpQueryServerSessionProperty: function(ServerSessionId: HTTP_SERVER_SESSION_ID; Property_: HTTP_SERVER_PROPERTY;
//    pPropertyInformation: PVOID; PropertyInformationLength: ULONG; pReturnLength: PULONG): HRESULT; stdcall;

HttpSetServerSessionProperty: function(ServerSessionId: HTTP_SERVER_SESSION_ID; AProperty: HTTP_SERVER_PROPERTY;
    pPropertyInformation: PVOID; PropertyInformationLength: ULONG): HRESULT; stdcall;

HttpAddUrl: function(ReqQueueHandle: THandle; pFullyQualifiedUrl: PWideChar; pReserved: PVOID = nil): HRESULT; stdcall;
HttpRemoveUrl: function(ReqQueueHandle: THandle; pFullyQualifiedUrl: PWideChar): HRESULT; stdcall;
HttpCreateUrlGroup: function(ServerSessionId: HTTP_SERVER_SESSION_ID; var pUrlGroupId: HTTP_URL_GROUP_ID; Reserved: ULONG = 0): HRESULT; stdcall;
HttpCloseUrlGroup: function(UrlGroupId: HTTP_URL_GROUP_ID): HRESULT; stdcall;
HttpAddUrlToUrlGroup: function(UrlGroupId: HTTP_URL_GROUP_ID; pFullyQualifiedUrl: PWideChar; UrlContext: HTTP_URL_CONTEXT; Reserved: ULONG = 0): HRESULT; stdcall;
HttpRemoveUrlFromUrlGroup: function(UrlGroupId: HTTP_URL_GROUP_ID; pFullyQualifiedUrl: PWideChar; Flags: ULONG): HRESULT; stdcall;
HttpSetUrlGroupProperty: function(UrlGroupId: HTTP_URL_GROUP_ID; Property_: HTTP_SERVER_PROPERTY;
    pPropertyInformation: PVOID; PropertyInformationLength: ULONG): HRESULT; stdcall;

//HttpQueryUrlGroupProperty: function(UrlGroupId: HTTP_URL_GROUP_ID; var AProperty: HTTP_SERVER_PROPERTY;
//    pPropertyInformation: PVOID; PropertyInformationLength: ULONG; pReturnLength: PULONG = nil): HRESULT; stdcall;

HttpReceiveHttpRequest: function(ReqQueueHandle: THandle; RequestId: HTTP_REQUEST_ID; Flags: ULONG;
    RequestBuffer: PHTTP_REQUEST; RequestBufferLength: ULONG; var pBytesReceived: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpReceiveRequestEntityBody: function(ReqQueueHandle: THandle; RequestId: HTTP_REQUEST_ID; Flags: ULONG;
    pBuffer: PVOID; BufferLength: ULONG; var pBytesReceived: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpSendHttpResponse: function(ReqQueueHandle: THandle; RequestId: HTTP_REQUEST_ID; Flags: ULONG;
    pHttpResponse: PHTTP_RESPONSE; pCachePolicy: PHTTP_CACHE_POLICY; var pBytesSend: ULONG; pReserved1: PVOID = nil;
    Reserved2: ULONG = 0; pOverlapped: POverlapped = nil; pLogData: PHTTP_LOG_DATA = nil): HRESULT; stdcall;
HttpSendResponseEntityBody: function(ReqQueueHandle: THandle; RequestId: HTTP_REQUEST_ID; Flags: ULONG;
    EntityChunkCount: USHORT; pEntityChunks: PHTTP_DATA_CHUNK; var pBytesSent: ULONG; pReserved1: PVOID = nil;
    Reserved2: ULONG = 0; pOverlapped: POverlapped = nil; pLogData: PHTTP_LOG_DATA = nil): HRESULT; stdcall;
HttpWaitForDisconnect: function(ReqQueueHandle: THandle; ConnectionId: HTTP_CONNECTION_ID; pOverlapped: POverlapped): HRESULT; stdcall;
HttpCancelHttpRequest: function(ReqQueueHandle: THandle; RequestId: HTTP_REQUEST_ID; pOverlapped: POverlapped): HRESULT; stdcall;
HttpWaitForDemandStart: function(ReqQueueHandle: THandle; pOverlapped: POverlapped): HRESULT; stdcall;
HttpFlushResponseCache: function(ReqQueueHandle: THandle; pUrlPrefix: PWideChar; Flags: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpAddFragmentToCache: function(ReqQueueHandle: THandle; pUrlPrefix: PWideChar; pDataChunk: PHTTP_DATA_CHUNK;
    pCachePolicy: PHTTP_CACHE_POLICY; pOverlapped: POverlapped): HRESULT; stdcall;
HttpReadFragmentFromCache: function(ReqQueueHandle: THandle; pUrlPrefix: PWideChar; pByteRange: PHTTP_BYTE_RANGE;
    pBuffer: PVOID; BufferLength: ULONG; var pBytesRead: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpSetServiceConfiguration: function(ServiceHandle: THandle; ConfigId: HTTP_SERVICE_CONFIG_ID;
    pConfigInformation: PVOID; ConfigInformationLength: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpDeleteServiceConfiguration: function(ServiceHandle: THandle; ConfigId: HTTP_SERVICE_CONFIG_ID;
    pConfigInformation: PVOID; ConfigInformationLength: ULONG; pOverlapped: POverlapped): HRESULT; stdcall;
HttpQueryServiceConfiguration: function(ServiceHandle: THandle; ConfigId: HTTP_SERVICE_CONFIG_ID;
    pInputConfigInformation: PVOID; InputConfigInformationLength: ULONG;
    pOutputConfigInformation: PVOID; OutputConfigInformationLength: ULONG; var pReturnLength: Cardinal;
    pOverlapped: POverlapped): HRESULT; stdcall;

type
EHttpApiException = class(Exception);

function LoadHttpApiLibrary: boolean;
procedure HttpCheck(HttpResult: HRESULT);

{$ENDIF}

implementation

{$IFDEF MSWINDOWS}

const
HttpApiDllName = 'httpapi.dll';

var
LibraryHandle: THandle;

procedure HttpCheck(HttpResult: HRESULT);
begin
if HttpResult &lt;&gt; NO_ERROR then
    raise EHttpApiException.Create('HTTP Server API Error.' + sLineBreak + SysErrorMessage(HttpResult));
end;

function LoadHttpApiLibrary: boolean;

function LoadProc(ProcName: string): Pointer;
begin
    Result := GetProcAddress(LibraryHandle, PChar(ProcName));
    Assert(Assigned(Result), HttpApiDllName + ' - Could not find method: ' + ProcName);
end;

begin
if LibraryHandle &lt;&gt; 0 then
    Exit(True);

Result := False;
LibraryHandle := SafeLoadLibrary(PChar(HttpApiDllName));
if (LibraryHandle &lt;&gt; 0) then
begin
    Result := True;

    HttpInitialize := LoadProc('HttpInitialize');
    HttpTerminate := LoadProc('HttpTerminate');
    HttpCreateHttpHandle := LoadProc('HttpCreateHttpHandle');
    HttpCreateRequestQueue := LoadProc('HttpCreateRequestQueue');
    HttpCloseRequestQueue := LoadProc('HttpCloseRequestQueue');
    HttpSetRequestQueueProperty := LoadProc('HttpSetRequestQueueProperty');
    HttpQueryRequestQueueProperty := LoadProc('HttpQueryRequestQueueProperty');
    HttpShutdownRequestQueue := LoadProc('HttpShutdownRequestQueue');
    HttpReceiveClientCertificate := LoadProc('HttpReceiveClientCertificate');
    HttpCreateServerSession := LoadProc('HttpCreateServerSession');
    HttpCloseServerSession := LoadProc('HttpCloseServerSession');
    HttpSetServerSessionProperty := LoadProc('HttpSetServerSessionProperty');
    HttpAddUrl := LoadProc('HttpAddUrl');
    HttpRemoveUrl := LoadProc('HttpRemoveUrl');
    HttpCreateUrlGroup := LoadProc('HttpCreateUrlGroup');
    HttpCloseUrlGroup := LoadProc('HttpCloseUrlGroup');
    HttpAddUrlToUrlGroup := LoadProc('HttpAddUrlToUrlGroup');
    HttpRemoveUrlFromUrlGroup := LoadProc('HttpRemoveUrlFromUrlGroup');
    HttpSetUrlGroupProperty := LoadProc('HttpSetUrlGroupProperty');
    HttpReceiveHttpRequest := LoadProc('HttpReceiveHttpRequest');
    HttpReceiveRequestEntityBody := LoadProc('HttpReceiveRequestEntityBody');
    HttpSendHttpResponse := LoadProc('HttpSendHttpResponse');
    HttpSendResponseEntityBody := LoadProc('HttpSendResponseEntityBody');
    HttpWaitForDisconnect := LoadProc('HttpWaitForDisconnect');
    HttpCancelHttpRequest := LoadProc('HttpCancelHttpRequest');
    HttpWaitForDemandStart := LoadProc('HttpWaitForDemandStart');
    HttpFlushResponseCache := LoadProc('HttpFlushResponseCache');
    HttpAddFragmentToCache := LoadProc('HttpAddFragmentToCache');
    HttpReadFragmentFromCache := LoadProc('HttpReadFragmentFromCache');
    HttpSetServiceConfiguration := LoadProc('HttpSetServiceConfiguration');
    HttpDeleteServiceConfiguration := LoadProc('HttpDeleteServiceConfiguration');
    HttpQueryServiceConfiguration := LoadProc('HttpQueryServiceConfiguration');
end;
end;

Initialization
LibraryHandle := 0;

finalization
if LibraryHandle &lt;&gt; 0 then
    FreeLibrary(LibraryHandle);

{$IFDEF WIN32}
{$if sizeof(HTTP_REQUEST_V2) &lt;&gt; 472} {$message error 'HTTP_REQUEST sizeof error.'} {$ifend}
{$if sizeof(HTTP_RESPONSE_V2) &lt;&gt; 288} {$message error 'HTTP_RESPONSE sizeof error.'} {$ifend}
{$if sizeof(HTTP_COOKED_URL) &lt;&gt;24} {$message error 'HTTP_COOKED_URL sizeof error.'} {$ifend}
{$if sizeof(HTTP_DATA_CHUNK) &lt;&gt;32} {$message error 'HTTP_DATA_CHUNK sizeof error.'} {$ifend}
{$if sizeof(HTTP_REQUEST_HEADERS) &lt;&gt; 344} {$message error 'HTTP_REQUEST_HEADERS sizeof error.'} {$ifend}
{$if sizeof(HTTP_RESPONSE_HEADERS) &lt;&gt; 256} {$message error 'HTTP_RESPONSE_HEADERS sizeof error.'} {$ifend}
{$if sizeof(HTTP_SSL_INFO) &lt;&gt;28} {$message error 'HTTP_SSL_INFO sizeof error.'} {$ifend}
{$ENDIF}

{$ENDIF}

end.
</pre>
</div>
<p>  附上编译开关文件sparkle.inc的源码:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">{$R-}

{.$DEFINE DEBUGLOG}

{$SCOPEDENUMS ON}
{$IFDEF NEXTGEN}
{$ZEROBASEDSTRINGS OFF}
{$ENDIF}

// Small test for internal build process
{$IFNDEF DEBUG}
{$IFNDEF RELEASE}
{$MESSAGE Fatal 'Invalid build config.'}
{$ENDIF}
{$ENDIF}

{$IF CompilerVersion &gt;= 24.0}
{$LEGACYIFEND ON}
{$DEFINE DELPHIXE3_LVL}
{$IFEND}

{$IF CompilerVersion &gt;= 22}
{$DEFINE DELPHIXE_LVL}
{$IFEND}

{$IF CompilerVersion &gt;= 23}
{$DEFINE DELPHIXE2_LVL}
{$IFEND}

{$IF CompilerVersion &gt;= 25}
{$DEFINE DELPHIXE4_LVL}
{$IFEND}

{$IF CompilerVersion &gt;= 26}
{$DEFINE DELPHIXE5_LVL}
{$IFDEF DEBUG}
    {$D1}//limited debug info.
{$ENDIF}
{$IFEND}

{$IF CompilerVersion &gt;= 27}
{$DEFINE DELPHIXE6_LVL}
{$IFEND}

{$IF CompilerVersion &gt;= 31}
{$DEFINE DELPHIBERLIN_LVL}
{$IFEND}

{$IF CompilerVersion &gt;= 32}
{$DEFINE DELPHITOKYO_LVL}
{$IFEND}
</pre>
</div>
<p>  </p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/13097893.html</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/13097893.html
頁: [1]
查看完整版本: DELPHI如何封装http.sys