|  | (* | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements. See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership. The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (the | 
|  | * "License"); you may not use this file except in compliance | 
|  | * with the License. You may obtain a copy of the License at | 
|  | * | 
|  | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied. See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | *) | 
|  | unit Thrift.WinHTTP; | 
|  |  | 
|  | {$I Thrift.Defines.inc} | 
|  | {$SCOPEDENUMS ON} | 
|  |  | 
|  | // packing according to winhttp.h | 
|  | {$IFDEF Win64} {$ALIGN 8} {$ELSE} {$ALIGN 4} {$ENDIF} | 
|  |  | 
|  | interface | 
|  |  | 
|  | uses | 
|  | Windows, | 
|  | Classes, | 
|  | SysUtils, | 
|  | Math, | 
|  | Generics.Collections; | 
|  |  | 
|  |  | 
|  | type | 
|  | HINTERNET = type Pointer; | 
|  | INTERNET_PORT = type WORD; | 
|  | INTERNET_SCHEME = type Integer; | 
|  | LPLPCWSTR = ^LPCWSTR; | 
|  |  | 
|  | LPURL_COMPONENTS = ^URL_COMPONENTS; | 
|  | URL_COMPONENTS = record | 
|  | dwStructSize      : DWORD;              // set to SizeOf(URL_COMPONENTS) | 
|  | lpszScheme        : LPWSTR;             // scheme name | 
|  | dwSchemeLength    : DWORD; | 
|  | nScheme           : INTERNET_SCHEME;    // enumerated scheme type | 
|  | lpszHostName      : LPWSTR;             // host name | 
|  | dwHostNameLength  : DWORD; | 
|  | nPort             : INTERNET_PORT;      // port number | 
|  | lpszUserName      : LPWSTR;             // user name | 
|  | dwUserNameLength  : DWORD; | 
|  | lpszPassword      : LPWSTR;             // password | 
|  | dwPasswordLength  : DWORD; | 
|  | lpszUrlPath       : LPWSTR;             // URL-path | 
|  | dwUrlPathLength   : DWORD; | 
|  | lpszExtraInfo     : LPWSTR;             // extra information | 
|  | dwExtraInfoLength : DWORD; | 
|  | end; | 
|  |  | 
|  | URL_COMPONENTSW = URL_COMPONENTS; | 
|  | LPURL_COMPONENTSW = LPURL_COMPONENTS; | 
|  |  | 
|  |  | 
|  | // When retrieving proxy data, an application must free the lpszProxy and | 
|  | // lpszProxyBypass strings contained in this structure (if they are non-NULL) | 
|  | // using the GlobalFree function. | 
|  | LPWINHTTP_PROXY_INFO = ^WINHTTP_PROXY_INFO; | 
|  | WINHTTP_PROXY_INFO = record | 
|  | dwAccessType    : DWORD;      // see WINHTTP_ACCESS_* types below | 
|  | lpszProxy       : LPWSTR;     // proxy server list | 
|  | lpszProxyBypass : LPWSTR;     // proxy bypass list | 
|  | end; | 
|  |  | 
|  | LPWINHTTP_PROXY_INFOW = ^WINHTTP_PROXY_INFOW; | 
|  | WINHTTP_PROXY_INFOW   = WINHTTP_PROXY_INFO; | 
|  |  | 
|  |  | 
|  | WINHTTP_AUTOPROXY_OPTIONS = record | 
|  | dwFlags                : DWORD; | 
|  | dwAutoDetectFlags      : DWORD; | 
|  | lpszAutoConfigUrl      : LPCWSTR; | 
|  | lpvReserved            : LPVOID; | 
|  | dwReserved             : DWORD; | 
|  | fAutoLogonIfChallenged : BOOL; | 
|  | end; | 
|  |  | 
|  |  | 
|  | WINHTTP_CURRENT_USER_IE_PROXY_CONFIG = record | 
|  | fAutoDetect       : BOOL; | 
|  | lpszAutoConfigUrl : LPWSTR; | 
|  | lpszProxy         : LPWSTR; | 
|  | lpszProxyBypass   : LPWSTR; | 
|  | end; | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | function WinHttpCloseHandle( aHandle : HINTERNET) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpOpen( const pszAgentW       : LPCWSTR; | 
|  | const dwAccessType    : DWORD; | 
|  | const pszProxyW       : LPCWSTR; | 
|  | const pszProxyBypassW : LPCWSTR; | 
|  | const dwFlags         : DWORD | 
|  | ) : HINTERNET;  stdcall; | 
|  |  | 
|  | function WinHttpConnect( const hSession : HINTERNET; | 
|  | const pswzServerName : LPCWSTR; | 
|  | const nServerPort : INTERNET_PORT; | 
|  | const dwReserved : DWORD | 
|  | ) : HINTERNET;  stdcall; | 
|  |  | 
|  | function WinHttpOpenRequest( const hConnect : HINTERNET; | 
|  | const pwszVerb, pwszObjectName, pwszVersion, pwszReferrer : LPCWSTR; | 
|  | const ppwszAcceptTypes : LPLPCWSTR; | 
|  | const dwFlags : DWORD | 
|  | ) : HINTERNET;  stdcall; | 
|  |  | 
|  | function WinHttpQueryOption( const hInternet : HINTERNET; | 
|  | const dwOption : DWORD; | 
|  | const pBuffer : Pointer; | 
|  | var dwBufferLength : DWORD) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpSetOption( const hInternet : HINTERNET; | 
|  | const dwOption : DWORD; | 
|  | const pBuffer : Pointer; | 
|  | const dwBufferLength : DWORD) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpSetTimeouts( const hRequestOrSession : HINTERNET; | 
|  | const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32 | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpAddRequestHeaders( const hRequest : HINTERNET; | 
|  | const pwszHeaders : LPCWSTR; | 
|  | const dwHeadersLengthInChars : DWORD; | 
|  | const dwModifiers : DWORD | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpGetProxyForUrl( const hSession  : HINTERNET; | 
|  | const lpcwszUrl : LPCWSTR; | 
|  | const options   : WINHTTP_AUTOPROXY_OPTIONS; | 
|  | const info      : WINHTTP_PROXY_INFO | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpGetIEProxyConfigForCurrentUser( var config : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  |  | 
|  | function WinHttpSendRequest( const hRequest : HINTERNET; | 
|  | const lpszHeaders : LPCWSTR; | 
|  | const dwHeadersLength : DWORD; | 
|  | const lpOptional : Pointer; | 
|  | const dwOptionalLength : DWORD; | 
|  | const dwTotalLength : DWORD; | 
|  | const pContext : Pointer | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpWriteData( const hRequest : HINTERNET; | 
|  | const pBuf : Pointer; | 
|  | const dwBytesToWrite : DWORD; | 
|  | out dwBytesWritten : DWORD | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpReceiveResponse( const hRequest : HINTERNET; const lpReserved : Pointer) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpQueryHeaders( const hRequest     : HINTERNET; | 
|  | const dwInfoLevel  : DWORD; | 
|  | const pwszName     : LPCWSTR; | 
|  | const lpBuffer     : Pointer; | 
|  | var dwBufferLength : DWORD; | 
|  | var dwIndex        : DWORD | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpQueryDataAvailable( const hRequest     : HINTERNET; | 
|  | var dwNumberOfBytesAvailable : DWORD | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpReadData( const hRequest      : HINTERNET; | 
|  | const lpBuffer      : Pointer; | 
|  | const dwBytesToRead : DWORD; | 
|  | out dwBytesRead     : DWORD | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpCrackUrl( const pwszUrl : LPCWSTR; | 
|  | const dwUrlLength : DWORD; | 
|  | const dwFlags : DWORD; | 
|  | var urlComponents : URL_COMPONENTS | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  | function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS; | 
|  | const dwFlags : DWORD; | 
|  | const pwszUrl : LPCWSTR; | 
|  | var pdwUrlLength : DWORD | 
|  | ) : BOOL;  stdcall; | 
|  |  | 
|  |  | 
|  | const | 
|  | // ports | 
|  | INTERNET_DEFAULT_PORT = 0;           // use the protocol-specific default (80 or 443) | 
|  | INTERNET_DEFAULT_HTTP_PORT = 80; | 
|  | INTERNET_DEFAULT_HTTPS_PORT = 443; | 
|  |  | 
|  | // 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_ESCAPE_DISABLE        = $00000040;  // disable escaping | 
|  | WINHTTP_FLAG_ESCAPE_DISABLE_QUERY  = $00000080;  // if escaping enabled escape path part, but do not escape query | 
|  | WINHTTP_FLAG_BYPASS_PROXY_CACHE    = $00000100;  // add "pragma: no-cache" request header | 
|  | WINHTTP_FLAG_REFRESH               = WINHTTP_FLAG_BYPASS_PROXY_CACHE; | 
|  |  | 
|  | // flags for WinHttpOpen(): | 
|  | WINHTTP_FLAG_ASYNC                 = $10000000;  // want async session, requires WinHttpSetStatusCallback() usage | 
|  |  | 
|  | // flags for WinHttpSendRequest(): | 
|  | WINHTTP_NO_PROXY_NAME           = nil; | 
|  | WINHTTP_NO_PROXY_BYPASS         = nil; | 
|  | WINHTTP_NO_CLIENT_CERT_CONTEXT  = nil; | 
|  | WINHTTP_NO_REFERER              = nil; | 
|  | WINHTTP_DEFAULT_ACCEPT_TYPES    = nil; | 
|  | 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; | 
|  |  | 
|  | // WinHttpAddRequestHeaders() dwModifiers | 
|  | WINHTTP_ADDREQ_INDEX_MASK = $0000FFFF; | 
|  | 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; | 
|  |  | 
|  | // URL functions | 
|  | 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 urls with username/pwd sections | 
|  |  | 
|  | INTERNET_SCHEME_HTTP  = INTERNET_SCHEME(1); | 
|  | INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2); | 
|  | INTERNET_SCHEME_FTP   = INTERNET_SCHEME(3); | 
|  | INTERNET_SCHEME_SOCKS = INTERNET_SCHEME(4); | 
|  |  | 
|  | // options manifests for WinHttp{Query|Set}Option | 
|  | WINHTTP_OPTION_CALLBACK = 1; | 
|  | 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_PROXY_RESULT_ENTRY = 39; | 
|  | 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_OPTION_TCP_PRIORITY_HINT = 128; | 
|  | WINHTTP_OPTION_CONNECTION_FILTER = 131; | 
|  | WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL = 133; | 
|  | WINHTTP_OPTION_HTTP_PROTOCOL_USED = 134; | 
|  | WINHTTP_OPTION_KDC_PROXY_SETTINGS = 136; | 
|  | WINHTTP_OPTION_ENCODE_EXTRA = 138; | 
|  | WINHTTP_OPTION_DISABLE_STREAM_QUEUE = 139; | 
|  | WINHTTP_OPTION_IPV6_FAST_FALLBACK = 140; | 
|  | WINHTTP_OPTION_CONNECTION_STATS_V0 = 141; | 
|  | WINHTTP_OPTION_REQUEST_TIMES = 142; | 
|  | WINHTTP_OPTION_EXPIRE_CONNECTION = 143; | 
|  | WINHTTP_OPTION_DISABLE_SECURE_PROTOCOL_FALLBACK = 144; | 
|  | WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED = 145; | 
|  | WINHTTP_OPTION_REQUEST_STATS = 146; | 
|  | WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT = 147; | 
|  | WINHTTP_OPTION_CONNECTION_STATS_V1 = 150; | 
|  | WINHTTP_OPTION_SECURITY_INFO = 151; | 
|  | WINHTTP_OPTION_TCP_KEEPALIVE = 152; | 
|  | WINHTTP_OPTION_TCP_FAST_OPEN = 153; | 
|  | WINHTTP_OPTION_TCP_FALSE_START = 154; | 
|  | WINHTTP_OPTION_IGNORE_CERT_REVOCATION_OFFLINE = 155; | 
|  | WINHTTP_OPTION_TLS_PROTOCOL_INSECURE_FALLBACK = 158; | 
|  | WINHTTP_OPTION_STREAM_ERROR_CODE = 159; | 
|  | WINHTTP_OPTION_REQUIRE_STREAM_END = 160; | 
|  | WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT = 161; | 
|  | WINHTTP_OPTION_FAILED_CONNECTION_RETRIES = 162; | 
|  | WINHTTP_OPTION_HTTP2_KEEPALIVE = 164; | 
|  | WINHTTP_OPTION_RESOLUTION_HOSTNAME = 165; | 
|  | WINHTTP_OPTION_SET_TOKEN_BINDING = 166; | 
|  | WINHTTP_OPTION_TOKEN_BINDING_PUBLIC_KEY = 167; | 
|  | WINHTTP_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 168; | 
|  | WINHTTP_OPTION_HTTP2_PLUS_TRANSFER_ENCODING = 169; | 
|  | WINHTTP_OPTION_RESOLVER_CACHE_CONFIG = 170; | 
|  | WINHTTP_OPTION_DISABLE_CERT_CHAIN_BUILDING = 171; | 
|  | WINHTTP_OPTION_BACKGROUND_CONNECTIONS = 172; | 
|  | WINHTTP_OPTION_FIRST_AVAILABLE_CONNECTION = 173; | 
|  | WINHTTP_OPTION_TCP_PRIORITY_STATUS = 177; | 
|  | WINHTTP_OPTION_CONNECTION_GUID = 178; | 
|  | WINHTTP_OPTION_MATCH_CONNECTION_GUID = 179; | 
|  | WINHTTP_OPTION_HTTP2_RECEIVE_WINDOW = 183; | 
|  | WINHTTP_OPTION_FEATURE_SUPPORTED = 184; | 
|  | WINHTTP_OPTION_QUIC_STATS = 185; | 
|  | WINHTTP_OPTION_HTTP3_KEEPALIVE = 188; | 
|  | WINHTTP_OPTION_HTTP3_HANDSHAKE_TIMEOUT = 189; | 
|  | WINHTTP_OPTION_HTTP3_INITIAL_RTT = 190; | 
|  | WINHTTP_OPTION_HTTP3_STREAM_ERROR_CODE = 191; | 
|  | WINHTTP_OPTION_REQUEST_ANNOTATION = 192; | 
|  | WINHTTP_OPTION_DISABLE_PROXY_AUTH_SCHEMES = 193; | 
|  | WINHTTP_OPTION_REVERT_IMPERSONATION_SERVER_CERT = 194; | 
|  | WINHTTP_OPTION_DISABLE_GLOBAL_POOLING = 195; | 
|  | WINHTTP_OPTION_USE_SESSION_SCH_CRED = 196; | 
|  | WINHTTP_OPTION_QUIC_STATS_V2 = 200; | 
|  | WINHTTP_OPTION_QUIC_STREAM_STATS = 202; | 
|  | WINHTTP_OPTION_USE_LOOKASIDE = 203; | 
|  | WINHTTP_OPTION_ERROR_LOG_GUID = 204; | 
|  | WINHTTP_OPTION_ENABLE_FAST_FORWARDING = 205; | 
|  | WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_DATA = 206; | 
|  | WINHTTP_OPTION_UPGRADE_TO_PROTOCOL = 207; | 
|  | WINHTTP_OPTION_CONNECTION_STATS_V2 = 208; | 
|  | WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS = 209; | 
|  |  | 
|  | WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK; | 
|  | //WINHTTP_LAST_OPTION = WINHTTP_OPTION_FAST_FORWARDING_RESPONSE_STATUS; | 
|  |  | 
|  | WINHTTP_OPTION_USERNAME = $1000; | 
|  | WINHTTP_OPTION_PASSWORD = $1001; | 
|  | WINHTTP_OPTION_PROXY_USERNAME = $1002; | 
|  | WINHTTP_OPTION_PROXY_PASSWORD = $1003; | 
|  |  | 
|  | // manifest value for WINHTTP_OPTION_MAX_CONNS_PER_SERVER and WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER | 
|  | WINHTTP_CONNS_PER_SERVER_UNLIMITED    = $FFFFFFFF; | 
|  |  | 
|  | // values for WINHTTP_OPTION_AUTOLOGON_POLICY | 
|  | 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; | 
|  |  | 
|  | // values for WINHTTP_OPTION_REDIRECT_POLICY | 
|  | 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; | 
|  |  | 
|  | // values for WINHTTP_OPTION_DISABLE_FEATURE | 
|  | WINHTTP_DISABLE_COOKIES            = $00000001; | 
|  | WINHTTP_DISABLE_REDIRECTS          = $00000002; | 
|  | WINHTTP_DISABLE_AUTHENTICATION     = $00000004; | 
|  | WINHTTP_DISABLE_KEEP_ALIVE         = $00000008; | 
|  |  | 
|  | // values for WINHTTP_OPTION_ENABLE_FEATURE | 
|  | WINHTTP_ENABLE_SSL_REVOCATION            = $00000001; | 
|  | WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION  = $00000002; | 
|  |  | 
|  | // values for WINHTTP_OPTION_SPN | 
|  | WINHTTP_DISABLE_SPN_SERVER_PORT    = $00000000; | 
|  | WINHTTP_ENABLE_SPN_SERVER_PORT     = $00000001; | 
|  | WINHTTP_OPTION_SPN_MASK            = WINHTTP_ENABLE_SPN_SERVER_PORT; | 
|  |  | 
|  | // winhttp handle types | 
|  | WINHTTP_HANDLE_TYPE_SESSION  = 1; | 
|  | WINHTTP_HANDLE_TYPE_CONNECT  = 2; | 
|  | WINHTTP_HANDLE_TYPE_REQUEST  = 3; | 
|  |  | 
|  | // values for auth schemes | 
|  | 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 supported Authentication Targets | 
|  | WINHTTP_AUTH_TARGET_SERVER     = $00000000; | 
|  | WINHTTP_AUTH_TARGET_PROXY      = $00000001; | 
|  |  | 
|  | // options for WINHTTP_OPTION_DECOMPRESSION | 
|  | WINHTTP_DECOMPRESSION_FLAG_GZIP    = $00000001; | 
|  | WINHTTP_DECOMPRESSION_FLAG_DEFLATE = $00000002; | 
|  | WINHTTP_DECOMPRESSION_FLAG_ALL     = WINHTTP_DECOMPRESSION_FLAG_GZIP | 
|  | or WINHTTP_DECOMPRESSION_FLAG_DEFLATE; | 
|  |  | 
|  | // WinHttpOpen dwAccessType values | 
|  | 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_IGNORE_REQUEST_TOTAL_LENGTH = 0; | 
|  |  | 
|  | // values for WINHTTP_OPTION_SECURITY_FLAGS | 
|  |  | 
|  | // query only | 
|  | SECURITY_FLAG_SECURE           = $00000001; // can query only | 
|  | SECURITY_FLAG_STRENGTH_WEAK    = $10000000; | 
|  | SECURITY_FLAG_STRENGTH_MEDIUM  = $40000000; | 
|  | SECURITY_FLAG_STRENGTH_STRONG  = $20000000; | 
|  |  | 
|  | // query flags | 
|  | 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; | 
|  | WINHTTP_QUERY_STATUS_CODE                  = 19; | 
|  | WINHTTP_QUERY_STATUS_TEXT                  = 20; | 
|  | WINHTTP_QUERY_RAW_HEADERS                  = 21; | 
|  | WINHTTP_QUERY_RAW_HEADERS_CRLF             = 22; | 
|  | 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; | 
|  | 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; | 
|  | WINHTTP_QUERY_FLAG_NUMBER64                = $08000000; | 
|  |  | 
|  | // Secure connection error status flags | 
|  | 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_TLS1_3 = $00002000; | 
|  |  | 
|  | // Note: SECURE_PROTOCOL_ALL does NOT include TLS1.1 and higher! | 
|  | WINHTTP_FLAG_SECURE_PROTOCOL_ALL    = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 | 
|  | or WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | 
|  | or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1; | 
|  |  | 
|  | // AutoProxy | 
|  | WINHTTP_AUTOPROXY_AUTO_DETECT           = $00000001; | 
|  | WINHTTP_AUTOPROXY_CONFIG_URL            = $00000002; | 
|  | WINHTTP_AUTOPROXY_HOST_KEEPCASE         = $00000004; | 
|  | WINHTTP_AUTOPROXY_HOST_LOWERCASE        = $00000008; | 
|  | WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG      = $00000100; | 
|  | WINHTTP_AUTOPROXY_ALLOW_STATIC          = $00000200; | 
|  | WINHTTP_AUTOPROXY_ALLOW_CM              = $00000400; | 
|  | WINHTTP_AUTOPROXY_RUN_INPROCESS         = $00010000; | 
|  | WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY   = $00020000; | 
|  | WINHTTP_AUTOPROXY_NO_DIRECTACCESS       = $00040000; | 
|  | WINHTTP_AUTOPROXY_NO_CACHE_CLIENT       = $00080000; | 
|  | WINHTTP_AUTOPROXY_NO_CACHE_SVC          = $00100000; | 
|  | WINHTTP_AUTOPROXY_SORT_RESULTS          = $00400000; | 
|  |  | 
|  | // Flags for dwAutoDetectFlags | 
|  | WINHTTP_AUTO_DETECT_TYPE_DHCP           = $00000001; | 
|  | WINHTTP_AUTO_DETECT_TYPE_DNS_A          = $00000002; | 
|  |  | 
|  | 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_SECURE_CERT_DATE_INVALID  = WINHTTP_ERROR_BASE + 37; - see below | 
|  | //ERROR_WINHTTP_SECURE_CERT_CN_INVALID    = WINHTTP_ERROR_BASE + 38; - see below | 
|  | ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED   = WINHTTP_ERROR_BASE + 44; | 
|  | //ERROR_WINHTTP_SECURE_INVALID_CA         = WINHTTP_ERROR_BASE + 45; - see below | 
|  | //ERROR_WINHTTP_SECURE_CERT_REV_FAILED    = WINHTTP_ERROR_BASE + 57; - see below | 
|  | 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_SECURE_CHANNEL_ERROR      = WINHTTP_ERROR_BASE + 157; - see below | 
|  | ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT     = WINHTTP_ERROR_BASE + 166; | 
|  | ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = WINHTTP_ERROR_BASE + 167; | 
|  | //ERROR_WINHTTP_SECURE_INVALID_CERT       = WINHTTP_ERROR_BASE + 169; - see below | 
|  | ERROR_WINHTTP_NOT_INITIALIZED           = WINHTTP_ERROR_BASE + 172; | 
|  | ERROR_WINHTTP_SECURE_FAILURE            = WINHTTP_ERROR_BASE + 175; | 
|  | ERROR_WINHTTP_UNHANDLED_SCRIPT_TYPE     = WINHTTP_ERROR_BASE + 176; | 
|  | ERROR_WINHTTP_SCRIPT_EXECUTION_ERROR    = WINHTTP_ERROR_BASE + 177; | 
|  | ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR  = WINHTTP_ERROR_BASE + 178; | 
|  |  | 
|  | // Certificate security errors. Additional information is provided | 
|  | // via the WINHTTP_CALLBACK_STATUS_SECURE_FAILURE callback notification. | 
|  | 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; | 
|  | ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED_PROXY         = WINHTTP_ERROR_BASE + 187; | 
|  | ERROR_WINHTTP_SECURE_FAILURE_PROXY                  = WINHTTP_ERROR_BASE + 188; | 
|  | ERROR_WINHTTP_RESERVED_189                          = WINHTTP_ERROR_BASE + 189; | 
|  | ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH                = WINHTTP_ERROR_BASE + 190; | 
|  |  | 
|  | WINHTTP_ERROR_LAST                                  = ERROR_WINHTTP_HTTP_PROTOCOL_MISMATCH; | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | const | 
|  | WINHTTP_THRIFT_DEFAULTS = WINHTTP_FLAG_NULL_CODEPAGE | 
|  | or WINHTTP_FLAG_BYPASS_PROXY_CACHE | 
|  | or WINHTTP_FLAG_ESCAPE_DISABLE; | 
|  |  | 
|  |  | 
|  |  | 
|  | type | 
|  | IWinHTTPSession = interface; | 
|  | IWinHTTPConnection = interface; | 
|  |  | 
|  | IWinHTTPRequest = interface | 
|  | ['{FADA4B45-D447-4F07-8361-1AD6656E5E8C}'] | 
|  | function  Handle : HINTERNET; | 
|  | function  Connection : IWinHTTPConnection; | 
|  | function  AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean; | 
|  | function  SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; | 
|  | procedure TryAutoProxy( const aUrl : string); | 
|  | procedure EnableAutomaticContentDecompression( const aEnable : Boolean); | 
|  | function  SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean; | 
|  | function  WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD; | 
|  | function  FlushAndReceiveResponse : Boolean; | 
|  | function  ReadData( const dwRead : DWORD) : TBytes;  overload; | 
|  | function  ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD;  overload; | 
|  | function  QueryDataAvailable : DWORD; | 
|  | function  QueryTotalResponseSize( out dwSize : DWORD) : Boolean; | 
|  | function  QueryHttpStatus( out dwStatusCode : DWORD; out sStatusText : string) : Boolean; | 
|  | end; | 
|  |  | 
|  | IWinHTTPConnection = interface | 
|  | ['{ED5BCA49-84D6-4CFE-BF18-3238B1FF2AFB}'] | 
|  | function  Handle : HINTERNET; | 
|  | function  Session : IWinHTTPSession; | 
|  | function  OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest; | 
|  | end; | 
|  |  | 
|  | IWinHTTPSession = interface | 
|  | ['{261ADCB7-5465-4407-8840-468C17F009F0}'] | 
|  | function  Handle : HINTERNET; | 
|  | function  Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection; | 
|  | function  SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; | 
|  | function  EnableSecureProtocols( const aFlagSet : DWORD) : Boolean; | 
|  | end; | 
|  |  | 
|  | IWinHTTPUrl = interface | 
|  | ['{78BE977C-4171-4AF5-A250-FD2890205E63}'] | 
|  | // url parts getter | 
|  | function  GetScheme : UnicodeString; | 
|  | function  GetNumScheme : INTERNET_SCHEME; | 
|  | function  GetHostName  : UnicodeString; | 
|  | function  GetPort : INTERNET_PORT; | 
|  | function  GetUserName  : UnicodeString; | 
|  | function  GetPassword  : UnicodeString; | 
|  | function  GetUrlPath   : UnicodeString; | 
|  | function  GetExtraInfo : UnicodeString; | 
|  |  | 
|  | // url parts setter | 
|  | procedure SetScheme( const value : UnicodeString); | 
|  | procedure SetHostName ( const value : UnicodeString); | 
|  | procedure SetPort( const value : INTERNET_PORT); | 
|  | procedure SetUserName( const value : UnicodeString); | 
|  | procedure SetPassword( const value : UnicodeString); | 
|  | procedure SetUrlPath( const value : UnicodeString); | 
|  | procedure SetExtraInfo( const value : UnicodeString); | 
|  |  | 
|  | // url as a whole | 
|  | function  BuildUrl : UnicodeString; | 
|  | procedure CrackUrl( const value : UnicodeString); | 
|  |  | 
|  | // url parts | 
|  | property  Scheme    : UnicodeString   read GetScheme    write SetScheme; | 
|  | property  NumScheme : INTERNET_SCHEME read GetNumScheme; // readonly | 
|  | property  HostName  : UnicodeString   read GetHostName  write SetHostName; | 
|  | property  Port      : INTERNET_PORT   read GetPort      write SetPort; | 
|  | property  UserName  : UnicodeString   read GetUserName  write SetUserName; | 
|  | property  Password  : UnicodeString   read GetPassword  write SetPassword; | 
|  | property  UrlPath   : UnicodeString   read GetUrlPath   write SetUrlPath; | 
|  | property  ExtraInfo : UnicodeString   read GetExtraInfo write SetExtraInfo; | 
|  |  | 
|  | // url as a whole | 
|  | property  CompleteURL : UnicodeString read BuildUrl write CrackUrl; | 
|  | end; | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | type | 
|  | TWinHTTPHandleObjectImpl = class( TInterfacedObject) | 
|  | strict protected | 
|  | FHandle : HINTERNET; | 
|  | function  Handle : HINTERNET; | 
|  | public | 
|  | constructor Create( const aHandle : HINTERNET); | 
|  | destructor Destroy;  override; | 
|  | end; | 
|  |  | 
|  |  | 
|  | TWinHTTPSessionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPSession) | 
|  | strict protected | 
|  |  | 
|  | // IWinHTTPSession | 
|  | function  Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection; | 
|  | function  SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; | 
|  | function  EnableSecureProtocols( const aFlagSet : DWORD) : Boolean; | 
|  | public | 
|  | constructor Create( const aAgent : UnicodeString; | 
|  | const aAccessType : DWORD          = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY; | 
|  | const aProxy : UnicodeString       = ''; | 
|  | const aProxyBypass : UnicodeString = ''; | 
|  | const aFlags : DWORD               = 0); | 
|  | destructor Destroy;  override; | 
|  | end; | 
|  |  | 
|  |  | 
|  | TWinHTTPConnectionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPConnection) | 
|  | strict protected | 
|  | FSession : IWinHTTPSession; | 
|  |  | 
|  | // IWinHTTPConnection | 
|  | function  OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest; | 
|  | function  Session : IWinHTTPSession; | 
|  |  | 
|  | public | 
|  | constructor Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT); | 
|  | destructor Destroy;  override; | 
|  | end; | 
|  |  | 
|  |  | 
|  | TAcceptTypesArray = array of string; | 
|  |  | 
|  | TWinHTTPRequestImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPRequest) | 
|  | strict protected | 
|  | FConnection : IWinHTTPConnection; | 
|  |  | 
|  | // IWinHTTPRequest | 
|  | function  Connection : IWinHTTPConnection; | 
|  | function  AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean; | 
|  | function  SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; | 
|  | procedure TryAutoProxy( const aUrl : string); | 
|  | procedure EnableAutomaticContentDecompression( const aEnable : Boolean); | 
|  | function  SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean; | 
|  | function  WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD; | 
|  | function  FlushAndReceiveResponse : Boolean; | 
|  | function  ReadData( const dwRead : DWORD) : TBytes;  overload; | 
|  | function  ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD;  overload; | 
|  | function  QueryDataAvailable : DWORD; | 
|  | function  QueryTotalResponseSize( out dwSize : DWORD) : Boolean; | 
|  | function  QueryHttpStatus( out dwStatusCode : DWORD; out sStatusText : string) : Boolean; | 
|  |  | 
|  | public | 
|  | constructor Create( const aConnection : IWinHTTPConnection; | 
|  | const aVerb, aObjName : UnicodeString; | 
|  | const aVersion : UnicodeString = ''; | 
|  | const aReferrer : UnicodeString = ''; | 
|  | const aAcceptTypes : UnicodeString = '*/*'; | 
|  | const aFlags : DWORD = WINHTTP_THRIFT_DEFAULTS | 
|  | ); | 
|  |  | 
|  | destructor Destroy;  override; | 
|  | end; | 
|  |  | 
|  |  | 
|  | TWinHTTPUrlImpl = class( TInterfacedObject, IWinHTTPUrl) | 
|  | strict private | 
|  | FScheme    : UnicodeString; | 
|  | FNumScheme : INTERNET_SCHEME; | 
|  | FHostName  : UnicodeString; | 
|  | FPort      : INTERNET_PORT; | 
|  | FUserName  : UnicodeString; | 
|  | FPassword  : UnicodeString; | 
|  | FUrlPath   : UnicodeString; | 
|  | FExtraInfo : UnicodeString; | 
|  |  | 
|  | strict protected | 
|  | // url parts getter | 
|  | function  GetScheme    : UnicodeString; | 
|  | function  GetNumScheme : INTERNET_SCHEME; | 
|  | function  GetHostName  : UnicodeString; | 
|  | function  GetPort      : INTERNET_PORT; | 
|  | function  GetUserName  : UnicodeString; | 
|  | function  GetPassword  : UnicodeString; | 
|  | function  GetUrlPath   : UnicodeString; | 
|  | function  GetExtraInfo : UnicodeString; | 
|  |  | 
|  | // url parts setter | 
|  | procedure SetScheme(    const value : UnicodeString); | 
|  | procedure SetHostName ( const value : UnicodeString); | 
|  | procedure SetPort(      const value : INTERNET_PORT); | 
|  | procedure SetUserName(  const value : UnicodeString); | 
|  | procedure SetPassword(  const value : UnicodeString); | 
|  | procedure SetUrlPath(   const value : UnicodeString); | 
|  | procedure SetExtraInfo( const value : UnicodeString); | 
|  |  | 
|  | // url as a whole | 
|  | function  BuildUrl : UnicodeString; | 
|  | procedure CrackUrl( const value : UnicodeString); | 
|  |  | 
|  | public | 
|  | constructor Create( const aUri : UnicodeString); | 
|  | destructor Destroy;  override; | 
|  | end; | 
|  |  | 
|  |  | 
|  | WINHTTP_PROXY_INFO_Helper = record helper for WINHTTP_PROXY_INFO | 
|  | procedure Initialize; | 
|  | procedure FreeAllocatedResources; | 
|  | end; | 
|  |  | 
|  |  | 
|  | WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper = record helper for WINHTTP_CURRENT_USER_IE_PROXY_CONFIG | 
|  | procedure Initialize; | 
|  | procedure FreeAllocatedResources; | 
|  | end; | 
|  |  | 
|  |  | 
|  | EWinHTTPException = class(Exception); | 
|  |  | 
|  | { helper functions } | 
|  |  | 
|  | function WinHttpSysErrorMessage( const error : Cardinal): string; | 
|  | procedure RaiseLastWinHttpError; | 
|  |  | 
|  |  | 
|  | implementation | 
|  |  | 
|  | const WINHTTP_DLL = 'WinHTTP.dll'; | 
|  |  | 
|  | function WinHttpCloseHandle;  stdcall; external WINHTTP_DLL; | 
|  | function WinHttpOpen;  stdcall; external WINHTTP_DLL; | 
|  | function WinHttpConnect;  stdcall; external WINHTTP_DLL; | 
|  | function WinHttpOpenRequest; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpSendRequest; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpSetTimeouts; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpQueryOption; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpSetOption; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpAddRequestHeaders; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpGetProxyForUrl; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpGetIEProxyConfigForCurrentUser; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpWriteData; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpReceiveResponse; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpQueryHeaders; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpQueryDataAvailable; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpReadData; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpCrackUrl; stdcall; external WINHTTP_DLL; | 
|  | function WinHttpCreateUrl; stdcall; external WINHTTP_DLL; | 
|  |  | 
|  |  | 
|  | { helper functions } | 
|  |  | 
|  | function WinHttpSysErrorMessage( const error : Cardinal): string; | 
|  | const FLAGS = FORMAT_MESSAGE_ALLOCATE_BUFFER | 
|  | or FORMAT_MESSAGE_IGNORE_INSERTS | 
|  | or FORMAT_MESSAGE_FROM_SYSTEM | 
|  | or FORMAT_MESSAGE_FROM_HMODULE; | 
|  | var pBuffer : PChar; | 
|  | nChars : Cardinal; | 
|  | begin | 
|  | if (error < WINHTTP_ERROR_BASE) | 
|  | or (error > WINHTTP_ERROR_LAST) | 
|  | then Exit( SysUtils.SysErrorMessage( error)); | 
|  |  | 
|  | pBuffer := nil; | 
|  | try | 
|  | nChars := FormatMessage( FLAGS, | 
|  | Pointer( GetModuleHandle( WINHTTP_DLL)), | 
|  | error, | 
|  | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language | 
|  | @pBuffer, 0, | 
|  | nil); | 
|  | SetString( result, pBuffer, nChars); | 
|  | finally | 
|  | LocalFree( NativeUInt( pBuffer)); | 
|  | end; | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure RaiseLastWinHttpError; | 
|  | var error : Cardinal; | 
|  | sMsg  : string; | 
|  | begin | 
|  | error := Cardinal( GetLastError); | 
|  | if error <> NOERROR then begin | 
|  | sMSg := IntToStr(Integer(error))+' '+WinHttpSysErrorMessage(error); | 
|  | raise EWinHTTPException.Create( sMsg); | 
|  | end; | 
|  | end; | 
|  |  | 
|  |  | 
|  |  | 
|  | { misc. record helper } | 
|  |  | 
|  |  | 
|  | procedure GlobalFreeAndNil( var p : LPWSTR); | 
|  | begin | 
|  | if p <> nil then begin | 
|  | GlobalFree( HGLOBAL( p)); | 
|  | p := nil; | 
|  | end; | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure WINHTTP_PROXY_INFO_Helper.Initialize; | 
|  | begin | 
|  | FillChar( Self, SizeOf(Self), 0); | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure WINHTTP_PROXY_INFO_Helper.FreeAllocatedResources; | 
|  | // The caller must free the lpszProxy and lpszProxyBypass strings | 
|  | // if they are non-NULL. Use GlobalFree to free the strings. | 
|  | begin | 
|  | GlobalFreeAndNil( lpszProxy); | 
|  | GlobalFreeAndNil( lpszProxyBypass); | 
|  | Initialize; | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper.Initialize; | 
|  | begin | 
|  | FillChar( Self, SizeOf(Self), 0); | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper.FreeAllocatedResources; | 
|  | // The caller must free the lpszProxy, lpszProxyBypass and lpszAutoConfigUrl strings | 
|  | // if they are non-NULL. Use GlobalFree to free the strings. | 
|  | begin | 
|  | GlobalFreeAndNil( lpszProxy); | 
|  | GlobalFreeAndNil( lpszProxyBypass); | 
|  | GlobalFreeAndNil( lpszAutoConfigUrl); | 
|  | Initialize; | 
|  | end; | 
|  |  | 
|  |  | 
|  | { TWinHTTPHandleObjectImpl } | 
|  |  | 
|  | constructor TWinHTTPHandleObjectImpl.Create( const aHandle : HINTERNET); | 
|  | begin | 
|  | inherited Create; | 
|  | FHandle := aHandle; | 
|  |  | 
|  | if FHandle = nil | 
|  | then raise EWinHTTPException.Create('Invalid handle'); | 
|  | end; | 
|  |  | 
|  |  | 
|  | destructor TWinHTTPHandleObjectImpl.Destroy; | 
|  | begin | 
|  | try | 
|  | if Assigned(FHandle) then begin | 
|  | WinHttpCloseHandle(FHandle); | 
|  | FHandle := nil; | 
|  | end; | 
|  |  | 
|  | finally | 
|  | inherited Destroy; | 
|  | end; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPHandleObjectImpl.Handle : HINTERNET; | 
|  | begin | 
|  | result := FHandle; | 
|  | end; | 
|  |  | 
|  |  | 
|  | { TWinHTTPSessionImpl } | 
|  |  | 
|  |  | 
|  | constructor TWinHTTPSessionImpl.Create( const aAgent : UnicodeString; const aAccessType : DWORD; | 
|  | const aProxy, aProxyBypass : UnicodeString; const aFlags : DWORD); | 
|  | var handle : HINTERNET; | 
|  | begin | 
|  | handle := WinHttpOpen( PWideChar(aAgent), aAccessType, | 
|  | PWideChar(Pointer(aProxy)),        // may be nil | 
|  | PWideChar(Pointer(aProxyBypass)),  // may be nil | 
|  | aFlags); | 
|  | if handle = nil then RaiseLastWinHttpError; | 
|  | inherited Create( handle); | 
|  | end; | 
|  |  | 
|  |  | 
|  | destructor TWinHTTPSessionImpl.Destroy; | 
|  | begin | 
|  | inherited Destroy; | 
|  | // add code here | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPSessionImpl.Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT) : IWinHTTPConnection; | 
|  | begin | 
|  | result := TWinHTTPConnectionImpl.Create( Self, aHostName, aPort); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPSessionImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; | 
|  | begin | 
|  | result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPSessionImpl.EnableSecureProtocols( const aFlagSet : DWORD) : Boolean; | 
|  | var dwSize : DWORD; | 
|  | begin | 
|  | dwSize := SizeOf(aFlagSet); | 
|  | result := WinHttpSetOption( Handle, WINHTTP_OPTION_SECURE_PROTOCOLS, @aFlagset, dwSize); | 
|  | end; | 
|  |  | 
|  |  | 
|  | { TWinHTTPConnectionImpl } | 
|  |  | 
|  | constructor TWinHTTPConnectionImpl.Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT); | 
|  | var handle : HINTERNET; | 
|  | begin | 
|  | FSession := aSession; | 
|  | handle   := WinHttpConnect( FSession.Handle, PWideChar(aHostName), aPort, 0); | 
|  | if handle = nil then RaiseLastWinHttpError; | 
|  | inherited Create( handle); | 
|  | end; | 
|  |  | 
|  |  | 
|  | destructor TWinHTTPConnectionImpl.Destroy; | 
|  | begin | 
|  | inherited Destroy; | 
|  | FSession := nil; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPConnectionImpl.Session : IWinHTTPSession; | 
|  | begin | 
|  | result := FSession; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPConnectionImpl.OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest; | 
|  | var dwFlags : DWORD; | 
|  | begin | 
|  | dwFlags := WINHTTP_THRIFT_DEFAULTS; | 
|  | if secure | 
|  | then dwFlags := dwFlags or WINHTTP_FLAG_SECURE | 
|  | else dwFlags := dwFlags and not WINHTTP_FLAG_SECURE; | 
|  |  | 
|  | result := TWinHTTPRequestImpl.Create( Self, aVerb, aObjName, '', '', aAcceptTypes, dwFlags); | 
|  | end; | 
|  |  | 
|  |  | 
|  | { TWinHTTPRequestImpl } | 
|  |  | 
|  | constructor TWinHTTPRequestImpl.Create( const aConnection : IWinHTTPConnection; | 
|  | const aVerb, aObjName, aVersion, aReferrer : UnicodeString; | 
|  | const aAcceptTypes : UnicodeString; | 
|  | const aFlags : DWORD | 
|  | ); | 
|  | var handle : HINTERNET; | 
|  | accept : array[0..1] of PWideChar; | 
|  | begin | 
|  | FConnection := aConnection; | 
|  |  | 
|  | accept[0] := PWideChar(aAcceptTypes); | 
|  | accept[1] := nil; | 
|  |  | 
|  | handle      := WinHttpOpenRequest( FConnection.Handle, | 
|  | PWideChar(UpperCase(aVerb)), | 
|  | PWideChar(aObjName), | 
|  | PWideChar(aVersion), | 
|  | PWideChar(aReferrer), | 
|  | @accept, | 
|  | aFlags); | 
|  | if handle = nil then RaiseLastWinHttpError; | 
|  | inherited Create( handle); | 
|  | end; | 
|  |  | 
|  |  | 
|  | destructor TWinHTTPRequestImpl.Destroy; | 
|  | begin | 
|  | inherited Destroy; | 
|  | FConnection := nil; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.Connection : IWinHTTPConnection; | 
|  | begin | 
|  | result := FConnection; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean; | 
|  | begin | 
|  | result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.AddRequestHeader( const aHeader : string; const addflag : DWORD) : Boolean; | 
|  | begin | 
|  | result := WinHttpAddRequestHeaders( FHandle, PWideChar(aHeader), DWORD(-1), addflag); | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure TWinHTTPRequestImpl.TryAutoProxy( const aUrl : string); | 
|  | // From MSDN: | 
|  | //    AutoProxy support is not fully integrated into the HTTP stack in WinHTTP. | 
|  | //    Before sending a request, the application must call WinHttpGetProxyForUrl | 
|  | //    to obtain the name of a proxy server and then call WinHttpSetOption using | 
|  | //    WINHTTP_OPTION_PROXY to set the proxy configuration on the WinHTTP request | 
|  | //    handle created by WinHttpOpenRequest. | 
|  | //    See https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttp-autoproxy-api | 
|  | var | 
|  | options : WINHTTP_AUTOPROXY_OPTIONS; | 
|  | proxy   : WINHTTP_PROXY_INFO; | 
|  | ieProxy : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; | 
|  | dwSize  : DWORD; | 
|  | begin | 
|  | // try AutoProxy via PAC first | 
|  | proxy.Initialize; | 
|  | try | 
|  | FillChar( options, SizeOf(options), 0); | 
|  | options.dwFlags                := WINHTTP_AUTOPROXY_AUTO_DETECT; | 
|  | options.dwAutoDetectFlags      := WINHTTP_AUTO_DETECT_TYPE_DHCP or WINHTTP_AUTO_DETECT_TYPE_DNS_A; | 
|  | options.fAutoLogonIfChallenged := TRUE; | 
|  | if WinHttpGetProxyForUrl( FConnection.Session.Handle, PChar(aUrl), options, proxy) then begin | 
|  | dwSize  := SizeOf(proxy); | 
|  | WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize); | 
|  | Exit; | 
|  | end; | 
|  |  | 
|  | finally | 
|  | proxy.FreeAllocatedResources; | 
|  | end; | 
|  |  | 
|  | // Use IE settings as a fallback, useful in client (i.e. non-server) environments | 
|  | ieProxy.Initialize; | 
|  | try | 
|  | if WinHttpGetIEProxyConfigForCurrentUser( ieProxy) | 
|  | then begin | 
|  |  | 
|  | // lpszAutoConfigUrl = "Use automatic proxy configuration" | 
|  | if ieProxy.lpszAutoConfigUrl <> nil then begin | 
|  | options.lpszAutoConfigUrl := ieProxy.lpszAutoConfigUrl; | 
|  | options.dwFlags := options.dwFlags or WINHTTP_AUTOPROXY_CONFIG_URL; | 
|  |  | 
|  | proxy.Initialize; | 
|  | try | 
|  | if WinHttpGetProxyForUrl( FConnection.Session.Handle, PChar(aUrl), options, proxy) then begin | 
|  | dwSize := SizeOf(proxy); | 
|  | WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize); | 
|  | Exit; | 
|  | end; | 
|  | finally | 
|  | proxy.FreeAllocatedResources; | 
|  | end; | 
|  | end; | 
|  |  | 
|  | // lpszProxy = "use a proxy server" | 
|  | if ieProxy.lpszProxy <> nil then begin | 
|  | proxy.Initialize; | 
|  | try | 
|  | proxy.dwAccessType    := WINHTTP_ACCESS_TYPE_NAMED_PROXY; | 
|  | proxy.lpszProxy       := ieProxy.lpszProxy; | 
|  | proxy.lpszProxyBypass := ieProxy.lpszProxyBypass; | 
|  | dwSize := SizeOf(proxy); | 
|  | WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize); | 
|  | Exit; | 
|  | finally | 
|  | proxy.Initialize; // not FreeAllocatedResources, we only hold pointer copies! | 
|  | end; | 
|  | end; | 
|  |  | 
|  | end; | 
|  |  | 
|  | finally | 
|  | ieProxy.FreeAllocatedResources; | 
|  | end; | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure TWinHTTPRequestImpl.EnableAutomaticContentDecompression( const aEnable : Boolean); | 
|  | // Enable automatic gzip,deflate decompression on systems that support this option | 
|  | // From the docs: WinHTTP will automatically set an appropriate Accept-Encoding header, | 
|  | // overriding any value supplied by the caller -> we don't have to do this | 
|  | // Available on Win 8.1 or higher | 
|  | var value : DWORD; | 
|  | begin | 
|  | if aEnable | 
|  | then value := WINHTTP_DECOMPRESSION_FLAG_ALL | 
|  | else value := 0; | 
|  |  | 
|  | // ignore returned value, the option is not supported with older WinHTTP versions | 
|  | WinHttpSetOption( Handle, WINHTTP_OPTION_DECOMPRESSION, @value, SizeOf(DWORD)); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.SendRequest( const pBuf : Pointer; const dwBytes, dwExtra : DWORD) : Boolean; | 
|  | begin | 
|  | result := WinHttpSendRequest( FHandle, | 
|  | WINHTTP_NO_ADDITIONAL_HEADERS, 0, | 
|  | pBuf, dwBytes,      // number of bytes in pBuf | 
|  | dwBytes + dwExtra,  // becomes the Content-Length | 
|  | nil);               // context for async operations | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD; | 
|  | begin | 
|  | if not WinHttpWriteData( FHandle, pBuf, dwBytes, result) | 
|  | then result := 0; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.FlushAndReceiveResponse : Boolean; | 
|  | begin | 
|  | result := WinHttpReceiveResponse( FHandle, nil); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.ReadData( const dwRead : DWORD) : TBytes; | 
|  | var dwAvailable, dwReceived : DWORD; | 
|  | begin | 
|  | if WinHttpQueryDataAvailable( FHandle, dwAvailable) | 
|  | then dwAvailable := Min( dwRead, dwAvailable) | 
|  | else dwAvailable := 0; | 
|  |  | 
|  | SetLength( result, dwAvailable); | 
|  | if dwAvailable = 0 then Exit; | 
|  |  | 
|  | if WinHttpReadData( FHandle, @result[0], Length(result), dwReceived) | 
|  | then SetLength( result, dwReceived) | 
|  | else SetLength( result, 0); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; | 
|  | var dwAvailable : DWORD; | 
|  | begin | 
|  | if WinHttpQueryDataAvailable( FHandle, dwAvailable) | 
|  | then dwAvailable := Min( dwRead, dwAvailable) | 
|  | else dwAvailable := 0; | 
|  |  | 
|  | if (dwAvailable = 0) | 
|  | or not WinHttpReadData( FHandle, pBuf, dwAvailable, result) | 
|  | then result := 0; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.QueryDataAvailable : DWORD; | 
|  | begin | 
|  | if not WinHttpQueryDataAvailable( FHandle, result) | 
|  | then result := 0; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.QueryTotalResponseSize( out dwSize : DWORD) : Boolean; | 
|  | var dwBytes, dwError, dwIndex : DWORD; | 
|  | bytes : array[0..32-1] of Byte; | 
|  | begin | 
|  | dwBytes := SizeOf( result); | 
|  | dwIndex := DWORD( WINHTTP_NO_HEADER_INDEX); | 
|  | result := WinHttpQueryHeaders( FHandle, | 
|  | WINHTTP_QUERY_CONTENT_LENGTH or WINHTTP_QUERY_FLAG_NUMBER, | 
|  | WINHTTP_HEADER_NAME_BY_INDEX, | 
|  | @dwSize, dwBytes, | 
|  | dwIndex); | 
|  | if result then Exit; | 
|  | dwError := GetLastError; | 
|  |  | 
|  | // Hack: WinHttpQueryHeaders() sometimes returns error 122 even if the buffer is large enough | 
|  | // According to the docs, WINHTTP_QUERY_FLAG_NUMBER always returns a 32 bit number (which it does!) | 
|  | // but for some strange reason since win 10 build 18636.815 passing a 4 bytes buffer is not enough anymore | 
|  | if dwError = ERROR_INSUFFICIENT_BUFFER then begin | 
|  | dwBytes := sizeof(bytes); | 
|  | FillChar( bytes[0], dwBytes, 0); | 
|  | result := WinHttpQueryHeaders( FHandle, | 
|  | WINHTTP_QUERY_CONTENT_LENGTH or WINHTTP_QUERY_FLAG_NUMBER, | 
|  | WINHTTP_HEADER_NAME_BY_INDEX, | 
|  | @bytes[0], dwBytes, | 
|  | dwIndex); | 
|  | if result then begin | 
|  | ASSERT( dwBytes = SizeOf(dwSize));        // result is still a DWORD | 
|  | Move( bytes[0], dwSize, SizeOf(dwSize));  // copy over result data | 
|  | Exit; | 
|  | end; | 
|  | end; | 
|  |  | 
|  | // header may just not be there | 
|  | dwSize  := MAXINT;  // we don't know, just return something useful | 
|  | ASSERT( dwError = ERROR_WINHTTP_HEADER_NOT_FOUND);  // anything else would be an real error | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPRequestImpl.QueryHttpStatus( out dwStatusCode : DWORD; out sStatusText : string) : Boolean; | 
|  | var dwBytes, dwError, dwIndex : DWORD; | 
|  | begin | 
|  | // HTTP status code | 
|  | dwIndex := DWORD( WINHTTP_NO_HEADER_INDEX); | 
|  | dwBytes := SizeOf(dwStatusCode); | 
|  | result  := WinHttpQueryHeaders( FHandle, | 
|  | WINHTTP_QUERY_STATUS_CODE or WINHTTP_QUERY_FLAG_NUMBER, | 
|  | WINHTTP_HEADER_NAME_BY_INDEX, | 
|  | @dwStatusCode, dwBytes, | 
|  | dwIndex); | 
|  | if not result then begin | 
|  | dwStatusCode := 0;  // no data | 
|  | dwError      := GetLastError; | 
|  | if dwError <> ERROR_WINHTTP_HEADER_NOT_FOUND then ASSERT(FALSE);  // anything else would be an real error | 
|  | end; | 
|  |  | 
|  | // HTTP status text | 
|  | dwIndex := DWORD( WINHTTP_NO_HEADER_INDEX); | 
|  | dwBytes := 0; | 
|  | result  := WinHttpQueryHeaders( FHandle, | 
|  | WINHTTP_QUERY_STATUS_TEXT, | 
|  | WINHTTP_HEADER_NAME_BY_INDEX, | 
|  | WINHTTP_NO_OUTPUT_BUFFER,  // we need to determine the size first | 
|  | dwBytes,                   // will receive the required buffer size | 
|  | dwIndex); | 
|  | if dwBytes > 0 then begin  // allocate buffer and call again to get the value | 
|  | SetLength( sStatusText, dwBytes div SizeOf(Char)); | 
|  | dwBytes := Length(sStatusText) * SizeOf(Char); | 
|  | result  := WinHttpQueryHeaders( FHandle, | 
|  | WINHTTP_QUERY_STATUS_TEXT, | 
|  | WINHTTP_HEADER_NAME_BY_INDEX, | 
|  | @sStatusText[1], dwBytes, | 
|  | dwIndex); | 
|  | end; | 
|  | if result | 
|  | then SetLength( sStatusText, StrLen(PChar(sStatusText)))  // get rid of any terminating #0 chars | 
|  | else begin | 
|  | sStatusText := '';  // no data | 
|  | dwError     := GetLastError; | 
|  | if dwError <> ERROR_WINHTTP_HEADER_NOT_FOUND then ASSERT(FALSE);  // anything else would be an real error | 
|  | end; | 
|  |  | 
|  | // do we have at least something? | 
|  | result := (dwStatusCode <> 0) or (sStatusText <> ''); | 
|  | end; | 
|  |  | 
|  |  | 
|  | { TWinHTTPUrlImpl } | 
|  |  | 
|  | constructor TWinHTTPUrlImpl.Create(const aUri: UnicodeString); | 
|  | begin | 
|  | inherited Create; | 
|  | CrackUrl( aUri) | 
|  | end; | 
|  |  | 
|  |  | 
|  | destructor TWinHTTPUrlImpl.Destroy; | 
|  | begin | 
|  | inherited Destroy; | 
|  | end; | 
|  |  | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.CrackURL( const value : UnicodeString); | 
|  | const FLAGS = 0; // no special operations, leave components as-is | 
|  | var components : URL_COMPONENTS; | 
|  | begin | 
|  | FillChar(components, SizeOf(components), 0); | 
|  | components.dwStructSize := SizeOf(components); | 
|  |  | 
|  | if value <> '' then begin | 
|  | { For the WinHttpCrackUrl function, [...] if the pointer member is NULL but the | 
|  | length member is not zero, both the pointer and length members are returned. } | 
|  | components.dwSchemeLength    := DWORD(-1); | 
|  | components.dwHostNameLength  := DWORD(-1); | 
|  | components.dwUserNameLength  := DWORD(-1); | 
|  | components.dwPasswordLength  := DWORD(-1); | 
|  | components.dwUrlPathLength   := DWORD(-1); | 
|  | components.dwExtraInfoLength := DWORD(-1); | 
|  |  | 
|  | WinHttpCrackUrl( PWideChar(value), Length(value), FLAGS, components); | 
|  | end; | 
|  |  | 
|  | FNumScheme := components.nScheme; | 
|  | FPort      := components.nPort; | 
|  | SetString( FScheme,    components.lpszScheme,    components.dwSchemeLength); | 
|  | SetString( FHostName,  components.lpszHostName,  components.dwHostNameLength); | 
|  | SetString( FUserName,  components.lpszUserName,  components.dwUserNameLength); | 
|  | SetString( FPassword,  components.lpszPassword,  components.dwPasswordLength); | 
|  | SetString( FUrlPath,   components.lpszUrlPath,   components.dwUrlPathLength); | 
|  | SetString( FExtraInfo, components.lpszExtraInfo, components.dwExtraInfoLength); | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPUrlImpl.BuildUrl : UnicodeString; | 
|  | const FLAGS = 0; // no special operations, leave components as-is | 
|  | var components : URL_COMPONENTS; | 
|  | dwChars : DWORD; | 
|  | begin | 
|  | FillChar(components, SizeOf(components), 0); | 
|  | components.dwStructSize      := SizeOf(components); | 
|  | components.lpszScheme        := PWideChar(FScheme); | 
|  | components.dwSchemeLength    := Length(FScheme); | 
|  | components.lpszHostName      := PWideChar(FHostName); | 
|  | components.dwHostNameLength  := Length(FHostName); | 
|  | components.nPort             := FPort; | 
|  | components.lpszUserName      := PWideChar(FUserName); | 
|  | components.dwUserNameLength  := Length(FUserName); | 
|  | components.lpszPassword      := PWideChar(FPassword); | 
|  | components.dwPasswordLength  := Length(FPassword); | 
|  | components.lpszUrlPath       := PWideChar(FUrlPath); | 
|  | components.dwUrlPathLength   := Length(FUrlPath); | 
|  | components.lpszExtraInfo     := PWideChar(FExtraInfo); | 
|  | components.dwExtraInfoLength := Length(FExtraInfo); | 
|  |  | 
|  | WinHttpCreateUrl( components, FLAGS, nil, dwChars); | 
|  | if dwChars = 0 | 
|  | then result := '' | 
|  | else begin | 
|  | SetLength( result, dwChars + 1); | 
|  | WinHttpCreateUrl( components, FLAGS, @result[1], dwChars); | 
|  | SetLength( result, dwChars);  // cut off terminating #0 | 
|  | end; | 
|  | end; | 
|  |  | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetExtraInfo: UnicodeString; | 
|  | begin | 
|  | result := FExtraInfo; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetHostName: UnicodeString; | 
|  | begin | 
|  | result := FHostName; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetNumScheme: INTERNET_SCHEME; | 
|  | begin | 
|  | result := FNumScheme; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetPassword: UnicodeString; | 
|  | begin | 
|  | result := FPassword; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetPort: INTERNET_PORT; | 
|  | begin | 
|  | result := FPort; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetScheme: UnicodeString; | 
|  | begin | 
|  | result := FScheme; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetUrlPath: UnicodeString; | 
|  | begin | 
|  | result := FUrlPath; | 
|  | end; | 
|  |  | 
|  | function TWinHTTPUrlImpl.GetUserName: UnicodeString; | 
|  | begin | 
|  | result := FUserName; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetExtraInfo(const value: UnicodeString); | 
|  | begin | 
|  | FExtraInfo := value; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetHostName(const value: UnicodeString); | 
|  | begin | 
|  | FHostName := value; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetPassword(const value: UnicodeString); | 
|  | begin | 
|  | FPassword := value; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetPort(const value: INTERNET_PORT); | 
|  | begin | 
|  | FPort := value; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetScheme(const value: UnicodeString); | 
|  | begin | 
|  | FScheme := value; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetUrlPath(const value: UnicodeString); | 
|  | begin | 
|  | FUrlPath := value; | 
|  | end; | 
|  |  | 
|  | procedure TWinHTTPUrlImpl.SetUserName(const value: UnicodeString); | 
|  | begin | 
|  | FUserName := value; | 
|  | end; | 
|  |  | 
|  |  | 
|  | end. | 
|  |  | 
|  |  |