unit Sparkle.WinHttp.Api;

{$I Sparkle.Inc}

interface

{$IFDEF MSWINDOWS}

uses
  Winapi.Windows, System.SysUtils;

{$MinEnumSize 4}
{$Align 8}

type
  HINTERNET = Pointer;
  INTERNET_PORT = Word;

const
  INTERNET_DEFAULT_PORT = 0;
  INTERNET_DEFAULT_HTTP_PORT = 80;
  INTERNET_DEFAULT_HTTPS_PORT = 443;

  WINHTTP_FLAG_ASYNC = $10000000;

  // flags for WinHttpOpenRequest()
  WINHTTP_FLAG_SECURE = $00800000; // use SSL if applicable (HTTPS)
  WINHTTP_FLAG_ESCAPE_PERCENT = $00000004; // if escaping enabled, escape percent as well
  WINHTTP_FLAG_NULL_CODEPAGE = $00000008; // assume all symbols are ASCII, use fast convertion
  WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add 'pragma: no-cache' request header
  WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
  WINHTTP_FLAG_ESCAPE_DISABLE = $00000040; // disable escaping
  WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = $00000080; // if escaping enabled escape path part, but do not escape query


  SECURITY_FLAG_IGNORE_UNKNOWN_CA = $00000100;
  SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = $00002000; // expired X509 Cert.
  SECURITY_FLAG_IGNORE_CERT_CN_INVALID = $00001000; // bad common name in X509 Cert.
  SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE = $00000200;


type
  WINHTTP_ASYNC_RESULT = record
    dwResult: DWORD_PTR;
    dwError: LongInt;
  end;
  PWINHTTP_ASYNC_RESULT = ^WINHTTP_ASYNC_RESULT;

  HTTP_VERSION_INFO = record
    dwMajorVersion: LongInt;
    dwMinorVersion: LongInt;
  end;
  PHTTP_VERSION_INFO = ^HTTP_VERSION_INFO;

  INTERNET_SCHEME = LongInt;

const
  INTERNET_SCHEME_HTTP = 1;
  INTERNET_SCHEME_HTTPS = 2;

type
  URL_COMPONENTS = record
    dwStructSize: LongInt;
    lpszScheme: PWideChar;
    dwSchemeLength: LongInt;
    nScheme: INTERNET_SCHEME;
    lpszHostName: PWideChar;
    dwHostNameLength: LongInt;
    nPort: INTERNET_PORT;
    lpszUserName: PWideChar;
    dwUserNameLength: LongInt;
    lpszPassword: PWideChar;
    dwPasswordLength: LongInt;
    lpszUrlPath: PWideChar;
    dwUrlPathLength: LongInt;
    lpszExtraInfo: PWideChar;
    dwExtraInfoLength: LongInt;
  end;
  PURL_COMPONENTS = ^URL_COMPONENTS;

  WINHTTP_PROXY_INFO = record
    dwAccessType: LongInt;
    lpszProxy: PWideChar;
    lpszProxyBypass: PWideChar;
  end;
  PWINHTTP_PROXY_INFO = ^WINHTTP_PROXY_INFO;

  WINHTTP_AUTOPROXY_OPTIONS = record
    dwFlags: LongInt;
    dwAutoDetectFlags: LongInt;
    lpszAutoConfigUrl: PWideChar;
    lpvReserved: PVOID;
    dwReserved: LongInt;
    fAutoLogonIfChallenged: Bool;
  end;

const
  WINHTTP_AUTOPROXY_AUTO_DETECT = $00000001;
  WINHTTP_AUTOPROXY_CONFIG_URL = $00000002;
  WINHTTP_AUTOPROXY_HOST_KEEPCASE = $00000004;
  WINHTTP_AUTOPROXY_HOST_LOWERCASE = $00000008;
  WINHTTP_AUTOPROXY_RUN_INPROCESS = $00010000;
  WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = $00020000;

const
  WINHTTP_AUTO_DETECT_TYPE_DHCP = $00000001;
  WINHTTP_AUTO_DETECT_TYPE_DNS_A = $00000002;

type
  WINHTTP_CERTIFICATE_INFO = record
    ftExpiry: FILETIME;
    ftStart: FILETIME;
    lpszSubjectInfo: PWideChar;
    lpszIssuerInfo: PWideChar;
    lpszProtocolName: PWideChar;
    lpszSignatureAlgName: PWideChar;
    lpszEncryptionAlgName: PWideChar;
    dwKeySize: LongInt;
  end;

const
  WINHTTP_TIME_FORMAT_BUFSIZE = 62;

const
  ICU_NO_ENCODE = $20000000; // Don't convert unsafe characters to escape sequence
  ICU_DECODE = $10000000; // Convert %XX escape sequences to characters
  ICU_NO_META = $08000000; // Don't convert .. etc. meta path sequences
  ICU_ENCODE_SPACES_ONLY = $04000000; // Encode spaces only
  ICU_BROWSER_MODE = $02000000; // Special encode/decode rules for browser
  ICU_ENCODE_PERCENT = $00001000; // Encode any percent (ASCII25)


  ICU_ESCAPE = $80000000; // (un)escape URL characters
  ICU_ESCAPE_AUTHORITY = $00002000; //causes InternetCreateUrlA to escape chars in authority components (user, pwd, host)
  ICU_REJECT_USERPWD = $00004000; // rejects usrls whick have username/pwd sections

  WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
  WINHTTP_ACCESS_TYPE_NO_PROXY = 1;
  WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3;
  WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4;

  WINHTTP_NO_PROXY_NAME = nil;
  WINHTTP_NO_PROXY_BYPASS = nil;

  WINHTTP_NO_CLIENT_CERT_CONTEXT = nil;

  WINHTTP_OPTION_CALLBACK = 1;
  WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK;
  WINHTTP_OPTION_RESOLVE_TIMEOUT = 2;
  WINHTTP_OPTION_CONNECT_TIMEOUT = 3;
  WINHTTP_OPTION_CONNECT_RETRIES = 4;
  WINHTTP_OPTION_SEND_TIMEOUT = 5;
  WINHTTP_OPTION_RECEIVE_TIMEOUT = 6;
  WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT = 7;
  WINHTTP_OPTION_HANDLE_TYPE = 9;
  WINHTTP_OPTION_READ_BUFFER_SIZE = 12;
  WINHTTP_OPTION_WRITE_BUFFER_SIZE = 13;
  WINHTTP_OPTION_PARENT_HANDLE = 21;
  WINHTTP_OPTION_EXTENDED_ERROR = 24;
  WINHTTP_OPTION_SECURITY_FLAGS = 31;
  WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT = 32;
  WINHTTP_OPTION_URL = 34;
  WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36;
  WINHTTP_OPTION_PROXY = 38;

  WINHTTP_OPTION_USER_AGENT = 41;
  WINHTTP_OPTION_CONTEXT_VALUE = 45;
  WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47;
  WINHTTP_OPTION_REQUEST_PRIORITY = 58;
  WINHTTP_OPTION_HTTP_VERSION = 59;
  WINHTTP_OPTION_DISABLE_FEATURE = 63;

  WINHTTP_OPTION_CODEPAGE = 68;
  WINHTTP_OPTION_MAX_CONNS_PER_SERVER = 73;
  WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER = 74;
  WINHTTP_OPTION_AUTOLOGON_POLICY = 77;
  WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78;
  WINHTTP_OPTION_ENABLE_FEATURE = 79;
  WINHTTP_OPTION_WORKER_THREAD_COUNT = 80;
  WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT = 81;
  WINHTTP_OPTION_PASSPORT_COBRANDING_URL = 82;
  WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH = 83;
  WINHTTP_OPTION_SECURE_PROTOCOLS = 84;
  WINHTTP_OPTION_ENABLETRACING = 85;
  WINHTTP_OPTION_PASSPORT_SIGN_OUT = 86;
  WINHTTP_OPTION_PASSPORT_RETURN_URL = 87;
  WINHTTP_OPTION_REDIRECT_POLICY = 88;
  WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89;
  WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE = 90;
  WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE = 91;
  WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE = 92;
  WINHTTP_OPTION_CONNECTION_INFO = 93;
  WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST = 94;
  WINHTTP_OPTION_SPN = 96;

  WINHTTP_OPTION_GLOBAL_PROXY_CREDS = 97;
  WINHTTP_OPTION_GLOBAL_SERVER_CREDS = 98;

  WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT = 99;
  WINHTTP_OPTION_REJECT_USERPWD_IN_URL = 100;
  WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS = 101;

  WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE = 103;
  WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE = 104;

  WINHTTP_OPTION_SERVER_SPN_USED = 106;
  WINHTTP_OPTION_PROXY_SPN_USED = 107;
  WINHTTP_OPTION_SERVER_CBT = 108;


  WINHTTP_OPTION_UNSAFE_HEADER_PARSING = 110;
  WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111;

  WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114;
  WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT = 115;
  WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL = 116;

  WINHTTP_OPTION_DECOMPRESSION = 118;

  WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE = 122;
  WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE = 123;

  WINHTTP_LAST_OPTION = WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE;

  WINHTTP_OPTION_USERNAME = $1000;
  WINHTTP_OPTION_PASSWORD = $1001;
  WINHTTP_OPTION_PROXY_USERNAME = $1002;
  WINHTTP_OPTION_PROXY_PASSWORD = $1003;

  WINHTTP_CONNS_PER_SERVER_UNLIMITED = $FFFFFFF;

  WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM = 0;
  WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW = 1;
  WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH = 2;
  WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM;

  WINHTTP_OPTION_REDIRECT_POLICY_NEVER = 0;
  WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP = 1;
  WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS = 2;

  WINHTTP_OPTION_REDIRECT_POLICY_LAST = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
  WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP;

  WINHTTP_DISABLE_PASSPORT_AUTH = $00000000;
  WINHTTP_ENABLE_PASSPORT_AUTH = $10000000;
  WINHTTP_DISABLE_PASSPORT_KEYRING = $20000000;
  WINHTTP_ENABLE_PASSPORT_KEYRING = $40000000;

  WINHTTP_DISABLE_COOKIES = $00000001;
  WINHTTP_DISABLE_REDIRECTS = $00000002;
  WINHTTP_DISABLE_AUTHENTICATION = $00000004;
  WINHTTP_DISABLE_KEEP_ALIVE = $00000008;

  WINHTTP_ENABLE_SSL_REVOCATION = $00000001;
  WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION = $00000002;

  WINHTTP_DISABLE_SPN_SERVER_PORT = $00000000;
  WINHTTP_ENABLE_SPN_SERVER_PORT = $00000001;
  WINHTTP_OPTION_SPN_MASK = WINHTTP_ENABLE_SPN_SERVER_PORT;

const
  WINHTTP_DECOMPRESSION_FLAG_GZIP = $00000001;
  WINHTTP_DECOMPRESSION_FLAG_DEFLATE = $00000002;
  WINHTTP_DECOMPRESSION_FLAG_ALL = (WINHTTP_DECOMPRESSION_FLAG_GZIP or WINHTTP_DECOMPRESSION_FLAG_DEFLATE);

type
  tagWINHTTP_CREDS = record
    lpszUserName: PChar;
    lpszPassword: PChar;
    lpszRealm: PChar;
    dwAuthScheme: LongInt;
    lpszHostName: PChar;
    dwPort: LongInt;
  end;

  tagWINHTTP_CREDS_EX = record
    lpszUserName: PChar;
    lpszPassword: PChar;
    lpszRealm: PChar;
    dwAuthScheme: LongInt;
    lpszHostName: PChar;
    dwPort: LongInt;
    lpszUrl: PChar;
  end;

const
  WINHTTP_HANDLE_TYPE_SESSION = 1;
  WINHTTP_HANDLE_TYPE_CONNECT = 2;
  WINHTTP_HANDLE_TYPE_REQUEST = 3;

  WINHTTP_AUTH_SCHEME_BASIC = $00000001;
  WINHTTP_AUTH_SCHEME_NTLM = $00000002;
  WINHTTP_AUTH_SCHEME_PASSPORT = $00000004;
  WINHTTP_AUTH_SCHEME_DIGEST = $00000008;
  WINHTTP_AUTH_SCHEME_NEGOTIATE = $00000010;

  WINHTTP_AUTH_TARGET_SERVER = $00000000;
  WINHTTP_AUTH_TARGET_PROXY = $00000001;

  SECURITY_FLAG_SECURE = $00000001; {// can query only}
  SECURITY_FLAG_STRENGTH_WEAK = $10000000;
  SECURITY_FLAG_STRENGTH_MEDIUM = $40000000;
  SECURITY_FLAG_STRENGTH_STRONG = $20000000;

  WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = $00000001;
  WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT = $00000002;
  WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED = $00000004;
  WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA = $00000008;
  WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID = $00000010;
  WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID = $00000020;
  WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE = $00000040;
  WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR = $80000000;

  WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 = $00000008;
  WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 = $00000020;
  WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = $00000080;
  WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = $00000200;
  WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = $00000800;
  WINHTTP_FLAG_SECURE_PROTOCOL_ALL =
    WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 or
		WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 or
    WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;

type
  WINHTTP_STATUS_CALLBACK = procedure(hInternet: HINTERNET;
    dwContext: Pointer; dwInternetStatus: DWORD;
    lpvStatusInformation: Pointer; dwStatusInformationLength: DWORD); stdcall;
  PWINHTTP_STATUS_CALLBACK = ^WINHTTP_STATUS_CALLBACK;


const
  WINHTTP_CALLBACK_STATUS_RESOLVING_NAME = $00000001;
  WINHTTP_CALLBACK_STATUS_NAME_RESOLVED = $00000002;
  WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER = $00000004;
  WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER = $00000008;
  WINHTTP_CALLBACK_STATUS_SENDING_REQUEST = $00000010;
  WINHTTP_CALLBACK_STATUS_REQUEST_SENT = $00000020;
  WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE = $00000040;
  WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED = $00000080;
  WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION = $00000100;
  WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED = $00000200;
  WINHTTP_CALLBACK_STATUS_HANDLE_CREATED = $00000400;
  WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING = $00000800;
  WINHTTP_CALLBACK_STATUS_DETECTING_PROXY = $00001000;
  WINHTTP_CALLBACK_STATUS_REDIRECT = $00004000;
  WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE = $00008000;
  WINHTTP_CALLBACK_STATUS_SECURE_FAILURE = $00010000;
  WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE = $00020000;
  WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE = $00040000;
  WINHTTP_CALLBACK_STATUS_READ_COMPLETE = $00080000;
  WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE = $00100000;
  WINHTTP_CALLBACK_STATUS_REQUEST_ERROR = $00200000;
  WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE = $00400000;

  API_RECEIVE_RESPONSE = 1;
  API_QUERY_DATA_AVAILABLE = 2;
  API_READ_DATA = 3;
  API_WRITE_DATA = 4;
  API_SEND_REQUEST = 5;

  WINHTTP_CALLBACK_FLAG_RESOLVE_NAME =
    (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME or WINHTTP_CALLBACK_STATUS_NAME_RESOLVED);
  WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER =
    (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER or WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER);
  WINHTTP_CALLBACK_FLAG_SEND_REQUEST =
    (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST or WINHTTP_CALLBACK_STATUS_REQUEST_SENT);
  WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE =
    (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE or WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED);
  WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION =
    (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION or WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED);
  WINHTTP_CALLBACK_FLAG_HANDLES =
    (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED or WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING);
  WINHTTP_CALLBACK_FLAG_DETECTING_PROXY = WINHTTP_CALLBACK_STATUS_DETECTING_PROXY;
  WINHTTP_CALLBACK_FLAG_REDIRECT = WINHTTP_CALLBACK_STATUS_REDIRECT;
  WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE = WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE;
  WINHTTP_CALLBACK_FLAG_SECURE_FAILURE = WINHTTP_CALLBACK_STATUS_SECURE_FAILURE;
  WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE = WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE;
  WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE = WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE;
  WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE = WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE;
  WINHTTP_CALLBACK_FLAG_READ_COMPLETE = WINHTTP_CALLBACK_STATUS_READ_COMPLETE;
  WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE = WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE;
  WINHTTP_CALLBACK_FLAG_REQUEST_ERROR = WINHTTP_CALLBACK_STATUS_REQUEST_ERROR;

  WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS =
    WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE or
		WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE or
		WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE or
		WINHTTP_CALLBACK_STATUS_READ_COMPLETE or
		WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE or
    WINHTTP_CALLBACK_STATUS_REQUEST_ERROR;

  WINHTTP_INVALID_STATUS_CALLBACK = PWINHTTP_STATUS_CALLBACK(-1);

  WINHTTP_QUERY_MIME_VERSION = 0;
  WINHTTP_QUERY_CONTENT_TYPE = 1;
  WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING = 2;
  WINHTTP_QUERY_CONTENT_ID = 3;
  WINHTTP_QUERY_CONTENT_DESCRIPTION = 4;
  WINHTTP_QUERY_CONTENT_LENGTH = 5;
  WINHTTP_QUERY_CONTENT_LANGUAGE = 6;
  WINHTTP_QUERY_ALLOW = 7;
  WINHTTP_QUERY_PUBLIC = 8;
  WINHTTP_QUERY_DATE = 9;
  WINHTTP_QUERY_EXPIRES = 10;
  WINHTTP_QUERY_LAST_MODIFIED = 11;
  WINHTTP_QUERY_MESSAGE_ID = 12;
  WINHTTP_QUERY_URI = 13;
  WINHTTP_QUERY_DERIVED_FROM = 14;
  WINHTTP_QUERY_COST = 15;
  WINHTTP_QUERY_LINK = 16;
  WINHTTP_QUERY_PRAGMA = 17;
  WINHTTP_QUERY_VERSION = 18; // special: part of status line
  WINHTTP_QUERY_STATUS_CODE = 19; // special: part of status line
  WINHTTP_QUERY_STATUS_TEXT = 20; // special: part of status line
  WINHTTP_QUERY_RAW_HEADERS = 21; // special: all headers as ASCIIZ
  WINHTTP_QUERY_RAW_HEADERS_CRLF = 22; // special: all headers
  WINHTTP_QUERY_CONNECTION = 23;
  WINHTTP_QUERY_ACCEPT = 24;
  WINHTTP_QUERY_ACCEPT_CHARSET = 25;
  WINHTTP_QUERY_ACCEPT_ENCODING = 26;
  WINHTTP_QUERY_ACCEPT_LANGUAGE = 27;
  WINHTTP_QUERY_AUTHORIZATION = 28;
  WINHTTP_QUERY_CONTENT_ENCODING = 29;
  WINHTTP_QUERY_FORWARDED = 30;
  WINHTTP_QUERY_FROM = 31;
  WINHTTP_QUERY_IF_MODIFIED_SINCE = 32;
  WINHTTP_QUERY_LOCATION = 33;
  WINHTTP_QUERY_ORIG_URI = 34;
  WINHTTP_QUERY_REFERER = 35;
  WINHTTP_QUERY_RETRY_AFTER = 36;
  WINHTTP_QUERY_SERVER = 37;
  WINHTTP_QUERY_TITLE = 38;
  WINHTTP_QUERY_USER_AGENT = 39;
  WINHTTP_QUERY_WWW_AUTHENTICATE = 40;
  WINHTTP_QUERY_PROXY_AUTHENTICATE = 41;
  WINHTTP_QUERY_ACCEPT_RANGES = 42;
  WINHTTP_QUERY_SET_COOKIE = 43;
  WINHTTP_QUERY_COOKIE = 44;
  WINHTTP_QUERY_REQUEST_METHOD = 45; {// special: GET/POST etc.}
  WINHTTP_QUERY_REFRESH = 46;
  WINHTTP_QUERY_CONTENT_DISPOSITION = 47;

  WINHTTP_QUERY_AGE = 48;
  WINHTTP_QUERY_CACHE_CONTROL = 49;
  WINHTTP_QUERY_CONTENT_BASE = 50;
  WINHTTP_QUERY_CONTENT_LOCATION = 51;
  WINHTTP_QUERY_CONTENT_MD5 = 52;
  WINHTTP_QUERY_CONTENT_RANGE = 53;
  WINHTTP_QUERY_ETAG = 54;
  WINHTTP_QUERY_HOST = 55;
  WINHTTP_QUERY_IF_MATCH = 56;
  WINHTTP_QUERY_IF_NONE_MATCH = 57;
  WINHTTP_QUERY_IF_RANGE = 58;
  WINHTTP_QUERY_IF_UNMODIFIED_SINCE = 59;
  WINHTTP_QUERY_MAX_FORWARDS = 60;
  WINHTTP_QUERY_PROXY_AUTHORIZATION = 61;
  WINHTTP_QUERY_RANGE = 62;
  WINHTTP_QUERY_TRANSFER_ENCODING = 63;
  WINHTTP_QUERY_UPGRADE = 64;
  WINHTTP_QUERY_VARY = 65;
  WINHTTP_QUERY_VIA = 66;
  WINHTTP_QUERY_WARNING = 67;
  WINHTTP_QUERY_EXPECT = 68;
  WINHTTP_QUERY_PROXY_CONNECTION = 69;
  WINHTTP_QUERY_UNLESS_MODIFIED_SINCE = 70;

  WINHTTP_QUERY_PROXY_SUPPORT = 75;
  WINHTTP_QUERY_AUTHENTICATION_INFO = 76;
  WINHTTP_QUERY_PASSPORT_URLS = 77;
  WINHTTP_QUERY_PASSPORT_CONFIG = 78;

  WINHTTP_QUERY_MAX = 78;

  WINHTTP_QUERY_CUSTOM = 65535;

  WINHTTP_QUERY_FLAG_REQUEST_HEADERS = $80000000;
  WINHTTP_QUERY_FLAG_SYSTEMTIME = $40000000;
  WINHTTP_QUERY_FLAG_NUMBER = $20000000;

  HTTP_STATUS_CONTINUE = 100;
  HTTP_STATUS_SWITCH_PROTOCOLS = 101;

  HTTP_STATUS_OK = 200;
  HTTP_STATUS_CREATED = 201;
  HTTP_STATUS_ACCEPTED = 202;
  HTTP_STATUS_PARTIAL = 203;
  HTTP_STATUS_NO_CONTENT = 204;
  HTTP_STATUS_RESET_CONTENT = 205;
  HTTP_STATUS_PARTIAL_CONTENT = 206;
  HTTP_STATUS_WEBDAV_MULTI_STATUS = 207;

  HTTP_STATUS_AMBIGUOUS = 300;
  HTTP_STATUS_MOVED = 301;
  HTTP_STATUS_REDIRECT = 302;
  HTTP_STATUS_REDIRECT_METHOD = 303;
  HTTP_STATUS_NOT_MODIFIED = 304;
  HTTP_STATUS_USE_PROXY = 305;
  HTTP_STATUS_REDIRECT_KEEP_VERB = 307;

  HTTP_STATUS_BAD_REQUEST = 400;
  HTTP_STATUS_DENIED = 401;
  HTTP_STATUS_PAYMENT_REQ = 402;
  HTTP_STATUS_FORBIDDEN = 403;
  HTTP_STATUS_NOT_FOUND = 404;
  HTTP_STATUS_BAD_METHOD = 405;
  HTTP_STATUS_NONE_ACCEPTABLE = 406;
  HTTP_STATUS_PROXY_AUTH_REQ = 407;
  HTTP_STATUS_REQUEST_TIMEOUT = 408;
  HTTP_STATUS_CONFLICT = 409;
  HTTP_STATUS_GONE = 410;
  HTTP_STATUS_LENGTH_REQUIRED = 411;
  HTTP_STATUS_PRECOND_FAILED = 412;
  HTTP_STATUS_REQUEST_TOO_LARGE = 413;
  HTTP_STATUS_URI_TOO_LONG = 414;
  HTTP_STATUS_UNSUPPORTED_MEDIA = 415;
  HTTP_STATUS_RETRY_WITH = 449;

  HTTP_STATUS_SERVER_ERROR = 500;
  HTTP_STATUS_NOT_SUPPORTED = 501;
  HTTP_STATUS_BAD_GATEWAY = 502;
  HTTP_STATUS_SERVICE_UNAVAIL = 503;
  HTTP_STATUS_GATEWAY_TIMEOUT = 504;
  HTTP_STATUS_VERSION_NOT_SUP = 505;

  HTTP_STATUS_FIRST = HTTP_STATUS_CONTINUE;
  HTTP_STATUS_LAST = HTTP_STATUS_VERSION_NOT_SUP;

  WINHTTP_NO_REFERER = nil;
  WINHTTP_DEFAULT_ACCEPT_TYPES = nil;

  WINHTTP_ADDREQ_INDEX_MASK = $0000FFF;
  WINHTTP_ADDREQ_FLAGS_MASK = $FFFF0000;

  WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = $10000000;
  WINHTTP_ADDREQ_FLAG_ADD = $20000000;
  WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = $40000000;
  WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = $01000000;
  WINHTTP_ADDREQ_FLAG_COALESCE = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA;
  WINHTTP_ADDREQ_FLAG_REPLACE = $80000000;

  WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH = 0;

  WINHTTP_NO_ADDITIONAL_HEADERS = nil;
  WINHTTP_NO_REQUEST_DATA = nil;

  WINHTTP_HEADER_NAME_BY_INDEX = nil;
  WINHTTP_NO_OUTPUT_BUFFER = nil;
  WINHTTP_NO_HEADER_INDEX = nil;

type
  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG = record
    fAutoDetect: Bool;
    lpszAutoConfigUrl: PWideChar;
    lpszProxy: PWideChar;
    lpszProxyBypass: PWideChar;
  end;

const
  WINHTTP_ERROR_BASE = 12000;

  ERROR_WINHTTP_OUT_OF_HANDLES = (WINHTTP_ERROR_BASE + 1);
  ERROR_WINHTTP_TIMEOUT = (WINHTTP_ERROR_BASE + 2);
  ERROR_WINHTTP_INTERNAL_ERROR = (WINHTTP_ERROR_BASE + 4);
  ERROR_WINHTTP_INVALID_URL = (WINHTTP_ERROR_BASE + 5);
  ERROR_WINHTTP_UNRECOGNIZED_SCHEME = (WINHTTP_ERROR_BASE + 6);
  ERROR_WINHTTP_NAME_NOT_RESOLVED = (WINHTTP_ERROR_BASE + 7);
  ERROR_WINHTTP_INVALID_OPTION = (WINHTTP_ERROR_BASE + 9);
  ERROR_WINHTTP_OPTION_NOT_SETTABLE = (WINHTTP_ERROR_BASE + 11);
  ERROR_WINHTTP_SHUTDOWN = (WINHTTP_ERROR_BASE + 12);

  ERROR_WINHTTP_LOGIN_FAILURE = (WINHTTP_ERROR_BASE + 15);
  ERROR_WINHTTP_OPERATION_CANCELLED = (WINHTTP_ERROR_BASE + 17);
  ERROR_WINHTTP_INCORRECT_HANDLE_TYPE = (WINHTTP_ERROR_BASE + 18);
  ERROR_WINHTTP_INCORRECT_HANDLE_STATE = (WINHTTP_ERROR_BASE + 19);
  ERROR_WINHTTP_CANNOT_CONNECT = (WINHTTP_ERROR_BASE + 29);
  ERROR_WINHTTP_CONNECTION_ERROR = (WINHTTP_ERROR_BASE + 30);
  ERROR_WINHTTP_RESEND_REQUEST = (WINHTTP_ERROR_BASE + 32);

  ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = (WINHTTP_ERROR_BASE + 44);

  ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = (WINHTTP_ERROR_BASE + 100);
  ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = (WINHTTP_ERROR_BASE + 101);
  ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = (WINHTTP_ERROR_BASE + 102);
  ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = (WINHTTP_ERROR_BASE + 103);

  ERROR_WINHTTP_HEADER_NOT_FOUND = (WINHTTP_ERROR_BASE + 150);
  ERROR_WINHTTP_INVALID_SERVER_RESPONSE = (WINHTTP_ERROR_BASE + 152);
  ERROR_WINHTTP_INVALID_HEADER = (WINHTTP_ERROR_BASE + 153);
  ERROR_WINHTTP_INVALID_QUERY_REQUEST = (WINHTTP_ERROR_BASE + 154);
  ERROR_WINHTTP_HEADER_ALREADY_EXISTS = (WINHTTP_ERROR_BASE + 155);
  ERROR_WINHTTP_REDIRECT_FAILED = (WINHTTP_ERROR_BASE + 156);

  ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = (WINHTTP_ERROR_BASE + 178);
  ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = (WINHTTP_ERROR_BASE + 166);
  ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = (WINHTTP_ERROR_BASE + 167);

  ERROR_WINHTTP_NOT_INITIALIZED = (WINHTTP_ERROR_BASE + 172);
  ERROR_WINHTTP_SECURE_FAILURE = (WINHTTP_ERROR_BASE + 175);

  ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = (WINHTTP_ERROR_BASE + 37);
  ERROR_WINHTTP_SECURE_CERT_CN_INVALID = (WINHTTP_ERROR_BASE + 38);
  ERROR_WINHTTP_SECURE_INVALID_CA = (WINHTTP_ERROR_BASE + 45);
  ERROR_WINHTTP_SECURE_CERT_REV_FAILED = (WINHTTP_ERROR_BASE + 57);
  ERROR_WINHTTP_SECURE_CHANNEL_ERROR = (WINHTTP_ERROR_BASE + 157);
  ERROR_WINHTTP_SECURE_INVALID_CERT = (WINHTTP_ERROR_BASE + 169);
  ERROR_WINHTTP_SECURE_CERT_REVOKED = (WINHTTP_ERROR_BASE + 170);
  ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = (WINHTTP_ERROR_BASE + 179);

  ERROR_WINHTTP_AUTODETECTION_FAILED = (WINHTTP_ERROR_BASE + 180);
  ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = (WINHTTP_ERROR_BASE + 181);
  ERROR_WINHTTP_HEADER_SIZE_OVERFLOW = (WINHTTP_ERROR_BASE + 182);
  ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW = (WINHTTP_ERROR_BASE + 183);
  ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = (WINHTTP_ERROR_BASE + 184);
  ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = (WINHTTP_ERROR_BASE + 185);
  ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = (WINHTTP_ERROR_BASE + 186);

  WINHTTP_ERROR_LAST = (WINHTTP_ERROR_BASE + 186);

var
  WinHttpTimeFromSystemTime: function(pst: TSystemTime; pwszTime: PWideChar): BOOL; stdcall;
  WinHttpTimeToSystemTime: function(pwszTime: PWideCHar; var pst: TSystemTime): BOOL; stdcall;
  WinHttpCrackUrl: function(pwszUrl: PWideChar; dwUrlLength, dwFlags: DWORD;
    lpUrlComponents: PURL_COMPONENTS): BOOL; stdcall;
  WinHttpCreateUrl: function(lpUrlComponents: PURL_COMPONENTS; dwFlags: DWORD;
    pwszUrl: PWideChar; var pdwUrlLength: DWORD): BOOL; stdcall;
  WinHttpCheckPlatform: function: BOOL; stdcall;
  WinHttpGetDefaultProxyConfiguration: function(var pProxyInfo: WINHTTP_PROXY_INFO): BOOL; stdcall;
  WinHttpSetDefaultProxyConfiguration: function(pProxyInfo: WINHTTP_PROXY_INFO): BOOL; stdcall;
  WinHttpOpen: function(pszAgentW: PWideChar; dwAccessType: DWORD; pszProxyW: PWideChar;
    pszProxyBypassW: PWideChar; dwFlags: DWORD): HINTERNET; stdcall;
  WinHttpCloseHandle: function(hInternet: HINTERNET): BOOL; stdcall;
  WinHttpConnect: function(hSession: HINTERNET; pswzServerName: PWideChar;
    nServerPort: INTERNET_PORT; dwReserved: DWORD): HINTERNET; stdcall;
  WinHttpReadData: function(hRequest: HINTERNET; lpBuffer: Pointer;
    dwNumberOfBytesToRead: DWord; var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;
  WinHttpWriteData: function(hRequest: HINTERNET; lpBuffer: Pointer;
    dwNumberOfBytesToWrite: DWORD; var lpdwNumberOfBytesWritten: DWORD): BOOL; stdcall;
  WinHttpQueryDataAvailable: function(hRequest: HINTERNET; var lpdwNumberOfBytesAvailable: DWORD): BOOL; stdcall;
  WinHttpQueryOption: function(hInternet: HINTERNET; dwOption: DWORD;
    lpBuffer: Pointer; var lpdwBufferLength: DWORD): BOOL; stdcall;
  WinHttpSetOption: function(hInternet: HINTERNET; dwOption: DWORD;
    lpBuffer: Pointer; lpdwBufferLength: DWORD): BOOL; stdcall;
  WinHttpSetTimeouts: function(hInternet: HINTERNET; nResolveTimeout, nConnectTimeout,
    nSendTimeout, nReceiveTimeout: DWORD): BOOL; stdcall;
  WinHttpSetStatusCallback: function(hInternet: HINTERNET; lpfnInternetCallback: WINHTTP_STATUS_CALLBACK;
    dwNotificationFlags: DWORD; dwReserved: Pointer): PWINHTTP_STATUS_CALLBACK; stdcall;
  WinHttpAddRequestHeaders: function(hRequest: HINTERNET; pwszHeaders: PWideChar;
    dwHeadersLength, dwModifiers: DWORD): BOOL; stdcall;
  WinHttpOpenRequest: function(hConnect: HInternet; pwszVerb, pwszObjectName,
      pwszVersion, pwszReferrer, ppwszAcceptTypes: PWideChar; dwFlags: DWord): HINTERNET; stdcall;
  WinHttpSendRequest: function(hRequest: HINTERNET; lpszHeaders: PWideChar;
    dwHeadersLength: DWORD; lpOptional: Pointer; dwOptionalLength: DWORD;
    dwTotalLength: DWORD; dwContext: Pointer): BOOL; stdcall;
  WinHttpSetCredentials: function(hRequest: HInternet; AuthTargets, AuthScheme: DWord;
    pwszUserName, pwszPassWord: PWideChar; pAuthParams: Pointer): BOOL; stdcall;
  WinHttpQueryAuthSchemes: function(hRequest: HInternet; var lpdwSupportedSchemes,
    lpdwFirstScheme, pdwAuthTarget: DWord): BOOL; stdcall;
  WinHttpReceiveResponse: function(hRequest: HINTERNET; lpReserved: Pointer): BOOL; stdcall;
  WinHttpQueryHeaders: function(hRequest: HINTERNET; dwInfoLevel: DWORD; pwszName: PWideChar;
    lpBuffer: Pointer; var lpdwBufferLength: DWORD; lpdwIndex: Pointer): BOOL; stdcall;
  WinHttpDetectAutoProxyConfigUrl: function(dwAutoDetectFlags: LongInt;
    ppwstrAutoConfigUrl: PWideChar): BOOL; stdcall;
  WinHttpGetProxyForUrl: function(hSession: HINTERNET; lpcwszUrl: PWideChar;
    pAutoProxyOptions: WINHTTP_AUTOPROXY_OPTIONS; var pProxyInfo: WINHTTP_PROXY_INFO): BOOL; stdcall;
  WinHttpGetIEProxyConfigForCurrentUser: function(var pProxyConfig: WINHTTP_CURRENT_USER_IE_PROXY_CONFIG): BOOL; stdcall;

type
  EWinHttpClientException = class(Exception)
  end;

function LoadWinHttpLibrary: boolean;
procedure WinHttpCheck(Ok: boolean; const Msg: string = '');
function WinHttpErrorMessage(ErrorCode: integer): string;

{$ENDIF}

implementation

{$IFDEF MSWINDOWS}

const
  WinHttpDllName = 'winhttp.dll';

var
  LibraryHandle: THandle;

procedure WinHttpCheck(Ok: boolean; const Msg: string = '');
var
  ErrorCode: integer;
  ErrorMessage: string;
  ErrMsg: string;
begin
  if Ok then Exit;
  ErrorCode := GetLastError;
  if (ErrorCode >= WINHTTP_ERROR_BASE) and (ErrorCode <= WINHTTP_ERROR_LAST) then
    ErrorMessage := WinHttpErrorMessage(ErrorCode)
  else
    ErrorMessage := SysErrorMessage(ErrorCode);
  ErrMsg := 'Could not perform WinHttp operation.' + sLineBreak +
    'Error: (' + IntToStr(ErrorCode) + ') ' + ErrorMessage;
  if Msg <> '' then
    ErrMsg := ErrMsg + sLineBreak + Msg;
  raise EWinHttpClientException.Create(ErrMsg);
end;

function LoadWinHttpLibrary: boolean;

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

begin
  if LibraryHandle <> 0 then
    Exit(True);

  Result := False;
  LibraryHandle := SafeLoadLibrary(PChar(WinHttpDllName));
  if (LibraryHandle <> 0) then
  begin
    Result := True;

      WinHttpTimeFromSystemTime := LoadProc('WinHttpTimeFromSystemTime');
      WinHttpTimeToSystemTime := LoadProc('WinHttpTimeToSystemTime');
      WinHttpCrackUrl := LoadProc('WinHttpCrackUrl');
      WinHttpCreateUrl := LoadProc('WinHttpCreateUrl');
      WinHttpCheckPlatform := LoadProc('WinHttpCheckPlatform');
      WinHttpGetDefaultProxyConfiguration := LoadProc('WinHttpGetDefaultProxyConfiguration');
      WinHttpSetDefaultProxyConfiguration := LoadProc('WinHttpSetDefaultProxyConfiguration');
      WinHttpOpen := LoadProc('WinHttpOpen');
      WinHttpCloseHandle := LoadProc('WinHttpCloseHandle');
      WinHttpConnect := LoadProc('WinHttpConnect');
      WinHttpReadData := LoadProc('WinHttpReadData');
      WinHttpWriteData := LoadProc('WinHttpWriteData');
      WinHttpQueryDataAvailable := LoadProc('WinHttpQueryDataAvailable');
      WinHttpQueryOption := LoadProc('WinHttpQueryOption');
      WinHttpSetOption := LoadProc('WinHttpSetOption');
      WinHttpSetTimeouts := LoadProc('WinHttpSetTimeouts');
      WinHttpSetStatusCallback := LoadProc('WinHttpSetStatusCallback');
      WinHttpAddRequestHeaders := LoadProc('WinHttpAddRequestHeaders');
      WinHttpOpenRequest := LoadProc('WinHttpOpenRequest');
      WinHttpSendRequest := LoadProc('WinHttpSendRequest');
      WinHttpSetCredentials := LoadProc('WinHttpSetCredentials');
      WinHttpQueryAuthSchemes := LoadProc('WinHttpQueryAuthSchemes');

      WinHttpReceiveResponse := LoadProc('WinHttpReceiveResponse');
      WinHttpQueryHeaders := LoadProc('WinHttpQueryHeaders');
      WinHttpDetectAutoProxyConfigUrl := LoadProc('WinHttpDetectAutoProxyConfigUrl');
      WinHttpGetProxyForUrl := LoadProc('WinHttpGetProxyForUrl');
      WinHttpGetIEProxyConfigForCurrentUser := LoadProc('WinHttpGetIEProxyConfigForCurrentUser');
  end;
end;


function WinHttpErrorMessage(ErrorCode: integer): string;

begin

  case ErrorCode of
    ERROR_WINHTTP_TIMEOUT:                             Result := 'The request has timed out';
    ERROR_WINHTTP_CANNOT_CONNECT:                      Result := 'Could not connect to server';
    ERROR_WINHTTP_HEADER_NOT_FOUND:                    Result := 'The requested header cannot be located';
    ERROR_WINHTTP_INVALID_SERVER_RESPONSE:             Result := 'The server response cannot be parsed';
    ERROR_WINHTTP_SECURE_FAILURE:                      Result := 'Error in Server SSL Certificate';
    ERROR_WINHTTP_INVALID_URL:                         Result := 'The URL is not valid';
    ERROR_WINHTTP_NAME_NOT_RESOLVED:                   Result := 'The server name cannot be resolved';
    ERROR_WINHTTP_CONNECTION_ERROR:                    Result := 'The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered';
  else
    Result := '';
  end;
end;

initialization
  LibraryHandle := 0;

finalization
  if LibraryHandle <> 0 then
    FreeLibrary(LibraryHandle);

{$ENDIF}

end.


