winhttp/tests: Avoid test failures caused by connection errors.
[wine/wine-gecko.git] / dlls / winhttp / tests / winhttp.c
blob51fcc86c65b8593ec2f58044903a3ae4eead3a2b
1 /*
2 * WinHTTP - tests
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
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winsock2.h>
25 #include <ws2tcpip.h>
26 #include <winhttp.h>
27 #include <wincrypt.h>
28 #include <winreg.h>
29 #include "initguid.h"
30 #include <httprequest.h>
32 #include "wine/test.h"
34 static const WCHAR test_useragent[] =
35 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
36 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
37 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
39 static BOOL proxy_active(void)
41 WINHTTP_PROXY_INFO proxy_info;
42 BOOL active = FALSE;
44 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
46 active = (proxy_info.lpszProxy != NULL);
47 if (active)
48 GlobalFree(proxy_info.lpszProxy);
49 if (proxy_info.lpszProxyBypass != NULL)
50 GlobalFree(proxy_info.lpszProxyBypass);
52 else
53 active = FALSE;
55 return active;
58 static void test_QueryOption(void)
60 BOOL ret;
61 HINTERNET session, request, connection;
62 DWORD feature, size;
64 SetLastError(0xdeadbeef);
65 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
66 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
68 SetLastError(0xdeadbeef);
69 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
70 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
71 ok(GetLastError() == ERROR_INVALID_PARAMETER,
72 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
74 size = 0xdeadbeef;
75 SetLastError(0xdeadbeef);
76 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
77 ok(!ret, "should fail to query option\n");
78 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
79 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
80 ok(size == 4, "expected 4, got %u\n", size);
82 feature = 0xdeadbeef;
83 size = sizeof(feature) - 1;
84 SetLastError(0xdeadbeef);
85 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
86 ok(!ret, "should fail to query option\n");
87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
89 ok(size == 4, "expected 4, got %u\n", size);
91 feature = 0xdeadbeef;
92 size = sizeof(feature) + 1;
93 SetLastError(0xdeadbeef);
94 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
95 ok(ret, "failed to query option %u\n", GetLastError());
96 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
97 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
98 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
100 SetLastError(0xdeadbeef);
101 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
102 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
103 ok(GetLastError() == ERROR_INVALID_PARAMETER,
104 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
106 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
107 SetLastError(0xdeadbeef);
108 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
109 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
110 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
111 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
113 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
114 SetLastError(0xdeadbeef);
115 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
116 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
117 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
118 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
120 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
121 SetLastError(0xdeadbeef);
122 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
123 ok(ret, "failed to set redirect policy %u\n", GetLastError());
125 feature = 0xdeadbeef;
126 size = sizeof(feature);
127 SetLastError(0xdeadbeef);
128 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
129 ok(ret, "failed to query option %u\n", GetLastError());
130 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
131 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
133 feature = WINHTTP_DISABLE_COOKIES;
134 SetLastError(0xdeadbeef);
135 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
136 ok(!ret, "should fail to set disable feature for a session\n");
137 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
138 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
140 SetLastError(0xdeadbeef);
141 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
142 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
144 feature = WINHTTP_DISABLE_COOKIES;
145 SetLastError(0xdeadbeef);
146 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
147 ok(!ret, "should fail to set disable feature for a connection\n");
148 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
149 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151 SetLastError(0xdeadbeef);
152 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
153 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
154 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
156 skip("Network unreachable, skipping the test\n");
157 goto done;
160 feature = 0xdeadbeef;
161 size = sizeof(feature);
162 SetLastError(0xdeadbeef);
163 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
164 ok(!ret, "should fail to query disable feature for a request\n");
165 ok(GetLastError() == ERROR_INVALID_PARAMETER,
166 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
168 feature = 0;
169 size = sizeof(feature);
170 SetLastError(0xdeadbeef);
171 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
172 ok(ret, "failed to set feature %u\n", GetLastError());
174 feature = 0xffffffff;
175 size = sizeof(feature);
176 SetLastError(0xdeadbeef);
177 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
178 ok(ret, "failed to set feature %u\n", GetLastError());
180 feature = WINHTTP_DISABLE_COOKIES;
181 size = sizeof(feature);
182 SetLastError(0xdeadbeef);
183 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
184 ok(ret, "failed to set feature %u\n", GetLastError());
186 size = 0;
187 SetLastError(0xdeadbeef);
188 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
189 ok(!ret, "should fail to query disable feature for a request\n");
190 ok(GetLastError() == ERROR_INVALID_PARAMETER,
191 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
193 SetLastError(0xdeadbeef);
194 ret = WinHttpCloseHandle(request);
195 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
197 done:
198 SetLastError(0xdeadbeef);
199 ret = WinHttpCloseHandle(connection);
200 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
201 SetLastError(0xdeadbeef);
202 ret = WinHttpCloseHandle(session);
203 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
206 static void test_OpenRequest (void)
208 BOOL ret;
209 HINTERNET session, request, connection;
211 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
212 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
213 ok(session != NULL, "WinHttpOpen failed to open session.\n");
215 /* Test with a bad server name */
216 SetLastError(0xdeadbeef);
217 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
218 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
219 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
221 /* Test with a valid server name */
222 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
223 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
225 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
226 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
227 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
229 skip("Network unreachable, skipping.\n");
230 goto done;
232 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
234 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
235 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
237 skip("Connection failed, skipping.\n");
238 goto done;
240 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
241 ret = WinHttpCloseHandle(request);
242 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
244 done:
245 ret = WinHttpCloseHandle(connection);
246 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
247 ret = WinHttpCloseHandle(session);
248 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
252 static void test_empty_headers_param(void)
254 static const WCHAR empty[] = {0};
255 HINTERNET ses, con, req;
256 BOOL ret;
258 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
259 ok(ses != NULL, "failed to open session %u\n", GetLastError());
261 con = WinHttpConnect(ses, test_winehq, 80, 0);
262 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
264 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
265 ok(req != NULL, "failed to open a request %u\n", GetLastError());
267 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
268 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
270 skip("connection failed, skipping\n");
271 goto done;
273 ok(ret, "failed to send request %u\n", GetLastError());
275 done:
276 WinHttpCloseHandle(req);
277 WinHttpCloseHandle(con);
278 WinHttpCloseHandle(ses);
281 static void test_SendRequest (void)
283 static const WCHAR content_type[] =
284 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
285 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
286 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
287 static const WCHAR test_verb[] = {'P','O','S','T',0};
288 static CHAR post_data[] = "mode=Test";
289 static const char test_post[] = "mode => Test\0\n";
290 HINTERNET session, request, connection;
291 DWORD header_len, optional_len, total_len, bytes_rw, size;
292 DWORD_PTR context;
293 BOOL ret;
294 CHAR buffer[256];
295 int i;
297 header_len = -1L;
298 total_len = optional_len = sizeof(post_data);
299 memset(buffer, 0xff, sizeof(buffer));
301 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
302 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
303 ok(session != NULL, "WinHttpOpen failed to open session.\n");
305 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
306 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
308 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
309 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
310 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
312 skip("Network unreachable, skipping.\n");
313 goto done;
315 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
316 if (!request) goto done;
318 context = 0xdeadbeef;
319 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
320 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
322 context++;
323 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
324 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
326 skip("connection failed, skipping\n");
327 goto done;
329 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
331 context = 0;
332 size = sizeof(context);
333 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
334 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
335 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
337 for (i = 3; post_data[i]; i++)
339 bytes_rw = -1;
340 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
341 if (ret)
342 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
343 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
345 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
346 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
350 ret = WinHttpReceiveResponse(request, NULL);
351 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
353 bytes_rw = -1;
354 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
355 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
357 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw);
358 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
360 done:
361 ret = WinHttpCloseHandle(request);
362 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
363 ret = WinHttpCloseHandle(connection);
364 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
365 ret = WinHttpCloseHandle(session);
366 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
369 static void test_WinHttpTimeFromSystemTime(void)
371 BOOL ret;
372 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
373 static const WCHAR expected_string[] =
374 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
375 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
376 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
378 ret = WinHttpTimeFromSystemTime(&time, time_string);
379 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
380 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
381 "Time string returned did not match expected time string.\n");
384 static void test_WinHttpTimeToSystemTime(void)
386 BOOL ret;
387 SYSTEMTIME time;
388 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
389 static const WCHAR time_string1[] =
390 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
391 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
392 static const WCHAR time_string2[] =
393 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
394 '1','0',' ','0','5',' ','5','2','\n',0};
396 ret = WinHttpTimeToSystemTime(time_string1, &time);
397 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
398 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
399 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
401 ret = WinHttpTimeToSystemTime(time_string2, &time);
402 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
403 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
404 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
407 static void test_WinHttpAddHeaders(void)
409 HINTERNET session, request, connection;
410 BOOL ret, reverse;
411 WCHAR buffer[MAX_PATH];
412 WCHAR check_buffer[MAX_PATH];
413 DWORD index, len, oldlen;
415 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
416 static const WCHAR test_verb[] = {'P','O','S','T',0};
417 static const WCHAR test_header_begin[] =
418 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
419 static const WCHAR full_path_test_header_begin[] =
420 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0','/','p','o','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
421 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
422 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
424 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
425 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
426 static const WCHAR test_flag_coalesce_comma[] =
427 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
428 static const WCHAR test_flag_coalesce_comma_reverse[] =
429 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
430 static const WCHAR test_flag_coalesce_semicolon[] =
431 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
432 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
433 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
435 static const WCHAR field[] = {'f','i','e','l','d',0};
436 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
437 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
439 static const WCHAR test_headers[][14] =
441 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
442 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
443 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
444 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
445 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
446 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
447 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
448 {0},
449 {':',0},
450 {'a',':',0},
451 {':','b',0},
452 {'c','d',0},
453 {' ','e',' ',':','f',0},
454 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
456 static const WCHAR test_indices[][6] =
458 {'t','e','s','t','1',0},
459 {'t','e','s','t','2',0},
460 {'t','e','s','t','3',0},
461 {'t','e','s','t','4',0}
464 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
465 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
466 ok(session != NULL, "WinHttpOpen failed to open session.\n");
468 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
469 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
471 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
472 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
473 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
475 skip("Network unreachable, skipping.\n");
476 goto done;
478 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
480 index = 0;
481 len = sizeof(buffer);
482 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
483 test_header_name, buffer, &len, &index);
484 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
485 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
486 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
488 index = 0;
489 len = sizeof(buffer);
490 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
491 test_header_name, buffer, &len, &index);
492 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
493 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
494 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
495 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
497 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
498 test_header_name, buffer, &len, &index);
499 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
501 /* Try to fetch the header info with a buffer that's big enough to fit the
502 * string but not the NULL terminator.
504 index = 0;
505 len = 5*sizeof(WCHAR);
506 memset(check_buffer, 0xab, sizeof(check_buffer));
507 memcpy(buffer, check_buffer, sizeof(buffer));
508 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
509 test_header_name, buffer, &len, &index);
510 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
511 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
512 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
513 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
515 /* Try with a NULL buffer */
516 index = 0;
517 len = sizeof(buffer);
518 SetLastError(0xdeadbeef);
519 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
520 test_header_name, NULL, &len, &index);
521 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
522 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
523 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
524 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
526 /* Try with a NULL buffer and a length that's too small */
527 index = 0;
528 len = 10;
529 SetLastError(0xdeadbeef);
530 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
531 test_header_name, NULL, &len, &index);
532 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
533 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
534 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
535 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
536 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
538 index = 0;
539 len = 0;
540 SetLastError(0xdeadbeef);
541 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
542 test_header_name, NULL, &len, &index);
543 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
544 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
545 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
546 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
547 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
549 /* valid query */
550 oldlen = len;
551 index = 0;
552 len = sizeof(buffer);
553 memset(buffer, 0xff, sizeof(buffer));
554 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
555 test_header_name, buffer, &len, &index);
556 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
557 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
558 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
559 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
560 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
561 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
562 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
563 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
564 "WinHttpQueryHeaders returned invalid end of header string.\n");
565 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
567 index = 0;
568 len = 0;
569 SetLastError(0xdeadbeef);
570 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
571 test_header_name, NULL, &len, &index);
572 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
573 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
574 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
575 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
576 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
578 oldlen = len;
579 index = 0;
580 len = sizeof(buffer);
581 memset(buffer, 0xff, sizeof(buffer));
582 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
583 test_header_name, buffer, &len, &index);
584 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
585 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
586 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
587 "no double NULL terminator\n");
588 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
589 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
590 "invalid beginning of header string.\n");
591 ok(index == 0, "header index was incremented\n");
593 /* tests for more indices */
594 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
595 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
597 index = 0;
598 len = sizeof(buffer);
599 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
600 test_header_name, buffer, &len, &index);
601 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
602 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
603 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
605 len = sizeof(buffer);
606 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
607 test_header_name, buffer, &len, &index);
608 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
609 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
610 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
612 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
613 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
615 index = 0;
616 len = sizeof(buffer);
617 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
618 test_header_name, buffer, &len, &index);
619 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
620 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
621 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
622 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
624 len = sizeof(buffer);
625 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
626 test_header_name, buffer, &len, &index);
627 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
628 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
629 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
631 /* add if new flag */
632 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
633 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
635 index = 0;
636 len = sizeof(buffer);
637 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
638 test_header_name, buffer, &len, &index);
639 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
640 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
641 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
643 len = sizeof(buffer);
644 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
645 test_header_name, buffer, &len, &index);
646 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
647 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
648 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
650 len = sizeof(buffer);
651 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
652 test_header_name, buffer, &len, &index);
653 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
655 /* coalesce flag */
656 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
657 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
659 index = 0;
660 len = sizeof(buffer);
661 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
662 test_header_name, buffer, &len, &index);
663 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
664 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
665 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
666 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
672 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
673 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
675 len = sizeof(buffer);
676 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
677 test_header_name, buffer, &len, &index);
678 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
680 /* coalesce with comma flag */
681 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
682 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
684 index = 0;
685 len = sizeof(buffer);
686 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
687 test_header_name, buffer, &len, &index);
688 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
689 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
690 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
691 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
692 "WinHttpQueryHeaders returned incorrect string.\n");
694 len = sizeof(buffer);
695 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
696 test_header_name, buffer, &len, &index);
697 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
698 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
699 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
701 len = sizeof(buffer);
702 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
703 test_header_name, buffer, &len, &index);
704 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
707 /* coalesce with semicolon flag */
708 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
709 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
711 index = 0;
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 == 1, "WinHttpQueryHeaders failed to increment index.\n");
717 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
718 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
719 "WinHttpQueryHeaders returned incorrect string.\n");
721 len = sizeof(buffer);
722 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
723 test_header_name, buffer, &len, &index);
724 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
725 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
726 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
728 len = sizeof(buffer);
729 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
730 test_header_name, buffer, &len, &index);
731 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
733 /* add and replace flags */
734 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
735 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
737 index = 0;
738 len = sizeof(buffer);
739 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
740 test_header_name, buffer, &len, &index);
741 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
742 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
743 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
745 len = sizeof(buffer);
746 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
747 test_header_name, buffer, &len, &index);
748 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
749 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
750 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
752 len = sizeof(buffer);
753 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
754 test_header_name, buffer, &len, &index);
755 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
757 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
758 ok(!ret, "WinHttpAddRequestHeaders failed\n");
760 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
761 ok(ret, "WinHttpAddRequestHeaders failed\n");
763 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
764 ok(!ret, "WinHttpAddRequestHeaders failed\n");
766 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
767 ok(!ret, "WinHttpAddRequestHeaders failed\n");
769 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
770 ok(!ret, "WinHttpAddRequestHeaders failed\n");
772 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
773 ok(ret, "WinHttpAddRequestHeaders failed\n");
775 index = 0;
776 buffer[0] = 0;
777 len = sizeof(buffer);
778 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
779 field, buffer, &len, &index);
780 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
781 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
783 ret = WinHttpCloseHandle(request);
784 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
785 done:
786 ret = WinHttpCloseHandle(connection);
787 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
788 ret = WinHttpCloseHandle(session);
789 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
793 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len)
795 DWORD flags = *(DWORD *)buf;
797 if (!flags)
799 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
800 return;
802 #define X(x) if (flags & x) trace("%s\n", #x);
803 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
804 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
805 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
806 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
807 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
808 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
809 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
810 #undef X
813 static void test_secure_connection(void)
815 HINTERNET ses, con, req;
816 DWORD size, status, policy, bitness, read_size;
817 BOOL ret;
818 CERT_CONTEXT *cert;
819 WINHTTP_CERTIFICATE_INFO info;
820 char buffer[32];
822 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
823 ok(ses != NULL, "failed to open session %u\n", GetLastError());
825 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
826 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
827 ok(ret, "failed to set redirect policy %u\n", GetLastError());
829 con = WinHttpConnect(ses, test_winehq, 443, 0);
830 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
832 /* try without setting WINHTTP_FLAG_SECURE */
833 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
834 ok(req != NULL, "failed to open a request %u\n", GetLastError());
836 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
837 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
839 skip("Connection failed, skipping.\n");
840 goto cleanup;
842 ok(ret, "failed to send request %u\n", GetLastError());
844 ret = WinHttpReceiveResponse(req, NULL);
845 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
847 size = 0;
848 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
849 ok(!ret, "succeeded unexpectedly\n");
851 WinHttpCloseHandle(req);
853 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
854 ok(req != NULL, "failed to open a request %u\n", GetLastError());
856 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
858 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
859 if (!ret && (GetLastError() == ERROR_WINHTTP_SECURE_FAILURE || GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT))
861 skip("secure connection failed, skipping remaining secure tests\n");
862 goto cleanup;
864 ok(ret, "failed to send request %u\n", GetLastError());
866 size = sizeof(cert);
867 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
868 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
869 if (ret) CertFreeCertificateContext(cert);
871 size = sizeof(bitness);
872 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
873 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
875 size = sizeof(info);
876 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
877 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
879 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
880 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
881 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
882 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
883 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
884 trace("dwKeySize %u\n", info.dwKeySize);
886 ret = WinHttpReceiveResponse(req, NULL);
887 ok(ret, "failed to receive response %u\n", GetLastError());
889 size = sizeof(status);
890 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
891 ok(ret, "failed unexpectedly %u\n", GetLastError());
892 ok(status == 200, "request failed unexpectedly %u\n", status);
894 size = 0;
895 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
896 ok(!ret, "succeeded unexpectedly\n");
898 read_size = 0;
899 for (;;)
901 size = 0;
902 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
903 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
904 if (!size) break;
905 read_size += size;
907 ok(read_size > 2014, "read_size = %u\n", read_size);
909 cleanup:
910 WinHttpCloseHandle(req);
911 WinHttpCloseHandle(con);
912 WinHttpCloseHandle(ses);
915 static void test_request_parameter_defaults(void)
917 static const WCHAR empty[] = {0};
918 HINTERNET ses, con, req;
919 DWORD size, status, error;
920 WCHAR *version;
921 BOOL ret;
923 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
924 ok(ses != NULL, "failed to open session %u\n", GetLastError());
926 con = WinHttpConnect(ses, test_winehq, 0, 0);
927 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
929 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
930 ok(req != NULL, "failed to open a request %u\n", GetLastError());
932 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
933 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
935 skip("connection failed, skipping\n");
936 goto done;
938 ok(ret, "failed to send request %u\n", GetLastError());
940 ret = WinHttpReceiveResponse(req, NULL);
941 ok(ret, "failed to receive response %u\n", GetLastError());
943 size = sizeof(status);
944 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
945 ok(ret, "failed unexpectedly %u\n", GetLastError());
946 ok(status == 200, "request failed unexpectedly %u\n", status);
948 WinHttpCloseHandle(req);
950 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
951 ok(req != NULL, "failed to open a request %u\n", GetLastError());
953 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
954 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
956 skip("connection failed, skipping\n");
957 goto done;
959 ok(ret, "failed to send request %u\n", GetLastError());
961 ret = WinHttpReceiveResponse(req, NULL);
962 ok(ret, "failed to receive response %u\n", GetLastError());
964 size = 0;
965 SetLastError(0xdeadbeef);
966 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
967 error = GetLastError();
968 ok(!ret, "succeeded unexpectedly\n");
969 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
971 version = HeapAlloc(GetProcessHeap(), 0, size);
972 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
973 ok(ret, "failed unexpectedly %u\n", GetLastError());
974 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
975 HeapFree(GetProcessHeap(), 0, version);
977 size = sizeof(status);
978 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
979 ok(ret, "failed unexpectedly %u\n", GetLastError());
980 ok(status == 200, "request failed unexpectedly %u\n", status);
982 done:
983 WinHttpCloseHandle(req);
984 WinHttpCloseHandle(con);
985 WinHttpCloseHandle(ses);
988 static const WCHAR Connections[] = {
989 'S','o','f','t','w','a','r','e','\\',
990 'M','i','c','r','o','s','o','f','t','\\',
991 'W','i','n','d','o','w','s','\\',
992 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
993 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
994 'C','o','n','n','e','c','t','i','o','n','s',0 };
995 static const WCHAR WinHttpSettings[] = {
996 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
998 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
1000 LONG l;
1001 HKEY key;
1002 DWORD ret = 0;
1004 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
1005 if (!l)
1007 DWORD size = 0;
1009 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
1010 if (!l)
1012 if (size <= len)
1013 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1014 &size );
1015 if (!l)
1016 ret = size;
1018 RegCloseKey( key );
1020 return ret;
1023 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1025 LONG l;
1026 HKEY key;
1028 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
1029 KEY_WRITE, NULL, &key, NULL );
1030 if (!l)
1032 if (len)
1033 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1034 else
1035 RegDeleteValueW( key, WinHttpSettings );
1036 RegCloseKey( key );
1040 static void test_set_default_proxy_config(void)
1042 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1043 static WCHAR normalString[] = { 'f','o','o',0 };
1044 DWORD type, len;
1045 BYTE *saved_proxy_settings = NULL;
1046 WINHTTP_PROXY_INFO info;
1047 BOOL ret;
1049 /* FIXME: it would be simpler to read the current settings using
1050 * WinHttpGetDefaultProxyConfiguration and save them using
1051 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1053 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1054 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1055 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1056 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1057 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1058 * the lpszProxy and lpszProxyBypass values are ignored.
1059 * Thus, if a proxy is set with proxycfg, then calling
1060 * WinHttpGetDefaultProxyConfiguration followed by
1061 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1062 * getting deleted from the registry.
1064 * Instead I read the current registry value and restore it directly.
1066 len = get_default_proxy_reg_value( NULL, 0, &type );
1067 if (len)
1069 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1070 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1073 if (0)
1075 /* Crashes on Vista and higher */
1076 SetLastError(0xdeadbeef);
1077 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1078 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1079 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1082 /* test with invalid access type */
1083 info.dwAccessType = 0xdeadbeef;
1084 info.lpszProxy = info.lpszProxyBypass = NULL;
1085 SetLastError(0xdeadbeef);
1086 ret = WinHttpSetDefaultProxyConfiguration(&info);
1087 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1088 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1090 /* at a minimum, the proxy server must be set */
1091 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1092 info.lpszProxy = info.lpszProxyBypass = NULL;
1093 SetLastError(0xdeadbeef);
1094 ret = WinHttpSetDefaultProxyConfiguration(&info);
1095 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1096 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1097 info.lpszProxyBypass = normalString;
1098 SetLastError(0xdeadbeef);
1099 ret = WinHttpSetDefaultProxyConfiguration(&info);
1100 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1101 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1103 /* the proxy server can't have wide characters */
1104 info.lpszProxy = wideString;
1105 SetLastError(0xdeadbeef);
1106 ret = WinHttpSetDefaultProxyConfiguration(&info);
1107 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1108 skip("couldn't set default proxy configuration: access denied\n");
1109 else
1110 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1111 broken(ret), /* Earlier winhttp versions on W2K/XP */
1112 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1114 info.lpszProxy = normalString;
1115 SetLastError(0xdeadbeef);
1116 ret = WinHttpSetDefaultProxyConfiguration(&info);
1117 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1118 skip("couldn't set default proxy configuration: access denied\n");
1119 else
1120 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1121 GetLastError());
1123 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1126 static void test_Timeouts (void)
1128 BOOL ret;
1129 DWORD value, size;
1130 HINTERNET ses, req, con;
1132 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1133 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1135 SetLastError(0xdeadbeef);
1136 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1137 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1138 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1140 SetLastError(0xdeadbeef);
1141 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1142 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1143 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1145 SetLastError(0xdeadbeef);
1146 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1147 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1148 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1150 SetLastError(0xdeadbeef);
1151 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1152 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1153 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1155 SetLastError(0xdeadbeef);
1156 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1157 ok(ret, "%u\n", GetLastError());
1159 SetLastError(0xdeadbeef);
1160 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1161 ok(ret, "%u\n", GetLastError());
1163 SetLastError(0xdeadbeef);
1164 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1165 ok(ret, "%u\n", GetLastError());
1167 SetLastError(0xdeadbeef);
1168 value = 0xdeadbeef;
1169 size = sizeof(DWORD);
1170 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1171 ok(ret, "%u\n", GetLastError());
1172 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1174 SetLastError(0xdeadbeef);
1175 value = 0xdeadbeef;
1176 size = sizeof(DWORD);
1177 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1178 ok(ret, "%u\n", GetLastError());
1179 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1181 SetLastError(0xdeadbeef);
1182 value = 0xdeadbeef;
1183 size = sizeof(DWORD);
1184 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1185 ok(ret, "%u\n", GetLastError());
1186 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1188 SetLastError(0xdeadbeef);
1189 value = 0xdeadbeef;
1190 size = sizeof(DWORD);
1191 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1192 ok(ret, "%u\n", GetLastError());
1193 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1195 SetLastError(0xdeadbeef);
1196 value = 0;
1197 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1198 ok(ret, "%u\n", GetLastError());
1200 SetLastError(0xdeadbeef);
1201 value = 0xdeadbeef;
1202 size = sizeof(DWORD);
1203 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1204 ok(ret, "%u\n", GetLastError());
1205 ok(value == 0, "Expected 0, got %u\n", value);
1207 SetLastError(0xdeadbeef);
1208 value = 0;
1209 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1210 ok(ret, "%u\n", GetLastError());
1212 SetLastError(0xdeadbeef);
1213 value = 0xdeadbeef;
1214 size = sizeof(DWORD);
1215 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1216 ok(ret, "%u\n", GetLastError());
1217 ok(value == 0, "Expected 0, got %u\n", value);
1219 SetLastError(0xdeadbeef);
1220 value = 0;
1221 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1222 ok(ret, "%u\n", GetLastError());
1224 SetLastError(0xdeadbeef);
1225 value = 0xdeadbeef;
1226 size = sizeof(DWORD);
1227 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1228 ok(ret, "%u\n", GetLastError());
1229 ok(value == 0, "Expected 0, got %u\n", value);
1231 SetLastError(0xdeadbeef);
1232 value = 0;
1233 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1234 ok(ret, "%u\n", GetLastError());
1236 SetLastError(0xdeadbeef);
1237 value = 0xdeadbeef;
1238 size = sizeof(DWORD);
1239 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1240 ok(ret, "%u\n", GetLastError());
1241 ok(value == 0, "Expected 0, got %u\n", value);
1243 SetLastError(0xdeadbeef);
1244 value = 0xbeefdead;
1245 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1246 ok(ret, "%u\n", GetLastError());
1248 SetLastError(0xdeadbeef);
1249 value = 0xdeadbeef;
1250 size = sizeof(DWORD);
1251 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1252 ok(ret, "%u\n", GetLastError());
1253 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1255 SetLastError(0xdeadbeef);
1256 value = 0xbeefdead;
1257 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1258 ok(ret, "%u\n", GetLastError());
1260 SetLastError(0xdeadbeef);
1261 value = 0xdeadbeef;
1262 size = sizeof(DWORD);
1263 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1264 ok(ret, "%u\n", GetLastError());
1265 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1267 SetLastError(0xdeadbeef);
1268 value = 0xbeefdead;
1269 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1270 ok(ret, "%u\n", GetLastError());
1272 SetLastError(0xdeadbeef);
1273 value = 0xdeadbeef;
1274 size = sizeof(DWORD);
1275 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1276 ok(ret, "%u\n", GetLastError());
1277 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1279 SetLastError(0xdeadbeef);
1280 value = 0xbeefdead;
1281 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1282 ok(ret, "%u\n", GetLastError());
1284 SetLastError(0xdeadbeef);
1285 value = 0xdeadbeef;
1286 size = sizeof(DWORD);
1287 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1288 ok(ret, "%u\n", GetLastError());
1289 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1291 con = WinHttpConnect(ses, test_winehq, 0, 0);
1292 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1294 /* Timeout values should match the last one set for session */
1295 SetLastError(0xdeadbeef);
1296 value = 0xdeadbeef;
1297 size = sizeof(DWORD);
1298 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1299 ok(ret, "%u\n", GetLastError());
1300 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1302 SetLastError(0xdeadbeef);
1303 value = 0xdeadbeef;
1304 size = sizeof(DWORD);
1305 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1306 ok(ret, "%u\n", GetLastError());
1307 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1309 SetLastError(0xdeadbeef);
1310 value = 0xdeadbeef;
1311 size = sizeof(DWORD);
1312 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1313 ok(ret, "%u\n", GetLastError());
1314 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1316 SetLastError(0xdeadbeef);
1317 value = 0xdeadbeef;
1318 size = sizeof(DWORD);
1319 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1320 ok(ret, "%u\n", GetLastError());
1321 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1323 SetLastError(0xdeadbeef);
1324 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1325 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1326 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1328 SetLastError(0xdeadbeef);
1329 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1330 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1331 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1333 SetLastError(0xdeadbeef);
1334 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1335 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1336 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1338 SetLastError(0xdeadbeef);
1339 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1340 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1341 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1343 SetLastError(0xdeadbeef);
1344 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1345 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1346 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1348 SetLastError(0xdeadbeef);
1349 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1350 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1351 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1353 SetLastError(0xdeadbeef);
1354 value = 0;
1355 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1356 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1357 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1359 SetLastError(0xdeadbeef);
1360 value = 0;
1361 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1362 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1363 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1365 SetLastError(0xdeadbeef);
1366 value = 0;
1367 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1368 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1369 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1371 SetLastError(0xdeadbeef);
1372 value = 0;
1373 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1374 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1375 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1377 /* Changing timeout values for session should affect the values for connection */
1378 SetLastError(0xdeadbeef);
1379 value = 0xdead;
1380 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1381 ok(ret, "%u\n", GetLastError());
1383 SetLastError(0xdeadbeef);
1384 value = 0xdeadbeef;
1385 size = sizeof(DWORD);
1386 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1387 ok(ret, "%u\n", GetLastError());
1388 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1390 SetLastError(0xdeadbeef);
1391 value = 0xdead;
1392 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1393 ok(ret, "%u\n", GetLastError());
1395 SetLastError(0xdeadbeef);
1396 value = 0xdeadbeef;
1397 size = sizeof(DWORD);
1398 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1399 ok(ret, "%u\n", GetLastError());
1400 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1402 SetLastError(0xdeadbeef);
1403 value = 0xdead;
1404 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1405 ok(ret, "%u\n", GetLastError());
1407 SetLastError(0xdeadbeef);
1408 value = 0xdeadbeef;
1409 size = sizeof(DWORD);
1410 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1411 ok(ret, "%u\n", GetLastError());
1412 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1414 SetLastError(0xdeadbeef);
1415 value = 0xdead;
1416 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1417 ok(ret, "%u\n", GetLastError());
1419 SetLastError(0xdeadbeef);
1420 value = 0xdeadbeef;
1421 size = sizeof(DWORD);
1422 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1423 ok(ret, "%u\n", GetLastError());
1424 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1426 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1427 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1429 /* Timeout values should match the last one set for session */
1430 SetLastError(0xdeadbeef);
1431 value = 0xdeadbeef;
1432 size = sizeof(DWORD);
1433 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1434 ok(ret, "%u\n", GetLastError());
1435 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1437 SetLastError(0xdeadbeef);
1438 value = 0xdeadbeef;
1439 size = sizeof(DWORD);
1440 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1441 ok(ret, "%u\n", GetLastError());
1442 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1444 SetLastError(0xdeadbeef);
1445 value = 0xdeadbeef;
1446 size = sizeof(DWORD);
1447 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1448 ok(ret, "%u\n", GetLastError());
1449 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1451 SetLastError(0xdeadbeef);
1452 value = 0xdeadbeef;
1453 size = sizeof(DWORD);
1454 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1455 ok(ret, "%u\n", GetLastError());
1456 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1458 SetLastError(0xdeadbeef);
1459 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1460 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1461 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1463 SetLastError(0xdeadbeef);
1464 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1465 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1466 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1468 SetLastError(0xdeadbeef);
1469 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1470 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1471 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1473 SetLastError(0xdeadbeef);
1474 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1475 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1476 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1478 SetLastError(0xdeadbeef);
1479 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1480 ok(ret, "%u\n", GetLastError());
1482 SetLastError(0xdeadbeef);
1483 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1484 ok(ret, "%u\n", GetLastError());
1486 SetLastError(0xdeadbeef);
1487 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1488 ok(ret, "%u\n", GetLastError());
1490 SetLastError(0xdeadbeef);
1491 value = 0xdeadbeef;
1492 size = sizeof(DWORD);
1493 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1494 ok(ret, "%u\n", GetLastError());
1495 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1497 SetLastError(0xdeadbeef);
1498 value = 0xdeadbeef;
1499 size = sizeof(DWORD);
1500 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1501 ok(ret, "%u\n", GetLastError());
1502 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1504 SetLastError(0xdeadbeef);
1505 value = 0xdeadbeef;
1506 size = sizeof(DWORD);
1507 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1508 ok(ret, "%u\n", GetLastError());
1509 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1511 SetLastError(0xdeadbeef);
1512 value = 0xdeadbeef;
1513 size = sizeof(DWORD);
1514 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1515 ok(ret, "%u\n", GetLastError());
1516 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1518 SetLastError(0xdeadbeef);
1519 value = 0;
1520 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1521 ok(ret, "%u\n", GetLastError());
1523 SetLastError(0xdeadbeef);
1524 value = 0xdeadbeef;
1525 size = sizeof(DWORD);
1526 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1527 ok(ret, "%u\n", GetLastError());
1528 ok(value == 0, "Expected 0, got %u\n", value);
1530 SetLastError(0xdeadbeef);
1531 value = 0;
1532 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1533 ok(ret, "%u\n", GetLastError());
1535 SetLastError(0xdeadbeef);
1536 value = 0xdeadbeef;
1537 size = sizeof(DWORD);
1538 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1539 ok(ret, "%u\n", GetLastError());
1540 ok(value == 0, "Expected 0, got %u\n", value);
1542 SetLastError(0xdeadbeef);
1543 value = 0;
1544 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1545 ok(ret, "%u\n", GetLastError());
1547 SetLastError(0xdeadbeef);
1548 value = 0xdeadbeef;
1549 size = sizeof(DWORD);
1550 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1551 ok(ret, "%u\n", GetLastError());
1552 ok(value == 0, "Expected 0, got %u\n", value);
1554 SetLastError(0xdeadbeef);
1555 value = 0;
1556 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1557 ok(ret, "%u\n", GetLastError());
1559 SetLastError(0xdeadbeef);
1560 value = 0xdeadbeef;
1561 size = sizeof(DWORD);
1562 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1563 ok(ret, "%u\n", GetLastError());
1564 ok(value == 0, "Expected 0, got %u\n", value);
1566 SetLastError(0xdeadbeef);
1567 value = 0xbeefdead;
1568 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1569 ok(ret, "%u\n", GetLastError());
1571 SetLastError(0xdeadbeef);
1572 value = 0xdeadbeef;
1573 size = sizeof(DWORD);
1574 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1575 ok(ret, "%u\n", GetLastError());
1576 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1578 SetLastError(0xdeadbeef);
1579 value = 0xbeefdead;
1580 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1581 ok(ret, "%u\n", GetLastError());
1583 SetLastError(0xdeadbeef);
1584 value = 0xdeadbeef;
1585 size = sizeof(DWORD);
1586 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1587 ok(ret, "%u\n", GetLastError());
1588 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1590 SetLastError(0xdeadbeef);
1591 value = 0xbeefdead;
1592 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1593 ok(ret, "%u\n", GetLastError());
1595 SetLastError(0xdeadbeef);
1596 value = 0xdeadbeef;
1597 size = sizeof(DWORD);
1598 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1599 ok(ret, "%u\n", GetLastError());
1600 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1602 SetLastError(0xdeadbeef);
1603 value = 0xbeefdead;
1604 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1605 ok(ret, "%u\n", GetLastError());
1607 SetLastError(0xdeadbeef);
1608 value = 0xdeadbeef;
1609 size = sizeof(DWORD);
1610 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1611 ok(ret, "%u\n", GetLastError());
1612 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1614 /* Changing timeout values for session should not affect the values for a request,
1615 * neither should the other way around.
1617 SetLastError(0xdeadbeef);
1618 value = 0xbeefdead;
1619 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1620 ok(ret, "%u\n", GetLastError());
1622 SetLastError(0xdeadbeef);
1623 value = 0xdeadbeef;
1624 size = sizeof(DWORD);
1625 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1626 ok(ret, "%u\n", GetLastError());
1627 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1629 SetLastError(0xdeadbeef);
1630 value = 0xbeefdead;
1631 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1632 ok(ret, "%u\n", GetLastError());
1634 SetLastError(0xdeadbeef);
1635 value = 0xdeadbeef;
1636 size = sizeof(DWORD);
1637 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1638 ok(ret, "%u\n", GetLastError());
1639 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1641 SetLastError(0xdeadbeef);
1642 value = 0xbeefdead;
1643 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1644 ok(ret, "%u\n", GetLastError());
1646 SetLastError(0xdeadbeef);
1647 value = 0xdeadbeef;
1648 size = sizeof(DWORD);
1649 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1650 ok(ret, "%u\n", GetLastError());
1651 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1653 SetLastError(0xdeadbeef);
1654 value = 0xbeefdead;
1655 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1656 ok(ret, "%u\n", GetLastError());
1658 SetLastError(0xdeadbeef);
1659 value = 0xdeadbeef;
1660 size = sizeof(DWORD);
1661 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1662 ok(ret, "%u\n", GetLastError());
1663 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1665 SetLastError(0xdeadbeef);
1666 value = 0xbeef;
1667 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1668 ok(ret, "%u\n", GetLastError());
1670 SetLastError(0xdeadbeef);
1671 value = 0xdeadbeef;
1672 size = sizeof(DWORD);
1673 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1674 ok(ret, "%u\n", GetLastError());
1675 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1677 SetLastError(0xdeadbeef);
1678 value = 0xbeef;
1679 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1680 ok(ret, "%u\n", GetLastError());
1682 SetLastError(0xdeadbeef);
1683 value = 0xdeadbeef;
1684 size = sizeof(DWORD);
1685 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1686 ok(ret, "%u\n", GetLastError());
1687 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1689 SetLastError(0xdeadbeef);
1690 value = 0xbeef;
1691 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1692 ok(ret, "%u\n", GetLastError());
1694 SetLastError(0xdeadbeef);
1695 value = 0xdeadbeef;
1696 size = sizeof(DWORD);
1697 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1698 ok(ret, "%u\n", GetLastError());
1699 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1701 SetLastError(0xdeadbeef);
1702 value = 0xbeef;
1703 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1704 ok(ret, "%u\n", GetLastError());
1706 SetLastError(0xdeadbeef);
1707 value = 0xdeadbeef;
1708 size = sizeof(DWORD);
1709 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1710 ok(ret, "%u\n", GetLastError());
1711 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1713 WinHttpCloseHandle(req);
1714 WinHttpCloseHandle(con);
1715 WinHttpCloseHandle(ses);
1718 static void test_resolve_timeout(void)
1720 static const WCHAR nxdomain[] =
1721 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1722 HINTERNET ses, con, req;
1723 DWORD timeout;
1724 BOOL ret;
1726 if (! proxy_active())
1728 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1729 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1731 timeout = 10000;
1732 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1733 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1735 con = WinHttpConnect(ses, nxdomain, 0, 0);
1736 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1738 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1739 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1741 SetLastError(0xdeadbeef);
1742 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1743 if (ret)
1745 skip("nxdomain returned success. Broken ISP redirects?\n");
1746 goto done;
1748 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1749 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1751 WinHttpCloseHandle(req);
1752 WinHttpCloseHandle(con);
1753 WinHttpCloseHandle(ses);
1755 else
1756 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1758 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1759 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1761 timeout = 10000;
1762 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1763 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1765 con = WinHttpConnect(ses, test_winehq, 0, 0);
1766 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1768 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1769 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1771 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1772 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
1774 skip("connection failed, skipping\n");
1775 goto done;
1777 ok(ret, "failed to send request\n");
1779 done:
1780 WinHttpCloseHandle(req);
1781 WinHttpCloseHandle(con);
1782 WinHttpCloseHandle(ses);
1785 static const char page1[] =
1786 "<HTML>\r\n"
1787 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1788 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1789 "</HTML>\r\n\r\n";
1791 static const char okmsg[] =
1792 "HTTP/1.1 200 OK\r\n"
1793 "Server: winetest\r\n"
1794 "\r\n";
1796 static const char nocontentmsg[] =
1797 "HTTP/1.1 204 No Content\r\n"
1798 "Server: winetest\r\n"
1799 "\r\n";
1801 static const char noauthmsg[] =
1802 "HTTP/1.1 401 Unauthorized\r\n"
1803 "Server: winetest\r\n"
1804 "Connection: close\r\n"
1805 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1806 "\r\n";
1808 struct server_info
1810 HANDLE event;
1811 int port;
1814 #define BIG_BUFFER_LEN 0x2250
1816 static DWORD CALLBACK server_thread(LPVOID param)
1818 struct server_info *si = param;
1819 int r, c, i, on;
1820 SOCKET s;
1821 struct sockaddr_in sa;
1822 char buffer[0x100];
1823 WSADATA wsaData;
1824 int last_request = 0;
1826 WSAStartup(MAKEWORD(1,1), &wsaData);
1828 s = socket(AF_INET, SOCK_STREAM, 0);
1829 if (s == INVALID_SOCKET)
1830 return 1;
1832 on = 1;
1833 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1835 memset(&sa, 0, sizeof sa);
1836 sa.sin_family = AF_INET;
1837 sa.sin_port = htons(si->port);
1838 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1840 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1841 if (r < 0)
1842 return 1;
1844 listen(s, 0);
1845 SetEvent(si->event);
1848 c = accept(s, NULL, NULL);
1850 memset(buffer, 0, sizeof buffer);
1851 for(i = 0; i < sizeof buffer - 1; i++)
1853 r = recv(c, &buffer[i], 1, 0);
1854 if (r != 1)
1855 break;
1856 if (i < 4) continue;
1857 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1858 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1859 break;
1861 if (strstr(buffer, "GET /basic"))
1863 send(c, okmsg, sizeof okmsg - 1, 0);
1864 send(c, page1, sizeof page1 - 1, 0);
1866 if (strstr(buffer, "/auth"))
1868 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1869 send(c, okmsg, sizeof okmsg - 1, 0);
1870 else
1871 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1873 if (strstr(buffer, "/big"))
1875 char msg[BIG_BUFFER_LEN];
1876 memset(msg, 'm', sizeof(msg));
1877 send(c, okmsg, sizeof(okmsg) - 1, 0);
1878 send(c, msg, sizeof(msg), 0);
1880 if (strstr(buffer, "/no_headers"))
1882 send(c, page1, sizeof page1 - 1, 0);
1884 if (strstr(buffer, "GET /no_content"))
1886 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
1888 if (strstr(buffer, "GET /quit"))
1890 send(c, okmsg, sizeof okmsg - 1, 0);
1891 send(c, page1, sizeof page1 - 1, 0);
1892 last_request = 1;
1894 shutdown(c, 2);
1895 closesocket(c);
1897 } while (!last_request);
1899 closesocket(s);
1900 return 0;
1903 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1905 HINTERNET ses, con, req;
1906 char buffer[0x100];
1907 DWORD count, status, size, error, supported, first, target;
1908 BOOL ret;
1910 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1911 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1913 con = WinHttpConnect(ses, localhostW, port, 0);
1914 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1916 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1917 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1919 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1920 ok(ret, "failed to send request %u\n", GetLastError());
1922 ret = WinHttpReceiveResponse(req, NULL);
1923 ok(ret, "failed to receive response %u\n", GetLastError());
1925 size = sizeof(status);
1926 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1927 ok(ret, "failed to query status code %u\n", GetLastError());
1928 ok(status == 200, "request failed unexpectedly %u\n", status);
1930 supported = first = target = 0xdeadbeef;
1931 SetLastError(0xdeadbeef);
1932 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
1933 error = GetLastError();
1934 ok(!ret, "unexpected success\n");
1935 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
1936 ok(supported == 0xdeadbeef, "got %x\n", supported);
1937 ok(first == 0xdeadbeef, "got %x\n", first);
1938 ok(target == 0xdeadbeef, "got %x\n", target);
1940 count = 0;
1941 memset(buffer, 0, sizeof(buffer));
1942 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1943 ok(ret, "failed to read data %u\n", GetLastError());
1944 ok(count == sizeof page1 - 1, "count was wrong\n");
1945 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1947 WinHttpCloseHandle(req);
1948 WinHttpCloseHandle(con);
1949 WinHttpCloseHandle(ses);
1952 static void test_basic_authentication(int port)
1954 static const WCHAR authW[] = {'/','a','u','t','h',0};
1955 static const WCHAR userW[] = {'u','s','e','r',0};
1956 static const WCHAR passW[] = {'p','w','d',0};
1957 HINTERNET ses, con, req;
1958 DWORD status, size, error, supported, first, target;
1959 BOOL ret;
1961 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1962 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1964 con = WinHttpConnect(ses, localhostW, port, 0);
1965 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1967 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1968 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1970 SetLastError(0xdeadbeef);
1971 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
1972 error = GetLastError();
1973 ok(!ret, "expected failure\n");
1974 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
1976 SetLastError(0xdeadbeef);
1977 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
1978 error = GetLastError();
1979 ok(!ret, "expected failure\n");
1980 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
1982 supported = 0xdeadbeef;
1983 SetLastError(0xdeadbeef);
1984 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
1985 error = GetLastError();
1986 ok(!ret, "expected failure\n");
1987 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
1988 ok(supported == 0xdeadbeef, "got %x\n", supported);
1990 supported = first = 0xdeadbeef;
1991 SetLastError(0xdeadbeef);
1992 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
1993 error = GetLastError();
1994 ok(!ret, "expected failure\n");
1995 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
1996 ok(supported == 0xdeadbeef, "got %x\n", supported);
1997 ok(first == 0xdeadbeef, "got %x\n", first);
1999 supported = first = target = 0xdeadbeef;
2000 SetLastError(0xdeadbeef);
2001 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2002 error = GetLastError();
2003 ok(!ret, "expected failure\n");
2004 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2005 ok(supported == 0xdeadbeef, "got %x\n", supported);
2006 ok(first == 0xdeadbeef, "got %x\n", first);
2007 ok(target == 0xdeadbeef, "got %x\n", target);
2009 supported = first = target = 0xdeadbeef;
2010 SetLastError(0xdeadbeef);
2011 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2012 error = GetLastError();
2013 ok(!ret, "expected failure\n");
2014 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2015 ok(supported == 0xdeadbeef, "got %x\n", supported);
2016 ok(first == 0xdeadbeef, "got %x\n", first);
2017 ok(target == 0xdeadbeef, "got %x\n", target);
2019 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2020 ok(ret, "failed to send request %u\n", GetLastError());
2022 ret = WinHttpReceiveResponse(req, NULL);
2023 ok(ret, "failed to receive response %u\n", GetLastError());
2025 size = sizeof(status);
2026 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2027 ok(ret, "failed to query status code %u\n", GetLastError());
2028 ok(status == 401, "request failed unexpectedly %u\n", status);
2030 supported = first = target = 0xdeadbeef;
2031 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2032 ok(ret, "failed to query authentication schemes %u\n", GetLastError());
2033 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2034 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2035 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2037 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2038 ok(ret, "failed to set credentials %u\n", GetLastError());
2040 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2041 ok(ret, "failed to set credentials %u\n", GetLastError());
2043 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2044 ok(ret, "failed to set credentials %u\n", GetLastError());
2046 SetLastError(0xdeadbeef);
2047 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2048 error = GetLastError();
2049 ok(!ret, "expected failure\n");
2050 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2052 SetLastError(0xdeadbeef);
2053 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2054 error = GetLastError();
2055 ok(!ret, "expected failure\n");
2056 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2058 SetLastError(0xdeadbeef);
2059 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2060 error = GetLastError();
2061 ok(!ret, "expected failure\n");
2062 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2064 SetLastError(0xdeadbeef);
2065 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2066 error = GetLastError();
2067 ok(!ret, "expected failure\n");
2068 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2070 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2071 ok(ret, "failed to set credentials %u\n", GetLastError());
2073 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2074 ok(ret, "failed to send request %u\n", GetLastError());
2076 ret = WinHttpReceiveResponse(req, NULL);
2077 ok(ret, "failed to receive response %u\n", GetLastError());
2079 size = sizeof(status);
2080 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2081 ok(ret, "failed to query status code %u\n", GetLastError());
2082 ok(status == 200, "request failed unexpectedly %u\n", status);
2084 WinHttpCloseHandle(req);
2085 WinHttpCloseHandle(con);
2086 WinHttpCloseHandle(ses);
2089 static void test_no_headers(int port)
2091 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2092 HINTERNET ses, con, req;
2093 DWORD error;
2094 BOOL ret;
2096 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2097 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2099 con = WinHttpConnect(ses, localhostW, port, 0);
2100 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2102 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2103 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2105 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2106 if (!ret)
2108 error = GetLastError();
2109 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2111 else
2113 SetLastError(0xdeadbeef);
2114 ret = WinHttpReceiveResponse(req, NULL);
2115 error = GetLastError();
2116 ok(!ret, "expected failure\n");
2117 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2120 WinHttpCloseHandle(req);
2121 WinHttpCloseHandle(con);
2122 WinHttpCloseHandle(ses);
2125 static void test_no_content(int port)
2127 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2128 HINTERNET ses, con, req;
2129 WCHAR buf[128];
2130 DWORD size, len = sizeof(buf), bytes_read, status;
2131 BOOL ret;
2133 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2134 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2136 con = WinHttpConnect(ses, localhostW, port, 0);
2137 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2139 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0);
2140 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2142 size = 12345;
2143 SetLastError(0xdeadbeef);
2144 ret = WinHttpQueryDataAvailable(req, &size);
2145 todo_wine {
2146 ok(!ret, "expected error\n");
2147 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE,
2148 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2149 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
2150 "expected 12345, got %u\n", size);
2153 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2154 ok(ret, "expected success\n");
2156 ret = WinHttpReceiveResponse(req, NULL);
2157 ok(ret, "expected success\n");
2159 size = sizeof(status);
2160 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2161 NULL, &status, &size, NULL);
2162 ok(ret, "expected success\n");
2163 ok(status == 204, "expected status 204, got %d\n", status);
2165 SetLastError(0xdeadbeef);
2166 size = sizeof(status);
2167 status = 12345;
2168 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2169 NULL, &status, &size, 0);
2170 ok(!ret, "expected no content-length header\n");
2171 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND,
2172 "wrong error %u\n", GetLastError() );
2173 ok(status == 12345, "expected 0, got %d\n", status);
2175 size = 12345;
2176 ret = WinHttpQueryDataAvailable(req, &size);
2177 ok(ret, "expected success\n");
2178 ok(size == 0, "expected 0, got %d\n", size);
2180 ret = WinHttpReadData(req, buf, len, &bytes_read);
2181 ok( bytes_read == 0, "expected 0, got %u available\n", bytes_read );
2183 size = 12345;
2184 ret = WinHttpQueryDataAvailable(req, &size);
2185 ok(ret, "expected success\n");
2186 ok(size == 0, "expected 0, got %d\n", size);
2188 WinHttpCloseHandle(req);
2190 size = 12345;
2191 SetLastError(0xdeadbeef);
2192 ret = WinHttpQueryDataAvailable(req, &size);
2193 ok(!ret, "expected error\n");
2194 ok(GetLastError() == ERROR_INVALID_HANDLE,
2195 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2196 ok(size == 12345, "expected 12345, got %u\n", size);
2198 WinHttpCloseHandle(con);
2199 WinHttpCloseHandle(ses);
2202 static void test_bad_header( int port )
2204 static const WCHAR bad_headerW[] =
2205 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2206 't','e','x','t','/','h','t','m','l','\n','\r',0};
2207 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
2208 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2209 WCHAR buffer[32];
2210 HINTERNET ses, con, req;
2211 DWORD index, len;
2212 BOOL ret;
2214 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2215 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2217 con = WinHttpConnect( ses, localhostW, port, 0 );
2218 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2220 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2221 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2223 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2224 ok( ret, "failed to add header %u\n", GetLastError() );
2226 index = 0;
2227 buffer[0] = 0;
2228 len = sizeof(buffer);
2229 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2230 content_typeW, buffer, &len, &index );
2231 ok( ret, "failed to query headers %u\n", GetLastError() );
2232 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2234 WinHttpCloseHandle( req );
2235 WinHttpCloseHandle( con );
2236 WinHttpCloseHandle( ses );
2239 static void test_multiple_reads(int port)
2241 static const WCHAR bigW[] = {'b','i','g',0};
2242 HINTERNET ses, con, req;
2243 DWORD total_len = 0;
2244 BOOL ret;
2246 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2247 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2249 con = WinHttpConnect(ses, localhostW, port, 0);
2250 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2252 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
2253 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2255 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2256 ok(ret, "failed to send request %u\n", GetLastError());
2258 ret = WinHttpReceiveResponse(req, NULL);
2259 ok(ret == TRUE, "expected success\n");
2261 for (;;)
2263 DWORD len = 0xdeadbeef;
2264 ret = WinHttpQueryDataAvailable( req, &len );
2265 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2266 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2267 if (len)
2269 DWORD bytes_read;
2270 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
2272 ret = WinHttpReadData( req, buf, len, &bytes_read );
2273 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
2275 HeapFree( GetProcessHeap(), 0, buf );
2276 if (!bytes_read) break;
2277 total_len += bytes_read;
2279 if (!len) break;
2281 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
2283 WinHttpCloseHandle(req);
2284 WinHttpCloseHandle(con);
2285 WinHttpCloseHandle(ses);
2288 static void test_connection_info( int port )
2290 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2291 HINTERNET ses, con, req;
2292 WINHTTP_CONNECTION_INFO info;
2293 DWORD size, error;
2294 BOOL ret;
2296 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2297 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2299 con = WinHttpConnect( ses, localhostW, port, 0 );
2300 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2302 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
2303 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2305 size = sizeof(info);
2306 SetLastError( 0xdeadbeef );
2307 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2308 error = GetLastError();
2309 if (!ret && error == ERROR_INVALID_PARAMETER)
2311 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2312 return;
2314 ok( !ret, "unexpected success\n" );
2315 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
2317 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2318 ok( ret, "failed to send request %u\n", GetLastError() );
2320 size = 0;
2321 SetLastError( 0xdeadbeef );
2322 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2323 error = GetLastError();
2324 ok( !ret, "unexpected success\n" );
2325 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
2327 size = sizeof(info);
2328 memset( &info, 0, sizeof(info) );
2329 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2330 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2331 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2333 ret = WinHttpReceiveResponse( req, NULL );
2334 ok( ret, "failed to receive response %u\n", GetLastError() );
2336 size = sizeof(info);
2337 memset( &info, 0, sizeof(info) );
2338 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2339 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2340 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2342 WinHttpCloseHandle( req );
2343 WinHttpCloseHandle( con );
2344 WinHttpCloseHandle( ses );
2347 static void test_credentials(void)
2349 static WCHAR userW[] = {'u','s','e','r',0};
2350 static WCHAR passW[] = {'p','a','s','s',0};
2351 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2352 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2353 HINTERNET ses, con, req;
2354 DWORD size, error;
2355 WCHAR buffer[32];
2356 BOOL ret;
2358 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2359 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2361 con = WinHttpConnect(ses, localhostW, 0, 0);
2362 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2364 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2365 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2367 size = sizeof(buffer)/sizeof(WCHAR);
2368 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2369 ok(ret, "failed to query proxy username %u\n", GetLastError());
2370 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2371 ok(!size, "expected 0, got %u\n", size);
2373 size = sizeof(buffer)/sizeof(WCHAR);
2374 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2375 ok(ret, "failed to query proxy password %u\n", GetLastError());
2376 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2377 ok(!size, "expected 0, got %u\n", size);
2379 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2380 ok(ret, "failed to set username %u\n", GetLastError());
2382 size = sizeof(buffer)/sizeof(WCHAR);
2383 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2384 ok(ret, "failed to query proxy username %u\n", GetLastError());
2385 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2386 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2388 size = sizeof(buffer)/sizeof(WCHAR);
2389 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2390 ok(ret, "failed to query username %u\n", GetLastError());
2391 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2392 ok(!size, "expected 0, got %u\n", size);
2394 size = sizeof(buffer)/sizeof(WCHAR);
2395 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2396 ok(ret, "failed to query password %u\n", GetLastError());
2397 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2398 ok(!size, "expected 0, got %u\n", size);
2400 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2401 ok(ret, "failed to set proxy password %u\n", GetLastError());
2403 size = sizeof(buffer)/sizeof(WCHAR);
2404 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2405 ok(ret, "failed to query proxy password %u\n", GetLastError());
2406 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2407 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2409 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2410 ok(ret, "failed to set username %u\n", GetLastError());
2412 size = sizeof(buffer)/sizeof(WCHAR);
2413 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2414 ok(ret, "failed to query username %u\n", GetLastError());
2415 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2416 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2418 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2419 ok(ret, "failed to set password %u\n", GetLastError());
2421 size = sizeof(buffer)/sizeof(WCHAR);
2422 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2423 ok(ret, "failed to query password %u\n", GetLastError());
2424 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2425 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2427 WinHttpCloseHandle(req);
2429 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2430 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2432 SetLastError(0xdeadbeef);
2433 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2434 error = GetLastError();
2435 ok(!ret, "expected failure\n");
2436 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2438 SetLastError(0xdeadbeef);
2439 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2440 error = GetLastError();
2441 ok(!ret, "expected failure\n");
2442 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2444 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2445 ok(ret, "failed to set credentials %u\n", GetLastError());
2447 size = sizeof(buffer)/sizeof(WCHAR);
2448 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2449 ok(ret, "failed to query username %u\n", GetLastError());
2450 todo_wine {
2451 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2452 ok(!size, "expected 0, got %u\n", size);
2455 size = sizeof(buffer)/sizeof(WCHAR);
2456 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2457 ok(ret, "failed to query password %u\n", GetLastError());
2458 todo_wine {
2459 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2460 ok(!size, "expected 0, got %u\n", size);
2463 WinHttpCloseHandle(req);
2464 WinHttpCloseHandle(con);
2465 WinHttpCloseHandle(ses);
2468 static void test_IWinHttpRequest(void)
2470 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2471 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2472 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2473 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2474 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
2475 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
2476 static const WCHAR method1W[] = {'G','E','T',0};
2477 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2478 static const WCHAR method3W[] = {'P','O','S','T',0};
2479 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2480 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2481 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2482 static const WCHAR dateW[] = {'D','a','t','e',0};
2483 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
2484 HRESULT hr;
2485 IWinHttpRequest *req;
2486 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2487 BSTR date, today, connection, value = NULL;
2488 VARIANT async, empty, timeout, body, proxy_server, bypass_list, data;
2489 VARIANT_BOOL succeeded;
2490 LONG status;
2491 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2492 SYSTEMTIME st;
2494 GetSystemTime( &st );
2495 WinHttpTimeFromSystemTime( &st, todayW );
2497 CoInitialize( NULL );
2498 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2499 ok( hr == S_OK, "got %08x\n", hr );
2501 V_VT( &empty ) = VT_ERROR;
2502 V_ERROR( &empty ) = 0xdeadbeef;
2504 V_VT( &async ) = VT_BOOL;
2505 V_BOOL( &async ) = VARIANT_FALSE;
2507 method = SysAllocString( method3W );
2508 url = SysAllocString( url3W );
2509 hr = IWinHttpRequest_Open( req, method, url, async );
2510 ok( hr == S_OK, "got %08x\n", hr );
2511 SysFreeString( method );
2512 SysFreeString( url );
2514 V_VT( &data ) = VT_BSTR;
2515 V_BSTR( &data ) = SysAllocString( test_dataW );
2516 hr = IWinHttpRequest_Send( req, data );
2517 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
2518 "got %08x\n", hr );
2519 SysFreeString( V_BSTR( &data ) );
2521 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2522 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2524 method = SysAllocString( method1W );
2525 hr = IWinHttpRequest_Open( req, method, NULL, empty );
2526 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2528 hr = IWinHttpRequest_Open( req, method, NULL, async );
2529 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2531 url = SysAllocString( url1W );
2532 hr = IWinHttpRequest_Open( req, NULL, url, empty );
2533 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2535 hr = IWinHttpRequest_Abort( req );
2536 ok( hr == S_OK, "got %08x\n", hr );
2538 hr = IWinHttpRequest_Open( req, method, url, empty );
2539 ok( hr == S_OK, "got %08x\n", hr );
2541 hr = IWinHttpRequest_Abort( req );
2542 ok( hr == S_OK, "got %08x\n", hr );
2544 hr = IWinHttpRequest_Release( req );
2545 ok( hr == S_OK, "got %08x\n", hr );
2547 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2548 ok( hr == S_OK, "got %08x\n", hr );
2550 SysFreeString( url );
2551 url = SysAllocString( url2W );
2552 hr = IWinHttpRequest_Open( req, method, url, async );
2553 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2555 SysFreeString( method );
2556 method = SysAllocString( method2W );
2557 hr = IWinHttpRequest_Open( req, method, url, async );
2558 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2560 SysFreeString( method );
2561 method = SysAllocString( method1W );
2562 SysFreeString( url );
2563 url = SysAllocString( url1W );
2564 hr = IWinHttpRequest_Open( req, method, url, async );
2565 ok( hr == S_OK, "got %08x\n", hr );
2567 hr = IWinHttpRequest_Abort( req );
2568 ok( hr == S_OK, "got %08x\n", hr );
2570 hr = IWinHttpRequest_Send( req, empty );
2571 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2573 hr = IWinHttpRequest_Abort( req );
2574 ok( hr == S_OK, "got %08x\n", hr );
2576 hr = IWinHttpRequest_Release( req );
2577 ok( hr == S_OK, "got %08x\n", hr );
2579 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2580 ok( hr == S_OK, "got %08x\n", hr );
2582 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2583 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2585 hr = IWinHttpRequest_get_ResponseText( req, &response );
2586 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2588 hr = IWinHttpRequest_get_Status( req, NULL );
2589 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2591 hr = IWinHttpRequest_get_Status( req, &status );
2592 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2594 hr = IWinHttpRequest_get_StatusText( req, NULL );
2595 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2597 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2598 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2600 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2601 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2603 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2604 ok( hr == S_OK, "got %08x\n", hr );
2606 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2607 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2609 VariantInit( &proxy_server );
2610 V_VT( &proxy_server ) = VT_ERROR;
2611 VariantInit( &bypass_list );
2612 V_VT( &bypass_list ) = VT_ERROR;
2613 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2614 ok( hr == S_OK, "got %08x\n", hr );
2616 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2617 ok( hr == S_OK, "got %08x\n", hr );
2619 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2620 ok( hr == S_OK, "got %08x\n", hr );
2622 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2623 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2625 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2626 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2628 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2629 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2631 connection = SysAllocString( connectionW );
2632 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2633 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2635 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2636 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2638 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2639 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2641 date = SysAllocString( dateW );
2642 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2643 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2645 today = SysAllocString( todayW );
2646 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2647 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2649 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2650 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2652 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2653 ok( hr == S_OK, "got %08x\n", hr );
2655 SysFreeString( method );
2656 method = SysAllocString( method1W );
2657 SysFreeString( url );
2658 url = SysAllocString( url1W );
2659 hr = IWinHttpRequest_Open( req, method, url, async );
2660 ok( hr == S_OK, "got %08x\n", hr );
2662 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2663 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2665 hr = IWinHttpRequest_get_ResponseText( req, &response );
2666 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2668 hr = IWinHttpRequest_get_Status( req, &status );
2669 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2671 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2672 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2674 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2675 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2677 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2678 ok( hr == S_OK, "got %08x\n", hr );
2680 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2681 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2683 username = SysAllocString( usernameW );
2684 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2685 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2687 password = SysAllocString( passwordW );
2688 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2689 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2691 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2692 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2694 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2695 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2697 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2698 ok( hr == S_OK, "got %08x\n", hr );
2700 V_VT( &proxy_server ) = VT_BSTR;
2701 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2702 V_VT( &bypass_list ) = VT_BSTR;
2703 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2704 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2705 ok( hr == S_OK, "got %08x\n", hr );
2707 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2708 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2710 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2711 ok( hr == S_OK, "got %08x\n", hr );
2713 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2714 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2716 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2717 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2719 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2720 ok( hr == S_OK, "got %08x\n", hr );
2722 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2723 ok( hr == S_OK, "got %08x\n", hr );
2725 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2726 ok( hr == S_OK, "got %08x\n", hr );
2728 hr = IWinHttpRequest_Send( req, empty );
2729 ok( hr == S_OK, "got %08x\n", hr );
2731 hr = IWinHttpRequest_Send( req, empty );
2732 ok( hr == S_OK, "got %08x\n", hr );
2734 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2735 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2737 hr = IWinHttpRequest_get_ResponseText( req, &response );
2738 ok( hr == S_OK, "got %08x\n", hr );
2739 SysFreeString( response );
2741 hr = IWinHttpRequest_get_Status( req, NULL );
2742 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2744 status = 0;
2745 hr = IWinHttpRequest_get_Status( req, &status );
2746 ok( hr == S_OK, "got %08x\n", hr );
2747 trace("Status=%d\n", status);
2749 hr = IWinHttpRequest_get_StatusText( req, NULL );
2750 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2752 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2753 ok( hr == S_OK, "got %08x\n", hr );
2754 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
2755 SysFreeString( status_text );
2757 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2758 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2760 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2761 ok( hr == S_OK, "got %08x\n", hr );
2763 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2764 ok( hr == S_OK, "got %08x\n", hr );
2766 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2767 ok( hr == S_OK, "got %08x\n", hr );
2769 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2770 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2772 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2773 ok( hr == S_OK, "got %08x\n", hr );
2774 SysFreeString( headers );
2776 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2777 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2779 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2780 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2782 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2783 ok( hr == S_OK, "got %08x\n", hr );
2784 SysFreeString( value );
2786 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2787 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2789 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2790 ok( hr == S_OK, "got %08x\n", hr );
2792 VariantInit( &timeout );
2793 V_VT( &timeout ) = VT_I4;
2794 V_I4( &timeout ) = 10;
2795 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2796 ok( hr == S_OK, "got %08x\n", hr );
2798 hr = IWinHttpRequest_get_Status( req, &status );
2799 ok( hr == S_OK, "got %08x\n", hr );
2801 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2802 ok( hr == S_OK, "got %08x\n", hr );
2803 SysFreeString( status_text );
2805 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2806 ok( hr == S_OK, "got %08x\n", hr );
2808 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2809 ok( hr == S_OK, "got %08x\n", hr );
2811 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2812 ok( hr == S_OK, "got %08x\n", hr );
2814 hr = IWinHttpRequest_Send( req, empty );
2815 ok( hr == S_OK, "got %08x\n", hr );
2817 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2818 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2820 hr = IWinHttpRequest_get_ResponseText( req, &response );
2821 ok( hr == S_OK, "got %08x\n", hr );
2822 SysFreeString( response );
2824 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2825 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2827 VariantInit( &body );
2828 V_VT( &body ) = VT_ERROR;
2829 hr = IWinHttpRequest_get_ResponseBody( req, &body );
2830 ok( hr == S_OK, "got %08x\n", hr );
2831 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2833 hr = VariantClear( &body );
2834 ok( hr == S_OK, "got %08x\n", hr );
2836 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2837 ok( hr == S_OK, "got %08x\n", hr );
2839 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2840 ok( hr == S_OK, "got %08x\n", hr );
2842 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2843 ok( hr == S_OK, "got %08x\n", hr );
2844 SysFreeString( headers );
2846 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2847 ok( hr == S_OK, "got %08x\n", hr );
2848 SysFreeString( value );
2850 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2851 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2853 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2854 ok( hr == S_OK, "got %08x\n", hr );
2856 hr = IWinHttpRequest_Send( req, empty );
2857 ok( hr == S_OK, "got %08x\n", hr );
2859 hr = IWinHttpRequest_Abort( req );
2860 ok( hr == S_OK, "got %08x\n", hr );
2862 hr = IWinHttpRequest_Abort( req );
2863 ok( hr == S_OK, "got %08x\n", hr );
2865 hr = IWinHttpRequest_Release( req );
2866 ok( hr == S_OK, "got %08x\n", hr );
2868 SysFreeString( method );
2869 SysFreeString( url );
2870 SysFreeString( username );
2871 SysFreeString( password );
2872 SysFreeString( connection );
2873 SysFreeString( date );
2874 SysFreeString( today );
2875 VariantClear( &proxy_server );
2876 VariantClear( &bypass_list );
2877 CoUninitialize();
2880 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2882 BOOL ret;
2883 WCHAR *url;
2884 DWORD error;
2886 if (0) /* crashes on some win2k systems */
2888 SetLastError(0xdeadbeef);
2889 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
2890 error = GetLastError();
2891 ok( !ret, "expected failure\n" );
2892 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2894 url = NULL;
2895 SetLastError(0xdeadbeef);
2896 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
2897 error = GetLastError();
2898 ok( !ret, "expected failure\n" );
2899 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2901 if (0) /* crashes on some win2k systems */
2903 SetLastError(0xdeadbeef);
2904 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
2905 error = GetLastError();
2906 ok( !ret, "expected failure\n" );
2907 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2909 url = (WCHAR *)0xdeadbeef;
2910 SetLastError(0xdeadbeef);
2911 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
2912 error = GetLastError();
2913 if (!ret)
2915 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2916 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
2918 else
2920 trace("%s\n", wine_dbgstr_w(url));
2921 GlobalFree( url );
2924 url = (WCHAR *)0xdeadbeef;
2925 SetLastError(0xdeadbeef);
2926 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
2927 error = GetLastError();
2928 if (!ret)
2930 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2931 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
2933 else
2935 trace("%s\n", wine_dbgstr_w(url));
2936 GlobalFree( url );
2940 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2942 BOOL ret;
2943 DWORD error;
2944 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
2946 memset( &cfg, 0, sizeof(cfg) );
2948 SetLastError(0xdeadbeef);
2949 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
2950 error = GetLastError();
2951 ok( !ret, "expected failure\n" );
2952 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2954 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
2955 ok( ret, "expected success\n" );
2956 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
2957 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
2958 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
2959 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
2960 GlobalFree( cfg.lpszAutoConfigUrl );
2961 GlobalFree( cfg.lpszProxy );
2962 GlobalFree( cfg.lpszProxyBypass );
2965 static void test_WinHttpGetProxyForUrl(void)
2967 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2968 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
2969 static const WCHAR emptyW[] = {0};
2970 BOOL ret;
2971 DWORD error;
2972 HINTERNET session;
2973 WINHTTP_AUTOPROXY_OPTIONS options;
2974 WINHTTP_PROXY_INFO info;
2976 memset( &options, 0, sizeof(options) );
2978 SetLastError(0xdeadbeef);
2979 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
2980 error = GetLastError();
2981 ok( !ret, "expected failure\n" );
2982 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
2984 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2985 ok( session != NULL, "failed to open session %u\n", GetLastError() );
2987 SetLastError(0xdeadbeef);
2988 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
2989 error = GetLastError();
2990 ok( !ret, "expected failure\n" );
2991 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2993 SetLastError(0xdeadbeef);
2994 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
2995 error = GetLastError();
2996 ok( !ret, "expected failure\n" );
2997 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2999 SetLastError(0xdeadbeef);
3000 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
3001 error = GetLastError();
3002 ok( !ret, "expected failure\n" );
3003 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3005 SetLastError(0xdeadbeef);
3006 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3007 error = GetLastError();
3008 ok( !ret, "expected failure\n" );
3009 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3011 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3012 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3014 SetLastError(0xdeadbeef);
3015 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
3016 error = GetLastError();
3017 ok( !ret, "expected failure\n" );
3018 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3020 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3021 options.dwAutoDetectFlags = 0;
3023 SetLastError(0xdeadbeef);
3024 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3025 error = GetLastError();
3026 ok( !ret, "expected failure\n" );
3027 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3029 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
3030 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3032 SetLastError(0xdeadbeef);
3033 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3034 error = GetLastError();
3035 ok( !ret, "expected failure\n" );
3036 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3038 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3039 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3041 memset( &info, 0, sizeof(info) );
3042 SetLastError(0xdeadbeef);
3043 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3044 error = GetLastError();
3045 if (!ret) ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED ||
3046 error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
3047 else
3049 trace("Proxy.AccessType=%u\n", info.dwAccessType);
3050 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
3051 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
3052 GlobalFree( info.lpszProxy );
3053 GlobalFree( info.lpszProxyBypass );
3056 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
3057 options.dwAutoDetectFlags = 0;
3058 options.lpszAutoConfigUrl = wpadW;
3060 memset( &info, 0, sizeof(info) );
3061 SetLastError(0xdeadbeef);
3062 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3063 error = GetLastError();
3064 if (!ret) ok( error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
3065 else
3067 trace("Proxy.AccessType=%u\n", info.dwAccessType);
3068 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
3069 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
3070 GlobalFree( info.lpszProxy );
3071 GlobalFree( info.lpszProxyBypass );
3073 WinHttpCloseHandle( session );
3076 static void test_chunked_read(void)
3078 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
3079 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
3080 WCHAR header[32];
3081 DWORD len;
3082 HINTERNET ses, con = NULL, req = NULL;
3083 BOOL ret;
3085 trace( "starting chunked read test\n" );
3087 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
3088 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
3089 if (!ses) goto done;
3091 con = WinHttpConnect( ses, test_winehq, 0, 0 );
3092 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
3093 if (!con) goto done;
3095 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
3096 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
3097 if (!req) goto done;
3099 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3100 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
3102 skip("connection failed, skipping\n");
3103 goto done;
3105 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
3107 ret = WinHttpReceiveResponse( req, NULL );
3108 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
3110 header[0] = 0;
3111 len = sizeof(header);
3112 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
3113 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
3114 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
3115 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
3117 header[0] = 0;
3118 len = sizeof(header);
3119 SetLastError( 0xdeadbeef );
3120 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
3121 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
3122 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
3124 trace( "entering query loop\n" );
3125 for (;;)
3127 len = 0xdeadbeef;
3128 ret = WinHttpQueryDataAvailable( req, &len );
3129 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3130 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3131 trace( "got %u available\n", len );
3132 if (len)
3134 DWORD bytes_read;
3135 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
3137 ret = WinHttpReadData( req, buf, len, &bytes_read );
3139 buf[bytes_read] = 0;
3140 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
3141 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
3142 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
3144 HeapFree( GetProcessHeap(), 0, buf );
3145 if (!bytes_read) break;
3147 if (!len) break;
3149 trace( "done\n" );
3151 done:
3152 if (req) WinHttpCloseHandle( req );
3153 if (con) WinHttpCloseHandle( con );
3154 if (ses) WinHttpCloseHandle( ses );
3157 START_TEST (winhttp)
3159 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
3160 static const WCHAR quitW[] = {'/','q','u','i','t',0};
3161 struct server_info si;
3162 HANDLE thread;
3163 DWORD ret;
3165 test_OpenRequest();
3166 test_SendRequest();
3167 test_WinHttpTimeFromSystemTime();
3168 test_WinHttpTimeToSystemTime();
3169 test_WinHttpAddHeaders();
3170 test_secure_connection();
3171 test_request_parameter_defaults();
3172 test_QueryOption();
3173 test_set_default_proxy_config();
3174 test_empty_headers_param();
3175 test_Timeouts();
3176 test_resolve_timeout();
3177 test_credentials();
3178 test_IWinHttpRequest();
3179 test_WinHttpDetectAutoProxyConfigUrl();
3180 test_WinHttpGetIEProxyConfigForCurrentUser();
3181 test_WinHttpGetProxyForUrl();
3182 test_chunked_read();
3184 si.event = CreateEventW(NULL, 0, 0, NULL);
3185 si.port = 7532;
3187 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
3188 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
3190 ret = WaitForSingleObject(si.event, 10000);
3191 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
3192 if (ret != WAIT_OBJECT_0)
3193 return;
3195 test_connection_info(si.port);
3196 test_basic_request(si.port, NULL, basicW);
3197 test_no_headers(si.port);
3198 test_no_content(si.port);
3199 test_basic_authentication(si.port);
3200 test_bad_header(si.port);
3201 test_multiple_reads(si.port);
3203 /* send the basic request again to shutdown the server thread */
3204 test_basic_request(si.port, NULL, quitW);
3206 WaitForSingleObject(thread, 3000);