winhttp/tests: Add a test for data returned by IWinHttpRequest::get_ResponseText().
[wine.git] / dlls / winhttp / tests / winhttp.c
blobbc36fa2343f2e11e6895197e0d689af981ffaf68
1 /*
2 * WinHTTP - tests
4 * Copyright 2008 Google (Zac Brown)
5 * Copyright 2015 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
23 #include <stdarg.h>
24 #include <windef.h>
25 #include <winsock2.h>
26 #include <ws2tcpip.h>
27 #include <winhttp.h>
28 #include <wincrypt.h>
29 #include <winreg.h>
30 #include <initguid.h>
31 #include <httprequest.h>
32 #include <httprequestid.h>
34 #include "wine/test.h"
36 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
38 static const WCHAR test_useragent[] =
39 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
40 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
41 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
43 static BOOL proxy_active(void)
45 WINHTTP_PROXY_INFO proxy_info;
46 BOOL active = FALSE;
48 SetLastError(0xdeadbeef);
49 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
51 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
52 "got %u\n", GetLastError());
53 active = (proxy_info.lpszProxy != NULL);
54 if (active)
55 GlobalFree(proxy_info.lpszProxy);
56 if (proxy_info.lpszProxyBypass != NULL)
57 GlobalFree(proxy_info.lpszProxyBypass);
59 else
60 active = FALSE;
62 return active;
65 static void test_QueryOption(void)
67 BOOL ret;
68 HINTERNET session, request, connection;
69 DWORD feature, size;
71 SetLastError(0xdeadbeef);
72 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
73 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
75 SetLastError(0xdeadbeef);
76 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
77 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
78 ok(GetLastError() == ERROR_INVALID_PARAMETER,
79 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
81 size = 0xdeadbeef;
82 SetLastError(0xdeadbeef);
83 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
84 ok(!ret, "should fail to query option\n");
85 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
86 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
87 ok(size == 4, "expected 4, got %u\n", size);
89 feature = 0xdeadbeef;
90 size = sizeof(feature) - 1;
91 SetLastError(0xdeadbeef);
92 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
93 ok(!ret, "should fail to query option\n");
94 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
95 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
96 ok(size == 4, "expected 4, got %u\n", size);
98 feature = 0xdeadbeef;
99 size = sizeof(feature) + 1;
100 SetLastError(0xdeadbeef);
101 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
102 ok(ret, "failed to query option %u\n", GetLastError());
103 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
104 "got %u\n", GetLastError());
105 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
106 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
107 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
109 SetLastError(0xdeadbeef);
110 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
111 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
112 ok(GetLastError() == ERROR_INVALID_PARAMETER,
113 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
115 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
116 SetLastError(0xdeadbeef);
117 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
118 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
119 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
120 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
122 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
123 SetLastError(0xdeadbeef);
124 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
125 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
126 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
127 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
129 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
130 SetLastError(0xdeadbeef);
131 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
132 ok(ret, "failed to set redirect policy %u\n", GetLastError());
134 feature = 0xdeadbeef;
135 size = sizeof(feature);
136 SetLastError(0xdeadbeef);
137 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
138 ok(ret, "failed to query option %u\n", GetLastError());
139 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
140 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
142 feature = WINHTTP_DISABLE_COOKIES;
143 SetLastError(0xdeadbeef);
144 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
145 ok(!ret, "should fail to set disable feature for a session\n");
146 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
147 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
149 SetLastError(0xdeadbeef);
150 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
151 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
153 feature = WINHTTP_DISABLE_COOKIES;
154 SetLastError(0xdeadbeef);
155 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
156 ok(!ret, "should fail to set disable feature for a connection\n");
157 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
158 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
160 SetLastError(0xdeadbeef);
161 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
162 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
163 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
165 skip("Network unreachable, skipping the test\n");
166 goto done;
169 feature = 0xdeadbeef;
170 size = sizeof(feature);
171 SetLastError(0xdeadbeef);
172 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
173 ok(!ret, "should fail to query disable feature for a request\n");
174 ok(GetLastError() == ERROR_INVALID_PARAMETER,
175 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
177 feature = 0;
178 size = sizeof(feature);
179 SetLastError(0xdeadbeef);
180 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
181 ok(ret, "failed to set feature %u\n", GetLastError());
183 feature = 0xffffffff;
184 size = sizeof(feature);
185 SetLastError(0xdeadbeef);
186 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
187 ok(ret, "failed to set feature %u\n", GetLastError());
189 feature = WINHTTP_DISABLE_COOKIES;
190 size = sizeof(feature);
191 SetLastError(0xdeadbeef);
192 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
193 ok(ret, "failed to set feature %u\n", GetLastError());
195 size = 0;
196 SetLastError(0xdeadbeef);
197 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
198 ok(!ret, "should fail to query disable feature for a request\n");
199 ok(GetLastError() == ERROR_INVALID_PARAMETER,
200 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
202 SetLastError(0xdeadbeef);
203 ret = WinHttpCloseHandle(request);
204 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
206 done:
207 SetLastError(0xdeadbeef);
208 ret = WinHttpCloseHandle(connection);
209 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
210 SetLastError(0xdeadbeef);
211 ret = WinHttpCloseHandle(session);
212 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
215 static void test_OpenRequest (void)
217 BOOL ret;
218 HINTERNET session, request, connection;
219 DWORD err;
221 SetLastError(0xdeadbeef);
222 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
223 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
224 err = GetLastError();
225 ok(session != NULL, "WinHttpOpen failed to open session.\n");
226 ok(err == ERROR_SUCCESS, "got %u\n", err);
228 /* Test with a bad server name */
229 SetLastError(0xdeadbeef);
230 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
231 err = GetLastError();
232 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
233 ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err);
235 /* Test with a valid server name */
236 SetLastError(0xdeadbeef);
237 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
238 err = GetLastError();
239 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err);
240 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err);
242 SetLastError(0xdeadbeef);
243 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
244 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
245 err = GetLastError();
246 if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED)
248 skip("Network unreachable, skipping.\n");
249 goto done;
251 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err);
252 ok(err == ERROR_SUCCESS, "got %u\n", err);
254 SetLastError(0xdeadbeef);
255 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
256 err = GetLastError();
257 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
259 skip("Connection failed, skipping.\n");
260 goto done;
262 ok(ret, "WinHttpSendRequest failed: %u\n", err);
263 ok(err == ERROR_SUCCESS, "got %u\n", err);
265 SetLastError(0xdeadbeef);
266 ret = WinHttpCloseHandle(request);
267 err = GetLastError();
268 ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err);
269 ok(err == ERROR_SUCCESS, "got %u\n", err);
271 done:
272 ret = WinHttpCloseHandle(connection);
273 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
274 ret = WinHttpCloseHandle(session);
275 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
279 static void test_empty_headers_param(void)
281 static const WCHAR empty[] = {0};
282 HINTERNET ses, con, req;
283 DWORD err;
284 BOOL ret;
286 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
287 ok(ses != NULL, "failed to open session %u\n", GetLastError());
289 con = WinHttpConnect(ses, test_winehq, 80, 0);
290 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
292 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
293 ok(req != NULL, "failed to open a request %u\n", GetLastError());
295 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
296 err = GetLastError();
297 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
299 skip("connection failed, skipping\n");
300 goto done;
302 ok(ret, "failed to send request %u\n", GetLastError());
304 done:
305 WinHttpCloseHandle(req);
306 WinHttpCloseHandle(con);
307 WinHttpCloseHandle(ses);
310 static void test_SendRequest (void)
312 static const WCHAR content_type[] =
313 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
314 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
315 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
316 static const WCHAR test_verb[] = {'P','O','S','T',0};
317 static CHAR post_data[] = "mode=Test";
318 static const char test_post[] = "mode => Test\0\n";
319 HINTERNET session, request, connection;
320 DWORD header_len, optional_len, total_len, bytes_rw, size, err;
321 DWORD_PTR context;
322 BOOL ret;
323 CHAR buffer[256];
324 int i;
326 header_len = -1L;
327 total_len = optional_len = sizeof(post_data);
328 memset(buffer, 0xff, sizeof(buffer));
330 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
331 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
332 ok(session != NULL, "WinHttpOpen failed to open session.\n");
334 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
335 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
337 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
338 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
339 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
341 skip("Network unreachable, skipping.\n");
342 goto done;
344 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
345 if (!request) goto done;
347 context = 0xdeadbeef;
348 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
349 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
351 context++;
352 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
353 err = GetLastError();
354 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
356 skip("connection failed, skipping\n");
357 goto done;
359 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
361 context = 0;
362 size = sizeof(context);
363 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
364 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
365 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
367 for (i = 3; post_data[i]; i++)
369 bytes_rw = -1;
370 SetLastError(0xdeadbeef);
371 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
372 if (ret)
374 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
375 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
377 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
379 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
380 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
384 SetLastError(0xdeadbeef);
385 ret = WinHttpReceiveResponse(request, NULL);
386 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */,
387 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
388 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
390 bytes_rw = -1;
391 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
392 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
394 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw);
395 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
397 done:
398 ret = WinHttpCloseHandle(request);
399 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
400 ret = WinHttpCloseHandle(connection);
401 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
402 ret = WinHttpCloseHandle(session);
403 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
406 static void test_WinHttpTimeFromSystemTime(void)
408 BOOL ret;
409 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
410 static const WCHAR expected_string[] =
411 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
412 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
413 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
414 DWORD err;
416 SetLastError(0xdeadbeef);
417 ret = WinHttpTimeFromSystemTime(&time, NULL);
418 err = GetLastError();
419 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
420 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
422 SetLastError(0xdeadbeef);
423 ret = WinHttpTimeFromSystemTime(NULL, time_string);
424 err = GetLastError();
425 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
426 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
428 SetLastError(0xdeadbeef);
429 ret = WinHttpTimeFromSystemTime(&time, time_string);
430 err = GetLastError();
431 ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err);
432 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
433 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
434 "Time string returned did not match expected time string.\n");
437 static void test_WinHttpTimeToSystemTime(void)
439 BOOL ret;
440 SYSTEMTIME time;
441 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
442 static const WCHAR time_string1[] =
443 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
444 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
445 static const WCHAR time_string2[] =
446 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
447 '1','0',' ','0','5',' ','5','2','\n',0};
448 DWORD err;
450 SetLastError(0xdeadbeef);
451 ret = WinHttpTimeToSystemTime(time_string1, NULL);
452 err = GetLastError();
453 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
454 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
456 SetLastError(0xdeadbeef);
457 ret = WinHttpTimeToSystemTime(NULL, &time);
458 err = GetLastError();
459 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
460 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
462 SetLastError(0xdeadbeef);
463 ret = WinHttpTimeToSystemTime(time_string1, &time);
464 err = GetLastError();
465 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
466 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
467 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
468 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
470 SetLastError(0xdeadbeef);
471 ret = WinHttpTimeToSystemTime(time_string2, &time);
472 err = GetLastError();
473 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
474 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
475 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
476 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
479 static void test_WinHttpAddHeaders(void)
481 HINTERNET session, request, connection;
482 BOOL ret, reverse;
483 WCHAR buffer[MAX_PATH];
484 WCHAR check_buffer[MAX_PATH];
485 DWORD err, index, len, oldlen;
487 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
488 static const WCHAR test_verb[] = {'P','O','S','T',0};
489 static const WCHAR test_header_begin[] =
490 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
491 static const WCHAR full_path_test_header_begin[] =
492 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
493 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
494 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
495 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
496 static const WCHAR test_header_name2[] = {'n','a','m','e',0};
497 static const WCHAR test_header_name3[] = {'a',0};
498 static const WCHAR test_header_range[] = {'R','a','n','g','e',0};
499 static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
500 static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
502 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
503 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
504 static const WCHAR test_flag_coalesce_comma[] =
505 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
506 static const WCHAR test_flag_coalesce_comma_reverse[] =
507 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
508 static const WCHAR test_flag_coalesce_semicolon[] =
509 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
510 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
511 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
513 static const WCHAR field[] = {'f','i','e','l','d',0};
514 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
515 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
516 static const WCHAR empty[] = {0};
518 static const WCHAR test_headers[][14] =
520 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
521 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
522 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
523 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
524 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
525 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
526 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
527 {0},
528 {':',0},
529 {'a',':',0},
530 {':','b',0},
531 {'c','d',0},
532 {' ','e',' ',':','f',0},
533 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
534 {'n','a','m','e',':',' ','v','a','l','u','e',0},
535 {'n','a','m','e',':',0}
537 static const WCHAR test_indices[][6] =
539 {'t','e','s','t','1',0},
540 {'t','e','s','t','2',0},
541 {'t','e','s','t','3',0},
542 {'t','e','s','t','4',0}
545 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
546 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
547 ok(session != NULL, "WinHttpOpen failed to open session.\n");
549 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
550 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
552 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
553 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
554 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
556 skip("Network unreachable, skipping.\n");
557 goto done;
559 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
561 index = 0;
562 len = sizeof(buffer);
563 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
564 test_header_name, buffer, &len, &index);
565 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
566 SetLastError(0xdeadbeef);
567 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
568 err = GetLastError();
569 ok(ret, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, err);
570 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
572 index = 0;
573 len = sizeof(buffer);
574 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
575 test_header_name, buffer, &len, &index);
576 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
577 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
578 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
579 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
581 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
582 test_header_name, buffer, &len, &index);
583 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
585 /* Try to fetch the header info with a buffer that's big enough to fit the
586 * string but not the NULL terminator.
588 index = 0;
589 len = 5*sizeof(WCHAR);
590 memset(check_buffer, 0xab, sizeof(check_buffer));
591 memcpy(buffer, check_buffer, sizeof(buffer));
592 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
593 test_header_name, buffer, &len, &index);
594 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
595 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
596 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
597 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
599 /* Try with a NULL buffer */
600 index = 0;
601 len = sizeof(buffer);
602 SetLastError(0xdeadbeef);
603 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
604 test_header_name, NULL, &len, &index);
605 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
606 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
607 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
608 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
610 /* Try with a NULL buffer and a length that's too small */
611 index = 0;
612 len = 10;
613 SetLastError(0xdeadbeef);
614 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
615 test_header_name, NULL, &len, &index);
616 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
617 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
618 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
619 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
620 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
622 index = 0;
623 len = 0;
624 SetLastError(0xdeadbeef);
625 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
626 test_header_name, NULL, &len, &index);
627 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
628 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
629 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
630 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
631 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
633 /* valid query */
634 oldlen = len;
635 index = 0;
636 len = sizeof(buffer);
637 memset(buffer, 0xff, sizeof(buffer));
638 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
639 test_header_name, buffer, &len, &index);
640 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
641 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
642 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
643 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
644 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
645 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
646 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
647 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
648 "WinHttpQueryHeaders returned invalid end of header string.\n");
649 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
651 index = 0;
652 len = 0;
653 SetLastError(0xdeadbeef);
654 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
655 test_header_name, NULL, &len, &index);
656 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
657 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
658 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
659 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
660 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
662 oldlen = len;
663 index = 0;
664 len = sizeof(buffer);
665 memset(buffer, 0xff, sizeof(buffer));
666 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
667 test_header_name, buffer, &len, &index);
668 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
669 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
670 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
671 "no double NULL terminator\n");
672 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
673 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
674 "invalid beginning of header string.\n");
675 ok(index == 0, "header index was incremented\n");
677 /* tests for more indices */
678 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
679 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
681 index = 0;
682 len = sizeof(buffer);
683 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
684 test_header_name, buffer, &len, &index);
685 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
686 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
687 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
689 len = sizeof(buffer);
690 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
691 test_header_name, buffer, &len, &index);
692 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
693 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
694 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
696 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
697 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
699 index = 0;
700 len = sizeof(buffer);
701 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
702 test_header_name, buffer, &len, &index);
703 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
704 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
705 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
706 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
708 len = sizeof(buffer);
709 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
710 test_header_name, buffer, &len, &index);
711 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
712 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
713 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
715 /* add if new flag */
716 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
717 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
719 index = 0;
720 len = sizeof(buffer);
721 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
722 test_header_name, buffer, &len, &index);
723 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
724 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
725 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
727 len = sizeof(buffer);
728 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
729 test_header_name, buffer, &len, &index);
730 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
731 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
732 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
734 len = sizeof(buffer);
735 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
736 test_header_name, buffer, &len, &index);
737 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
739 /* coalesce flag */
740 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
741 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
743 index = 0;
744 len = sizeof(buffer);
745 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
746 test_header_name, buffer, &len, &index);
747 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
748 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
749 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
750 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
756 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
757 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
759 len = sizeof(buffer);
760 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
761 test_header_name, buffer, &len, &index);
762 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
764 /* coalesce with comma flag */
765 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
766 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
768 index = 0;
769 len = sizeof(buffer);
770 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
771 test_header_name, buffer, &len, &index);
772 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
773 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
774 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
775 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
776 "WinHttpQueryHeaders returned incorrect string.\n");
778 len = sizeof(buffer);
779 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
780 test_header_name, buffer, &len, &index);
781 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
782 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
783 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
785 len = sizeof(buffer);
786 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
787 test_header_name, buffer, &len, &index);
788 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
791 /* coalesce with semicolon flag */
792 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
793 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
795 index = 0;
796 len = sizeof(buffer);
797 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
798 test_header_name, buffer, &len, &index);
799 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
800 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
801 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
802 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
803 "WinHttpQueryHeaders returned incorrect string.\n");
805 len = sizeof(buffer);
806 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
807 test_header_name, buffer, &len, &index);
808 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
809 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
810 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
812 len = sizeof(buffer);
813 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
814 test_header_name, buffer, &len, &index);
815 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
817 /* add and replace flags */
818 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
819 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
821 index = 0;
822 len = sizeof(buffer);
823 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
824 test_header_name, buffer, &len, &index);
825 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
826 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
827 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
829 len = sizeof(buffer);
830 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
831 test_header_name, buffer, &len, &index);
832 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
833 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
834 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
836 len = sizeof(buffer);
837 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
838 test_header_name, buffer, &len, &index);
839 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
841 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
842 ok(!ret, "WinHttpAddRequestHeaders failed\n");
844 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
845 ok(ret, "WinHttpAddRequestHeaders failed\n");
847 index = 0;
848 memset(buffer, 0xff, sizeof(buffer));
849 len = sizeof(buffer);
850 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
851 test_header_name3, buffer, &len, &index);
852 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
853 ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n");
855 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
856 ok(!ret, "WinHttpAddRequestHeaders failed\n");
858 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
859 ok(!ret, "WinHttpAddRequestHeaders failed\n");
861 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
862 ok(!ret, "WinHttpAddRequestHeaders failed\n");
864 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
865 ok(ret, "WinHttpAddRequestHeaders failed\n");
867 index = 0;
868 buffer[0] = 0;
869 len = sizeof(buffer);
870 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
871 field, buffer, &len, &index);
872 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
873 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
875 SetLastError(0xdeadbeef);
876 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, 0,
877 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
878 err = GetLastError();
879 ok(!ret, "unexpected success\n");
880 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
882 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, ~0u,
883 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
884 ok(ret, "failed to add header: %u\n", GetLastError());
886 index = 0;
887 len = sizeof(buffer);
888 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
889 test_header_range, buffer, &len, &index);
890 ok(ret, "failed to get range header %u\n", GetLastError());
891 ok(!memcmp(buffer, test_header_bytes, sizeof(test_header_bytes)), "incorrect string returned\n");
892 ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len);
893 ok(index == 1, "wrong index %u\n", index);
895 index = 0;
896 len = sizeof(buffer);
897 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
898 test_header_name2, buffer, &len, &index);
899 ok(!ret, "unexpected success\n");
901 SetLastError(0xdeadbeef);
902 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
903 err = GetLastError();
904 ok(!ret, "unexpected success\n");
905 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
907 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
908 ok(ret, "got %u\n", GetLastError());
910 index = 0;
911 len = sizeof(buffer);
912 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
913 test_header_name2, buffer, &len, &index);
914 ok(ret, "got %u\n", GetLastError());
915 ok(index == 1, "wrong index %u\n", index);
916 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
918 ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
919 ok(ret, "got %u\n", GetLastError());
921 index = 0;
922 len = sizeof(buffer);
923 SetLastError(0xdeadbeef);
924 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
925 test_header_name2, buffer, &len, &index);
926 err = GetLastError();
927 ok(!ret, "unexpected success\n");
928 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
930 ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0);
931 ok(ret, "got %u\n", GetLastError());
933 index = 0;
934 len = sizeof(buffer);
935 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
936 test_header_name2, buffer, &len, &index);
937 ok(ret, "got %u\n", GetLastError());
938 ok(index == 1, "wrong index %u\n", index);
939 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
941 ret = WinHttpCloseHandle(request);
942 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
943 done:
944 ret = WinHttpCloseHandle(connection);
945 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
946 ret = WinHttpCloseHandle(session);
947 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
951 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len)
953 DWORD flags = *(DWORD *)buf;
955 if (!flags)
957 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
958 return;
960 #define X(x) if (flags & x) trace("%s\n", #x);
961 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
962 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
963 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
964 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
965 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
966 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
967 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
968 #undef X
971 static void test_secure_connection(void)
973 static const char data_start[] = "<!DOCTYPE html PUBLIC";
974 HINTERNET ses, con, req;
975 DWORD size, status, policy, bitness, read_size, err, available_size;
976 BOOL ret;
977 CERT_CONTEXT *cert;
978 WINHTTP_CERTIFICATE_INFO info;
979 char buffer[32];
981 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
982 ok(ses != NULL, "failed to open session %u\n", GetLastError());
984 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
985 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
986 ok(ret, "failed to set redirect policy %u\n", GetLastError());
988 con = WinHttpConnect(ses, test_winehq, 443, 0);
989 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
991 /* try without setting WINHTTP_FLAG_SECURE */
992 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
993 ok(req != NULL, "failed to open a request %u\n", GetLastError());
995 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
996 err = GetLastError();
997 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
999 skip("Connection failed, skipping.\n");
1000 goto cleanup;
1002 ok(ret, "failed to send request %u\n", GetLastError());
1004 ret = WinHttpReceiveResponse(req, NULL);
1005 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
1007 size = 0;
1008 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1009 ok(!ret, "succeeded unexpectedly\n");
1011 WinHttpCloseHandle(req);
1013 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
1014 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1016 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
1018 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1019 err = GetLastError();
1020 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT ||
1021 err == ERROR_WINHTTP_TIMEOUT))
1023 skip("secure connection failed, skipping remaining secure tests\n");
1024 goto cleanup;
1026 ok(ret, "failed to send request %u\n", GetLastError());
1028 size = sizeof(cert);
1029 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
1030 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1031 if (ret) CertFreeCertificateContext(cert);
1033 size = sizeof(bitness);
1034 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
1035 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
1037 size = sizeof(info);
1038 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
1039 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
1041 if (ret)
1043 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
1044 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
1045 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
1046 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
1047 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
1048 trace("dwKeySize %u\n", info.dwKeySize);
1051 ret = WinHttpReceiveResponse(req, NULL);
1052 ok(ret, "failed to receive response %u\n", GetLastError());
1054 available_size = 0;
1055 ret = WinHttpQueryDataAvailable(req, &available_size);
1056 ok(ret, "failed to query available data %u\n", GetLastError());
1057 ok(available_size > 2014, "available_size = %u\n", available_size);
1059 status = 0xdeadbeef;
1060 size = sizeof(status);
1061 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1062 ok(ret, "failed unexpectedly %u\n", GetLastError());
1063 ok(status == 200, "request failed unexpectedly %u\n", status);
1065 size = 0;
1066 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1067 ok(!ret, "succeeded unexpectedly\n");
1069 read_size = 0;
1070 for (;;)
1072 size = 0;
1073 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
1074 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
1075 if (!size) break;
1076 read_size += size;
1078 if (read_size <= 32)
1079 ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer);
1081 ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size);
1083 cleanup:
1084 WinHttpCloseHandle(req);
1085 WinHttpCloseHandle(con);
1086 WinHttpCloseHandle(ses);
1089 static void test_request_parameter_defaults(void)
1091 static const WCHAR empty[] = {0};
1092 HINTERNET ses, con, req;
1093 DWORD size, status, error;
1094 WCHAR *version;
1095 BOOL ret;
1097 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1098 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1100 con = WinHttpConnect(ses, test_winehq, 0, 0);
1101 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1103 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1104 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1106 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1107 error = GetLastError();
1108 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1110 skip("connection failed, skipping\n");
1111 goto done;
1113 ok(ret, "failed to send request %u\n", GetLastError());
1115 ret = WinHttpReceiveResponse(req, NULL);
1116 if (!ret && GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE) /* win2k */
1118 win_skip("invalid response\n");
1119 goto done;
1121 ok(ret, "failed to receive response %u\n", GetLastError());
1123 status = 0xdeadbeef;
1124 size = sizeof(status);
1125 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1126 ok(ret, "failed unexpectedly %u\n", GetLastError());
1127 ok(status == 200, "request failed unexpectedly %u\n", status);
1129 WinHttpCloseHandle(req);
1131 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
1132 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1134 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1135 error = GetLastError();
1136 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1138 skip("connection failed, skipping\n");
1139 goto done;
1141 ok(ret, "failed to send request %u\n", GetLastError());
1143 ret = WinHttpReceiveResponse(req, NULL);
1144 ok(ret, "failed to receive response %u\n", GetLastError());
1146 size = 0;
1147 SetLastError(0xdeadbeef);
1148 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
1149 error = GetLastError();
1150 ok(!ret, "succeeded unexpectedly\n");
1151 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
1153 version = HeapAlloc(GetProcessHeap(), 0, size);
1154 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
1155 ok(ret, "failed unexpectedly %u\n", GetLastError());
1156 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
1157 HeapFree(GetProcessHeap(), 0, version);
1159 status = 0xdeadbeef;
1160 size = sizeof(status);
1161 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1162 ok(ret, "failed unexpectedly %u\n", GetLastError());
1163 ok(status == 200, "request failed unexpectedly %u\n", status);
1165 done:
1166 WinHttpCloseHandle(req);
1167 WinHttpCloseHandle(con);
1168 WinHttpCloseHandle(ses);
1171 static const WCHAR Connections[] = {
1172 'S','o','f','t','w','a','r','e','\\',
1173 'M','i','c','r','o','s','o','f','t','\\',
1174 'W','i','n','d','o','w','s','\\',
1175 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1176 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1177 'C','o','n','n','e','c','t','i','o','n','s',0 };
1178 static const WCHAR WinHttpSettings[] = {
1179 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1181 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
1183 LONG l;
1184 HKEY key;
1185 DWORD ret = 0;
1187 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
1188 if (!l)
1190 DWORD size = 0;
1192 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
1193 if (!l)
1195 if (size <= len)
1196 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1197 &size );
1198 if (!l)
1199 ret = size;
1201 RegCloseKey( key );
1203 return ret;
1206 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1208 LONG l;
1209 HKEY key;
1211 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
1212 KEY_WRITE, NULL, &key, NULL );
1213 if (!l)
1215 if (len)
1216 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1217 else
1218 RegDeleteValueW( key, WinHttpSettings );
1219 RegCloseKey( key );
1223 static void test_set_default_proxy_config(void)
1225 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1226 static WCHAR normalString[] = { 'f','o','o',0 };
1227 DWORD type, len;
1228 BYTE *saved_proxy_settings = NULL;
1229 WINHTTP_PROXY_INFO info;
1230 BOOL ret;
1232 /* FIXME: it would be simpler to read the current settings using
1233 * WinHttpGetDefaultProxyConfiguration and save them using
1234 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1236 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1237 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1238 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1239 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1240 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1241 * the lpszProxy and lpszProxyBypass values are ignored.
1242 * Thus, if a proxy is set with proxycfg, then calling
1243 * WinHttpGetDefaultProxyConfiguration followed by
1244 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1245 * getting deleted from the registry.
1247 * Instead I read the current registry value and restore it directly.
1249 len = get_default_proxy_reg_value( NULL, 0, &type );
1250 if (len)
1252 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1253 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1256 if (0)
1258 /* Crashes on Vista and higher */
1259 SetLastError(0xdeadbeef);
1260 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1261 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1262 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1265 /* test with invalid access type */
1266 info.dwAccessType = 0xdeadbeef;
1267 info.lpszProxy = info.lpszProxyBypass = NULL;
1268 SetLastError(0xdeadbeef);
1269 ret = WinHttpSetDefaultProxyConfiguration(&info);
1270 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1271 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1273 /* at a minimum, the proxy server must be set */
1274 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1275 info.lpszProxy = info.lpszProxyBypass = NULL;
1276 SetLastError(0xdeadbeef);
1277 ret = WinHttpSetDefaultProxyConfiguration(&info);
1278 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1279 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1280 info.lpszProxyBypass = normalString;
1281 SetLastError(0xdeadbeef);
1282 ret = WinHttpSetDefaultProxyConfiguration(&info);
1283 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1284 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1286 /* the proxy server can't have wide characters */
1287 info.lpszProxy = wideString;
1288 SetLastError(0xdeadbeef);
1289 ret = WinHttpSetDefaultProxyConfiguration(&info);
1290 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1291 skip("couldn't set default proxy configuration: access denied\n");
1292 else
1293 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1294 broken(ret), /* Earlier winhttp versions on W2K/XP */
1295 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1297 info.lpszProxy = normalString;
1298 SetLastError(0xdeadbeef);
1299 ret = WinHttpSetDefaultProxyConfiguration(&info);
1300 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1301 skip("couldn't set default proxy configuration: access denied\n");
1302 else
1304 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1305 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1306 "got %u\n", GetLastError());
1308 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1311 static void test_Timeouts (void)
1313 BOOL ret;
1314 DWORD value, size;
1315 HINTERNET ses, req, con;
1317 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1318 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1320 SetLastError(0xdeadbeef);
1321 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1322 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1323 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1325 SetLastError(0xdeadbeef);
1326 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1327 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1328 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1330 SetLastError(0xdeadbeef);
1331 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1332 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1333 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1335 SetLastError(0xdeadbeef);
1336 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1337 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1338 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1340 SetLastError(0xdeadbeef);
1341 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1342 ok(ret, "%u\n", GetLastError());
1343 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1344 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1346 SetLastError(0xdeadbeef);
1347 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1348 ok(ret, "%u\n", GetLastError());
1350 SetLastError(0xdeadbeef);
1351 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1352 ok(ret, "%u\n", GetLastError());
1354 SetLastError(0xdeadbeef);
1355 value = 0xdeadbeef;
1356 size = sizeof(DWORD);
1357 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1358 ok(ret, "%u\n", GetLastError());
1359 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1361 SetLastError(0xdeadbeef);
1362 value = 0xdeadbeef;
1363 size = sizeof(DWORD);
1364 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1365 ok(ret, "%u\n", GetLastError());
1366 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1368 SetLastError(0xdeadbeef);
1369 value = 0xdeadbeef;
1370 size = sizeof(DWORD);
1371 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1372 ok(ret, "%u\n", GetLastError());
1373 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1375 SetLastError(0xdeadbeef);
1376 value = 0xdeadbeef;
1377 size = sizeof(DWORD);
1378 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1379 ok(ret, "%u\n", GetLastError());
1380 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1382 SetLastError(0xdeadbeef);
1383 value = 0;
1384 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1385 ok(ret, "%u\n", GetLastError());
1387 SetLastError(0xdeadbeef);
1388 value = 0xdeadbeef;
1389 size = sizeof(DWORD);
1390 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1391 ok(ret, "%u\n", GetLastError());
1392 ok(value == 0, "Expected 0, got %u\n", value);
1394 SetLastError(0xdeadbeef);
1395 value = 0;
1396 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1397 ok(ret, "%u\n", GetLastError());
1399 SetLastError(0xdeadbeef);
1400 value = 0xdeadbeef;
1401 size = sizeof(DWORD);
1402 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1403 ok(ret, "%u\n", GetLastError());
1404 ok(value == 0, "Expected 0, got %u\n", value);
1406 SetLastError(0xdeadbeef);
1407 value = 0;
1408 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1409 ok(ret, "%u\n", GetLastError());
1411 SetLastError(0xdeadbeef);
1412 value = 0xdeadbeef;
1413 size = sizeof(DWORD);
1414 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1415 ok(ret, "%u\n", GetLastError());
1416 ok(value == 0, "Expected 0, got %u\n", value);
1418 SetLastError(0xdeadbeef);
1419 value = 0;
1420 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1421 ok(ret, "%u\n", GetLastError());
1423 SetLastError(0xdeadbeef);
1424 value = 0xdeadbeef;
1425 size = sizeof(DWORD);
1426 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1427 ok(ret, "%u\n", GetLastError());
1428 ok(value == 0, "Expected 0, got %u\n", value);
1430 SetLastError(0xdeadbeef);
1431 value = 0xbeefdead;
1432 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1433 ok(ret, "%u\n", GetLastError());
1435 SetLastError(0xdeadbeef);
1436 value = 0xdeadbeef;
1437 size = sizeof(DWORD);
1438 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1439 ok(ret, "%u\n", GetLastError());
1440 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1442 SetLastError(0xdeadbeef);
1443 value = 0xbeefdead;
1444 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1445 ok(ret, "%u\n", GetLastError());
1447 SetLastError(0xdeadbeef);
1448 value = 0xdeadbeef;
1449 size = sizeof(DWORD);
1450 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1451 ok(ret, "%u\n", GetLastError());
1452 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1454 SetLastError(0xdeadbeef);
1455 value = 0xbeefdead;
1456 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1457 ok(ret, "%u\n", GetLastError());
1459 SetLastError(0xdeadbeef);
1460 value = 0xdeadbeef;
1461 size = sizeof(DWORD);
1462 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1463 ok(ret, "%u\n", GetLastError());
1464 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1466 SetLastError(0xdeadbeef);
1467 value = 0xbeefdead;
1468 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1469 ok(ret, "%u\n", GetLastError());
1471 SetLastError(0xdeadbeef);
1472 value = 0xdeadbeef;
1473 size = sizeof(DWORD);
1474 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1475 ok(ret, "%u\n", GetLastError());
1476 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1478 con = WinHttpConnect(ses, test_winehq, 0, 0);
1479 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1481 /* Timeout values should match the last one set for session */
1482 SetLastError(0xdeadbeef);
1483 value = 0xdeadbeef;
1484 size = sizeof(DWORD);
1485 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1486 ok(ret, "%u\n", GetLastError());
1487 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1489 SetLastError(0xdeadbeef);
1490 value = 0xdeadbeef;
1491 size = sizeof(DWORD);
1492 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1493 ok(ret, "%u\n", GetLastError());
1494 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1496 SetLastError(0xdeadbeef);
1497 value = 0xdeadbeef;
1498 size = sizeof(DWORD);
1499 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1500 ok(ret, "%u\n", GetLastError());
1501 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1503 SetLastError(0xdeadbeef);
1504 value = 0xdeadbeef;
1505 size = sizeof(DWORD);
1506 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1507 ok(ret, "%u\n", GetLastError());
1508 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1510 SetLastError(0xdeadbeef);
1511 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1512 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1513 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1515 SetLastError(0xdeadbeef);
1516 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1517 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1518 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1520 SetLastError(0xdeadbeef);
1521 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1522 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1523 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1525 SetLastError(0xdeadbeef);
1526 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1527 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1528 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1530 SetLastError(0xdeadbeef);
1531 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1532 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1533 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1535 SetLastError(0xdeadbeef);
1536 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1537 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1538 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1540 SetLastError(0xdeadbeef);
1541 value = 0;
1542 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1543 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1544 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1546 SetLastError(0xdeadbeef);
1547 value = 0;
1548 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1549 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1550 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1552 SetLastError(0xdeadbeef);
1553 value = 0;
1554 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1555 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1556 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1558 SetLastError(0xdeadbeef);
1559 value = 0;
1560 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1561 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1562 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1564 /* Changing timeout values for session should affect the values for connection */
1565 SetLastError(0xdeadbeef);
1566 value = 0xdead;
1567 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1568 ok(ret, "%u\n", GetLastError());
1570 SetLastError(0xdeadbeef);
1571 value = 0xdeadbeef;
1572 size = sizeof(DWORD);
1573 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1574 ok(ret, "%u\n", GetLastError());
1575 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1577 SetLastError(0xdeadbeef);
1578 value = 0xdead;
1579 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1580 ok(ret, "%u\n", GetLastError());
1582 SetLastError(0xdeadbeef);
1583 value = 0xdeadbeef;
1584 size = sizeof(DWORD);
1585 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1586 ok(ret, "%u\n", GetLastError());
1587 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1589 SetLastError(0xdeadbeef);
1590 value = 0xdead;
1591 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1592 ok(ret, "%u\n", GetLastError());
1594 SetLastError(0xdeadbeef);
1595 value = 0xdeadbeef;
1596 size = sizeof(DWORD);
1597 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1598 ok(ret, "%u\n", GetLastError());
1599 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1601 SetLastError(0xdeadbeef);
1602 value = 0xdead;
1603 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1604 ok(ret, "%u\n", GetLastError());
1606 SetLastError(0xdeadbeef);
1607 value = 0xdeadbeef;
1608 size = sizeof(DWORD);
1609 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1610 ok(ret, "%u\n", GetLastError());
1611 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1613 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1614 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1616 /* Timeout values should match the last one set for session */
1617 SetLastError(0xdeadbeef);
1618 value = 0xdeadbeef;
1619 size = sizeof(DWORD);
1620 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1621 ok(ret, "%u\n", GetLastError());
1622 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1624 SetLastError(0xdeadbeef);
1625 value = 0xdeadbeef;
1626 size = sizeof(DWORD);
1627 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1628 ok(ret, "%u\n", GetLastError());
1629 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1631 SetLastError(0xdeadbeef);
1632 value = 0xdeadbeef;
1633 size = sizeof(DWORD);
1634 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1635 ok(ret, "%u\n", GetLastError());
1636 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1638 SetLastError(0xdeadbeef);
1639 value = 0xdeadbeef;
1640 size = sizeof(DWORD);
1641 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1642 ok(ret, "%u\n", GetLastError());
1643 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1645 SetLastError(0xdeadbeef);
1646 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1647 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1648 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1650 SetLastError(0xdeadbeef);
1651 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1652 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1653 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1655 SetLastError(0xdeadbeef);
1656 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1657 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1658 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1660 SetLastError(0xdeadbeef);
1661 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1662 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1663 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1665 SetLastError(0xdeadbeef);
1666 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1667 ok(ret, "%u\n", GetLastError());
1669 SetLastError(0xdeadbeef);
1670 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1671 ok(ret, "%u\n", GetLastError());
1673 SetLastError(0xdeadbeef);
1674 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1675 ok(ret, "%u\n", GetLastError());
1677 SetLastError(0xdeadbeef);
1678 value = 0xdeadbeef;
1679 size = sizeof(DWORD);
1680 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1681 ok(ret, "%u\n", GetLastError());
1682 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1684 SetLastError(0xdeadbeef);
1685 value = 0xdeadbeef;
1686 size = sizeof(DWORD);
1687 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1688 ok(ret, "%u\n", GetLastError());
1689 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1691 SetLastError(0xdeadbeef);
1692 value = 0xdeadbeef;
1693 size = sizeof(DWORD);
1694 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1695 ok(ret, "%u\n", GetLastError());
1696 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1698 SetLastError(0xdeadbeef);
1699 value = 0xdeadbeef;
1700 size = sizeof(DWORD);
1701 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1702 ok(ret, "%u\n", GetLastError());
1703 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1705 SetLastError(0xdeadbeef);
1706 value = 0;
1707 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1708 ok(ret, "%u\n", GetLastError());
1710 SetLastError(0xdeadbeef);
1711 value = 0xdeadbeef;
1712 size = sizeof(DWORD);
1713 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1714 ok(ret, "%u\n", GetLastError());
1715 ok(value == 0, "Expected 0, got %u\n", value);
1717 SetLastError(0xdeadbeef);
1718 value = 0;
1719 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1720 ok(ret, "%u\n", GetLastError());
1722 SetLastError(0xdeadbeef);
1723 value = 0xdeadbeef;
1724 size = sizeof(DWORD);
1725 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1726 ok(ret, "%u\n", GetLastError());
1727 ok(value == 0, "Expected 0, got %u\n", value);
1729 SetLastError(0xdeadbeef);
1730 value = 0;
1731 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1732 ok(ret, "%u\n", GetLastError());
1734 SetLastError(0xdeadbeef);
1735 value = 0xdeadbeef;
1736 size = sizeof(DWORD);
1737 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1738 ok(ret, "%u\n", GetLastError());
1739 ok(value == 0, "Expected 0, got %u\n", value);
1741 SetLastError(0xdeadbeef);
1742 value = 0;
1743 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1744 ok(ret, "%u\n", GetLastError());
1746 SetLastError(0xdeadbeef);
1747 value = 0xdeadbeef;
1748 size = sizeof(DWORD);
1749 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1750 ok(ret, "%u\n", GetLastError());
1751 ok(value == 0, "Expected 0, got %u\n", value);
1753 SetLastError(0xdeadbeef);
1754 value = 0xbeefdead;
1755 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1756 ok(ret, "%u\n", GetLastError());
1758 SetLastError(0xdeadbeef);
1759 value = 0xdeadbeef;
1760 size = sizeof(DWORD);
1761 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1762 ok(ret, "%u\n", GetLastError());
1763 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1765 SetLastError(0xdeadbeef);
1766 value = 0xbeefdead;
1767 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1768 ok(ret, "%u\n", GetLastError());
1770 SetLastError(0xdeadbeef);
1771 value = 0xdeadbeef;
1772 size = sizeof(DWORD);
1773 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1774 ok(ret, "%u\n", GetLastError());
1775 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1777 SetLastError(0xdeadbeef);
1778 value = 0xbeefdead;
1779 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1780 ok(ret, "%u\n", GetLastError());
1782 SetLastError(0xdeadbeef);
1783 value = 0xdeadbeef;
1784 size = sizeof(DWORD);
1785 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1786 ok(ret, "%u\n", GetLastError());
1787 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1789 SetLastError(0xdeadbeef);
1790 value = 0xbeefdead;
1791 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1792 ok(ret, "%u\n", GetLastError());
1794 SetLastError(0xdeadbeef);
1795 value = 0xdeadbeef;
1796 size = sizeof(DWORD);
1797 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1798 ok(ret, "%u\n", GetLastError());
1799 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1801 /* Changing timeout values for session should not affect the values for a request,
1802 * neither should the other way around.
1804 SetLastError(0xdeadbeef);
1805 value = 0xbeefdead;
1806 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1807 ok(ret, "%u\n", GetLastError());
1809 SetLastError(0xdeadbeef);
1810 value = 0xdeadbeef;
1811 size = sizeof(DWORD);
1812 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1813 ok(ret, "%u\n", GetLastError());
1814 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1816 SetLastError(0xdeadbeef);
1817 value = 0xbeefdead;
1818 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1819 ok(ret, "%u\n", GetLastError());
1821 SetLastError(0xdeadbeef);
1822 value = 0xdeadbeef;
1823 size = sizeof(DWORD);
1824 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1825 ok(ret, "%u\n", GetLastError());
1826 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1828 SetLastError(0xdeadbeef);
1829 value = 0xbeefdead;
1830 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1831 ok(ret, "%u\n", GetLastError());
1833 SetLastError(0xdeadbeef);
1834 value = 0xdeadbeef;
1835 size = sizeof(DWORD);
1836 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1837 ok(ret, "%u\n", GetLastError());
1838 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1840 SetLastError(0xdeadbeef);
1841 value = 0xbeefdead;
1842 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1843 ok(ret, "%u\n", GetLastError());
1845 SetLastError(0xdeadbeef);
1846 value = 0xdeadbeef;
1847 size = sizeof(DWORD);
1848 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1849 ok(ret, "%u\n", GetLastError());
1850 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1852 SetLastError(0xdeadbeef);
1853 value = 0xbeef;
1854 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1855 ok(ret, "%u\n", GetLastError());
1857 SetLastError(0xdeadbeef);
1858 value = 0xdeadbeef;
1859 size = sizeof(DWORD);
1860 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1861 ok(ret, "%u\n", GetLastError());
1862 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1864 SetLastError(0xdeadbeef);
1865 value = 0xbeef;
1866 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1867 ok(ret, "%u\n", GetLastError());
1869 SetLastError(0xdeadbeef);
1870 value = 0xdeadbeef;
1871 size = sizeof(DWORD);
1872 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1873 ok(ret, "%u\n", GetLastError());
1874 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1876 SetLastError(0xdeadbeef);
1877 value = 0xbeef;
1878 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1879 ok(ret, "%u\n", GetLastError());
1881 SetLastError(0xdeadbeef);
1882 value = 0xdeadbeef;
1883 size = sizeof(DWORD);
1884 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1885 ok(ret, "%u\n", GetLastError());
1886 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1888 SetLastError(0xdeadbeef);
1889 value = 0xbeef;
1890 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1891 ok(ret, "%u\n", GetLastError());
1893 SetLastError(0xdeadbeef);
1894 value = 0xdeadbeef;
1895 size = sizeof(DWORD);
1896 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1897 ok(ret, "%u\n", GetLastError());
1898 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1900 WinHttpCloseHandle(req);
1901 WinHttpCloseHandle(con);
1902 WinHttpCloseHandle(ses);
1905 static void test_resolve_timeout(void)
1907 static const WCHAR nxdomain[] =
1908 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1909 HINTERNET ses, con, req;
1910 DWORD timeout;
1911 BOOL ret;
1913 if (! proxy_active())
1915 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1916 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1918 timeout = 10000;
1919 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1920 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1922 con = WinHttpConnect(ses, nxdomain, 0, 0);
1923 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1925 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1926 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1928 SetLastError(0xdeadbeef);
1929 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1930 if (ret)
1932 skip("nxdomain returned success. Broken ISP redirects?\n");
1933 goto done;
1935 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1936 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1938 WinHttpCloseHandle(req);
1939 WinHttpCloseHandle(con);
1940 WinHttpCloseHandle(ses);
1942 else
1943 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1945 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1946 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1948 timeout = 10000;
1949 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1950 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1952 con = WinHttpConnect(ses, test_winehq, 0, 0);
1953 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1955 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1956 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1958 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1959 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
1961 skip("connection failed, skipping\n");
1962 goto done;
1964 ok(ret, "failed to send request\n");
1966 done:
1967 WinHttpCloseHandle(req);
1968 WinHttpCloseHandle(con);
1969 WinHttpCloseHandle(ses);
1972 static const char page1[] =
1973 "<HTML>\r\n"
1974 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1975 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1976 "</HTML>\r\n\r\n";
1978 static const char okmsg[] =
1979 "HTTP/1.1 200 OK\r\n"
1980 "Server: winetest\r\n"
1981 "\r\n";
1983 static const char notokmsg[] =
1984 "HTTP/1.1 400 Bad Request\r\n"
1985 "\r\n";
1987 static const char cookiemsg[] =
1988 "HTTP/1.1 200 OK\r\n"
1989 "Set-Cookie: name = value \r\n"
1990 "Set-Cookie: NAME = value \r\n"
1991 "\r\n";
1993 static const char nocontentmsg[] =
1994 "HTTP/1.1 204 No Content\r\n"
1995 "Server: winetest\r\n"
1996 "\r\n";
1998 static const char notmodified[] =
1999 "HTTP/1.1 304 Not Modified\r\n"
2000 "\r\n";
2002 static const char noauthmsg[] =
2003 "HTTP/1.1 401 Unauthorized\r\n"
2004 "Server: winetest\r\n"
2005 "Connection: close\r\n"
2006 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2007 "\r\n";
2009 static const char okauthmsg[] =
2010 "HTTP/1.1 200 OK\r\n"
2011 "Server: winetest\r\n"
2012 "Connection: close\r\n"
2013 "\r\n";
2015 static const char headmsg[] =
2016 "HTTP/1.1 200 OK\r\n"
2017 "Content-Length: 100\r\n"
2018 "\r\n";
2020 struct server_info
2022 HANDLE event;
2023 int port;
2026 #define BIG_BUFFER_LEN 0x2250
2028 static DWORD CALLBACK server_thread(LPVOID param)
2030 struct server_info *si = param;
2031 int r, c = -1, i, on;
2032 SOCKET s;
2033 struct sockaddr_in sa;
2034 char buffer[0x100];
2035 WSADATA wsaData;
2036 int last_request = 0;
2038 WSAStartup(MAKEWORD(1,1), &wsaData);
2040 s = socket(AF_INET, SOCK_STREAM, 0);
2041 if (s == INVALID_SOCKET)
2042 return 1;
2044 on = 1;
2045 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2047 memset(&sa, 0, sizeof sa);
2048 sa.sin_family = AF_INET;
2049 sa.sin_port = htons(si->port);
2050 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2052 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
2053 if (r < 0)
2054 return 1;
2056 listen(s, 0);
2057 SetEvent(si->event);
2060 if (c == -1) c = accept(s, NULL, NULL);
2062 memset(buffer, 0, sizeof buffer);
2063 for(i = 0; i < sizeof buffer - 1; i++)
2065 r = recv(c, &buffer[i], 1, 0);
2066 if (r != 1)
2067 break;
2068 if (i < 4) continue;
2069 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
2070 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
2071 break;
2073 if (strstr(buffer, "GET /basic"))
2075 send(c, okmsg, sizeof okmsg - 1, 0);
2076 send(c, page1, sizeof page1 - 1, 0);
2078 if (strstr(buffer, "/auth"))
2080 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2081 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2082 else
2083 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
2085 if (strstr(buffer, "/big"))
2087 char msg[BIG_BUFFER_LEN];
2088 memset(msg, 'm', sizeof(msg));
2089 send(c, okmsg, sizeof(okmsg) - 1, 0);
2090 send(c, msg, sizeof(msg), 0);
2092 if (strstr(buffer, "/no_headers"))
2094 send(c, page1, sizeof page1 - 1, 0);
2096 if (strstr(buffer, "GET /no_content"))
2098 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
2099 continue;
2101 if (strstr(buffer, "GET /not_modified"))
2103 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0);
2104 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2105 continue;
2107 if (strstr(buffer, "HEAD /head"))
2109 send(c, headmsg, sizeof headmsg - 1, 0);
2110 continue;
2112 if (strstr(buffer, "GET /cookie3"))
2114 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2115 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL))
2116 send(c, okmsg, sizeof(okmsg) - 1, 0);
2117 else
2118 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2120 if (strstr(buffer, "GET /cookie2"))
2122 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") ||
2123 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL))
2124 send(c, okmsg, sizeof(okmsg) - 1, 0);
2125 else
2126 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2128 else if (strstr(buffer, "GET /cookie"))
2130 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
2131 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2133 if (strstr(buffer, "GET /quit"))
2135 send(c, okmsg, sizeof okmsg - 1, 0);
2136 send(c, page1, sizeof page1 - 1, 0);
2137 last_request = 1;
2139 shutdown(c, 2);
2140 closesocket(c);
2141 c = -1;
2143 } while (!last_request);
2145 closesocket(s);
2146 return 0;
2149 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
2151 static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0};
2152 static const WCHAR test_header_end_raw[] = {0,0};
2153 HINTERNET ses, con, req;
2154 char buffer[0x100];
2155 WCHAR buffer2[0x100];
2156 DWORD count, status, size, error, supported, first, target;
2157 BOOL ret;
2159 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2160 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2162 con = WinHttpConnect(ses, localhostW, port, 0);
2163 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2165 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
2166 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2168 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2169 ok(ret, "failed to send request %u\n", GetLastError());
2171 ret = WinHttpReceiveResponse(req, NULL);
2172 ok(ret, "failed to receive response %u\n", GetLastError());
2174 status = 0xdeadbeef;
2175 size = sizeof(status);
2176 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2177 ok(ret, "failed to query status code %u\n", GetLastError());
2178 ok(status == 200, "request failed unexpectedly %u\n", status);
2180 supported = first = target = 0xdeadbeef;
2181 SetLastError(0xdeadbeef);
2182 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2183 error = GetLastError();
2184 ok(!ret, "unexpected success\n");
2185 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2186 ok(supported == 0xdeadbeef, "got %x\n", supported);
2187 ok(first == 0xdeadbeef, "got %x\n", first);
2188 ok(target == 0xdeadbeef, "got %x\n", target);
2190 size = sizeof(buffer2);
2191 memset(buffer2, 0, sizeof(buffer2));
2192 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL);
2193 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2194 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)),
2195 "WinHttpQueryHeaders returned invalid end of header string\n");
2197 size = sizeof(buffer2);
2198 memset(buffer2, 0, sizeof(buffer2));
2199 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL);
2200 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2201 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)),
2202 "WinHttpQueryHeaders returned invalid end of header string\n");
2203 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n");
2205 count = 0;
2206 memset(buffer, 0, sizeof(buffer));
2207 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
2208 ok(ret, "failed to read data %u\n", GetLastError());
2209 ok(count == sizeof page1 - 1, "count was wrong\n");
2210 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2212 WinHttpCloseHandle(req);
2213 WinHttpCloseHandle(con);
2214 WinHttpCloseHandle(ses);
2217 static void test_basic_authentication(int port)
2219 static const WCHAR authW[] = {'/','a','u','t','h',0};
2220 static WCHAR userW[] = {'u','s','e','r',0};
2221 static WCHAR passW[] = {'p','w','d',0};
2222 static WCHAR pass2W[] = {'p','w','d','2',0};
2223 HINTERNET ses, con, req;
2224 DWORD status, size, error, supported, first, target;
2225 BOOL ret;
2227 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2228 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2230 con = WinHttpConnect(ses, localhostW, port, 0);
2231 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2233 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2234 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2236 SetLastError(0xdeadbeef);
2237 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
2238 error = GetLastError();
2239 ok(!ret, "expected failure\n");
2240 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2242 SetLastError(0xdeadbeef);
2243 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
2244 error = GetLastError();
2245 ok(!ret, "expected failure\n");
2246 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2248 supported = 0xdeadbeef;
2249 SetLastError(0xdeadbeef);
2250 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2251 error = GetLastError();
2252 ok(!ret, "expected failure\n");
2253 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2254 ok(supported == 0xdeadbeef, "got %x\n", supported);
2256 supported = first = 0xdeadbeef;
2257 SetLastError(0xdeadbeef);
2258 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
2259 error = GetLastError();
2260 ok(!ret, "expected failure\n");
2261 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2262 ok(supported == 0xdeadbeef, "got %x\n", supported);
2263 ok(first == 0xdeadbeef, "got %x\n", first);
2265 supported = first = target = 0xdeadbeef;
2266 SetLastError(0xdeadbeef);
2267 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2268 error = GetLastError();
2269 ok(!ret, "expected failure\n");
2270 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2271 ok(supported == 0xdeadbeef, "got %x\n", supported);
2272 ok(first == 0xdeadbeef, "got %x\n", first);
2273 ok(target == 0xdeadbeef, "got %x\n", target);
2275 supported = first = target = 0xdeadbeef;
2276 SetLastError(0xdeadbeef);
2277 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2278 error = GetLastError();
2279 ok(!ret, "expected failure\n");
2280 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2281 ok(supported == 0xdeadbeef, "got %x\n", supported);
2282 ok(first == 0xdeadbeef, "got %x\n", first);
2283 ok(target == 0xdeadbeef, "got %x\n", target);
2285 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2286 ok(ret, "failed to send request %u\n", GetLastError());
2288 ret = WinHttpReceiveResponse(req, NULL);
2289 ok(ret, "failed to receive response %u\n", GetLastError());
2291 status = 0xdeadbeef;
2292 size = sizeof(status);
2293 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2294 ok(ret, "failed to query status code %u\n", GetLastError());
2295 ok(status == 401, "request failed unexpectedly %u\n", status);
2297 supported = first = target = 0xdeadbeef;
2298 SetLastError(0xdeadbeef);
2299 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2300 error = GetLastError();
2301 ok(ret, "failed to query authentication schemes %u\n", error);
2302 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2303 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2304 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2305 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2307 SetLastError(0xdeadbeef);
2308 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2309 error = GetLastError();
2310 ok(ret, "failed to set credentials %u\n", error);
2311 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2313 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2314 ok(ret, "failed to set credentials %u\n", GetLastError());
2316 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2317 ok(ret, "failed to set credentials %u\n", GetLastError());
2319 SetLastError(0xdeadbeef);
2320 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2321 error = GetLastError();
2322 ok(!ret, "expected failure\n");
2323 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2325 SetLastError(0xdeadbeef);
2326 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2327 error = GetLastError();
2328 ok(!ret, "expected failure\n");
2329 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2331 SetLastError(0xdeadbeef);
2332 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2333 error = GetLastError();
2334 ok(!ret, "expected failure\n");
2335 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2337 SetLastError(0xdeadbeef);
2338 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2339 error = GetLastError();
2340 ok(!ret, "expected failure\n");
2341 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2343 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2344 ok(ret, "failed to set credentials %u\n", GetLastError());
2346 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2347 ok(ret, "failed to send request %u\n", GetLastError());
2349 ret = WinHttpReceiveResponse(req, NULL);
2350 ok(ret, "failed to receive response %u\n", GetLastError());
2352 status = 0xdeadbeef;
2353 size = sizeof(status);
2354 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2355 ok(ret, "failed to query status code %u\n", GetLastError());
2356 ok(status == 200, "request failed unexpectedly %u\n", status);
2358 WinHttpCloseHandle(req);
2359 WinHttpCloseHandle(con);
2360 WinHttpCloseHandle(ses);
2362 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2364 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2365 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2367 con = WinHttpConnect(ses, localhostW, port, 0);
2368 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2370 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2371 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2373 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2374 ok(ret, "failed to set credentials %u\n", GetLastError());
2376 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2377 ok(ret, "failed to set username %u\n", GetLastError());
2379 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W));
2380 ok(ret, "failed to set password %u\n", GetLastError());
2382 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2383 ok(ret, "failed to send request %u\n", GetLastError());
2385 ret = WinHttpReceiveResponse(req, NULL);
2386 ok(ret, "failed to receive response %u\n", GetLastError());
2388 status = 0xdeadbeef;
2389 size = sizeof(status);
2390 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2391 ok(ret, "failed to query status code %u\n", GetLastError());
2392 ok(status == 200, "request failed unexpectedly %u\n", status);
2394 WinHttpCloseHandle(req);
2395 WinHttpCloseHandle(con);
2396 WinHttpCloseHandle(ses);
2398 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2399 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2401 con = WinHttpConnect(ses, localhostW, port, 0);
2402 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2404 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2405 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2407 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2408 ok(ret, "failed to set username %u\n", GetLastError());
2410 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(passW));
2411 ok(ret, "failed to set password %u\n", GetLastError());
2413 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, NULL);
2414 ok(ret, "failed to set credentials %u\n", GetLastError());
2416 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2417 ok(ret, "failed to send request %u\n", GetLastError());
2419 ret = WinHttpReceiveResponse(req, NULL);
2420 ok(ret, "failed to receive response %u\n", GetLastError());
2422 status = 0xdeadbeef;
2423 size = sizeof(status);
2424 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2425 ok(ret, "failed to query status code %u\n", GetLastError());
2426 ok(status == 401, "request failed unexpectedly %u\n", status);
2428 WinHttpCloseHandle(req);
2429 WinHttpCloseHandle(con);
2430 WinHttpCloseHandle(ses);
2433 static void test_no_headers(int port)
2435 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2436 HINTERNET ses, con, req;
2437 DWORD error;
2438 BOOL ret;
2440 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2441 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2443 con = WinHttpConnect(ses, localhostW, port, 0);
2444 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2446 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2447 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2449 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2450 if (!ret)
2452 error = GetLastError();
2453 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2455 else
2457 SetLastError(0xdeadbeef);
2458 ret = WinHttpReceiveResponse(req, NULL);
2459 error = GetLastError();
2460 ok(!ret, "expected failure\n");
2461 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2464 WinHttpCloseHandle(req);
2465 WinHttpCloseHandle(con);
2466 WinHttpCloseHandle(ses);
2469 static void test_no_content(int port)
2471 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2472 HINTERNET ses, con, req;
2473 char buf[128];
2474 DWORD size, len = sizeof(buf), bytes_read, status;
2475 BOOL ret;
2477 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2478 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2480 con = WinHttpConnect(ses, localhostW, port, 0);
2481 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2483 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0);
2484 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2486 size = 12345;
2487 SetLastError(0xdeadbeef);
2488 ret = WinHttpQueryDataAvailable(req, &size);
2489 todo_wine {
2490 ok(!ret, "expected error\n");
2491 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE,
2492 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2493 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
2494 "expected 12345, got %u\n", size);
2497 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2498 ok(ret, "expected success\n");
2500 ret = WinHttpReceiveResponse(req, NULL);
2501 ok(ret, "expected success\n");
2503 status = 0xdeadbeef;
2504 size = sizeof(status);
2505 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2506 NULL, &status, &size, NULL);
2507 ok(ret, "expected success\n");
2508 ok(status == 204, "expected status 204, got %d\n", status);
2510 SetLastError(0xdeadbeef);
2511 size = sizeof(status);
2512 status = 12345;
2513 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2514 NULL, &status, &size, 0);
2515 ok(!ret, "expected no content-length header\n");
2516 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError());
2517 ok(status == 12345, "expected 0, got %d\n", status);
2519 SetLastError(0xdeadbeef);
2520 size = 12345;
2521 ret = WinHttpQueryDataAvailable(req, &size);
2522 ok(ret, "expected success\n");
2523 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2524 "wrong error %u\n", GetLastError());
2525 ok(!size, "expected 0, got %u\n", size);
2527 SetLastError(0xdeadbeef);
2528 ret = WinHttpReadData(req, buf, len, &bytes_read);
2529 ok(ret, "expected success\n");
2530 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2531 "wrong error %u\n", GetLastError());
2532 ok(!bytes_read, "expected 0, got %u\n", bytes_read);
2534 size = 12345;
2535 ret = WinHttpQueryDataAvailable(req, &size);
2536 ok(ret, "expected success\n");
2537 ok(size == 0, "expected 0, got %d\n", size);
2539 WinHttpCloseHandle(req);
2541 size = 12345;
2542 SetLastError(0xdeadbeef);
2543 ret = WinHttpQueryDataAvailable(req, &size);
2544 ok(!ret, "expected error\n");
2545 ok(GetLastError() == ERROR_INVALID_HANDLE,
2546 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2547 ok(size == 12345, "expected 12345, got %u\n", size);
2549 WinHttpCloseHandle(con);
2550 WinHttpCloseHandle(ses);
2553 static void test_head_request(int port)
2555 static const WCHAR verbW[] = {'H','E','A','D',0};
2556 static const WCHAR headW[] = {'/','h','e','a','d',0};
2557 HINTERNET ses, con, req;
2558 char buf[128];
2559 DWORD size, len, count, status;
2560 BOOL ret;
2562 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2563 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2565 con = WinHttpConnect(ses, localhostW, port, 0);
2566 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2568 req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0);
2569 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2571 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2572 ok(ret, "failed to send request %u\n", GetLastError());
2574 ret = WinHttpReceiveResponse(req, NULL);
2575 ok(ret, "failed to receive response %u\n", GetLastError());
2577 status = 0xdeadbeef;
2578 size = sizeof(status);
2579 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2580 NULL, &status, &size, NULL);
2581 ok(ret, "failed to get status code %u\n", GetLastError());
2582 ok(status == 200, "got %u\n", status);
2584 len = 0xdeadbeef;
2585 size = sizeof(len);
2586 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2587 NULL, &len, &size, 0);
2588 ok(ret, "failed to get content-length header %u\n", GetLastError());
2589 ok(len == 100, "got %u\n", len);
2591 count = 0xdeadbeef;
2592 ret = WinHttpQueryDataAvailable(req, &count);
2593 ok(ret, "failed to query data available %u\n", GetLastError());
2594 ok(!count, "got %u\n", count);
2596 len = sizeof(buf);
2597 count = 0xdeadbeef;
2598 ret = WinHttpReadData(req, buf, len, &count);
2599 ok(ret, "failed to read data %u\n", GetLastError());
2600 ok(!count, "got %u\n", count);
2602 count = 0xdeadbeef;
2603 ret = WinHttpQueryDataAvailable(req, &count);
2604 ok(ret, "failed to query data available %u\n", GetLastError());
2605 ok(!count, "got %u\n", count);
2607 WinHttpCloseHandle(req);
2608 WinHttpCloseHandle(con);
2609 WinHttpCloseHandle(ses);
2612 static void test_not_modified(int port)
2614 static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2615 static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2616 static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2617 BOOL ret;
2618 HINTERNET session, request, connection;
2619 DWORD index, len, status, size, start = GetTickCount();
2620 SYSTEMTIME st;
2621 WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32];
2623 memcpy(today, ifmodifiedW, sizeof(ifmodifiedW));
2624 GetSystemTime(&st);
2625 WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]);
2627 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY,
2628 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
2629 ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError());
2631 connection = WinHttpConnect(session, localhostW, port, 0);
2632 ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError());
2634 request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER,
2635 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
2636 ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError());
2638 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0);
2639 ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError());
2641 ret = WinHttpReceiveResponse(request, NULL);
2642 ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2644 index = 0;
2645 len = sizeof(buffer);
2646 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2647 ifmodified2W, buffer, &len, &index);
2648 ok(ret, "failed to get header %u\n", GetLastError());
2650 status = 0xdeadbeef;
2651 size = sizeof(status);
2652 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
2653 NULL, &status, &size, NULL);
2654 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2655 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status);
2657 size = 0xdeadbeef;
2658 ret = WinHttpQueryDataAvailable(request, &size);
2659 ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2660 ok(!size, "got %u\n", size);
2662 WinHttpCloseHandle(request);
2663 WinHttpCloseHandle(connection);
2664 WinHttpCloseHandle(session);
2665 start = GetTickCount() - start;
2666 ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start);
2669 static void test_bad_header( int port )
2671 static const WCHAR bad_headerW[] =
2672 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2673 't','e','x','t','/','h','t','m','l','\n','\r',0};
2674 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
2675 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2676 WCHAR buffer[32];
2677 HINTERNET ses, con, req;
2678 DWORD index, len;
2679 BOOL ret;
2681 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2682 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2684 con = WinHttpConnect( ses, localhostW, port, 0 );
2685 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2687 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2688 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2690 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2691 ok( ret, "failed to add header %u\n", GetLastError() );
2693 index = 0;
2694 buffer[0] = 0;
2695 len = sizeof(buffer);
2696 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2697 content_typeW, buffer, &len, &index );
2698 ok( ret, "failed to query headers %u\n", GetLastError() );
2699 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2701 WinHttpCloseHandle( req );
2702 WinHttpCloseHandle( con );
2703 WinHttpCloseHandle( ses );
2706 static void test_multiple_reads(int port)
2708 static const WCHAR bigW[] = {'b','i','g',0};
2709 HINTERNET ses, con, req;
2710 DWORD total_len = 0;
2711 BOOL ret;
2713 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2714 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2716 con = WinHttpConnect(ses, localhostW, port, 0);
2717 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2719 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
2720 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2722 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2723 ok(ret, "failed to send request %u\n", GetLastError());
2725 ret = WinHttpReceiveResponse(req, NULL);
2726 ok(ret == TRUE, "expected success\n");
2728 for (;;)
2730 DWORD len = 0xdeadbeef;
2731 ret = WinHttpQueryDataAvailable( req, &len );
2732 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2733 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2734 if (len)
2736 DWORD bytes_read;
2737 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
2739 ret = WinHttpReadData( req, buf, len, &bytes_read );
2740 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
2742 HeapFree( GetProcessHeap(), 0, buf );
2743 if (!bytes_read) break;
2744 total_len += bytes_read;
2746 if (!len) break;
2748 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
2750 WinHttpCloseHandle(req);
2751 WinHttpCloseHandle(con);
2752 WinHttpCloseHandle(ses);
2755 static void test_cookies( int port )
2757 static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0};
2758 static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0};
2759 static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0};
2760 static const WCHAR cookieheaderW[] =
2761 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2762 HINTERNET ses, con, req;
2763 DWORD status, size;
2764 BOOL ret;
2766 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2767 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2769 con = WinHttpConnect( ses, localhostW, port, 0 );
2770 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2772 req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 );
2773 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2775 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2776 ok( ret, "failed to send request %u\n", GetLastError() );
2778 ret = WinHttpReceiveResponse( req, NULL );
2779 ok( ret, "failed to receive response %u\n", GetLastError() );
2781 status = 0xdeadbeef;
2782 size = sizeof(status);
2783 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2784 ok( ret, "failed to query status code %u\n", GetLastError() );
2785 ok( status == 200, "request failed unexpectedly %u\n", status );
2787 WinHttpCloseHandle( req );
2789 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2790 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2792 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2793 ok( ret, "failed to send request %u\n", GetLastError() );
2795 ret = WinHttpReceiveResponse( req, NULL );
2796 ok( ret, "failed to receive response %u\n", GetLastError() );
2798 status = 0xdeadbeef;
2799 size = sizeof(status);
2800 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2801 ok( ret, "failed to query status code %u\n", GetLastError() );
2802 ok( status == 200, "request failed unexpectedly %u\n", status );
2804 WinHttpCloseHandle( req );
2805 WinHttpCloseHandle( con );
2807 con = WinHttpConnect( ses, localhostW, port, 0 );
2808 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2810 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2811 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2813 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2814 ok( ret, "failed to send request %u\n", GetLastError() );
2816 ret = WinHttpReceiveResponse( req, NULL );
2817 ok( ret, "failed to receive response %u\n", GetLastError() );
2819 status = 0xdeadbeef;
2820 size = sizeof(status);
2821 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2822 ok( ret, "failed to query status code %u\n", GetLastError() );
2823 ok( status == 200, "request failed unexpectedly %u\n", status );
2825 WinHttpCloseHandle( req );
2827 req = WinHttpOpenRequest( con, NULL, cookie3W, NULL, NULL, NULL, 0 );
2828 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2830 ret = WinHttpSendRequest( req, cookieheaderW, ~0u, NULL, 0, 0, 0 );
2831 ok( ret, "failed to send request %u\n", GetLastError() );
2833 ret = WinHttpReceiveResponse( req, NULL );
2834 ok( ret, "failed to receive response %u\n", GetLastError() );
2836 status = 0xdeadbeef;
2837 size = sizeof(status);
2838 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2839 ok( ret, "failed to query status code %u\n", GetLastError() );
2840 ok( status == 200 || broken(status == 400), "request failed unexpectedly %u\n", status );
2842 WinHttpCloseHandle( req );
2843 WinHttpCloseHandle( con );
2844 WinHttpCloseHandle( ses );
2846 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2847 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2849 con = WinHttpConnect( ses, localhostW, port, 0 );
2850 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2852 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2853 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2855 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2856 ok( ret, "failed to send request %u\n", GetLastError() );
2858 ret = WinHttpReceiveResponse( req, NULL );
2859 ok( ret, "failed to receive response %u\n", GetLastError() );
2861 status = 0xdeadbeef;
2862 size = sizeof(status);
2863 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2864 ok( ret, "failed to query status code %u\n", GetLastError() );
2865 ok( status == 400, "request failed unexpectedly %u\n", status );
2867 WinHttpCloseHandle( req );
2868 WinHttpCloseHandle( con );
2869 WinHttpCloseHandle( ses );
2872 static void test_connection_info( int port )
2874 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2875 HINTERNET ses, con, req;
2876 WINHTTP_CONNECTION_INFO info;
2877 DWORD size, error;
2878 BOOL ret;
2880 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2881 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2883 con = WinHttpConnect( ses, localhostW, port, 0 );
2884 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2886 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
2887 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2889 size = sizeof(info);
2890 SetLastError( 0xdeadbeef );
2891 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2892 error = GetLastError();
2893 if (!ret && error == ERROR_INVALID_PARAMETER)
2895 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2896 return;
2898 ok( !ret, "unexpected success\n" );
2899 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
2901 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2902 ok( ret, "failed to send request %u\n", GetLastError() );
2904 size = 0;
2905 SetLastError( 0xdeadbeef );
2906 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2907 error = GetLastError();
2908 ok( !ret, "unexpected success\n" );
2909 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
2911 size = sizeof(info);
2912 memset( &info, 0, sizeof(info) );
2913 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2914 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2915 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize );
2917 ret = WinHttpReceiveResponse( req, NULL );
2918 ok( ret, "failed to receive response %u\n", GetLastError() );
2920 size = sizeof(info);
2921 memset( &info, 0, sizeof(info) );
2922 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2923 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2924 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize );
2926 WinHttpCloseHandle( req );
2927 WinHttpCloseHandle( con );
2928 WinHttpCloseHandle( ses );
2931 static void test_credentials(void)
2933 static WCHAR userW[] = {'u','s','e','r',0};
2934 static WCHAR passW[] = {'p','a','s','s',0};
2935 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2936 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2937 HINTERNET ses, con, req;
2938 DWORD size, error;
2939 WCHAR buffer[32];
2940 BOOL ret;
2942 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2943 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2945 con = WinHttpConnect(ses, localhostW, 0, 0);
2946 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2948 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2949 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2951 size = sizeof(buffer)/sizeof(WCHAR);
2952 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2953 ok(ret, "failed to query proxy username %u\n", GetLastError());
2954 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2955 ok(!size, "expected 0, got %u\n", size);
2957 size = sizeof(buffer)/sizeof(WCHAR);
2958 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2959 ok(ret, "failed to query proxy password %u\n", GetLastError());
2960 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2961 ok(!size, "expected 0, got %u\n", size);
2963 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2964 ok(ret, "failed to set username %u\n", GetLastError());
2966 size = sizeof(buffer)/sizeof(WCHAR);
2967 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2968 ok(ret, "failed to query proxy username %u\n", GetLastError());
2969 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2970 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2972 size = sizeof(buffer)/sizeof(WCHAR);
2973 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2974 ok(ret, "failed to query username %u\n", GetLastError());
2975 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2976 ok(!size, "expected 0, got %u\n", size);
2978 size = sizeof(buffer)/sizeof(WCHAR);
2979 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2980 ok(ret, "failed to query password %u\n", GetLastError());
2981 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2982 ok(!size, "expected 0, got %u\n", size);
2984 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2985 ok(ret, "failed to set proxy password %u\n", GetLastError());
2987 size = sizeof(buffer)/sizeof(WCHAR);
2988 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2989 ok(ret, "failed to query proxy password %u\n", GetLastError());
2990 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2991 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2993 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2994 ok(ret, "failed to set username %u\n", GetLastError());
2996 size = sizeof(buffer)/sizeof(WCHAR);
2997 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2998 ok(ret, "failed to query username %u\n", GetLastError());
2999 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3000 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
3002 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
3003 ok(ret, "failed to set password %u\n", GetLastError());
3005 size = sizeof(buffer)/sizeof(WCHAR);
3006 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3007 ok(ret, "failed to query password %u\n", GetLastError());
3008 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3009 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
3011 WinHttpCloseHandle(req);
3013 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
3014 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3016 SetLastError(0xdeadbeef);
3017 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
3018 error = GetLastError();
3019 ok(!ret, "expected failure\n");
3020 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3022 SetLastError(0xdeadbeef);
3023 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
3024 error = GetLastError();
3025 ok(!ret, "expected failure\n");
3026 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3028 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
3029 ok(ret, "failed to set credentials %u\n", GetLastError());
3031 size = sizeof(buffer)/sizeof(WCHAR);
3032 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3033 ok(ret, "failed to query username %u\n", GetLastError());
3034 todo_wine {
3035 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3036 ok(!size, "expected 0, got %u\n", size);
3039 size = sizeof(buffer)/sizeof(WCHAR);
3040 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3041 ok(ret, "failed to query password %u\n", GetLastError());
3042 todo_wine {
3043 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3044 ok(!size, "expected 0, got %u\n", size);
3047 WinHttpCloseHandle(req);
3048 WinHttpCloseHandle(con);
3049 WinHttpCloseHandle(ses);
3052 static void test_IWinHttpRequest(void)
3054 static const WCHAR data_start[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3055 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
3056 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
3057 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3058 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3059 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3060 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3061 static const WCHAR method1W[] = {'G','E','T',0};
3062 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
3063 static const WCHAR method3W[] = {'P','O','S','T',0};
3064 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3065 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
3066 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
3067 static const WCHAR dateW[] = {'D','a','t','e',0};
3068 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
3069 static const WCHAR utf8W[] = {'u','t','f','-','8',0};
3070 HRESULT hr;
3071 IWinHttpRequest *req;
3072 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
3073 BSTR date, today, connection, value = NULL;
3074 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp;
3075 VARIANT_BOOL succeeded;
3076 LONG status;
3077 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
3078 SYSTEMTIME st;
3079 IStream *stream, *stream2;
3080 LARGE_INTEGER pos;
3081 char buf[128];
3082 DWORD count;
3084 GetSystemTime( &st );
3085 WinHttpTimeFromSystemTime( &st, todayW );
3087 CoInitialize( NULL );
3088 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3089 ok( hr == S_OK, "got %08x\n", hr );
3091 V_VT( &empty ) = VT_ERROR;
3092 V_ERROR( &empty ) = 0xdeadbeef;
3094 V_VT( &async ) = VT_BOOL;
3095 V_BOOL( &async ) = VARIANT_FALSE;
3097 method = SysAllocString( method3W );
3098 url = SysAllocString( url3W );
3099 hr = IWinHttpRequest_Open( req, method, url, async );
3100 ok( hr == S_OK, "got %08x\n", hr );
3101 SysFreeString( method );
3102 SysFreeString( url );
3104 V_VT( &data ) = VT_BSTR;
3105 V_BSTR( &data ) = SysAllocString( test_dataW );
3106 hr = IWinHttpRequest_Send( req, data );
3107 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
3108 "got %08x\n", hr );
3109 SysFreeString( V_BSTR( &data ) );
3111 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
3112 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3114 method = SysAllocString( method1W );
3115 hr = IWinHttpRequest_Open( req, method, NULL, empty );
3116 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3118 hr = IWinHttpRequest_Open( req, method, NULL, async );
3119 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3121 url = SysAllocString( url1W );
3122 hr = IWinHttpRequest_Open( req, NULL, url, empty );
3123 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3125 hr = IWinHttpRequest_Abort( req );
3126 ok( hr == S_OK, "got %08x\n", hr );
3128 hr = IWinHttpRequest_Open( req, method, url, empty );
3129 ok( hr == S_OK, "got %08x\n", hr );
3131 hr = IWinHttpRequest_Abort( req );
3132 ok( hr == S_OK, "got %08x\n", hr );
3134 IWinHttpRequest_Release( req );
3136 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3137 ok( hr == S_OK, "got %08x\n", hr );
3139 SysFreeString( url );
3140 url = SysAllocString( url2W );
3141 hr = IWinHttpRequest_Open( req, method, url, async );
3142 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3144 SysFreeString( method );
3145 method = SysAllocString( method2W );
3146 hr = IWinHttpRequest_Open( req, method, url, async );
3147 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3149 SysFreeString( method );
3150 method = SysAllocString( method1W );
3151 SysFreeString( url );
3152 url = SysAllocString( url1W );
3153 V_VT( &async ) = VT_ERROR;
3154 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND;
3155 hr = IWinHttpRequest_Open( req, method, url, async );
3156 ok( hr == S_OK, "got %08x\n", hr );
3158 V_VT( &cp ) = VT_ERROR;
3159 V_ERROR( &cp ) = 0xdeadbeef;
3160 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3161 ok( hr == S_OK, "got %08x\n", hr );
3162 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3163 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3165 V_VT( &cp ) = VT_UI4;
3166 V_UI4( &cp ) = CP_ACP;
3167 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3168 ok( hr == S_OK, "got %08x\n", hr );
3170 V_VT( &cp ) = VT_ERROR;
3171 V_ERROR( &cp ) = 0xdeadbeef;
3172 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3173 ok( hr == S_OK, "got %08x\n", hr );
3174 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3175 ok( V_I4( &cp ) == CP_ACP, "got %u\n", V_I4( &cp ) );
3177 value = SysAllocString( utf8W );
3178 V_VT( &cp ) = VT_BSTR;
3179 V_BSTR( &cp ) = value;
3180 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3181 ok( hr == S_OK, "got %08x\n", hr );
3182 SysFreeString( value );
3184 V_VT( &cp ) = VT_ERROR;
3185 V_ERROR( &cp ) = 0xdeadbeef;
3186 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3187 ok( hr == S_OK, "got %08x\n", hr );
3188 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3189 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3191 hr = IWinHttpRequest_Abort( req );
3192 ok( hr == S_OK, "got %08x\n", hr );
3194 hr = IWinHttpRequest_Send( req, empty );
3195 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3197 hr = IWinHttpRequest_Abort( req );
3198 ok( hr == S_OK, "got %08x\n", hr );
3200 IWinHttpRequest_Release( req );
3202 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3203 ok( hr == S_OK, "got %08x\n", hr );
3205 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3206 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3208 hr = IWinHttpRequest_get_ResponseText( req, &response );
3209 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3211 hr = IWinHttpRequest_get_Status( req, NULL );
3212 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3214 hr = IWinHttpRequest_get_Status( req, &status );
3215 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3217 hr = IWinHttpRequest_get_StatusText( req, NULL );
3218 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3220 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3221 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3223 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3224 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3226 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3227 ok( hr == S_OK, "got %08x\n", hr );
3229 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3230 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3232 VariantInit( &proxy_server );
3233 V_VT( &proxy_server ) = VT_ERROR;
3234 VariantInit( &bypass_list );
3235 V_VT( &bypass_list ) = VT_ERROR;
3236 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3237 ok( hr == S_OK, "got %08x\n", hr );
3239 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3240 ok( hr == S_OK, "got %08x\n", hr );
3242 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3243 ok( hr == S_OK, "got %08x\n", hr );
3245 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3246 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3248 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3249 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3251 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3252 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3254 connection = SysAllocString( connectionW );
3255 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3256 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3258 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3259 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3261 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
3262 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3264 date = SysAllocString( dateW );
3265 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3266 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3268 today = SysAllocString( todayW );
3269 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3270 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3272 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
3273 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3275 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3276 ok( hr == S_OK, "got %08x\n", hr );
3278 SysFreeString( method );
3279 method = SysAllocString( method1W );
3280 SysFreeString( url );
3281 url = SysAllocString( url1W );
3282 hr = IWinHttpRequest_Open( req, method, url, async );
3283 ok( hr == S_OK, "got %08x\n", hr );
3285 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3286 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3288 hr = IWinHttpRequest_get_ResponseText( req, &response );
3289 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3291 hr = IWinHttpRequest_get_Status( req, &status );
3292 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3294 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3295 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3297 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3298 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3300 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3301 ok( hr == S_OK, "got %08x\n", hr );
3303 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3304 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3306 username = SysAllocString( usernameW );
3307 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
3308 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3310 password = SysAllocString( passwordW );
3311 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
3312 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3314 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
3315 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3317 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3318 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3320 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3321 ok( hr == S_OK, "got %08x\n", hr );
3323 V_VT( &proxy_server ) = VT_BSTR;
3324 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
3325 V_VT( &bypass_list ) = VT_BSTR;
3326 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
3327 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3328 ok( hr == S_OK, "got %08x\n", hr );
3330 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
3331 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3333 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3334 ok( hr == S_OK, "got %08x\n", hr );
3336 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3337 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3339 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3340 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3342 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3343 ok( hr == S_OK, "got %08x\n", hr );
3345 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3346 ok( hr == S_OK, "got %08x\n", hr );
3348 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3349 ok( hr == S_OK, "got %08x\n", hr );
3351 hr = IWinHttpRequest_Send( req, empty );
3352 ok( hr == S_OK, "got %08x\n", hr );
3354 hr = IWinHttpRequest_Send( req, empty );
3355 ok( hr == S_OK, "got %08x\n", hr );
3357 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3358 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3360 hr = IWinHttpRequest_get_ResponseText( req, &response );
3361 ok( hr == S_OK, "got %08x\n", hr );
3362 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
3363 SysFreeString( response );
3365 hr = IWinHttpRequest_get_Status( req, NULL );
3366 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3368 status = 0;
3369 hr = IWinHttpRequest_get_Status( req, &status );
3370 ok( hr == S_OK, "got %08x\n", hr );
3371 trace("Status=%d\n", status);
3373 hr = IWinHttpRequest_get_StatusText( req, NULL );
3374 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3376 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3377 ok( hr == S_OK, "got %08x\n", hr );
3378 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
3379 SysFreeString( status_text );
3381 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3382 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3384 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3385 ok( hr == S_OK, "got %08x\n", hr );
3387 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3388 ok( hr == S_OK, "got %08x\n", hr );
3390 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3391 ok( hr == S_OK, "got %08x\n", hr );
3393 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3394 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3396 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3397 ok( hr == S_OK, "got %08x\n", hr );
3398 SysFreeString( headers );
3400 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3401 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3403 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3404 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3406 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3407 ok( hr == S_OK, "got %08x\n", hr );
3408 SysFreeString( value );
3410 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3411 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
3413 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3414 ok( hr == S_OK, "got %08x\n", hr );
3416 VariantInit( &timeout );
3417 V_VT( &timeout ) = VT_I4;
3418 V_I4( &timeout ) = 10;
3419 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
3420 ok( hr == S_OK, "got %08x\n", hr );
3422 hr = IWinHttpRequest_get_Status( req, &status );
3423 ok( hr == S_OK, "got %08x\n", hr );
3425 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3426 ok( hr == S_OK, "got %08x\n", hr );
3427 SysFreeString( status_text );
3429 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3430 ok( hr == S_OK, "got %08x\n", hr );
3432 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3433 ok( hr == S_OK, "got %08x\n", hr );
3435 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3436 ok( hr == S_OK, "got %08x\n", hr );
3438 hr = IWinHttpRequest_Send( req, empty );
3439 ok( hr == S_OK, "got %08x\n", hr );
3441 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3442 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3444 hr = IWinHttpRequest_get_ResponseText( req, &response );
3445 ok( hr == S_OK, "got %08x\n", hr );
3446 SysFreeString( response );
3448 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3449 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3451 VariantInit( &body );
3452 V_VT( &body ) = VT_ERROR;
3453 hr = IWinHttpRequest_get_ResponseBody( req, &body );
3454 ok( hr == S_OK, "got %08x\n", hr );
3455 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
3457 hr = VariantClear( &body );
3458 ok( hr == S_OK, "got %08x\n", hr );
3460 VariantInit( &body );
3461 V_VT( &body ) = VT_ERROR;
3462 hr = IWinHttpRequest_get_ResponseStream( req, &body );
3463 ok( hr == S_OK, "got %08x\n", hr );
3464 ok( V_VT( &body ) == VT_UNKNOWN, "got %08x\n", V_VT( &body ) );
3466 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream );
3467 ok( hr == S_OK, "got %08x\n", hr );
3468 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" );
3470 buf[0] = 0;
3471 count = 0xdeadbeef;
3472 hr = IStream_Read( stream, buf, 128, &count );
3473 ok( hr == S_OK, "got %08x\n", hr );
3474 ok( count != 0xdeadbeef, "count not set\n" );
3475 ok( buf[0], "no data\n" );
3477 VariantInit( &body2 );
3478 V_VT( &body2 ) = VT_ERROR;
3479 hr = IWinHttpRequest_get_ResponseStream( req, &body2 );
3480 ok( hr == S_OK, "got %08x\n", hr );
3481 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %08x\n", V_VT( &body2 ) );
3482 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" );
3484 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 );
3485 ok( hr == S_OK, "got %08x\n", hr );
3486 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" );
3487 IStream_Release( stream2 );
3489 hr = VariantClear( &body );
3490 ok( hr == S_OK, "got %08x\n", hr );
3492 hr = VariantClear( &body2 );
3493 ok( hr == S_OK, "got %08x\n", hr );
3495 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3496 ok( hr == S_OK, "got %08x\n", hr );
3498 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3499 ok( hr == S_OK, "got %08x\n", hr );
3501 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3502 ok( hr == S_OK, "got %08x\n", hr );
3503 SysFreeString( headers );
3505 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3506 ok( hr == S_OK, "got %08x\n", hr );
3507 SysFreeString( value );
3509 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3510 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
3512 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3513 ok( hr == S_OK, "got %08x\n", hr );
3515 hr = IWinHttpRequest_Send( req, empty );
3516 ok( hr == S_OK, "got %08x\n", hr );
3518 hr = IWinHttpRequest_Abort( req );
3519 ok( hr == S_OK, "got %08x\n", hr );
3521 hr = IWinHttpRequest_Abort( req );
3522 ok( hr == S_OK, "got %08x\n", hr );
3524 IWinHttpRequest_Release( req );
3526 pos.QuadPart = 0;
3527 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL );
3528 ok( hr == S_OK, "got %08x\n", hr );
3530 buf[0] = 0;
3531 count = 0xdeadbeef;
3532 hr = IStream_Read( stream, buf, 128, &count );
3533 ok( hr == S_OK, "got %08x\n", hr );
3534 ok( count != 0xdeadbeef, "count not set\n" );
3535 ok( buf[0], "no data\n" );
3536 IStream_Release( stream );
3538 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3539 ok( hr == S_OK, "got %08x\n", hr );
3541 V_VT( &async ) = VT_I4;
3542 V_I4( &async ) = 1;
3543 hr = IWinHttpRequest_Open( req, method, url, async );
3544 ok( hr == S_OK, "got %08x\n", hr );
3546 hr = IWinHttpRequest_Send( req, empty );
3547 ok( hr == S_OK, "got %08x\n", hr );
3549 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
3550 ok( hr == S_OK, "got %08x\n", hr );
3552 IWinHttpRequest_Release( req );
3554 SysFreeString( method );
3555 SysFreeString( url );
3556 SysFreeString( username );
3557 SysFreeString( password );
3558 SysFreeString( connection );
3559 SysFreeString( date );
3560 SysFreeString( today );
3561 VariantClear( &proxy_server );
3562 VariantClear( &bypass_list );
3563 CoUninitialize();
3566 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret)
3568 DISPPARAMS params;
3569 VARIANT arg;
3570 HRESULT hr;
3572 memset(&params, 0, sizeof(params));
3573 params.cNamedArgs = 0;
3574 params.rgdispidNamedArgs = NULL;
3575 params.cArgs = 1;
3576 params.rgvarg = &arg;
3577 VariantInit(&arg);
3578 V_VT(&arg) = VT_I4;
3579 V_I4(&arg) = property;
3580 VariantInit(ret);
3581 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3582 DISPATCH_PROPERTYGET, &params, ret, NULL, NULL);
3583 ok(hr == S_OK, "error %#x\n", hr);
3586 static void test_IWinHttpRequest_Invoke(void)
3588 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
3589 static const WCHAR regid[] = {'W','i','n','H','t','t','p','.','W','i','n','H','t','t','p','R','e','q','u','e','s','t','.','5','.','1',0};
3590 WCHAR openW[] = {'O','p','e','n',0};
3591 WCHAR optionW[] = {'O','p','t','i','o','n',0};
3592 OLECHAR *open = openW, *option = optionW;
3593 BSTR utf8;
3594 CLSID clsid;
3595 IWinHttpRequest *request;
3596 IDispatch *dispatch;
3597 DISPID id;
3598 DISPPARAMS params;
3599 VARIANT arg[3], ret;
3600 UINT err;
3601 BOOL bret;
3602 HRESULT hr;
3604 CoInitialize(NULL);
3606 hr = CLSIDFromProgID(regid, &clsid);
3607 ok(hr == S_OK, "CLSIDFromProgID error %#x\n", hr);
3608 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest);
3609 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid));
3611 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request);
3612 ok(hr == S_OK, "error %#x\n", hr);
3614 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch);
3615 ok(hr == S_OK, "error %#x\n", hr);
3616 IDispatch_Release(dispatch);
3618 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id);
3619 ok(hr == S_OK, "error %#x\n", hr);
3620 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id);
3622 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id);
3623 ok(hr == S_OK, "error %#x\n", hr);
3624 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id);
3626 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3627 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3628 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3630 memset(&params, 0, sizeof(params));
3631 params.cArgs = 2;
3632 params.cNamedArgs = 0;
3633 params.rgvarg = arg;
3634 V_VT(&arg[0]) = VT_I4;
3635 V_I4(&arg[0]) = 1252;
3636 V_VT(&arg[1]) = VT_R8;
3637 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3638 VariantInit(&ret);
3639 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3640 DISPATCH_METHOD, &params, NULL, NULL, &err);
3641 ok(hr == S_OK, "error %#x\n", hr);
3643 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3644 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3645 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3647 memset(&params, 0, sizeof(params));
3648 params.cArgs = 2;
3649 params.cNamedArgs = 0;
3650 params.rgvarg = arg;
3651 V_VT(&arg[0]) = VT_I4;
3652 V_I4(&arg[0]) = 1252;
3653 V_VT(&arg[1]) = VT_R8;
3654 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3655 VariantInit(&ret);
3656 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3657 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
3658 ok(hr == S_OK, "error %#x\n", hr);
3660 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3661 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3662 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3664 memset(&params, 0, sizeof(params));
3665 params.cArgs = 2;
3666 params.cNamedArgs = 0;
3667 params.rgvarg = arg;
3668 V_VT(&arg[0]) = VT_I4;
3669 V_I4(&arg[0]) = 1252;
3670 V_VT(&arg[1]) = VT_R8;
3671 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3672 VariantInit(&ret);
3673 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3674 DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
3675 ok(hr == S_OK, "error %#x\n", hr);
3677 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3678 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3679 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3681 memset(&params, 0, sizeof(params));
3682 params.cArgs = 2;
3683 params.cNamedArgs = 0;
3684 params.rgvarg = arg;
3685 V_VT(&arg[0]) = VT_BSTR;
3686 utf8 = SysAllocString(utf8W);
3687 V_BSTR(&arg[0]) = utf8;
3688 V_VT(&arg[1]) = VT_R8;
3689 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3690 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, &err);
3691 ok(hr == S_OK, "error %#x\n", hr);
3693 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3694 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3695 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3697 VariantInit(&ret);
3698 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, &err);
3699 ok(hr == S_OK, "error %#x\n", hr);
3701 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3702 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3703 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3705 VariantInit(&ret);
3706 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3707 ok(hr == S_OK, "error %#x\n", hr);
3709 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3710 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3711 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3713 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
3714 ok(hr == S_OK, "error %#x\n", hr);
3716 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
3717 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#x\n", hr);
3719 VariantInit(&ret);
3720 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3721 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
3723 VariantInit(&ret);
3724 if (0) /* crashes */
3725 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err);
3727 params.cArgs = 1;
3728 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3729 ok(hr == DISP_E_TYPEMISMATCH, "error %#x\n", hr);
3731 VariantInit(&arg[2]);
3732 params.cArgs = 3;
3733 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3734 todo_wine
3735 ok(hr == S_OK, "error %#x\n", hr);
3737 VariantInit(&arg[0]);
3738 VariantInit(&arg[1]);
3739 VariantInit(&arg[2]);
3741 params.cArgs = 1;
3742 V_VT(&arg[0]) = VT_I4;
3743 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage;
3744 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3745 ok(hr == S_OK, "error %#x\n", hr);
3747 V_VT(&ret) = 0xdead;
3748 V_I4(&ret) = 0xbeef;
3749 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, &ret, NULL, NULL);
3750 ok(hr == S_OK, "error %#x\n", hr);
3751 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3752 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3754 V_VT(&ret) = 0xdead;
3755 V_I4(&ret) = 0xbeef;
3756 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, NULL);
3757 ok(hr == S_OK, "error %#x\n", hr);
3758 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3759 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3761 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3762 ok(hr == S_OK, "error %#x\n", hr);
3764 V_VT(&ret) = 0xdead;
3765 V_I4(&ret) = 0xbeef;
3766 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, &ret, NULL, NULL);
3767 ok(hr == S_OK, "error %#x\n", hr);
3768 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %d\n", V_VT(&ret));
3769 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret));
3771 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, NULL, NULL, NULL);
3772 ok(hr == S_OK, "error %#x\n", hr);
3774 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3775 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
3777 params.cArgs = 2;
3778 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3779 todo_wine
3780 ok(hr == S_OK, "error %#x\n", hr);
3782 params.cArgs = 0;
3783 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3784 ok(hr == DISP_E_PARAMNOTFOUND, "error %#x\n", hr);
3786 SysFreeString(utf8);
3788 params.cArgs = 1;
3789 V_VT(&arg[0]) = VT_I4;
3790 V_I4(&arg[0]) = AutoLogonPolicy_Never;
3791 VariantInit(&ret);
3792 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0,
3793 DISPATCH_METHOD, &params, &ret, NULL, NULL);
3794 ok(hr == S_OK, "error %#x\n", hr);
3796 IWinHttpRequest_Release(request);
3798 CoUninitialize();
3801 static void test_WinHttpDetectAutoProxyConfigUrl(void)
3803 BOOL ret;
3804 WCHAR *url;
3805 DWORD error;
3807 if (0) /* crashes on some win2k systems */
3809 SetLastError(0xdeadbeef);
3810 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
3811 error = GetLastError();
3812 ok( !ret, "expected failure\n" );
3813 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3815 url = NULL;
3816 SetLastError(0xdeadbeef);
3817 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
3818 error = GetLastError();
3819 ok( !ret, "expected failure\n" );
3820 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3822 if (0) /* crashes on some win2k systems */
3824 SetLastError(0xdeadbeef);
3825 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
3826 error = GetLastError();
3827 ok( !ret, "expected failure\n" );
3828 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3830 url = (WCHAR *)0xdeadbeef;
3831 SetLastError(0xdeadbeef);
3832 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
3833 error = GetLastError();
3834 if (!ret)
3836 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
3837 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
3839 else
3841 trace("%s\n", wine_dbgstr_w(url));
3842 GlobalFree( url );
3845 url = (WCHAR *)0xdeadbeef;
3846 SetLastError(0xdeadbeef);
3847 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
3848 error = GetLastError();
3849 if (!ret)
3851 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
3852 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
3854 else
3856 ok( error == ERROR_SUCCESS, "got %u\n", error );
3857 trace("%s\n", wine_dbgstr_w(url));
3858 GlobalFree( url );
3862 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
3864 BOOL ret;
3865 DWORD error;
3866 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
3868 memset( &cfg, 0, sizeof(cfg) );
3870 SetLastError(0xdeadbeef);
3871 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
3872 error = GetLastError();
3873 ok( !ret, "expected failure\n" );
3874 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3876 SetLastError(0xdeadbeef);
3877 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
3878 error = GetLastError();
3879 ok( ret, "expected success\n" );
3880 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error );
3882 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
3883 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
3884 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
3885 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
3886 GlobalFree( cfg.lpszAutoConfigUrl );
3887 GlobalFree( cfg.lpszProxy );
3888 GlobalFree( cfg.lpszProxyBypass );
3891 static void test_WinHttpGetProxyForUrl(void)
3893 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
3894 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
3895 static const WCHAR emptyW[] = {0};
3896 BOOL ret;
3897 DWORD error;
3898 HINTERNET session;
3899 WINHTTP_AUTOPROXY_OPTIONS options;
3900 WINHTTP_PROXY_INFO info;
3902 memset( &options, 0, sizeof(options) );
3904 SetLastError(0xdeadbeef);
3905 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
3906 error = GetLastError();
3907 ok( !ret, "expected failure\n" );
3908 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
3910 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
3911 ok( session != NULL, "failed to open session %u\n", GetLastError() );
3913 SetLastError(0xdeadbeef);
3914 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
3915 error = GetLastError();
3916 ok( !ret, "expected failure\n" );
3917 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3919 SetLastError(0xdeadbeef);
3920 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
3921 error = GetLastError();
3922 ok( !ret, "expected failure\n" );
3923 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3925 SetLastError(0xdeadbeef);
3926 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
3927 error = GetLastError();
3928 ok( !ret, "expected failure\n" );
3929 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3931 SetLastError(0xdeadbeef);
3932 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3933 error = GetLastError();
3934 ok( !ret, "expected failure\n" );
3935 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3937 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3938 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3940 SetLastError(0xdeadbeef);
3941 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
3942 error = GetLastError();
3943 ok( !ret, "expected failure\n" );
3944 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3946 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3947 options.dwAutoDetectFlags = 0;
3949 SetLastError(0xdeadbeef);
3950 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3951 error = GetLastError();
3952 ok( !ret, "expected failure\n" );
3953 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3955 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
3956 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3958 SetLastError(0xdeadbeef);
3959 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3960 error = GetLastError();
3961 ok( !ret, "expected failure\n" );
3962 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3964 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3965 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3967 memset( &info, 0, sizeof(info) );
3968 SetLastError(0xdeadbeef);
3969 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3970 error = GetLastError();
3971 if (ret)
3973 ok( error == ERROR_SUCCESS, "got %u\n", error );
3974 trace("Proxy.AccessType=%u\n", info.dwAccessType);
3975 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
3976 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
3977 GlobalFree( info.lpszProxy );
3978 GlobalFree( info.lpszProxyBypass );
3981 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
3982 options.dwAutoDetectFlags = 0;
3983 options.lpszAutoConfigUrl = wpadW;
3985 memset( &info, 0, sizeof(info) );
3986 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3987 if (ret)
3989 trace("Proxy.AccessType=%u\n", info.dwAccessType);
3990 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
3991 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
3992 GlobalFree( info.lpszProxy );
3993 GlobalFree( info.lpszProxyBypass );
3995 WinHttpCloseHandle( session );
3998 static void test_chunked_read(void)
4000 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4001 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
4002 WCHAR header[32];
4003 DWORD len, err;
4004 HINTERNET ses, con = NULL, req = NULL;
4005 BOOL ret;
4007 trace( "starting chunked read test\n" );
4009 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
4010 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
4011 if (!ses) goto done;
4013 con = WinHttpConnect( ses, test_winehq, 0, 0 );
4014 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
4015 if (!con) goto done;
4017 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
4018 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4019 if (!req) goto done;
4021 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4022 err = GetLastError();
4023 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
4025 skip("connection failed, skipping\n");
4026 goto done;
4028 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4030 ret = WinHttpReceiveResponse( req, NULL );
4031 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4033 header[0] = 0;
4034 len = sizeof(header);
4035 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
4036 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4037 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
4038 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
4040 header[0] = 0;
4041 len = sizeof(header);
4042 SetLastError( 0xdeadbeef );
4043 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
4044 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
4045 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
4047 trace( "entering query loop\n" );
4048 for (;;)
4050 len = 0xdeadbeef;
4051 ret = WinHttpQueryDataAvailable( req, &len );
4052 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4053 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4054 trace( "got %u available\n", len );
4055 if (len)
4057 DWORD bytes_read;
4058 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
4060 ret = WinHttpReadData( req, buf, len, &bytes_read );
4062 buf[bytes_read] = 0;
4063 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
4064 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
4065 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
4067 HeapFree( GetProcessHeap(), 0, buf );
4068 if (!bytes_read) break;
4070 if (!len) break;
4072 trace( "done\n" );
4074 done:
4075 if (req) WinHttpCloseHandle( req );
4076 if (con) WinHttpCloseHandle( con );
4077 if (ses) WinHttpCloseHandle( ses );
4080 START_TEST (winhttp)
4082 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
4083 static const WCHAR quitW[] = {'/','q','u','i','t',0};
4084 struct server_info si;
4085 HANDLE thread;
4086 DWORD ret;
4088 test_OpenRequest();
4089 test_SendRequest();
4090 test_WinHttpTimeFromSystemTime();
4091 test_WinHttpTimeToSystemTime();
4092 test_WinHttpAddHeaders();
4093 test_secure_connection();
4094 test_request_parameter_defaults();
4095 test_QueryOption();
4096 test_set_default_proxy_config();
4097 test_empty_headers_param();
4098 test_Timeouts();
4099 test_resolve_timeout();
4100 test_credentials();
4101 test_IWinHttpRequest();
4102 test_IWinHttpRequest_Invoke();
4103 test_WinHttpDetectAutoProxyConfigUrl();
4104 test_WinHttpGetIEProxyConfigForCurrentUser();
4105 test_WinHttpGetProxyForUrl();
4106 test_chunked_read();
4108 si.event = CreateEventW(NULL, 0, 0, NULL);
4109 si.port = 7532;
4111 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
4112 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
4114 ret = WaitForSingleObject(si.event, 10000);
4115 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
4116 if (ret != WAIT_OBJECT_0)
4117 return;
4119 test_connection_info(si.port);
4120 test_basic_request(si.port, NULL, basicW);
4121 test_no_headers(si.port);
4122 test_no_content(si.port);
4123 test_head_request(si.port);
4124 test_not_modified(si.port);
4125 test_basic_authentication(si.port);
4126 test_bad_header(si.port);
4127 test_multiple_reads(si.port);
4128 test_cookies(si.port);
4130 /* send the basic request again to shutdown the server thread */
4131 test_basic_request(si.port, NULL, quitW);
4133 WaitForSingleObject(thread, 3000);