]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/delphi/src/Thrift.WinHTTP.pas
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / delphi / src / Thrift.WinHTTP.pas
1 (*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19 unit Thrift.WinHTTP;
20
21 {$I Thrift.Defines.inc}
22 {$SCOPEDENUMS ON}
23
24 // packing according to winhttp.h
25 {$IFDEF Win64} {$ALIGN 8} {$ELSE} {$ALIGN 4} {$ENDIF}
26
27 interface
28
29 uses
30 Windows,
31 Classes,
32 SysUtils,
33 Math,
34 Generics.Collections;
35
36
37 type
38 HINTERNET = type Pointer;
39 INTERNET_PORT = type WORD;
40 INTERNET_SCHEME = type Integer;
41 LPLPCWSTR = ^LPCWSTR;
42
43 LPURL_COMPONENTS = ^URL_COMPONENTS;
44 URL_COMPONENTS = record
45 dwStructSize : DWORD; // set to SizeOf(URL_COMPONENTS)
46 lpszScheme : LPWSTR; // scheme name
47 dwSchemeLength : DWORD;
48 nScheme : INTERNET_SCHEME; // enumerated scheme type
49 lpszHostName : LPWSTR; // host name
50 dwHostNameLength : DWORD;
51 nPort : INTERNET_PORT; // port number
52 lpszUserName : LPWSTR; // user name
53 dwUserNameLength : DWORD;
54 lpszPassword : LPWSTR; // password
55 dwPasswordLength : DWORD;
56 lpszUrlPath : LPWSTR; // URL-path
57 dwUrlPathLength : DWORD;
58 lpszExtraInfo : LPWSTR; // extra information
59 dwExtraInfoLength : DWORD;
60 end;
61
62 URL_COMPONENTSW = URL_COMPONENTS;
63 LPURL_COMPONENTSW = LPURL_COMPONENTS;
64
65
66 // When retrieving proxy data, an application must free the lpszProxy and
67 // lpszProxyBypass strings contained in this structure (if they are non-NULL)
68 // using the GlobalFree function.
69 LPWINHTTP_PROXY_INFO = ^WINHTTP_PROXY_INFO;
70 WINHTTP_PROXY_INFO = record
71 dwAccessType : DWORD; // see WINHTTP_ACCESS_* types below
72 lpszProxy : LPWSTR; // proxy server list
73 lpszProxyBypass : LPWSTR; // proxy bypass list
74 end;
75
76 LPWINHTTP_PROXY_INFOW = ^WINHTTP_PROXY_INFOW;
77 WINHTTP_PROXY_INFOW = WINHTTP_PROXY_INFO;
78
79
80 WINHTTP_AUTOPROXY_OPTIONS = record
81 dwFlags : DWORD;
82 dwAutoDetectFlags : DWORD;
83 lpszAutoConfigUrl : LPCWSTR;
84 lpvReserved : LPVOID;
85 dwReserved : DWORD;
86 fAutoLogonIfChallenged : BOOL;
87 end;
88
89
90 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG = record
91 fAutoDetect : BOOL;
92 lpszAutoConfigUrl : LPWSTR;
93 lpszProxy : LPWSTR;
94 lpszProxyBypass : LPWSTR;
95 end;
96
97
98
99
100 function WinHttpCloseHandle( aHandle : HINTERNET) : BOOL; stdcall;
101
102 function WinHttpOpen( const pszAgentW : LPCWSTR;
103 const dwAccessType : DWORD;
104 const pszProxyW : LPCWSTR;
105 const pszProxyBypassW : LPCWSTR;
106 const dwFlags : DWORD
107 ) : HINTERNET; stdcall;
108
109 function WinHttpConnect( const hSession : HINTERNET;
110 const pswzServerName : LPCWSTR;
111 const nServerPort : INTERNET_PORT;
112 const dwReserved : DWORD
113 ) : HINTERNET; stdcall;
114
115 function WinHttpOpenRequest( const hConnect : HINTERNET;
116 const pwszVerb, pwszObjectName, pwszVersion, pwszReferrer : LPCWSTR;
117 const ppwszAcceptTypes : LPLPCWSTR;
118 const dwFlags : DWORD
119 ) : HINTERNET; stdcall;
120
121 function WinHttpQueryOption( const hInternet : HINTERNET;
122 const dwOption : DWORD;
123 const pBuffer : Pointer;
124 var dwBufferLength : DWORD) : BOOL; stdcall;
125
126 function WinHttpSetOption( const hInternet : HINTERNET;
127 const dwOption : DWORD;
128 const pBuffer : Pointer;
129 const dwBufferLength : DWORD) : BOOL; stdcall;
130
131 function WinHttpSetTimeouts( const hRequestOrSession : HINTERNET;
132 const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32
133 ) : BOOL; stdcall;
134
135 function WinHttpAddRequestHeaders( const hRequest : HINTERNET;
136 const pwszHeaders : LPCWSTR;
137 const dwHeadersLengthInChars : DWORD;
138 const dwModifiers : DWORD
139 ) : BOOL; stdcall;
140
141 function WinHttpGetProxyForUrl( const hSession : HINTERNET;
142 const lpcwszUrl : LPCWSTR;
143 const options : WINHTTP_AUTOPROXY_OPTIONS;
144 const info : WINHTTP_PROXY_INFO
145 ) : BOOL; stdcall;
146
147 function WinHttpGetIEProxyConfigForCurrentUser( var config : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
148 ) : BOOL; stdcall;
149
150
151 function WinHttpSendRequest( const hRequest : HINTERNET;
152 const lpszHeaders : LPCWSTR;
153 const dwHeadersLength : DWORD;
154 const lpOptional : Pointer;
155 const dwOptionalLength : DWORD;
156 const dwTotalLength : DWORD;
157 const pContext : Pointer
158 ) : BOOL; stdcall;
159
160 function WinHttpWriteData( const hRequest : HINTERNET;
161 const pBuf : Pointer;
162 const dwBytesToWrite : DWORD;
163 out dwBytesWritten : DWORD
164 ) : BOOL; stdcall;
165
166 function WinHttpReceiveResponse( const hRequest : HINTERNET; const lpReserved : Pointer) : BOOL; stdcall;
167
168 function WinHttpQueryHeaders( const hRequest : HINTERNET;
169 const dwInfoLevel : DWORD;
170 const pwszName : LPCWSTR;
171 const lpBuffer : Pointer;
172 var dwBufferLength : DWORD;
173 var dwIndex : DWORD
174 ) : BOOL; stdcall;
175
176 function WinHttpQueryDataAvailable( const hRequest : HINTERNET;
177 var dwNumberOfBytesAvailable : DWORD
178 ) : BOOL; stdcall;
179
180 function WinHttpReadData( const hRequest : HINTERNET;
181 const lpBuffer : Pointer;
182 const dwBytesToRead : DWORD;
183 out dwBytesRead : DWORD
184 ) : BOOL; stdcall;
185
186 function WinHttpCrackUrl( const pwszUrl : LPCWSTR;
187 const dwUrlLength : DWORD;
188 const dwFlags : DWORD;
189 var urlComponents : URL_COMPONENTS
190 ) : BOOL; stdcall;
191
192 function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS;
193 const dwFlags : DWORD;
194 const pwszUrl : LPCWSTR;
195 var pdwUrlLength : DWORD
196 ) : BOOL; stdcall;
197
198
199 const
200 // WinHttpOpen dwAccessType values
201 WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
202 WINHTTP_ACCESS_TYPE_NO_PROXY = 1;
203 WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3;
204
205 // flags for WinHttpOpen():
206 WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage
207
208 // ports
209 INTERNET_DEFAULT_PORT = 0; // use the protocol-specific default (80 or 443)
210
211 // flags for WinHttpOpenRequest():
212 WINHTTP_FLAG_SECURE = $00800000; // use SSL if applicable (HTTPS)
213 WINHTTP_FLAG_ESCAPE_PERCENT = $00000004; // if escaping enabled, escape percent as well
214 WINHTTP_FLAG_NULL_CODEPAGE = $00000008; // assume all symbols are ASCII, use fast convertion
215 WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header
216 WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
217 WINHTTP_FLAG_ESCAPE_DISABLE = $00000040; // disable escaping
218 WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = $00000080; // if escaping enabled escape path part, but do not escape query
219
220 // flags for WinHttpSendRequest():
221 WINHTTP_NO_ADDITIONAL_HEADERS = nil;
222 WINHTTP_NO_REQUEST_DATA = nil;
223
224 // WinHttpAddRequestHeaders() dwModifiers
225 WINHTTP_ADDREQ_INDEX_MASK = $0000FFFF;
226 WINHTTP_ADDREQ_FLAGS_MASK = $FFFF0000;
227
228 WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = $10000000;
229 WINHTTP_ADDREQ_FLAG_ADD = $20000000;
230 WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = $40000000;
231 WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = $01000000;
232 WINHTTP_ADDREQ_FLAG_COALESCE = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA;
233 WINHTTP_ADDREQ_FLAG_REPLACE = $80000000;
234
235 // URL functions
236 ICU_NO_ENCODE = $20000000; // Don't convert unsafe characters to escape sequence
237 ICU_DECODE = $10000000; // Convert %XX escape sequences to characters
238 ICU_NO_META = $08000000; // Don't convert .. etc. meta path sequences
239 ICU_ENCODE_SPACES_ONLY = $04000000; // Encode spaces only
240 ICU_BROWSER_MODE = $02000000; // Special encode/decode rules for browser
241 ICU_ENCODE_PERCENT = $00001000; // Encode any percent (ASCII25)
242
243 ICU_ESCAPE = $80000000; // (un)escape URL characters
244 ICU_ESCAPE_AUTHORITY = $00002000; // causes InternetCreateUrlA to escape chars in authority components (user, pwd, host)
245 ICU_REJECT_USERPWD = $00004000; // rejects usrls whick have username/pwd sections
246
247 INTERNET_SCHEME_HTTP = INTERNET_SCHEME(1);
248 INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2);
249
250 WINHTTP_NO_CLIENT_CERT_CONTEXT = nil;
251
252 // options manifests for WinHttp{Query|Set}Option
253 WINHTTP_OPTION_CALLBACK = 1;
254 WINHTTP_OPTION_RESOLVE_TIMEOUT = 2;
255 WINHTTP_OPTION_CONNECT_TIMEOUT = 3;
256 WINHTTP_OPTION_CONNECT_RETRIES = 4;
257 WINHTTP_OPTION_SEND_TIMEOUT = 5;
258 WINHTTP_OPTION_RECEIVE_TIMEOUT = 6;
259 WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT = 7;
260 WINHTTP_OPTION_HANDLE_TYPE = 9;
261 WINHTTP_OPTION_READ_BUFFER_SIZE = 12;
262 WINHTTP_OPTION_WRITE_BUFFER_SIZE = 13;
263 WINHTTP_OPTION_PARENT_HANDLE = 21;
264 WINHTTP_OPTION_EXTENDED_ERROR = 24;
265 WINHTTP_OPTION_SECURITY_FLAGS = 31;
266 WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT = 32;
267 WINHTTP_OPTION_URL = 34;
268 WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36;
269 WINHTTP_OPTION_PROXY = 38;
270 WINHTTP_OPTION_USER_AGENT = 41;
271 WINHTTP_OPTION_CONTEXT_VALUE = 45;
272 WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47;
273 WINHTTP_OPTION_REQUEST_PRIORITY = 58;
274 WINHTTP_OPTION_HTTP_VERSION = 59;
275 WINHTTP_OPTION_DISABLE_FEATURE = 63;
276 WINHTTP_OPTION_CODEPAGE = 68;
277 WINHTTP_OPTION_MAX_CONNS_PER_SERVER = 73;
278 WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER = 74;
279 WINHTTP_OPTION_AUTOLOGON_POLICY = 77;
280 WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78;
281 WINHTTP_OPTION_ENABLE_FEATURE = 79;
282 WINHTTP_OPTION_WORKER_THREAD_COUNT = 80;
283 WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT = 81;
284 WINHTTP_OPTION_PASSPORT_COBRANDING_URL = 82;
285 WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH = 83;
286 WINHTTP_OPTION_SECURE_PROTOCOLS = 84;
287 WINHTTP_OPTION_ENABLETRACING = 85;
288 WINHTTP_OPTION_PASSPORT_SIGN_OUT = 86;
289 WINHTTP_OPTION_PASSPORT_RETURN_URL = 87;
290 WINHTTP_OPTION_REDIRECT_POLICY = 88;
291 WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89;
292 WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE = 90;
293 WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE = 91;
294 WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE = 92;
295 WINHTTP_OPTION_CONNECTION_INFO = 93;
296 WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST = 94;
297 WINHTTP_OPTION_SPN = 96;
298 WINHTTP_OPTION_GLOBAL_PROXY_CREDS = 97;
299 WINHTTP_OPTION_GLOBAL_SERVER_CREDS = 98;
300 WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT = 99;
301 WINHTTP_OPTION_REJECT_USERPWD_IN_URL = 100;
302 WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS = 101;
303 WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE = 103;
304 WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE = 104;
305 WINHTTP_OPTION_SERVER_SPN_USED = 106;
306 WINHTTP_OPTION_PROXY_SPN_USED = 107;
307 WINHTTP_OPTION_SERVER_CBT = 108;
308 // options for newer WinHTTP versions
309 WINHTTP_OPTION_DECOMPRESSION = 118;
310 //
311 WINHTTP_FIRST_OPTION = WINHTTP_OPTION_CALLBACK;
312 //WINHTTP_LAST_OPTION = WINHTTP_OPTION_SERVER_CBT;
313
314 WINHTTP_OPTION_USERNAME = $1000;
315 WINHTTP_OPTION_PASSWORD = $1001;
316 WINHTTP_OPTION_PROXY_USERNAME = $1002;
317 WINHTTP_OPTION_PROXY_PASSWORD = $1003;
318
319 // manifest value for WINHTTP_OPTION_MAX_CONNS_PER_SERVER and WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER
320 WINHTTP_CONNS_PER_SERVER_UNLIMITED = $FFFFFFFF;
321
322 // values for WINHTTP_OPTION_AUTOLOGON_POLICY
323 WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM = 0;
324 WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW = 1;
325 WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH = 2;
326
327 WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM;
328
329 // values for WINHTTP_OPTION_REDIRECT_POLICY
330 WINHTTP_OPTION_REDIRECT_POLICY_NEVER = 0;
331 WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP = 1;
332 WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS = 2;
333
334 WINHTTP_OPTION_REDIRECT_POLICY_LAST = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
335 WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP;
336
337 WINHTTP_DISABLE_PASSPORT_AUTH = $00000000;
338 WINHTTP_ENABLE_PASSPORT_AUTH = $10000000;
339 WINHTTP_DISABLE_PASSPORT_KEYRING = $20000000;
340 WINHTTP_ENABLE_PASSPORT_KEYRING = $40000000;
341
342 // values for WINHTTP_OPTION_DISABLE_FEATURE
343 WINHTTP_DISABLE_COOKIES = $00000001;
344 WINHTTP_DISABLE_REDIRECTS = $00000002;
345 WINHTTP_DISABLE_AUTHENTICATION = $00000004;
346 WINHTTP_DISABLE_KEEP_ALIVE = $00000008;
347
348 // values for WINHTTP_OPTION_ENABLE_FEATURE
349 WINHTTP_ENABLE_SSL_REVOCATION = $00000001;
350 WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION = $00000002;
351
352 // values for WINHTTP_OPTION_SPN
353 WINHTTP_DISABLE_SPN_SERVER_PORT = $00000000;
354 WINHTTP_ENABLE_SPN_SERVER_PORT = $00000001;
355 WINHTTP_OPTION_SPN_MASK = WINHTTP_ENABLE_SPN_SERVER_PORT;
356
357 // winhttp handle types
358 WINHTTP_HANDLE_TYPE_SESSION = 1;
359 WINHTTP_HANDLE_TYPE_CONNECT = 2;
360 WINHTTP_HANDLE_TYPE_REQUEST = 3;
361
362 // values for auth schemes
363 WINHTTP_AUTH_SCHEME_BASIC = $00000001;
364 WINHTTP_AUTH_SCHEME_NTLM = $00000002;
365 WINHTTP_AUTH_SCHEME_PASSPORT = $00000004;
366 WINHTTP_AUTH_SCHEME_DIGEST = $00000008;
367 WINHTTP_AUTH_SCHEME_NEGOTIATE = $00000010;
368
369 // WinHttp supported Authentication Targets
370 WINHTTP_AUTH_TARGET_SERVER = $00000000;
371 WINHTTP_AUTH_TARGET_PROXY = $00000001;
372
373 // options for WINHTTP_OPTION_DECOMPRESSION
374 WINHTTP_DECOMPRESSION_FLAG_GZIP = $00000001;
375 WINHTTP_DECOMPRESSION_FLAG_DEFLATE = $00000002;
376 WINHTTP_DECOMPRESSION_FLAG_ALL = WINHTTP_DECOMPRESSION_FLAG_GZIP
377 or WINHTTP_DECOMPRESSION_FLAG_DEFLATE;
378
379 // values for WINHTTP_OPTION_SECURITY_FLAGS
380
381 // query only
382 SECURITY_FLAG_SECURE = $00000001; // can query only
383 SECURITY_FLAG_STRENGTH_WEAK = $10000000;
384 SECURITY_FLAG_STRENGTH_MEDIUM = $40000000;
385 SECURITY_FLAG_STRENGTH_STRONG = $20000000;
386
387 // Secure connection error status flags
388 WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = $00000001;
389 WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT = $00000002;
390 WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED = $00000004;
391 WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA = $00000008;
392 WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID = $00000010;
393 WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID = $00000020;
394 WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE = $00000040;
395 WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR = $80000000;
396
397 WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 = $00000008;
398 WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 = $00000020;
399 WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = $00000080;
400 WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = $00000200;
401 WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = $00000800;
402
403 // Note: SECURE_PROTOCOL_ALL does not include TLS1.1 and higher!
404 WINHTTP_FLAG_SECURE_PROTOCOL_ALL = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2
405 or WINHTTP_FLAG_SECURE_PROTOCOL_SSL3
406 or WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
407
408 // AutoProxy
409 WINHTTP_AUTOPROXY_AUTO_DETECT = $00000001;
410 WINHTTP_AUTOPROXY_CONFIG_URL = $00000002;
411 WINHTTP_AUTOPROXY_HOST_KEEPCASE = $00000004;
412 WINHTTP_AUTOPROXY_HOST_LOWERCASE = $00000008;
413 WINHTTP_AUTOPROXY_RUN_INPROCESS = $00010000;
414 WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = $00020000;
415
416 // Flags for dwAutoDetectFlags
417 WINHTTP_AUTO_DETECT_TYPE_DHCP = $00000001;
418 WINHTTP_AUTO_DETECT_TYPE_DNS_A = $00000002;
419
420 const
421 WINHTTP_ERROR_BASE = 12000;
422 ERROR_WINHTTP_OUT_OF_HANDLES = WINHTTP_ERROR_BASE + 1;
423 ERROR_WINHTTP_TIMEOUT = WINHTTP_ERROR_BASE + 2;
424 ERROR_WINHTTP_INTERNAL_ERROR = WINHTTP_ERROR_BASE + 4;
425 ERROR_WINHTTP_INVALID_URL = WINHTTP_ERROR_BASE + 5;
426 ERROR_WINHTTP_UNRECOGNIZED_SCHEME = WINHTTP_ERROR_BASE + 6;
427 ERROR_WINHTTP_NAME_NOT_RESOLVED = WINHTTP_ERROR_BASE + 7;
428 ERROR_WINHTTP_INVALID_OPTION = WINHTTP_ERROR_BASE + 9;
429 ERROR_WINHTTP_OPTION_NOT_SETTABLE = WINHTTP_ERROR_BASE + 11;
430 ERROR_WINHTTP_SHUTDOWN = WINHTTP_ERROR_BASE + 12;
431 ERROR_WINHTTP_LOGIN_FAILURE = WINHTTP_ERROR_BASE + 15;
432 ERROR_WINHTTP_OPERATION_CANCELLED = WINHTTP_ERROR_BASE + 17;
433 ERROR_WINHTTP_INCORRECT_HANDLE_TYPE = WINHTTP_ERROR_BASE + 18;
434 ERROR_WINHTTP_INCORRECT_HANDLE_STATE = WINHTTP_ERROR_BASE + 19;
435 ERROR_WINHTTP_CANNOT_CONNECT = WINHTTP_ERROR_BASE + 29;
436 ERROR_WINHTTP_CONNECTION_ERROR = WINHTTP_ERROR_BASE + 30;
437 ERROR_WINHTTP_RESEND_REQUEST = WINHTTP_ERROR_BASE + 32;
438 ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = WINHTTP_ERROR_BASE + 44;
439 ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100;
440 ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101;
441 ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102;
442 ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103;
443 ERROR_WINHTTP_HEADER_NOT_FOUND = WINHTTP_ERROR_BASE + 150;
444 ERROR_WINHTTP_INVALID_SERVER_RESPONSE = WINHTTP_ERROR_BASE + 152;
445 ERROR_WINHTTP_INVALID_HEADER = WINHTTP_ERROR_BASE + 153;
446 ERROR_WINHTTP_INVALID_QUERY_REQUEST = WINHTTP_ERROR_BASE + 154;
447 ERROR_WINHTTP_HEADER_ALREADY_EXISTS = WINHTTP_ERROR_BASE + 155;
448 ERROR_WINHTTP_REDIRECT_FAILED = WINHTTP_ERROR_BASE + 156;
449 ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178;
450 ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = WINHTTP_ERROR_BASE + 166;
451 ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = WINHTTP_ERROR_BASE + 167;
452 ERROR_WINHTTP_NOT_INITIALIZED = WINHTTP_ERROR_BASE + 172;
453 ERROR_WINHTTP_SECURE_FAILURE = WINHTTP_ERROR_BASE + 175;
454
455 // Certificate security errors. Additional information is provided
456 // via the WINHTTP_CALLBACK_STATUS_SECURE_FAILURE callback notification.
457 ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37;
458 ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38;
459 ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45;
460 ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57;
461 ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157;
462 ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169;
463 ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170;
464 ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179;
465
466 ERROR_WINHTTP_AUTODETECTION_FAILED = WINHTTP_ERROR_BASE + 180;
467 ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = WINHTTP_ERROR_BASE + 181;
468 ERROR_WINHTTP_HEADER_SIZE_OVERFLOW = WINHTTP_ERROR_BASE + 182;
469 ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW = WINHTTP_ERROR_BASE + 183;
470 ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = WINHTTP_ERROR_BASE + 184;
471 ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = WINHTTP_ERROR_BASE + 185;
472 ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = WINHTTP_ERROR_BASE + 186;
473
474 WINHTTP_ERROR_LAST = WINHTTP_ERROR_BASE + 186;
475
476
477 const
478 WINHTTP_THRIFT_DEFAULTS = WINHTTP_FLAG_NULL_CODEPAGE
479 or WINHTTP_FLAG_BYPASS_PROXY_CACHE
480 or WINHTTP_FLAG_ESCAPE_DISABLE;
481
482
483
484 type
485 IWinHTTPSession = interface;
486 IWinHTTPConnection = interface;
487
488 IWinHTTPRequest = interface
489 ['{F65952F2-2F3B-47DC-B524-F1694E6D2AD7}']
490 function Handle : HINTERNET;
491 function Connection : IWinHTTPConnection;
492 function AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean;
493 function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
494 procedure TryAutoProxy( const aUrl : string);
495 procedure EnableAutomaticContentDecompression( const aEnable : Boolean);
496 function SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean;
497 function WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD;
498 function FlushAndReceiveResponse : Boolean;
499 function ReadData( const dwRead : DWORD) : TBytes; overload;
500 function ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; overload;
501 end;
502
503 IWinHTTPConnection = interface
504 ['{ED5BCA49-84D6-4CFE-BF18-3238B1FF2AFB}']
505 function Handle : HINTERNET;
506 function Session : IWinHTTPSession;
507 function OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest;
508 end;
509
510 IWinHTTPSession = interface
511 ['{261ADCB7-5465-4407-8840-468C17F009F0}']
512 function Handle : HINTERNET;
513 function Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection;
514 function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
515 function EnableSecureProtocols( const aFlagSet : DWORD) : Boolean;
516 end;
517
518 IWinHTTPUrl = interface
519 ['{78BE977C-4171-4AF5-A250-FD2890205E63}']
520 // url parts getter
521 function GetScheme : UnicodeString;
522 function GetNumScheme : INTERNET_SCHEME;
523 function GetHostName : UnicodeString;
524 function GetPort : INTERNET_PORT;
525 function GetUserName : UnicodeString;
526 function GetPassword : UnicodeString;
527 function GetUrlPath : UnicodeString;
528 function GetExtraInfo : UnicodeString;
529
530 // url parts setter
531 procedure SetScheme( const value : UnicodeString);
532 procedure SetHostName ( const value : UnicodeString);
533 procedure SetPort( const value : INTERNET_PORT);
534 procedure SetUserName( const value : UnicodeString);
535 procedure SetPassword( const value : UnicodeString);
536 procedure SetUrlPath( const value : UnicodeString);
537 procedure SetExtraInfo( const value : UnicodeString);
538
539 // url as a whole
540 function BuildUrl : UnicodeString;
541 procedure CrackUrl( const value : UnicodeString);
542
543 // url parts
544 property Scheme : UnicodeString read GetScheme write SetScheme;
545 property NumScheme : INTERNET_SCHEME read GetNumScheme; // readonly
546 property HostName : UnicodeString read GetHostName write SetHostName;
547 property Port : INTERNET_PORT read GetPort write SetPort;
548 property UserName : UnicodeString read GetUserName write SetUserName;
549 property Password : UnicodeString read GetPassword write SetPassword;
550 property UrlPath : UnicodeString read GetUrlPath write SetUrlPath;
551 property ExtraInfo : UnicodeString read GetExtraInfo write SetExtraInfo;
552
553 // url as a whole
554 property CompleteURL : UnicodeString read BuildUrl write CrackUrl;
555 end;
556
557
558
559
560 type
561 TWinHTTPHandleObjectImpl = class( TInterfacedObject)
562 strict protected
563 FHandle : HINTERNET;
564 function Handle : HINTERNET;
565 public
566 constructor Create( const aHandle : HINTERNET);
567 destructor Destroy; override;
568 end;
569
570
571 TWinHTTPSessionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPSession)
572 strict protected
573
574 // IWinHTTPSession
575 function Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection;
576 function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
577 function EnableSecureProtocols( const aFlagSet : DWORD) : Boolean;
578 public
579 constructor Create( const aAgent : UnicodeString;
580 const aAccessType : DWORD = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
581 const aProxy : UnicodeString = '';
582 const aProxyBypass : UnicodeString = '';
583 const aFlags : DWORD = 0);
584 destructor Destroy; override;
585 end;
586
587
588 TWinHTTPConnectionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPConnection)
589 strict protected
590 FSession : IWinHTTPSession;
591
592 // IWinHTTPConnection
593 function OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest;
594 function Session : IWinHTTPSession;
595
596 public
597 constructor Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT);
598 destructor Destroy; override;
599 end;
600
601
602 TAcceptTypesArray = array of string;
603
604 TWinHTTPRequestImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPRequest)
605 strict protected
606 FConnection : IWinHTTPConnection;
607
608 // IWinHTTPRequest
609 function Connection : IWinHTTPConnection;
610 function AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean;
611 function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
612 procedure TryAutoProxy( const aUrl : string);
613 procedure EnableAutomaticContentDecompression( const aEnable : Boolean);
614 function SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean;
615 function WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD;
616 function FlushAndReceiveResponse : Boolean;
617 function ReadData( const dwRead : DWORD) : TBytes; overload;
618 function ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; overload;
619
620 public
621 constructor Create( const aConnection : IWinHTTPConnection;
622 const aVerb, aObjName : UnicodeString;
623 const aVersion : UnicodeString = '';
624 const aReferrer : UnicodeString = '';
625 const aAcceptTypes : UnicodeString = '*/*';
626 const aFlags : DWORD = WINHTTP_THRIFT_DEFAULTS
627 );
628
629 destructor Destroy; override;
630 end;
631
632
633 TWinHTTPUrlImpl = class( TInterfacedObject, IWinHTTPUrl)
634 strict private
635 FScheme : UnicodeString;
636 FNumScheme : INTERNET_SCHEME;
637 FHostName : UnicodeString;
638 FPort : INTERNET_PORT;
639 FUserName : UnicodeString;
640 FPassword : UnicodeString;
641 FUrlPath : UnicodeString;
642 FExtraInfo : UnicodeString;
643
644 strict protected
645 // url parts getter
646 function GetScheme : UnicodeString;
647 function GetNumScheme : INTERNET_SCHEME;
648 function GetHostName : UnicodeString;
649 function GetPort : INTERNET_PORT;
650 function GetUserName : UnicodeString;
651 function GetPassword : UnicodeString;
652 function GetUrlPath : UnicodeString;
653 function GetExtraInfo : UnicodeString;
654
655 // url parts setter
656 procedure SetScheme( const value : UnicodeString);
657 procedure SetHostName ( const value : UnicodeString);
658 procedure SetPort( const value : INTERNET_PORT);
659 procedure SetUserName( const value : UnicodeString);
660 procedure SetPassword( const value : UnicodeString);
661 procedure SetUrlPath( const value : UnicodeString);
662 procedure SetExtraInfo( const value : UnicodeString);
663
664 // url as a whole
665 function BuildUrl : UnicodeString;
666 procedure CrackUrl( const value : UnicodeString);
667
668 public
669 constructor Create( const aUri : UnicodeString);
670 destructor Destroy; override;
671 end;
672
673
674 WINHTTP_PROXY_INFO_Helper = record helper for WINHTTP_PROXY_INFO
675 procedure Initialize;
676 procedure FreeAllocatedResources;
677 end;
678
679
680 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper = record helper for WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
681 procedure Initialize;
682 procedure FreeAllocatedResources;
683 end;
684
685
686 EWinHTTPException = class(Exception);
687
688 { helper functions }
689
690 function WinHttpSysErrorMessage( const error : Cardinal): string;
691 procedure RaiseLastWinHttpError;
692
693
694 implementation
695
696 const WINHTTP_DLL = 'WinHTTP.dll';
697
698 function WinHttpCloseHandle; stdcall; external WINHTTP_DLL;
699 function WinHttpOpen; stdcall; external WINHTTP_DLL;
700 function WinHttpConnect; stdcall; external WINHTTP_DLL;
701 function WinHttpOpenRequest; stdcall; external WINHTTP_DLL;
702 function WinHttpSendRequest; stdcall; external WINHTTP_DLL;
703 function WinHttpSetTimeouts; stdcall; external WINHTTP_DLL;
704 function WinHttpQueryOption; stdcall; external WINHTTP_DLL;
705 function WinHttpSetOption; stdcall; external WINHTTP_DLL;
706 function WinHttpAddRequestHeaders; stdcall; external WINHTTP_DLL;
707 function WinHttpGetProxyForUrl; stdcall; external WINHTTP_DLL;
708 function WinHttpGetIEProxyConfigForCurrentUser; stdcall; external WINHTTP_DLL;
709 function WinHttpWriteData; stdcall; external WINHTTP_DLL;
710 function WinHttpReceiveResponse; stdcall; external WINHTTP_DLL;
711 function WinHttpQueryHeaders; stdcall; external WINHTTP_DLL;
712 function WinHttpQueryDataAvailable; stdcall; external WINHTTP_DLL;
713 function WinHttpReadData; stdcall; external WINHTTP_DLL;
714 function WinHttpCrackUrl; stdcall; external WINHTTP_DLL;
715 function WinHttpCreateUrl; stdcall; external WINHTTP_DLL;
716
717
718 { helper functions }
719
720 function WinHttpSysErrorMessage( const error : Cardinal): string;
721 const FLAGS = FORMAT_MESSAGE_ALLOCATE_BUFFER
722 or FORMAT_MESSAGE_IGNORE_INSERTS
723 or FORMAT_MESSAGE_FROM_SYSTEM
724 or FORMAT_MESSAGE_FROM_HMODULE;
725 var pBuffer : PChar;
726 nChars : Cardinal;
727 begin
728 if (error < WINHTTP_ERROR_BASE)
729 or (error > WINHTTP_ERROR_LAST)
730 then Exit( SysUtils.SysErrorMessage( error));
731
732 pBuffer := nil;
733 try
734 nChars := FormatMessage( FLAGS,
735 Pointer( GetModuleHandle( WINHTTP_DLL)),
736 error,
737 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
738 @pBuffer, 0,
739 nil);
740 SetString( result, pBuffer, nChars);
741 finally
742 LocalFree( NativeUInt( pBuffer));
743 end;
744 end;
745
746
747 procedure RaiseLastWinHttpError;
748 var error : Cardinal;
749 sMsg : string;
750 begin
751 error := Cardinal( GetLastError);
752 if error <> NOERROR then begin
753 sMSg := IntToStr(Integer(error))+' '+WinHttpSysErrorMessage(error);
754 raise EWinHTTPException.Create( sMsg);
755 end;
756 end;
757
758
759
760 { misc. record helper }
761
762
763 procedure GlobalFreeAndNil( var p : LPWSTR);
764 begin
765 if p <> nil then begin
766 GlobalFree( HGLOBAL( p));
767 p := nil;
768 end;
769 end;
770
771
772 procedure WINHTTP_PROXY_INFO_Helper.Initialize;
773 begin
774 FillChar( Self, SizeOf(Self), 0);
775 end;
776
777
778 procedure WINHTTP_PROXY_INFO_Helper.FreeAllocatedResources;
779 // The caller must free the lpszProxy and lpszProxyBypass strings
780 // if they are non-NULL. Use GlobalFree to free the strings.
781 begin
782 GlobalFreeAndNil( lpszProxy);
783 GlobalFreeAndNil( lpszProxyBypass);
784 Initialize;
785 end;
786
787
788 procedure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper.Initialize;
789 begin
790 FillChar( Self, SizeOf(Self), 0);
791 end;
792
793
794 procedure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG_Helper.FreeAllocatedResources;
795 // The caller must free the lpszProxy, lpszProxyBypass and lpszAutoConfigUrl strings
796 // if they are non-NULL. Use GlobalFree to free the strings.
797 begin
798 GlobalFreeAndNil( lpszProxy);
799 GlobalFreeAndNil( lpszProxyBypass);
800 GlobalFreeAndNil( lpszAutoConfigUrl);
801 Initialize;
802 end;
803
804
805 { TWinHTTPHandleObjectImpl }
806
807 constructor TWinHTTPHandleObjectImpl.Create( const aHandle : HINTERNET);
808 begin
809 inherited Create;
810 FHandle := aHandle;
811
812 if FHandle = nil
813 then raise EWinHTTPException.Create('Invalid handle');
814 end;
815
816
817 destructor TWinHTTPHandleObjectImpl.Destroy;
818 begin
819 try
820 if Assigned(FHandle) then begin
821 WinHttpCloseHandle(FHandle);
822 FHandle := nil;
823 end;
824
825 finally
826 inherited Destroy;
827 end;
828 end;
829
830
831 function TWinHTTPHandleObjectImpl.Handle : HINTERNET;
832 begin
833 result := FHandle;
834 end;
835
836
837 { TWinHTTPSessionImpl }
838
839
840 constructor TWinHTTPSessionImpl.Create( const aAgent : UnicodeString; const aAccessType : DWORD;
841 const aProxy, aProxyBypass : UnicodeString; const aFlags : DWORD);
842 var handle : HINTERNET;
843 begin
844 handle := WinHttpOpen( PWideChar(aAgent), aAccessType,
845 PWideChar(Pointer(aProxy)), // may be nil
846 PWideChar(Pointer(aProxyBypass)), // may be nil
847 aFlags);
848 if handle = nil then RaiseLastWinHttpError;
849 inherited Create( handle);
850 end;
851
852
853 destructor TWinHTTPSessionImpl.Destroy;
854 begin
855 inherited Destroy;
856 // add code here
857 end;
858
859
860 function TWinHTTPSessionImpl.Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT) : IWinHTTPConnection;
861 begin
862 result := TWinHTTPConnectionImpl.Create( Self, aHostName, aPort);
863 end;
864
865
866 function TWinHTTPSessionImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
867 begin
868 result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout);
869 end;
870
871
872 function TWinHTTPSessionImpl.EnableSecureProtocols( const aFlagSet : DWORD) : Boolean;
873 var dwSize : DWORD;
874 begin
875 dwSize := SizeOf(aFlagSet);
876 result := WinHttpSetOption( Handle, WINHTTP_OPTION_SECURE_PROTOCOLS, @aFlagset, dwSize);
877 end;
878
879
880 { TWinHTTPConnectionImpl }
881
882 constructor TWinHTTPConnectionImpl.Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT);
883 var handle : HINTERNET;
884 begin
885 FSession := aSession;
886 handle := WinHttpConnect( FSession.Handle, PWideChar(aHostName), aPort, 0);
887 if handle = nil then RaiseLastWinHttpError;
888 inherited Create( handle);
889 end;
890
891
892 destructor TWinHTTPConnectionImpl.Destroy;
893 begin
894 inherited Destroy;
895 FSession := nil;
896 end;
897
898
899 function TWinHTTPConnectionImpl.Session : IWinHTTPSession;
900 begin
901 result := FSession;
902 end;
903
904
905 function TWinHTTPConnectionImpl.OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest;
906 var dwFlags : DWORD;
907 begin
908 dwFlags := WINHTTP_THRIFT_DEFAULTS;
909 if secure
910 then dwFlags := dwFlags or WINHTTP_FLAG_SECURE
911 else dwFlags := dwFlags and not WINHTTP_FLAG_SECURE;
912
913 result := TWinHTTPRequestImpl.Create( Self, aVerb, aObjName, '', '', aAcceptTypes, dwFlags);
914 end;
915
916
917 { TWinHTTPRequestImpl }
918
919 constructor TWinHTTPRequestImpl.Create( const aConnection : IWinHTTPConnection;
920 const aVerb, aObjName, aVersion, aReferrer : UnicodeString;
921 const aAcceptTypes : UnicodeString;
922 const aFlags : DWORD
923 );
924 var handle : HINTERNET;
925 accept : array[0..1] of PWideChar;
926 begin
927 FConnection := aConnection;
928
929 accept[0] := PWideChar(aAcceptTypes);
930 accept[1] := nil;
931
932 handle := WinHttpOpenRequest( FConnection.Handle,
933 PWideChar(UpperCase(aVerb)),
934 PWideChar(aObjName),
935 PWideChar(aVersion),
936 PWideChar(aReferrer),
937 @accept,
938 aFlags);
939 if handle = nil then RaiseLastWinHttpError;
940 inherited Create( handle);
941 end;
942
943
944 destructor TWinHTTPRequestImpl.Destroy;
945 begin
946 inherited Destroy;
947 FConnection := nil;
948 end;
949
950
951 function TWinHTTPRequestImpl.Connection : IWinHTTPConnection;
952 begin
953 result := FConnection;
954 end;
955
956
957 function TWinHTTPRequestImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
958 begin
959 result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout);
960 end;
961
962
963 function TWinHTTPRequestImpl.AddRequestHeader( const aHeader : string; const addflag : DWORD) : Boolean;
964 begin
965 result := WinHttpAddRequestHeaders( FHandle, PWideChar(aHeader), DWORD(-1), addflag);
966 end;
967
968
969 procedure TWinHTTPRequestImpl.TryAutoProxy( const aUrl : string);
970 // From MSDN:
971 // AutoProxy support is not fully integrated into the HTTP stack in WinHTTP.
972 // Before sending a request, the application must call WinHttpGetProxyForUrl
973 // to obtain the name of a proxy server and then call WinHttpSetOption using
974 // WINHTTP_OPTION_PROXY to set the proxy configuration on the WinHTTP request
975 // handle created by WinHttpOpenRequest.
976 // See https://docs.microsoft.com/en-us/windows/desktop/winhttp/winhttp-autoproxy-api
977 var
978 options : WINHTTP_AUTOPROXY_OPTIONS;
979 proxy : WINHTTP_PROXY_INFO;
980 ieProxy : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
981 dwSize : DWORD;
982 begin
983 // try AutoProxy via PAC first
984 proxy.Initialize;
985 try
986 FillChar( options, SizeOf(options), 0);
987 options.dwFlags := WINHTTP_AUTOPROXY_AUTO_DETECT;
988 options.dwAutoDetectFlags := WINHTTP_AUTO_DETECT_TYPE_DHCP or WINHTTP_AUTO_DETECT_TYPE_DNS_A;
989 options.fAutoLogonIfChallenged := TRUE;
990 if WinHttpGetProxyForUrl( FConnection.Session.Handle, PChar(aUrl), options, proxy) then begin
991 dwSize := SizeOf(proxy);
992 WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize);
993 Exit;
994 end;
995
996 finally
997 proxy.FreeAllocatedResources;
998 end;
999
1000 // Use IE settings as a fallback, useful in client (i.e. non-server) environments
1001 ieProxy.Initialize;
1002 try
1003 if WinHttpGetIEProxyConfigForCurrentUser( ieProxy)
1004 then begin
1005
1006 // lpszAutoConfigUrl = "Use automatic proxy configuration"
1007 if ieProxy.lpszAutoConfigUrl <> nil then begin
1008 options.lpszAutoConfigUrl := ieProxy.lpszAutoConfigUrl;
1009 options.dwFlags := options.dwFlags or WINHTTP_AUTOPROXY_CONFIG_URL;
1010
1011 proxy.Initialize;
1012 try
1013 if WinHttpGetProxyForUrl( FConnection.Session.Handle, PChar(aUrl), options, proxy) then begin
1014 dwSize := SizeOf(proxy);
1015 WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize);
1016 Exit;
1017 end;
1018 finally
1019 proxy.FreeAllocatedResources;
1020 end;
1021 end;
1022
1023 // lpszProxy = "use a proxy server"
1024 if ieProxy.lpszProxy <> nil then begin
1025 proxy.Initialize;
1026 try
1027 proxy.dwAccessType := WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1028 proxy.lpszProxy := ieProxy.lpszProxy;
1029 proxy.lpszProxyBypass := ieProxy.lpszProxyBypass;
1030 dwSize := SizeOf(proxy);
1031 WinHttpSetOption( Handle, WINHTTP_OPTION_PROXY, @proxy, dwSize);
1032 Exit;
1033 finally
1034 proxy.Initialize; // not FreeAllocatedResources, we only hold pointer copies!
1035 end;
1036 end;
1037
1038 end;
1039
1040 finally
1041 ieProxy.FreeAllocatedResources;
1042 end;
1043 end;
1044
1045
1046 procedure TWinHTTPRequestImpl.EnableAutomaticContentDecompression( const aEnable : Boolean);
1047 // Enable automatic gzip,deflate decompression on systems that support this option
1048 // From the docs: WinHTTP will automatically set an appropriate Accept-Encoding header,
1049 // overriding any value supplied by the caller -> we don't have to do this
1050 // Available on Win 8.1 or higher
1051 var value : DWORD;
1052 begin
1053 if aEnable
1054 then value := WINHTTP_DECOMPRESSION_FLAG_ALL
1055 else value := 0;
1056
1057 // ignore returned value, the option is not supported with older WinHTTP versions
1058 WinHttpSetOption( Handle, WINHTTP_OPTION_DECOMPRESSION, @value, SizeOf(DWORD));
1059 end;
1060
1061
1062 function TWinHTTPRequestImpl.SendRequest( const pBuf : Pointer; const dwBytes, dwExtra : DWORD) : Boolean;
1063 begin
1064 result := WinHttpSendRequest( FHandle,
1065 WINHTTP_NO_ADDITIONAL_HEADERS, 0,
1066 pBuf, dwBytes, // number of bytes in pBuf
1067 dwBytes + dwExtra, // becomes the Content-Length
1068 nil); // context for async operations
1069 end;
1070
1071
1072 function TWinHTTPRequestImpl.WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD;
1073 begin
1074 if not WinHttpWriteData( FHandle, pBuf, dwBytes, result)
1075 then result := 0;
1076 end;
1077
1078
1079 function TWinHTTPRequestImpl.FlushAndReceiveResponse : Boolean;
1080 begin
1081 result := WinHttpReceiveResponse( FHandle, nil);
1082 end;
1083
1084
1085 function TWinHTTPRequestImpl.ReadData( const dwRead : DWORD) : TBytes;
1086 var dwAvailable, dwReceived : DWORD;
1087 begin
1088 if WinHttpQueryDataAvailable( FHandle, dwAvailable)
1089 then dwAvailable := Min( dwRead, dwAvailable)
1090 else dwAvailable := 0;
1091
1092 SetLength( result, dwAvailable);
1093 if dwAvailable = 0 then Exit;
1094
1095 if WinHttpReadData( FHandle, @result[0], Length(result), dwReceived)
1096 then SetLength( result, dwReceived)
1097 else SetLength( result, 0);
1098 end;
1099
1100
1101 function TWinHTTPRequestImpl.ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD;
1102 var dwAvailable : DWORD;
1103 begin
1104 if WinHttpQueryDataAvailable( FHandle, dwAvailable)
1105 then dwAvailable := Min( dwRead, dwAvailable)
1106 else dwAvailable := 0;
1107
1108 if (dwAvailable = 0)
1109 or not WinHttpReadData( FHandle, pBuf, dwAvailable, result)
1110 then result := 0;
1111 end;
1112
1113
1114 { TWinHTTPUrlImpl }
1115
1116 constructor TWinHTTPUrlImpl.Create(const aUri: UnicodeString);
1117 begin
1118 inherited Create;
1119 CrackUrl( aUri)
1120 end;
1121
1122
1123 destructor TWinHTTPUrlImpl.Destroy;
1124 begin
1125 inherited Destroy;
1126 end;
1127
1128
1129 procedure TWinHTTPUrlImpl.CrackURL( const value : UnicodeString);
1130 const FLAGS = 0; // no special operations, leave components as-is
1131 var components : URL_COMPONENTS;
1132 begin
1133 FillChar(components, SizeOf(components), 0);
1134 components.dwStructSize := SizeOf(components);
1135
1136 if value <> '' then begin
1137 { For the WinHttpCrackUrl function, [...] if the pointer member is NULL but the
1138 length member is not zero, both the pointer and length members are returned. }
1139 components.dwSchemeLength := DWORD(-1);
1140 components.dwHostNameLength := DWORD(-1);
1141 components.dwUserNameLength := DWORD(-1);
1142 components.dwPasswordLength := DWORD(-1);
1143 components.dwUrlPathLength := DWORD(-1);
1144 components.dwExtraInfoLength := DWORD(-1);
1145
1146 WinHttpCrackUrl( PWideChar(value), Length(value), FLAGS, components);
1147 end;
1148
1149 FNumScheme := components.nScheme;
1150 FPort := components.nPort;
1151 SetString( FScheme, components.lpszScheme, components.dwSchemeLength);
1152 SetString( FHostName, components.lpszHostName, components.dwHostNameLength);
1153 SetString( FUserName, components.lpszUserName, components.dwUserNameLength);
1154 SetString( FPassword, components.lpszPassword, components.dwPasswordLength);
1155 SetString( FUrlPath, components.lpszUrlPath, components.dwUrlPathLength);
1156 SetString( FExtraInfo, components.lpszExtraInfo, components.dwExtraInfoLength);
1157 end;
1158
1159
1160 function TWinHTTPUrlImpl.BuildUrl : UnicodeString;
1161 const FLAGS = 0; // no special operations, leave components as-is
1162 var components : URL_COMPONENTS;
1163 dwChars : DWORD;
1164 begin
1165 FillChar(components, SizeOf(components), 0);
1166 components.dwStructSize := SizeOf(components);
1167 components.lpszScheme := PWideChar(FScheme);
1168 components.dwSchemeLength := Length(FScheme);
1169 components.lpszHostName := PWideChar(FHostName);
1170 components.dwHostNameLength := Length(FHostName);
1171 components.nPort := FPort;
1172 components.lpszUserName := PWideChar(FUserName);
1173 components.dwUserNameLength := Length(FUserName);
1174 components.lpszPassword := PWideChar(FPassword);
1175 components.dwPasswordLength := Length(FPassword);
1176 components.lpszUrlPath := PWideChar(FUrlPath);
1177 components.dwUrlPathLength := Length(FUrlPath);
1178 components.lpszExtraInfo := PWideChar(FExtraInfo);
1179 components.dwExtraInfoLength := Length(FExtraInfo);
1180
1181 WinHttpCreateUrl( components, FLAGS, nil, dwChars);
1182 if dwChars = 0
1183 then result := ''
1184 else begin
1185 SetLength( result, dwChars + 1);
1186 WinHttpCreateUrl( components, FLAGS, @result[1], dwChars);
1187 SetLength( result, dwChars); // cut off terminating #0
1188 end;
1189 end;
1190
1191
1192 function TWinHTTPUrlImpl.GetExtraInfo: UnicodeString;
1193 begin
1194 result := FExtraInfo;
1195 end;
1196
1197 function TWinHTTPUrlImpl.GetHostName: UnicodeString;
1198 begin
1199 result := FHostName;
1200 end;
1201
1202 function TWinHTTPUrlImpl.GetNumScheme: INTERNET_SCHEME;
1203 begin
1204 result := FNumScheme;
1205 end;
1206
1207 function TWinHTTPUrlImpl.GetPassword: UnicodeString;
1208 begin
1209 result := FPassword;
1210 end;
1211
1212 function TWinHTTPUrlImpl.GetPort: INTERNET_PORT;
1213 begin
1214 result := FPort;
1215 end;
1216
1217 function TWinHTTPUrlImpl.GetScheme: UnicodeString;
1218 begin
1219 result := FScheme;
1220 end;
1221
1222 function TWinHTTPUrlImpl.GetUrlPath: UnicodeString;
1223 begin
1224 result := FUrlPath;
1225 end;
1226
1227 function TWinHTTPUrlImpl.GetUserName: UnicodeString;
1228 begin
1229 result := FUserName;
1230 end;
1231
1232 procedure TWinHTTPUrlImpl.SetExtraInfo(const value: UnicodeString);
1233 begin
1234 FExtraInfo := value;
1235 end;
1236
1237 procedure TWinHTTPUrlImpl.SetHostName(const value: UnicodeString);
1238 begin
1239 FHostName := value;
1240 end;
1241
1242 procedure TWinHTTPUrlImpl.SetPassword(const value: UnicodeString);
1243 begin
1244 FPassword := value;
1245 end;
1246
1247 procedure TWinHTTPUrlImpl.SetPort(const value: INTERNET_PORT);
1248 begin
1249 FPort := value;
1250 end;
1251
1252 procedure TWinHTTPUrlImpl.SetScheme(const value: UnicodeString);
1253 begin
1254 FScheme := value;
1255 end;
1256
1257 procedure TWinHTTPUrlImpl.SetUrlPath(const value: UnicodeString);
1258 begin
1259 FUrlPath := value;
1260 end;
1261
1262 procedure TWinHTTPUrlImpl.SetUserName(const value: UnicodeString);
1263 begin
1264 FUserName := value;
1265 end;
1266
1267
1268 initialization
1269 OutputDebugString( PChar( SysErrorMessage( 12002)));
1270
1271 end.
1272
1273