4 * Copyright 2008 Google (Zac Brown)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/test.h"
32 static const WCHAR test_useragent
[] =
33 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
34 static const WCHAR test_server
[] = {'w','i','n','e','h','q','.','o','r','g',0};
35 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
37 static BOOL
proxy_active(void)
39 WINHTTP_PROXY_INFO proxy_info
;
42 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
44 active
= (proxy_info
.lpszProxy
!= NULL
);
46 GlobalFree((HGLOBAL
) proxy_info
.lpszProxy
);
47 if (proxy_info
.lpszProxyBypass
!= NULL
)
48 GlobalFree((HGLOBAL
) proxy_info
.lpszProxyBypass
);
56 static void test_QueryOption(void)
59 HINTERNET session
, request
, connection
;
62 SetLastError(0xdeadbeef);
63 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
64 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
66 SetLastError(0xdeadbeef);
67 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
68 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
69 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
70 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
73 SetLastError(0xdeadbeef);
74 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
75 ok(!ret
, "should fail to query option\n");
76 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
77 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
78 ok(size
== 4, "expected 4, got %u\n", size
);
81 size
= sizeof(feature
) - 1;
82 SetLastError(0xdeadbeef);
83 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
84 ok(!ret
, "should fail to query option\n");
85 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
86 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
87 ok(size
== 4, "expected 4, got %u\n", size
);
90 size
= sizeof(feature
) + 1;
91 SetLastError(0xdeadbeef);
92 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
93 ok(ret
, "failed to query option %u\n", GetLastError());
94 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
95 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
96 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
98 SetLastError(0xdeadbeef);
99 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
100 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
101 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
102 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
104 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
105 SetLastError(0xdeadbeef);
106 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
107 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
108 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
109 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
111 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
112 SetLastError(0xdeadbeef);
113 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
114 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
115 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
116 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
118 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
119 SetLastError(0xdeadbeef);
120 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
121 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
123 feature
= 0xdeadbeef;
124 size
= sizeof(feature
);
125 SetLastError(0xdeadbeef);
126 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
127 ok(ret
, "failed to query option %u\n", GetLastError());
128 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
129 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
131 feature
= WINHTTP_DISABLE_COOKIES
;
132 SetLastError(0xdeadbeef);
133 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
134 ok(!ret
, "should fail to set disable feature for a session\n");
135 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
136 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
138 SetLastError(0xdeadbeef);
139 connection
= WinHttpConnect(session
, test_server
, INTERNET_DEFAULT_HTTP_PORT
, 0);
140 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
142 feature
= WINHTTP_DISABLE_COOKIES
;
143 SetLastError(0xdeadbeef);
144 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
145 ok(!ret
, "should fail to set disable feature for a connection\n");
146 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
147 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
149 SetLastError(0xdeadbeef);
150 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
151 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
152 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
154 skip("Network unreachable, skipping the test\n");
158 feature
= 0xdeadbeef;
159 size
= sizeof(feature
);
160 SetLastError(0xdeadbeef);
161 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
162 ok(!ret
, "should fail to query disable feature for a request\n");
163 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
164 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
167 size
= sizeof(feature
);
168 SetLastError(0xdeadbeef);
169 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
170 ok(ret
, "failed to set feature %u\n", GetLastError());
172 feature
= 0xffffffff;
173 size
= sizeof(feature
);
174 SetLastError(0xdeadbeef);
175 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
176 ok(ret
, "failed to set feature %u\n", GetLastError());
178 feature
= WINHTTP_DISABLE_COOKIES
;
179 size
= sizeof(feature
);
180 SetLastError(0xdeadbeef);
181 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
182 ok(ret
, "failed to set feature %u\n", GetLastError());
185 SetLastError(0xdeadbeef);
186 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
187 ok(!ret
, "should fail to query disable feature for a request\n");
188 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
189 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
191 SetLastError(0xdeadbeef);
192 ret
= WinHttpCloseHandle(request
);
193 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
196 SetLastError(0xdeadbeef);
197 ret
= WinHttpCloseHandle(connection
);
198 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
199 SetLastError(0xdeadbeef);
200 ret
= WinHttpCloseHandle(session
);
201 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
204 static void test_OpenRequest (void)
207 HINTERNET session
, request
, connection
;
209 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
210 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
211 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
213 /* Test with a bad server name */
214 SetLastError(0xdeadbeef);
215 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
216 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
217 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
219 /* Test with a valid server name */
220 connection
= WinHttpConnect (session
, test_server
, INTERNET_DEFAULT_HTTP_PORT
, 0);
221 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
223 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
224 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
225 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
227 skip("Network unreachable, skipping.\n");
230 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
232 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
233 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
235 skip("Connection failed, skipping.\n");
238 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
239 ret
= WinHttpCloseHandle(request
);
240 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
243 ret
= WinHttpCloseHandle(connection
);
244 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
245 ret
= WinHttpCloseHandle(session
);
246 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
250 static void test_empty_headers_param(void)
252 static const WCHAR winehq
[] = {'w','i','n','e','h','q','.','o','r','g',0};
253 static const WCHAR empty
[] = {0};
254 HINTERNET ses
, con
, req
;
257 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
258 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
260 con
= WinHttpConnect(ses
, winehq
, 80, 0);
261 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
263 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
264 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
266 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
267 ok(ret
, "failed to send request %u\n", GetLastError());
269 WinHttpCloseHandle(req
);
270 WinHttpCloseHandle(con
);
271 WinHttpCloseHandle(ses
);
274 static void test_SendRequest (void)
276 HINTERNET session
, request
, connection
;
277 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
;
283 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
284 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
285 static const WCHAR content_type
[] =
286 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
287 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
288 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
289 static const WCHAR test_verb
[] = {'P','O','S','T',0};
290 static CHAR post_data
[] = "mode=Test";
291 static CHAR test_post
[] = "mode => Test\\0\n";
294 total_len
= optional_len
= sizeof(post_data
);
295 memset(buffer
, 0xff, sizeof(buffer
));
297 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
298 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
299 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
301 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
302 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
304 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
305 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
306 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
308 skip("Network unreachable, skipping.\n");
311 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
312 if (!request
) goto done
;
314 context
= 0xdeadbeef;
315 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
316 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
319 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
320 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
323 size
= sizeof(context
);
324 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
325 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
326 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
328 for (i
= 3; post_data
[i
]; i
++)
331 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
333 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
334 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
336 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
337 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
341 ret
= WinHttpReceiveResponse(request
, NULL
);
342 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
345 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
346 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
348 ok(bytes_rw
== strlen(test_post
), "Read %u bytes instead of %d.\n", bytes_rw
, lstrlen(test_post
));
349 ok(strncmp(buffer
, test_post
, bytes_rw
) == 0, "Data read did not match, got '%s'.\n", buffer
);
351 ret
= WinHttpCloseHandle(request
);
352 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
354 ret
= WinHttpCloseHandle(connection
);
355 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
356 ret
= WinHttpCloseHandle(session
);
357 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
360 static void test_WinHttpTimeFromSystemTime(void)
363 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
364 static const WCHAR expected_string
[] =
365 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
366 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
367 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
369 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
370 ok(ret
== TRUE
, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
371 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
372 "Time string returned did not match expected time string.\n");
375 static void test_WinHttpTimeToSystemTime(void)
379 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
380 static const WCHAR time_string1
[] =
381 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
382 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
383 static const WCHAR time_string2
[] =
384 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
385 '1','0',' ','0','5',' ','5','2','\n',0};
387 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
388 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
389 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
390 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
392 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
393 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
394 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
395 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
398 static void test_WinHttpAddHeaders(void)
400 HINTERNET session
, request
, connection
;
402 WCHAR buffer
[MAX_PATH
];
403 WCHAR check_buffer
[MAX_PATH
];
404 DWORD index
, len
, oldlen
;
406 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
407 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
408 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
409 static const WCHAR test_verb
[] = {'P','O','S','T',0};
411 static const WCHAR test_header_begin
[] =
412 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
413 static const WCHAR full_path_test_header_begin
[] =
414 {'P','O','S','T',' ','h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',':','8','0','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
415 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
416 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
418 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
419 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
420 static const WCHAR test_flag_coalesce_comma
[] =
421 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
422 static const WCHAR test_flag_coalesce_comma_reverse
[] =
423 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
424 static const WCHAR test_flag_coalesce_semicolon
[] =
425 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
426 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
427 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429 static const WCHAR field
[] = {'f','i','e','l','d',0};
430 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
431 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
433 static const WCHAR test_headers
[][14] =
435 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
436 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
437 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
438 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
439 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
440 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
441 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
447 {' ','e',' ',':','f',0},
448 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
450 static const WCHAR test_indices
[][6] =
452 {'t','e','s','t','1',0},
453 {'t','e','s','t','2',0},
454 {'t','e','s','t','3',0},
455 {'t','e','s','t','4',0}
458 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
459 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
460 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
462 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
463 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
465 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
466 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
467 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
469 skip("Network unreachable, skipping.\n");
472 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
475 len
= sizeof(buffer
);
476 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
477 test_header_name
, buffer
, &len
, &index
);
478 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
479 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
480 ok(ret
== TRUE
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, GetLastError());
483 len
= sizeof(buffer
);
484 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
485 test_header_name
, buffer
, &len
, &index
);
486 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
487 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
488 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
489 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
491 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
492 test_header_name
, buffer
, &len
, &index
);
493 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
495 /* Try to fetch the header info with a buffer that's big enough to fit the
496 * string but not the NULL terminator.
499 len
= 5*sizeof(WCHAR
);
500 memset(check_buffer
, 0xab, sizeof(check_buffer
));
501 memcpy(buffer
, check_buffer
, sizeof(buffer
));
502 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
503 test_header_name
, buffer
, &len
, &index
);
504 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
505 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
506 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
507 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
509 /* Try with a NULL buffer */
511 len
= sizeof(buffer
);
512 SetLastError(0xdeadbeef);
513 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
514 test_header_name
, NULL
, &len
, &index
);
515 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
516 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
517 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
518 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
520 /* Try with a NULL buffer and a length that's too small */
523 SetLastError(0xdeadbeef);
524 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
525 test_header_name
, NULL
, &len
, &index
);
526 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
527 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
528 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
529 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
530 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
534 SetLastError(0xdeadbeef);
535 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
536 test_header_name
, NULL
, &len
, &index
);
537 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
538 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
539 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
540 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
541 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
546 len
= sizeof(buffer
);
547 memset(buffer
, 0xff, sizeof(buffer
));
548 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
549 test_header_name
, buffer
, &len
, &index
);
550 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
551 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
552 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
553 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
554 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
555 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
556 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
557 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
558 "WinHttpQueryHeaders returned invalid end of header string.\n");
559 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
563 SetLastError(0xdeadbeef);
564 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
565 test_header_name
, NULL
, &len
, &index
);
566 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
567 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
568 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
569 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
570 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
574 len
= sizeof(buffer
);
575 memset(buffer
, 0xff, sizeof(buffer
));
576 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
577 test_header_name
, buffer
, &len
, &index
);
578 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
579 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
580 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
581 "no double NULL terminator\n");
582 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
583 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
584 "invalid beginning of header string.\n");
585 ok(index
== 0, "header index was incremented\n");
587 /* tests for more indices */
588 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
589 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
592 len
= sizeof(buffer
);
593 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
594 test_header_name
, buffer
, &len
, &index
);
595 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
596 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
597 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
599 len
= sizeof(buffer
);
600 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
601 test_header_name
, buffer
, &len
, &index
);
602 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
603 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
604 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
606 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
607 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
610 len
= sizeof(buffer
);
611 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
612 test_header_name
, buffer
, &len
, &index
);
613 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
614 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
615 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
616 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
618 len
= sizeof(buffer
);
619 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
620 test_header_name
, buffer
, &len
, &index
);
621 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
622 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
623 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
625 /* add if new flag */
626 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
627 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
630 len
= sizeof(buffer
);
631 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
632 test_header_name
, buffer
, &len
, &index
);
633 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
634 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
635 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
637 len
= sizeof(buffer
);
638 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
639 test_header_name
, buffer
, &len
, &index
);
640 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
641 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
642 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
644 len
= sizeof(buffer
);
645 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
646 test_header_name
, buffer
, &len
, &index
);
647 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
650 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
651 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
654 len
= sizeof(buffer
);
655 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
656 test_header_name
, buffer
, &len
, &index
);
657 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
658 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
659 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
, sizeof(reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
661 len
= sizeof(buffer
);
662 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
663 test_header_name
, buffer
, &len
, &index
);
664 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
665 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
666 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
668 len
= sizeof(buffer
);
669 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
670 test_header_name
, buffer
, &len
, &index
);
671 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
673 /* coalesce with comma flag */
674 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
675 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
678 len
= sizeof(buffer
);
679 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
680 test_header_name
, buffer
, &len
, &index
);
681 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
682 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
683 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
, sizeof(reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
)) == 0,
684 "WinHttpQueryHeaders returned incorrect string.\n");
686 len
= sizeof(buffer
);
687 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
688 test_header_name
, buffer
, &len
, &index
);
689 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
690 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
691 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
693 len
= sizeof(buffer
);
694 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
695 test_header_name
, buffer
, &len
, &index
);
696 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
699 /* coalesce with semicolon flag */
700 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
701 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
704 len
= sizeof(buffer
);
705 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
706 test_header_name
, buffer
, &len
, &index
);
707 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
708 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
709 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
, sizeof(reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
)) == 0,
710 "WinHttpQueryHeaders returned incorrect string.\n");
712 len
= sizeof(buffer
);
713 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
714 test_header_name
, buffer
, &len
, &index
);
715 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
716 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
717 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
719 len
= sizeof(buffer
);
720 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
721 test_header_name
, buffer
, &len
, &index
);
722 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
724 /* add and replace flags */
725 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
726 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
729 len
= sizeof(buffer
);
730 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
731 test_header_name
, buffer
, &len
, &index
);
732 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
733 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
734 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
736 len
= sizeof(buffer
);
737 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
738 test_header_name
, buffer
, &len
, &index
);
739 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
740 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
741 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
743 len
= sizeof(buffer
);
744 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
745 test_header_name
, buffer
, &len
, &index
);
746 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
748 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
749 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
751 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
752 ok(ret
, "WinHttpAddRequestHeaders failed\n");
754 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
755 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
757 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
758 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
760 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
761 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
763 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
764 ok(ret
, "WinHttpAddRequestHeaders failed\n");
768 len
= sizeof(buffer
);
769 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
770 field
, buffer
, &len
, &index
);
771 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
772 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
774 ret
= WinHttpCloseHandle(request
);
775 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
777 ret
= WinHttpCloseHandle(connection
);
778 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
779 ret
= WinHttpCloseHandle(session
);
780 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
784 static void test_secure_connection(void)
786 static const WCHAR google
[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
788 HINTERNET ses
, con
, req
;
789 DWORD size
, status
, policy
, bitness
;
792 WINHTTP_CERTIFICATE_INFO info
;
795 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
796 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
798 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
799 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
800 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
802 con
= WinHttpConnect(ses
, google
, 443, 0);
803 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
805 /* try without setting WINHTTP_FLAG_SECURE */
806 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
807 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
809 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
810 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
812 skip("Connection failed, skipping.\n");
815 ok(ret
, "failed to send request %u\n", GetLastError());
817 ret
= WinHttpReceiveResponse(req
, NULL
);
818 ok(!ret
|| proxy_active(), "succeeded unexpectedly\n");
821 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
822 ok(!ret
, "succeeded unexpectedly\n");
824 WinHttpCloseHandle(req
);
826 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
827 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
829 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
830 ok(ret
, "failed to send request %u\n", GetLastError());
833 skip("secure connection failed, skipping remaining secure tests\n");
838 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
839 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
841 CertFreeCertificateContext(cert
);
843 size
= sizeof(bitness
);
844 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
845 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
848 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
849 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
851 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
852 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
853 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
854 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
855 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
856 trace("dwKeySize %u\n", info
.dwKeySize
);
858 ret
= WinHttpReceiveResponse(req
, NULL
);
859 ok(ret
, "failed to receive response %u\n", GetLastError());
861 size
= sizeof(status
);
862 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
863 ok(ret
, "failed unexpectedly %u\n", GetLastError());
864 ok(status
== 200, "request failed unexpectedly %u\n", status
);
867 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
868 ok(!ret
, "succeeded unexpectedly\n");
873 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
874 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
879 WinHttpCloseHandle(req
);
880 WinHttpCloseHandle(con
);
881 WinHttpCloseHandle(ses
);
884 static void test_request_parameter_defaults(void)
886 static const WCHAR empty
[] = {0};
887 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
889 HINTERNET ses
, con
, req
;
890 DWORD size
, status
, error
;
894 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
895 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
897 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
898 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
900 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
901 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
903 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
904 ok(ret
, "failed to send request %u\n", GetLastError());
906 ret
= WinHttpReceiveResponse(req
, NULL
);
907 ok(ret
, "failed to receive response %u\n", GetLastError());
909 size
= sizeof(status
);
910 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
911 ok(ret
, "failed unexpectedly %u\n", GetLastError());
912 ok(status
== 200, "request failed unexpectedly %u\n", status
);
914 WinHttpCloseHandle(req
);
916 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
917 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
919 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
920 ok(ret
, "failed to send request %u\n", GetLastError());
922 ret
= WinHttpReceiveResponse(req
, NULL
);
923 ok(ret
, "failed to receive response %u\n", GetLastError());
926 SetLastError(0xdeadbeef);
927 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
928 error
= GetLastError();
929 ok(!ret
, "succeeded unexpectedly\n");
930 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
932 version
= HeapAlloc(GetProcessHeap(), 0, size
);
933 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
934 ok(ret
, "failed unexpectedly %u\n", GetLastError());
935 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
936 HeapFree(GetProcessHeap(), 0, version
);
938 size
= sizeof(status
);
939 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
940 ok(ret
, "failed unexpectedly %u\n", GetLastError());
941 ok(status
== 200, "request failed unexpectedly %u\n", status
);
943 WinHttpCloseHandle(req
);
944 WinHttpCloseHandle(con
);
945 WinHttpCloseHandle(ses
);
948 static const WCHAR Connections
[] = {
949 'S','o','f','t','w','a','r','e','\\',
950 'M','i','c','r','o','s','o','f','t','\\',
951 'W','i','n','d','o','w','s','\\',
952 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
953 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
954 'C','o','n','n','e','c','t','i','o','n','s',0 };
955 static const WCHAR WinHttpSettings
[] = {
956 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
958 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
964 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
969 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
973 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
983 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
988 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
989 KEY_WRITE
, NULL
, &key
, NULL
);
993 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
995 RegDeleteValueW( key
, WinHttpSettings
);
1000 static void test_set_default_proxy_config(void)
1002 static const WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1003 static const WCHAR normalString
[] = { 'f','o','o',0 };
1005 BYTE
*saved_proxy_settings
= NULL
;
1006 WINHTTP_PROXY_INFO info
;
1009 /* FIXME: it would be simpler to read the current settings using
1010 * WinHttpGetDefaultProxyConfiguration and save them using
1011 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1013 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1014 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1015 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1016 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1017 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1018 * the lpszProxy and lpszProxyBypass values are ignored.
1019 * Thus, if a proxy is set with proxycfg, then calling
1020 * WinHttpGetDefaultProxyConfiguration followed by
1021 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1022 * getting deleted from the registry.
1024 * Instead I read the current registry value and restore it directly.
1026 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1029 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1030 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1035 /* Crashes on Vista and higher */
1036 SetLastError(0xdeadbeef);
1037 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1038 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1039 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1042 /* test with invalid access type */
1043 info
.dwAccessType
= 0xdeadbeef;
1044 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1045 SetLastError(0xdeadbeef);
1046 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1047 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1048 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1050 /* at a minimum, the proxy server must be set */
1051 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1052 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1053 SetLastError(0xdeadbeef);
1054 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1055 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1056 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1057 info
.lpszProxyBypass
= normalString
;
1058 SetLastError(0xdeadbeef);
1059 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1060 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1061 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1063 /* the proxy server can't have wide characters */
1064 info
.lpszProxy
= wideString
;
1065 SetLastError(0xdeadbeef);
1066 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1067 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1068 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1069 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1071 info
.lpszProxy
= normalString
;
1072 SetLastError(0xdeadbeef);
1073 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1076 ok(ret
, "always true\n");
1077 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1079 else if (GetLastError() == ERROR_ACCESS_DENIED
)
1080 skip("couldn't set default proxy configuration: access denied\n");
1082 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1086 static void test_Timeouts (void)
1090 HINTERNET ses
, req
, con
;
1091 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1094 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1095 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1097 SetLastError(0xdeadbeef);
1098 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1099 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1100 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1102 SetLastError(0xdeadbeef);
1103 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1104 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1105 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1107 SetLastError(0xdeadbeef);
1108 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1109 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1110 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1112 SetLastError(0xdeadbeef);
1113 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1114 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1115 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1117 SetLastError(0xdeadbeef);
1118 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1119 ok(ret
, "%u\n", GetLastError());
1121 SetLastError(0xdeadbeef);
1122 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1123 ok(ret
, "%u\n", GetLastError());
1125 SetLastError(0xdeadbeef);
1126 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1127 ok(ret
, "%u\n", GetLastError());
1129 SetLastError(0xdeadbeef);
1131 size
= sizeof(DWORD
);
1132 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1133 ok(ret
, "%u\n", GetLastError());
1134 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1136 SetLastError(0xdeadbeef);
1138 size
= sizeof(DWORD
);
1139 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1140 ok(ret
, "%u\n", GetLastError());
1141 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1143 SetLastError(0xdeadbeef);
1145 size
= sizeof(DWORD
);
1146 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1147 ok(ret
, "%u\n", GetLastError());
1148 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1150 SetLastError(0xdeadbeef);
1152 size
= sizeof(DWORD
);
1153 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1154 ok(ret
, "%u\n", GetLastError());
1155 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1157 SetLastError(0xdeadbeef);
1159 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1160 ok(ret
, "%u\n", GetLastError());
1162 SetLastError(0xdeadbeef);
1164 size
= sizeof(DWORD
);
1165 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1166 ok(ret
, "%u\n", GetLastError());
1167 ok(value
== 0, "Expected 0, got %u\n", value
);
1169 SetLastError(0xdeadbeef);
1171 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1172 ok(ret
, "%u\n", GetLastError());
1174 SetLastError(0xdeadbeef);
1176 size
= sizeof(DWORD
);
1177 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1178 ok(ret
, "%u\n", GetLastError());
1179 ok(value
== 0, "Expected 0, got %u\n", value
);
1181 SetLastError(0xdeadbeef);
1183 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1184 ok(ret
, "%u\n", GetLastError());
1186 SetLastError(0xdeadbeef);
1188 size
= sizeof(DWORD
);
1189 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1190 ok(ret
, "%u\n", GetLastError());
1191 ok(value
== 0, "Expected 0, got %u\n", value
);
1193 SetLastError(0xdeadbeef);
1195 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1196 ok(ret
, "%u\n", GetLastError());
1198 SetLastError(0xdeadbeef);
1200 size
= sizeof(DWORD
);
1201 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1202 ok(ret
, "%u\n", GetLastError());
1203 ok(value
== 0, "Expected 0, got %u\n", value
);
1205 SetLastError(0xdeadbeef);
1207 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1208 ok(ret
, "%u\n", GetLastError());
1210 SetLastError(0xdeadbeef);
1212 size
= sizeof(DWORD
);
1213 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1214 ok(ret
, "%u\n", GetLastError());
1215 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1217 SetLastError(0xdeadbeef);
1219 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1220 ok(ret
, "%u\n", GetLastError());
1222 SetLastError(0xdeadbeef);
1224 size
= sizeof(DWORD
);
1225 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1226 ok(ret
, "%u\n", GetLastError());
1227 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1229 SetLastError(0xdeadbeef);
1231 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1232 ok(ret
, "%u\n", GetLastError());
1234 SetLastError(0xdeadbeef);
1236 size
= sizeof(DWORD
);
1237 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1238 ok(ret
, "%u\n", GetLastError());
1239 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1241 SetLastError(0xdeadbeef);
1243 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1244 ok(ret
, "%u\n", GetLastError());
1246 SetLastError(0xdeadbeef);
1248 size
= sizeof(DWORD
);
1249 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1250 ok(ret
, "%u\n", GetLastError());
1251 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1253 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1254 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1256 /* Timeout values should match the last one set for session */
1257 SetLastError(0xdeadbeef);
1259 size
= sizeof(DWORD
);
1260 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1261 ok(ret
, "%u\n", GetLastError());
1262 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1264 SetLastError(0xdeadbeef);
1266 size
= sizeof(DWORD
);
1267 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1268 ok(ret
, "%u\n", GetLastError());
1269 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1271 SetLastError(0xdeadbeef);
1273 size
= sizeof(DWORD
);
1274 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1275 ok(ret
, "%u\n", GetLastError());
1276 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1278 SetLastError(0xdeadbeef);
1280 size
= sizeof(DWORD
);
1281 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1282 ok(ret
, "%u\n", GetLastError());
1283 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1285 SetLastError(0xdeadbeef);
1286 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1287 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1288 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1290 SetLastError(0xdeadbeef);
1291 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1292 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1293 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1295 SetLastError(0xdeadbeef);
1296 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1297 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1298 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1300 SetLastError(0xdeadbeef);
1301 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1302 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1303 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1305 SetLastError(0xdeadbeef);
1306 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1307 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1308 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1310 SetLastError(0xdeadbeef);
1311 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1312 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1313 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1315 SetLastError(0xdeadbeef);
1317 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1318 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1319 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1321 SetLastError(0xdeadbeef);
1323 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1324 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1325 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1327 SetLastError(0xdeadbeef);
1329 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1330 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1331 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1333 SetLastError(0xdeadbeef);
1335 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1336 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1337 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1339 /* Changing timeout values for session should affect the values for connection */
1340 SetLastError(0xdeadbeef);
1342 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1343 ok(ret
, "%u\n", GetLastError());
1345 SetLastError(0xdeadbeef);
1347 size
= sizeof(DWORD
);
1348 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1349 ok(ret
, "%u\n", GetLastError());
1350 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1352 SetLastError(0xdeadbeef);
1354 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1355 ok(ret
, "%u\n", GetLastError());
1357 SetLastError(0xdeadbeef);
1359 size
= sizeof(DWORD
);
1360 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1361 ok(ret
, "%u\n", GetLastError());
1362 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1364 SetLastError(0xdeadbeef);
1366 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1367 ok(ret
, "%u\n", GetLastError());
1369 SetLastError(0xdeadbeef);
1371 size
= sizeof(DWORD
);
1372 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1373 ok(ret
, "%u\n", GetLastError());
1374 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1376 SetLastError(0xdeadbeef);
1378 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1379 ok(ret
, "%u\n", GetLastError());
1381 SetLastError(0xdeadbeef);
1383 size
= sizeof(DWORD
);
1384 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1385 ok(ret
, "%u\n", GetLastError());
1386 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1388 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1389 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1391 /* Timeout values should match the last one set for session */
1392 SetLastError(0xdeadbeef);
1394 size
= sizeof(DWORD
);
1395 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1396 ok(ret
, "%u\n", GetLastError());
1397 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1399 SetLastError(0xdeadbeef);
1401 size
= sizeof(DWORD
);
1402 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1403 ok(ret
, "%u\n", GetLastError());
1404 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1406 SetLastError(0xdeadbeef);
1408 size
= sizeof(DWORD
);
1409 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1410 ok(ret
, "%u\n", GetLastError());
1411 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1413 SetLastError(0xdeadbeef);
1415 size
= sizeof(DWORD
);
1416 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1417 ok(ret
, "%u\n", GetLastError());
1418 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1420 SetLastError(0xdeadbeef);
1421 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1422 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1423 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1425 SetLastError(0xdeadbeef);
1426 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1427 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1428 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1430 SetLastError(0xdeadbeef);
1431 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1432 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1433 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1435 SetLastError(0xdeadbeef);
1436 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1437 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1438 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1440 SetLastError(0xdeadbeef);
1441 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1442 ok(ret
, "%u\n", GetLastError());
1444 SetLastError(0xdeadbeef);
1445 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1446 ok(ret
, "%u\n", GetLastError());
1448 SetLastError(0xdeadbeef);
1449 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1450 ok(ret
, "%u\n", GetLastError());
1452 SetLastError(0xdeadbeef);
1454 size
= sizeof(DWORD
);
1455 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1456 ok(ret
, "%u\n", GetLastError());
1457 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1459 SetLastError(0xdeadbeef);
1461 size
= sizeof(DWORD
);
1462 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1463 ok(ret
, "%u\n", GetLastError());
1464 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1466 SetLastError(0xdeadbeef);
1468 size
= sizeof(DWORD
);
1469 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1470 ok(ret
, "%u\n", GetLastError());
1471 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1473 SetLastError(0xdeadbeef);
1475 size
= sizeof(DWORD
);
1476 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1477 ok(ret
, "%u\n", GetLastError());
1478 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1480 SetLastError(0xdeadbeef);
1482 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1483 ok(ret
, "%u\n", GetLastError());
1485 SetLastError(0xdeadbeef);
1487 size
= sizeof(DWORD
);
1488 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1489 ok(ret
, "%u\n", GetLastError());
1490 ok(value
== 0, "Expected 0, got %u\n", value
);
1492 SetLastError(0xdeadbeef);
1494 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1495 ok(ret
, "%u\n", GetLastError());
1497 SetLastError(0xdeadbeef);
1499 size
= sizeof(DWORD
);
1500 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1501 ok(ret
, "%u\n", GetLastError());
1502 ok(value
== 0, "Expected 0, got %u\n", value
);
1504 SetLastError(0xdeadbeef);
1506 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1507 ok(ret
, "%u\n", GetLastError());
1509 SetLastError(0xdeadbeef);
1511 size
= sizeof(DWORD
);
1512 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1513 ok(ret
, "%u\n", GetLastError());
1514 ok(value
== 0, "Expected 0, got %u\n", value
);
1516 SetLastError(0xdeadbeef);
1518 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1519 ok(ret
, "%u\n", GetLastError());
1521 SetLastError(0xdeadbeef);
1523 size
= sizeof(DWORD
);
1524 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1525 ok(ret
, "%u\n", GetLastError());
1526 ok(value
== 0, "Expected 0, got %u\n", value
);
1528 SetLastError(0xdeadbeef);
1530 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1531 ok(ret
, "%u\n", GetLastError());
1533 SetLastError(0xdeadbeef);
1535 size
= sizeof(DWORD
);
1536 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1537 ok(ret
, "%u\n", GetLastError());
1538 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1540 SetLastError(0xdeadbeef);
1542 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1543 ok(ret
, "%u\n", GetLastError());
1545 SetLastError(0xdeadbeef);
1547 size
= sizeof(DWORD
);
1548 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1549 ok(ret
, "%u\n", GetLastError());
1550 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1552 SetLastError(0xdeadbeef);
1554 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1555 ok(ret
, "%u\n", GetLastError());
1557 SetLastError(0xdeadbeef);
1559 size
= sizeof(DWORD
);
1560 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1561 ok(ret
, "%u\n", GetLastError());
1562 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1564 SetLastError(0xdeadbeef);
1566 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1567 ok(ret
, "%u\n", GetLastError());
1569 SetLastError(0xdeadbeef);
1571 size
= sizeof(DWORD
);
1572 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1573 ok(ret
, "%u\n", GetLastError());
1574 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1576 /* Changing timeout values for session should not affect the values for a request,
1577 * neither should the other way around.
1579 SetLastError(0xdeadbeef);
1581 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1582 ok(ret
, "%u\n", GetLastError());
1584 SetLastError(0xdeadbeef);
1586 size
= sizeof(DWORD
);
1587 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1588 ok(ret
, "%u\n", GetLastError());
1589 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1591 SetLastError(0xdeadbeef);
1593 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1594 ok(ret
, "%u\n", GetLastError());
1596 SetLastError(0xdeadbeef);
1598 size
= sizeof(DWORD
);
1599 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1600 ok(ret
, "%u\n", GetLastError());
1601 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1603 SetLastError(0xdeadbeef);
1605 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1606 ok(ret
, "%u\n", GetLastError());
1608 SetLastError(0xdeadbeef);
1610 size
= sizeof(DWORD
);
1611 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1612 ok(ret
, "%u\n", GetLastError());
1613 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1615 SetLastError(0xdeadbeef);
1617 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1618 ok(ret
, "%u\n", GetLastError());
1620 SetLastError(0xdeadbeef);
1622 size
= sizeof(DWORD
);
1623 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1624 ok(ret
, "%u\n", GetLastError());
1625 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1627 SetLastError(0xdeadbeef);
1629 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1630 ok(ret
, "%u\n", GetLastError());
1632 SetLastError(0xdeadbeef);
1634 size
= sizeof(DWORD
);
1635 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1636 ok(ret
, "%u\n", GetLastError());
1637 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1639 SetLastError(0xdeadbeef);
1641 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1642 ok(ret
, "%u\n", GetLastError());
1644 SetLastError(0xdeadbeef);
1646 size
= sizeof(DWORD
);
1647 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1648 ok(ret
, "%u\n", GetLastError());
1649 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1651 SetLastError(0xdeadbeef);
1653 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1654 ok(ret
, "%u\n", GetLastError());
1656 SetLastError(0xdeadbeef);
1658 size
= sizeof(DWORD
);
1659 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1660 ok(ret
, "%u\n", GetLastError());
1661 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1663 SetLastError(0xdeadbeef);
1665 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1666 ok(ret
, "%u\n", GetLastError());
1668 SetLastError(0xdeadbeef);
1670 size
= sizeof(DWORD
);
1671 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1672 ok(ret
, "%u\n", GetLastError());
1673 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1675 WinHttpCloseHandle(req
);
1676 WinHttpCloseHandle(con
);
1677 WinHttpCloseHandle(ses
);
1680 static void test_resolve_timeout(void)
1682 static const WCHAR codeweavers
[] =
1683 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1684 static const WCHAR nxdomain
[] =
1685 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1687 HINTERNET ses
, con
, req
;
1691 if (! proxy_active())
1693 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1694 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1697 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1698 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1700 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1701 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1703 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1704 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1706 SetLastError(0xdeadbeef);
1707 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1708 ok(!ret
, "sent request\n");
1709 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1710 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1712 WinHttpCloseHandle(req
);
1713 WinHttpCloseHandle(con
);
1714 WinHttpCloseHandle(ses
);
1717 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1719 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1720 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1723 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1724 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1726 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1727 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1729 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1730 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1732 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1733 ok(ret
, "failed to send request\n");
1735 WinHttpCloseHandle(req
);
1736 WinHttpCloseHandle(con
);
1737 WinHttpCloseHandle(ses
);
1740 static const char page1
[] =
1742 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1743 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1746 static const char okmsg
[] =
1747 "HTTP/1.1 200 OK\r\n"
1748 "Server: winetest\r\n"
1751 static const char notokmsg
[] =
1752 "HTTP/1.1 400 Bad Request\r\n"
1753 "Server: winetest\r\n"
1756 static const char noauthmsg
[] =
1757 "HTTP/1.1 401 Unauthorized\r\n"
1758 "Server: winetest\r\n"
1759 "Connection: close\r\n"
1760 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1763 static const char proxymsg
[] =
1764 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1765 "Server: winetest\r\n"
1766 "Proxy-Connection: close\r\n"
1767 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1776 static DWORD CALLBACK
server_thread(LPVOID param
)
1778 struct server_info
*si
= param
;
1781 struct sockaddr_in sa
;
1784 int last_request
= 0;
1786 WSAStartup(MAKEWORD(1,1), &wsaData
);
1788 s
= socket(AF_INET
, SOCK_STREAM
, 0);
1789 if (s
== INVALID_SOCKET
)
1793 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
1795 memset(&sa
, 0, sizeof sa
);
1796 sa
.sin_family
= AF_INET
;
1797 sa
.sin_port
= htons(si
->port
);
1798 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
1800 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
1805 SetEvent(si
->event
);
1808 c
= accept(s
, NULL
, NULL
);
1810 memset(buffer
, 0, sizeof buffer
);
1811 for(i
= 0; i
< sizeof buffer
- 1; i
++)
1813 r
= recv(c
, &buffer
[i
], 1, 0);
1816 if (i
< 4) continue;
1817 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
1818 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
1821 if (strstr(buffer
, "GET /basic"))
1823 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1824 send(c
, page1
, sizeof page1
- 1, 0);
1826 if (strstr(buffer
, "/auth"))
1828 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
1829 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1831 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
1833 if (strstr(buffer
, "/no_headers"))
1835 send(c
, page1
, sizeof page1
- 1, 0);
1837 if (strstr(buffer
, "GET /quit"))
1839 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1840 send(c
, page1
, sizeof page1
- 1, 0);
1846 } while (!last_request
);
1852 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
1854 HINTERNET ses
, con
, req
;
1856 DWORD count
, status
, size
;
1859 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1860 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1862 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1863 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1865 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
1866 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1868 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1869 ok(ret
, "failed to send request %u\n", GetLastError());
1871 ret
= WinHttpReceiveResponse(req
, NULL
);
1872 ok(ret
, "failed to receive response %u\n", GetLastError());
1874 size
= sizeof(status
);
1875 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1876 ok(ret
, "failed to query status code %u\n", GetLastError());
1877 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1880 memset(buffer
, 0, sizeof(buffer
));
1881 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
1882 ok(ret
, "failed to read data %u\n", GetLastError());
1883 ok(count
== sizeof page1
- 1, "count was wrong\n");
1884 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
1886 WinHttpCloseHandle(req
);
1887 WinHttpCloseHandle(con
);
1888 WinHttpCloseHandle(ses
);
1891 static void test_basic_authentication(int port
)
1893 static const WCHAR authW
[] = {'/','a','u','t','h',0};
1894 static const WCHAR userW
[] = {'u','s','e','r',0};
1895 static const WCHAR passW
[] = {'p','w','d',0};
1896 HINTERNET ses
, con
, req
;
1897 DWORD status
, size
, error
;
1900 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1901 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1903 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1904 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1906 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
1907 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1909 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1910 ok(ret
, "failed to send request %u\n", GetLastError());
1912 ret
= WinHttpReceiveResponse(req
, NULL
);
1913 ok(ret
, "failed to receive response %u\n", GetLastError());
1915 size
= sizeof(status
);
1916 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1917 ok(ret
, "failed to query status code %u\n", GetLastError());
1918 ok(status
== 401, "request failed unexpectedly %u\n", status
);
1920 SetLastError(0xdeadbeef);
1921 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
1922 error
= GetLastError();
1923 ok(!ret
, "expected failure\n");
1924 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
1926 SetLastError(0xdeadbeef);
1927 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
1928 error
= GetLastError();
1929 ok(!ret
, "expected failure\n");
1930 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
1932 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
1933 ok(ret
, "failed to set credentials %u\n", GetLastError());
1935 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1936 ok(ret
, "failed to send request %u\n", GetLastError());
1938 ret
= WinHttpReceiveResponse(req
, NULL
);
1939 ok(ret
, "failed to receive response %u\n", GetLastError());
1941 size
= sizeof(status
);
1942 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1943 ok(ret
, "failed to query status code %u\n", GetLastError());
1944 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1946 WinHttpCloseHandle(req
);
1947 WinHttpCloseHandle(con
);
1948 WinHttpCloseHandle(ses
);
1951 static void test_no_headers(int port
)
1953 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1954 HINTERNET ses
, con
, req
;
1957 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1958 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1960 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1961 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1963 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
1964 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1966 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1967 ok(ret
, "failed to send request %u\n", GetLastError());
1969 ret
= WinHttpReceiveResponse(req
, NULL
);
1970 ok(!ret
, "expected failure\n");
1972 WinHttpCloseHandle(req
);
1973 WinHttpCloseHandle(con
);
1974 WinHttpCloseHandle(ses
);
1977 static void test_credentials(void)
1979 static WCHAR userW
[] = {'u','s','e','r',0};
1980 static WCHAR passW
[] = {'p','a','s','s',0};
1981 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
1982 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
1983 HINTERNET ses
, con
, req
;
1988 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
1989 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1991 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
1992 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1994 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1995 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1997 size
= sizeof(buffer
)/sizeof(WCHAR
);
1998 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
1999 ok(ret
, "failed to query proxy username %u\n", GetLastError());
2000 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2001 ok(!size
, "expected 0, got %u\n", size
);
2003 size
= sizeof(buffer
)/sizeof(WCHAR
);
2004 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
2005 ok(ret
, "failed to query proxy password %u\n", GetLastError());
2006 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2007 ok(!size
, "expected 0, got %u\n", size
);
2009 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
2010 ok(ret
, "failed to set username %u\n", GetLastError());
2012 size
= sizeof(buffer
)/sizeof(WCHAR
);
2013 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
2014 ok(ret
, "failed to query proxy username %u\n", GetLastError());
2015 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2016 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2018 size
= sizeof(buffer
)/sizeof(WCHAR
);
2019 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2020 ok(ret
, "failed to query username %u\n", GetLastError());
2021 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2022 ok(!size
, "expected 0, got %u\n", size
);
2024 size
= sizeof(buffer
)/sizeof(WCHAR
);
2025 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2026 ok(ret
, "failed to query password %u\n", GetLastError());
2027 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2028 ok(!size
, "expected 0, got %u\n", size
);
2030 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
2031 ok(ret
, "failed to set proxy password %u\n", GetLastError());
2033 size
= sizeof(buffer
)/sizeof(WCHAR
);
2034 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
2035 ok(ret
, "failed to query proxy password %u\n", GetLastError());
2036 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2037 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2039 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2040 ok(ret
, "failed to set username %u\n", GetLastError());
2042 size
= sizeof(buffer
)/sizeof(WCHAR
);
2043 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2044 ok(ret
, "failed to query username %u\n", GetLastError());
2045 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2046 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2048 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2049 ok(ret
, "failed to set password %u\n", GetLastError());
2051 size
= sizeof(buffer
)/sizeof(WCHAR
);
2052 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2053 ok(ret
, "failed to query password %u\n", GetLastError());
2054 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2055 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2057 WinHttpCloseHandle(req
);
2059 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2060 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2062 SetLastError(0xdeadbeef);
2063 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2064 error
= GetLastError();
2065 ok(!ret
, "expected failure\n");
2066 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2068 SetLastError(0xdeadbeef);
2069 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2070 error
= GetLastError();
2071 ok(!ret
, "expected failure\n");
2072 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2074 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2075 ok(ret
, "failed to set credentials %u\n", GetLastError());
2077 size
= sizeof(buffer
)/sizeof(WCHAR
);
2078 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2079 ok(ret
, "failed to query username %u\n", GetLastError());
2081 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2082 ok(!size
, "expected 0, got %u\n", size
);
2085 size
= sizeof(buffer
)/sizeof(WCHAR
);
2086 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2087 ok(ret
, "failed to query password %u\n", GetLastError());
2089 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2090 ok(!size
, "expected 0, got %u\n", size
);
2093 WinHttpCloseHandle(req
);
2094 WinHttpCloseHandle(con
);
2095 WinHttpCloseHandle(ses
);
2098 START_TEST (winhttp
)
2100 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2101 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
2102 struct server_info si
;
2108 test_WinHttpTimeFromSystemTime();
2109 test_WinHttpTimeToSystemTime();
2110 test_WinHttpAddHeaders();
2111 test_secure_connection();
2112 test_request_parameter_defaults();
2114 test_set_default_proxy_config();
2115 test_empty_headers_param();
2117 test_resolve_timeout();
2120 si
.event
= CreateEvent(NULL
, 0, 0, NULL
);
2123 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
2124 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
2126 ret
= WaitForSingleObject(si
.event
, 10000);
2127 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
2128 if (ret
!= WAIT_OBJECT_0
)
2131 test_basic_request(si
.port
, NULL
, basicW
);
2132 test_no_headers(si
.port
);
2133 test_basic_authentication(si
.port
);
2135 /* send the basic request again to shutdown the server thread */
2136 test_basic_request(si
.port
, NULL
, quitW
);
2138 WaitForSingleObject(thread
, 3000);