widl: Do not create duplicate type info entries when tag and typedef names are the...
[wine/multimedia.git] / dlls / winhttp / tests / winhttp.c
blobbd6b47f3b9b8ba88b3e4ce8ffdabaa2961be58f3
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 HINTERNET ses, con, req;
974 DWORD size, status, policy, bitness, read_size, err;
975 BOOL ret;
976 CERT_CONTEXT *cert;
977 WINHTTP_CERTIFICATE_INFO info;
978 char buffer[32];
980 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
981 ok(ses != NULL, "failed to open session %u\n", GetLastError());
983 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
984 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
985 ok(ret, "failed to set redirect policy %u\n", GetLastError());
987 con = WinHttpConnect(ses, test_winehq, 443, 0);
988 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
990 /* try without setting WINHTTP_FLAG_SECURE */
991 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
992 ok(req != NULL, "failed to open a request %u\n", GetLastError());
994 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
995 err = GetLastError();
996 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
998 skip("Connection failed, skipping.\n");
999 goto cleanup;
1001 ok(ret, "failed to send request %u\n", GetLastError());
1003 ret = WinHttpReceiveResponse(req, NULL);
1004 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
1006 size = 0;
1007 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1008 ok(!ret, "succeeded unexpectedly\n");
1010 WinHttpCloseHandle(req);
1012 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
1013 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1015 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
1017 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1018 err = GetLastError();
1019 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT ||
1020 err == ERROR_WINHTTP_TIMEOUT))
1022 skip("secure connection failed, skipping remaining secure tests\n");
1023 goto cleanup;
1025 ok(ret, "failed to send request %u\n", GetLastError());
1027 size = sizeof(cert);
1028 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
1029 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1030 if (ret) CertFreeCertificateContext(cert);
1032 size = sizeof(bitness);
1033 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
1034 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
1036 size = sizeof(info);
1037 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
1038 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
1040 if (ret)
1042 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
1043 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
1044 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
1045 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
1046 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
1047 trace("dwKeySize %u\n", info.dwKeySize);
1050 ret = WinHttpReceiveResponse(req, NULL);
1051 ok(ret, "failed to receive response %u\n", GetLastError());
1053 status = 0xdeadbeef;
1054 size = sizeof(status);
1055 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1056 ok(ret, "failed unexpectedly %u\n", GetLastError());
1057 ok(status == 200, "request failed unexpectedly %u\n", status);
1059 size = 0;
1060 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1061 ok(!ret, "succeeded unexpectedly\n");
1063 read_size = 0;
1064 for (;;)
1066 size = 0;
1067 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
1068 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
1069 if (!size) break;
1070 read_size += size;
1072 ok(read_size > 2014, "read_size = %u\n", read_size);
1074 cleanup:
1075 WinHttpCloseHandle(req);
1076 WinHttpCloseHandle(con);
1077 WinHttpCloseHandle(ses);
1080 static void test_request_parameter_defaults(void)
1082 static const WCHAR empty[] = {0};
1083 HINTERNET ses, con, req;
1084 DWORD size, status, error;
1085 WCHAR *version;
1086 BOOL ret;
1088 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1089 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1091 con = WinHttpConnect(ses, test_winehq, 0, 0);
1092 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1094 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1095 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1097 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1098 error = GetLastError();
1099 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1101 skip("connection failed, skipping\n");
1102 goto done;
1104 ok(ret, "failed to send request %u\n", GetLastError());
1106 ret = WinHttpReceiveResponse(req, NULL);
1107 if (!ret && GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE) /* win2k */
1109 win_skip("invalid response\n");
1110 goto done;
1112 ok(ret, "failed to receive response %u\n", GetLastError());
1114 status = 0xdeadbeef;
1115 size = sizeof(status);
1116 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1117 ok(ret, "failed unexpectedly %u\n", GetLastError());
1118 ok(status == 200, "request failed unexpectedly %u\n", status);
1120 WinHttpCloseHandle(req);
1122 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
1123 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1125 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1126 error = GetLastError();
1127 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1129 skip("connection failed, skipping\n");
1130 goto done;
1132 ok(ret, "failed to send request %u\n", GetLastError());
1134 ret = WinHttpReceiveResponse(req, NULL);
1135 ok(ret, "failed to receive response %u\n", GetLastError());
1137 size = 0;
1138 SetLastError(0xdeadbeef);
1139 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
1140 error = GetLastError();
1141 ok(!ret, "succeeded unexpectedly\n");
1142 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
1144 version = HeapAlloc(GetProcessHeap(), 0, size);
1145 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
1146 ok(ret, "failed unexpectedly %u\n", GetLastError());
1147 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
1148 HeapFree(GetProcessHeap(), 0, version);
1150 status = 0xdeadbeef;
1151 size = sizeof(status);
1152 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1153 ok(ret, "failed unexpectedly %u\n", GetLastError());
1154 ok(status == 200, "request failed unexpectedly %u\n", status);
1156 done:
1157 WinHttpCloseHandle(req);
1158 WinHttpCloseHandle(con);
1159 WinHttpCloseHandle(ses);
1162 static const WCHAR Connections[] = {
1163 'S','o','f','t','w','a','r','e','\\',
1164 'M','i','c','r','o','s','o','f','t','\\',
1165 'W','i','n','d','o','w','s','\\',
1166 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1167 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1168 'C','o','n','n','e','c','t','i','o','n','s',0 };
1169 static const WCHAR WinHttpSettings[] = {
1170 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1172 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
1174 LONG l;
1175 HKEY key;
1176 DWORD ret = 0;
1178 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
1179 if (!l)
1181 DWORD size = 0;
1183 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
1184 if (!l)
1186 if (size <= len)
1187 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1188 &size );
1189 if (!l)
1190 ret = size;
1192 RegCloseKey( key );
1194 return ret;
1197 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1199 LONG l;
1200 HKEY key;
1202 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
1203 KEY_WRITE, NULL, &key, NULL );
1204 if (!l)
1206 if (len)
1207 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1208 else
1209 RegDeleteValueW( key, WinHttpSettings );
1210 RegCloseKey( key );
1214 static void test_set_default_proxy_config(void)
1216 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1217 static WCHAR normalString[] = { 'f','o','o',0 };
1218 DWORD type, len;
1219 BYTE *saved_proxy_settings = NULL;
1220 WINHTTP_PROXY_INFO info;
1221 BOOL ret;
1223 /* FIXME: it would be simpler to read the current settings using
1224 * WinHttpGetDefaultProxyConfiguration and save them using
1225 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1227 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1228 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1229 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1230 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1231 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1232 * the lpszProxy and lpszProxyBypass values are ignored.
1233 * Thus, if a proxy is set with proxycfg, then calling
1234 * WinHttpGetDefaultProxyConfiguration followed by
1235 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1236 * getting deleted from the registry.
1238 * Instead I read the current registry value and restore it directly.
1240 len = get_default_proxy_reg_value( NULL, 0, &type );
1241 if (len)
1243 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1244 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1247 if (0)
1249 /* Crashes on Vista and higher */
1250 SetLastError(0xdeadbeef);
1251 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1252 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1253 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1256 /* test with invalid access type */
1257 info.dwAccessType = 0xdeadbeef;
1258 info.lpszProxy = info.lpszProxyBypass = NULL;
1259 SetLastError(0xdeadbeef);
1260 ret = WinHttpSetDefaultProxyConfiguration(&info);
1261 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1262 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1264 /* at a minimum, the proxy server must be set */
1265 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1266 info.lpszProxy = info.lpszProxyBypass = NULL;
1267 SetLastError(0xdeadbeef);
1268 ret = WinHttpSetDefaultProxyConfiguration(&info);
1269 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1270 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1271 info.lpszProxyBypass = normalString;
1272 SetLastError(0xdeadbeef);
1273 ret = WinHttpSetDefaultProxyConfiguration(&info);
1274 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1275 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1277 /* the proxy server can't have wide characters */
1278 info.lpszProxy = wideString;
1279 SetLastError(0xdeadbeef);
1280 ret = WinHttpSetDefaultProxyConfiguration(&info);
1281 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1282 skip("couldn't set default proxy configuration: access denied\n");
1283 else
1284 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1285 broken(ret), /* Earlier winhttp versions on W2K/XP */
1286 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1288 info.lpszProxy = normalString;
1289 SetLastError(0xdeadbeef);
1290 ret = WinHttpSetDefaultProxyConfiguration(&info);
1291 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1292 skip("couldn't set default proxy configuration: access denied\n");
1293 else
1295 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1296 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1297 "got %u\n", GetLastError());
1299 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1302 static void test_Timeouts (void)
1304 BOOL ret;
1305 DWORD value, size;
1306 HINTERNET ses, req, con;
1308 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1309 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1311 SetLastError(0xdeadbeef);
1312 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1313 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1314 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1316 SetLastError(0xdeadbeef);
1317 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1318 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1319 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1321 SetLastError(0xdeadbeef);
1322 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1323 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1324 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1326 SetLastError(0xdeadbeef);
1327 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1328 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1329 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1331 SetLastError(0xdeadbeef);
1332 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1333 ok(ret, "%u\n", GetLastError());
1334 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1335 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1337 SetLastError(0xdeadbeef);
1338 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1339 ok(ret, "%u\n", GetLastError());
1341 SetLastError(0xdeadbeef);
1342 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1343 ok(ret, "%u\n", GetLastError());
1345 SetLastError(0xdeadbeef);
1346 value = 0xdeadbeef;
1347 size = sizeof(DWORD);
1348 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1349 ok(ret, "%u\n", GetLastError());
1350 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1352 SetLastError(0xdeadbeef);
1353 value = 0xdeadbeef;
1354 size = sizeof(DWORD);
1355 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1356 ok(ret, "%u\n", GetLastError());
1357 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1359 SetLastError(0xdeadbeef);
1360 value = 0xdeadbeef;
1361 size = sizeof(DWORD);
1362 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1363 ok(ret, "%u\n", GetLastError());
1364 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1366 SetLastError(0xdeadbeef);
1367 value = 0xdeadbeef;
1368 size = sizeof(DWORD);
1369 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1370 ok(ret, "%u\n", GetLastError());
1371 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1373 SetLastError(0xdeadbeef);
1374 value = 0;
1375 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1376 ok(ret, "%u\n", GetLastError());
1378 SetLastError(0xdeadbeef);
1379 value = 0xdeadbeef;
1380 size = sizeof(DWORD);
1381 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1382 ok(ret, "%u\n", GetLastError());
1383 ok(value == 0, "Expected 0, got %u\n", value);
1385 SetLastError(0xdeadbeef);
1386 value = 0;
1387 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1388 ok(ret, "%u\n", GetLastError());
1390 SetLastError(0xdeadbeef);
1391 value = 0xdeadbeef;
1392 size = sizeof(DWORD);
1393 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1394 ok(ret, "%u\n", GetLastError());
1395 ok(value == 0, "Expected 0, got %u\n", value);
1397 SetLastError(0xdeadbeef);
1398 value = 0;
1399 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1400 ok(ret, "%u\n", GetLastError());
1402 SetLastError(0xdeadbeef);
1403 value = 0xdeadbeef;
1404 size = sizeof(DWORD);
1405 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1406 ok(ret, "%u\n", GetLastError());
1407 ok(value == 0, "Expected 0, got %u\n", value);
1409 SetLastError(0xdeadbeef);
1410 value = 0;
1411 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1412 ok(ret, "%u\n", GetLastError());
1414 SetLastError(0xdeadbeef);
1415 value = 0xdeadbeef;
1416 size = sizeof(DWORD);
1417 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1418 ok(ret, "%u\n", GetLastError());
1419 ok(value == 0, "Expected 0, got %u\n", value);
1421 SetLastError(0xdeadbeef);
1422 value = 0xbeefdead;
1423 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1424 ok(ret, "%u\n", GetLastError());
1426 SetLastError(0xdeadbeef);
1427 value = 0xdeadbeef;
1428 size = sizeof(DWORD);
1429 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1430 ok(ret, "%u\n", GetLastError());
1431 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1433 SetLastError(0xdeadbeef);
1434 value = 0xbeefdead;
1435 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1436 ok(ret, "%u\n", GetLastError());
1438 SetLastError(0xdeadbeef);
1439 value = 0xdeadbeef;
1440 size = sizeof(DWORD);
1441 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1442 ok(ret, "%u\n", GetLastError());
1443 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1445 SetLastError(0xdeadbeef);
1446 value = 0xbeefdead;
1447 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1448 ok(ret, "%u\n", GetLastError());
1450 SetLastError(0xdeadbeef);
1451 value = 0xdeadbeef;
1452 size = sizeof(DWORD);
1453 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1454 ok(ret, "%u\n", GetLastError());
1455 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1457 SetLastError(0xdeadbeef);
1458 value = 0xbeefdead;
1459 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1460 ok(ret, "%u\n", GetLastError());
1462 SetLastError(0xdeadbeef);
1463 value = 0xdeadbeef;
1464 size = sizeof(DWORD);
1465 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1466 ok(ret, "%u\n", GetLastError());
1467 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1469 con = WinHttpConnect(ses, test_winehq, 0, 0);
1470 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1472 /* Timeout values should match the last one set for session */
1473 SetLastError(0xdeadbeef);
1474 value = 0xdeadbeef;
1475 size = sizeof(DWORD);
1476 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1477 ok(ret, "%u\n", GetLastError());
1478 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1480 SetLastError(0xdeadbeef);
1481 value = 0xdeadbeef;
1482 size = sizeof(DWORD);
1483 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1484 ok(ret, "%u\n", GetLastError());
1485 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1487 SetLastError(0xdeadbeef);
1488 value = 0xdeadbeef;
1489 size = sizeof(DWORD);
1490 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1491 ok(ret, "%u\n", GetLastError());
1492 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1494 SetLastError(0xdeadbeef);
1495 value = 0xdeadbeef;
1496 size = sizeof(DWORD);
1497 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1498 ok(ret, "%u\n", GetLastError());
1499 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1501 SetLastError(0xdeadbeef);
1502 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1503 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1504 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1506 SetLastError(0xdeadbeef);
1507 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1508 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1509 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1511 SetLastError(0xdeadbeef);
1512 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1513 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1514 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1516 SetLastError(0xdeadbeef);
1517 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1518 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1519 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1521 SetLastError(0xdeadbeef);
1522 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1523 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1524 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1526 SetLastError(0xdeadbeef);
1527 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1528 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1529 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1531 SetLastError(0xdeadbeef);
1532 value = 0;
1533 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1534 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1535 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1537 SetLastError(0xdeadbeef);
1538 value = 0;
1539 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1540 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1541 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1543 SetLastError(0xdeadbeef);
1544 value = 0;
1545 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1546 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1547 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1549 SetLastError(0xdeadbeef);
1550 value = 0;
1551 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1552 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1553 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1555 /* Changing timeout values for session should affect the values for connection */
1556 SetLastError(0xdeadbeef);
1557 value = 0xdead;
1558 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1559 ok(ret, "%u\n", GetLastError());
1561 SetLastError(0xdeadbeef);
1562 value = 0xdeadbeef;
1563 size = sizeof(DWORD);
1564 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1565 ok(ret, "%u\n", GetLastError());
1566 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1568 SetLastError(0xdeadbeef);
1569 value = 0xdead;
1570 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1571 ok(ret, "%u\n", GetLastError());
1573 SetLastError(0xdeadbeef);
1574 value = 0xdeadbeef;
1575 size = sizeof(DWORD);
1576 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1577 ok(ret, "%u\n", GetLastError());
1578 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1580 SetLastError(0xdeadbeef);
1581 value = 0xdead;
1582 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1583 ok(ret, "%u\n", GetLastError());
1585 SetLastError(0xdeadbeef);
1586 value = 0xdeadbeef;
1587 size = sizeof(DWORD);
1588 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1589 ok(ret, "%u\n", GetLastError());
1590 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1592 SetLastError(0xdeadbeef);
1593 value = 0xdead;
1594 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1595 ok(ret, "%u\n", GetLastError());
1597 SetLastError(0xdeadbeef);
1598 value = 0xdeadbeef;
1599 size = sizeof(DWORD);
1600 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1601 ok(ret, "%u\n", GetLastError());
1602 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1604 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1605 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1607 /* Timeout values should match the last one set for session */
1608 SetLastError(0xdeadbeef);
1609 value = 0xdeadbeef;
1610 size = sizeof(DWORD);
1611 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1612 ok(ret, "%u\n", GetLastError());
1613 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1615 SetLastError(0xdeadbeef);
1616 value = 0xdeadbeef;
1617 size = sizeof(DWORD);
1618 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1619 ok(ret, "%u\n", GetLastError());
1620 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1622 SetLastError(0xdeadbeef);
1623 value = 0xdeadbeef;
1624 size = sizeof(DWORD);
1625 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1626 ok(ret, "%u\n", GetLastError());
1627 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1629 SetLastError(0xdeadbeef);
1630 value = 0xdeadbeef;
1631 size = sizeof(DWORD);
1632 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1633 ok(ret, "%u\n", GetLastError());
1634 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1636 SetLastError(0xdeadbeef);
1637 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1638 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1639 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1641 SetLastError(0xdeadbeef);
1642 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1643 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1644 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1646 SetLastError(0xdeadbeef);
1647 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1648 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1649 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1651 SetLastError(0xdeadbeef);
1652 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1653 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1654 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1656 SetLastError(0xdeadbeef);
1657 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1658 ok(ret, "%u\n", GetLastError());
1660 SetLastError(0xdeadbeef);
1661 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1662 ok(ret, "%u\n", GetLastError());
1664 SetLastError(0xdeadbeef);
1665 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1666 ok(ret, "%u\n", GetLastError());
1668 SetLastError(0xdeadbeef);
1669 value = 0xdeadbeef;
1670 size = sizeof(DWORD);
1671 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1672 ok(ret, "%u\n", GetLastError());
1673 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1675 SetLastError(0xdeadbeef);
1676 value = 0xdeadbeef;
1677 size = sizeof(DWORD);
1678 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1679 ok(ret, "%u\n", GetLastError());
1680 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1682 SetLastError(0xdeadbeef);
1683 value = 0xdeadbeef;
1684 size = sizeof(DWORD);
1685 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1686 ok(ret, "%u\n", GetLastError());
1687 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1689 SetLastError(0xdeadbeef);
1690 value = 0xdeadbeef;
1691 size = sizeof(DWORD);
1692 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1693 ok(ret, "%u\n", GetLastError());
1694 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1696 SetLastError(0xdeadbeef);
1697 value = 0;
1698 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1699 ok(ret, "%u\n", GetLastError());
1701 SetLastError(0xdeadbeef);
1702 value = 0xdeadbeef;
1703 size = sizeof(DWORD);
1704 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1705 ok(ret, "%u\n", GetLastError());
1706 ok(value == 0, "Expected 0, got %u\n", value);
1708 SetLastError(0xdeadbeef);
1709 value = 0;
1710 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1711 ok(ret, "%u\n", GetLastError());
1713 SetLastError(0xdeadbeef);
1714 value = 0xdeadbeef;
1715 size = sizeof(DWORD);
1716 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1717 ok(ret, "%u\n", GetLastError());
1718 ok(value == 0, "Expected 0, got %u\n", value);
1720 SetLastError(0xdeadbeef);
1721 value = 0;
1722 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1723 ok(ret, "%u\n", GetLastError());
1725 SetLastError(0xdeadbeef);
1726 value = 0xdeadbeef;
1727 size = sizeof(DWORD);
1728 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1729 ok(ret, "%u\n", GetLastError());
1730 ok(value == 0, "Expected 0, got %u\n", value);
1732 SetLastError(0xdeadbeef);
1733 value = 0;
1734 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1735 ok(ret, "%u\n", GetLastError());
1737 SetLastError(0xdeadbeef);
1738 value = 0xdeadbeef;
1739 size = sizeof(DWORD);
1740 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1741 ok(ret, "%u\n", GetLastError());
1742 ok(value == 0, "Expected 0, got %u\n", value);
1744 SetLastError(0xdeadbeef);
1745 value = 0xbeefdead;
1746 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1747 ok(ret, "%u\n", GetLastError());
1749 SetLastError(0xdeadbeef);
1750 value = 0xdeadbeef;
1751 size = sizeof(DWORD);
1752 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1753 ok(ret, "%u\n", GetLastError());
1754 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1756 SetLastError(0xdeadbeef);
1757 value = 0xbeefdead;
1758 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1759 ok(ret, "%u\n", GetLastError());
1761 SetLastError(0xdeadbeef);
1762 value = 0xdeadbeef;
1763 size = sizeof(DWORD);
1764 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1765 ok(ret, "%u\n", GetLastError());
1766 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1768 SetLastError(0xdeadbeef);
1769 value = 0xbeefdead;
1770 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1771 ok(ret, "%u\n", GetLastError());
1773 SetLastError(0xdeadbeef);
1774 value = 0xdeadbeef;
1775 size = sizeof(DWORD);
1776 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1777 ok(ret, "%u\n", GetLastError());
1778 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1780 SetLastError(0xdeadbeef);
1781 value = 0xbeefdead;
1782 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1783 ok(ret, "%u\n", GetLastError());
1785 SetLastError(0xdeadbeef);
1786 value = 0xdeadbeef;
1787 size = sizeof(DWORD);
1788 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1789 ok(ret, "%u\n", GetLastError());
1790 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1792 /* Changing timeout values for session should not affect the values for a request,
1793 * neither should the other way around.
1795 SetLastError(0xdeadbeef);
1796 value = 0xbeefdead;
1797 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1798 ok(ret, "%u\n", GetLastError());
1800 SetLastError(0xdeadbeef);
1801 value = 0xdeadbeef;
1802 size = sizeof(DWORD);
1803 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1804 ok(ret, "%u\n", GetLastError());
1805 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1807 SetLastError(0xdeadbeef);
1808 value = 0xbeefdead;
1809 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1810 ok(ret, "%u\n", GetLastError());
1812 SetLastError(0xdeadbeef);
1813 value = 0xdeadbeef;
1814 size = sizeof(DWORD);
1815 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1816 ok(ret, "%u\n", GetLastError());
1817 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1819 SetLastError(0xdeadbeef);
1820 value = 0xbeefdead;
1821 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1822 ok(ret, "%u\n", GetLastError());
1824 SetLastError(0xdeadbeef);
1825 value = 0xdeadbeef;
1826 size = sizeof(DWORD);
1827 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1828 ok(ret, "%u\n", GetLastError());
1829 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1831 SetLastError(0xdeadbeef);
1832 value = 0xbeefdead;
1833 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1834 ok(ret, "%u\n", GetLastError());
1836 SetLastError(0xdeadbeef);
1837 value = 0xdeadbeef;
1838 size = sizeof(DWORD);
1839 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1840 ok(ret, "%u\n", GetLastError());
1841 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1843 SetLastError(0xdeadbeef);
1844 value = 0xbeef;
1845 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1846 ok(ret, "%u\n", GetLastError());
1848 SetLastError(0xdeadbeef);
1849 value = 0xdeadbeef;
1850 size = sizeof(DWORD);
1851 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1852 ok(ret, "%u\n", GetLastError());
1853 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1855 SetLastError(0xdeadbeef);
1856 value = 0xbeef;
1857 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1858 ok(ret, "%u\n", GetLastError());
1860 SetLastError(0xdeadbeef);
1861 value = 0xdeadbeef;
1862 size = sizeof(DWORD);
1863 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1864 ok(ret, "%u\n", GetLastError());
1865 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1867 SetLastError(0xdeadbeef);
1868 value = 0xbeef;
1869 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1870 ok(ret, "%u\n", GetLastError());
1872 SetLastError(0xdeadbeef);
1873 value = 0xdeadbeef;
1874 size = sizeof(DWORD);
1875 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1876 ok(ret, "%u\n", GetLastError());
1877 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1879 SetLastError(0xdeadbeef);
1880 value = 0xbeef;
1881 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1882 ok(ret, "%u\n", GetLastError());
1884 SetLastError(0xdeadbeef);
1885 value = 0xdeadbeef;
1886 size = sizeof(DWORD);
1887 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1888 ok(ret, "%u\n", GetLastError());
1889 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1891 WinHttpCloseHandle(req);
1892 WinHttpCloseHandle(con);
1893 WinHttpCloseHandle(ses);
1896 static void test_resolve_timeout(void)
1898 static const WCHAR nxdomain[] =
1899 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1900 HINTERNET ses, con, req;
1901 DWORD timeout;
1902 BOOL ret;
1904 if (! proxy_active())
1906 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1907 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1909 timeout = 10000;
1910 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1911 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1913 con = WinHttpConnect(ses, nxdomain, 0, 0);
1914 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1916 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1917 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1919 SetLastError(0xdeadbeef);
1920 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1921 if (ret)
1923 skip("nxdomain returned success. Broken ISP redirects?\n");
1924 goto done;
1926 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1927 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1929 WinHttpCloseHandle(req);
1930 WinHttpCloseHandle(con);
1931 WinHttpCloseHandle(ses);
1933 else
1934 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1936 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1937 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1939 timeout = 10000;
1940 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1941 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1943 con = WinHttpConnect(ses, test_winehq, 0, 0);
1944 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1946 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1947 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1949 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1950 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
1952 skip("connection failed, skipping\n");
1953 goto done;
1955 ok(ret, "failed to send request\n");
1957 done:
1958 WinHttpCloseHandle(req);
1959 WinHttpCloseHandle(con);
1960 WinHttpCloseHandle(ses);
1963 static const char page1[] =
1964 "<HTML>\r\n"
1965 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1966 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1967 "</HTML>\r\n\r\n";
1969 static const char okmsg[] =
1970 "HTTP/1.1 200 OK\r\n"
1971 "Server: winetest\r\n"
1972 "\r\n";
1974 static const char notokmsg[] =
1975 "HTTP/1.1 400 Bad Request\r\n"
1976 "\r\n";
1978 static const char cookiemsg[] =
1979 "HTTP/1.1 200 OK\r\n"
1980 "Set-Cookie: name = value \r\n"
1981 "Set-Cookie: NAME = value \r\n"
1982 "\r\n";
1984 static const char nocontentmsg[] =
1985 "HTTP/1.1 204 No Content\r\n"
1986 "Server: winetest\r\n"
1987 "\r\n";
1989 static const char notmodified[] =
1990 "HTTP/1.1 304 Not Modified\r\n"
1991 "\r\n";
1993 static const char noauthmsg[] =
1994 "HTTP/1.1 401 Unauthorized\r\n"
1995 "Server: winetest\r\n"
1996 "Connection: close\r\n"
1997 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1998 "\r\n";
2000 static const char okauthmsg[] =
2001 "HTTP/1.1 200 OK\r\n"
2002 "Server: winetest\r\n"
2003 "Connection: close\r\n"
2004 "\r\n";
2006 static const char headmsg[] =
2007 "HTTP/1.1 200 OK\r\n"
2008 "Content-Length: 100\r\n"
2009 "\r\n";
2011 struct server_info
2013 HANDLE event;
2014 int port;
2017 #define BIG_BUFFER_LEN 0x2250
2019 static DWORD CALLBACK server_thread(LPVOID param)
2021 struct server_info *si = param;
2022 int r, c = -1, i, on;
2023 SOCKET s;
2024 struct sockaddr_in sa;
2025 char buffer[0x100];
2026 WSADATA wsaData;
2027 int last_request = 0;
2029 WSAStartup(MAKEWORD(1,1), &wsaData);
2031 s = socket(AF_INET, SOCK_STREAM, 0);
2032 if (s == INVALID_SOCKET)
2033 return 1;
2035 on = 1;
2036 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2038 memset(&sa, 0, sizeof sa);
2039 sa.sin_family = AF_INET;
2040 sa.sin_port = htons(si->port);
2041 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2043 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
2044 if (r < 0)
2045 return 1;
2047 listen(s, 0);
2048 SetEvent(si->event);
2051 if (c == -1) c = accept(s, NULL, NULL);
2053 memset(buffer, 0, sizeof buffer);
2054 for(i = 0; i < sizeof buffer - 1; i++)
2056 r = recv(c, &buffer[i], 1, 0);
2057 if (r != 1)
2058 break;
2059 if (i < 4) continue;
2060 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
2061 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
2062 break;
2064 if (strstr(buffer, "GET /basic"))
2066 send(c, okmsg, sizeof okmsg - 1, 0);
2067 send(c, page1, sizeof page1 - 1, 0);
2069 if (strstr(buffer, "/auth"))
2071 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2072 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2073 else
2074 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
2076 if (strstr(buffer, "/big"))
2078 char msg[BIG_BUFFER_LEN];
2079 memset(msg, 'm', sizeof(msg));
2080 send(c, okmsg, sizeof(okmsg) - 1, 0);
2081 send(c, msg, sizeof(msg), 0);
2083 if (strstr(buffer, "/no_headers"))
2085 send(c, page1, sizeof page1 - 1, 0);
2087 if (strstr(buffer, "GET /no_content"))
2089 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
2090 continue;
2092 if (strstr(buffer, "GET /not_modified"))
2094 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0);
2095 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2096 continue;
2098 if (strstr(buffer, "HEAD /head"))
2100 send(c, headmsg, sizeof headmsg - 1, 0);
2101 continue;
2103 if (strstr(buffer, "GET /cookie3"))
2105 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2106 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL))
2107 send(c, okmsg, sizeof(okmsg) - 1, 0);
2108 else
2109 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2111 if (strstr(buffer, "GET /cookie2"))
2113 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") ||
2114 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL))
2115 send(c, okmsg, sizeof(okmsg) - 1, 0);
2116 else
2117 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2119 else if (strstr(buffer, "GET /cookie"))
2121 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
2122 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2124 if (strstr(buffer, "GET /quit"))
2126 send(c, okmsg, sizeof okmsg - 1, 0);
2127 send(c, page1, sizeof page1 - 1, 0);
2128 last_request = 1;
2130 shutdown(c, 2);
2131 closesocket(c);
2132 c = -1;
2134 } while (!last_request);
2136 closesocket(s);
2137 return 0;
2140 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
2142 static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0};
2143 static const WCHAR test_header_end_raw[] = {0,0};
2144 HINTERNET ses, con, req;
2145 char buffer[0x100];
2146 WCHAR buffer2[0x100];
2147 DWORD count, status, size, error, supported, first, target;
2148 BOOL ret;
2150 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2151 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2153 con = WinHttpConnect(ses, localhostW, port, 0);
2154 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2156 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
2157 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2159 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2160 ok(ret, "failed to send request %u\n", GetLastError());
2162 ret = WinHttpReceiveResponse(req, NULL);
2163 ok(ret, "failed to receive response %u\n", GetLastError());
2165 status = 0xdeadbeef;
2166 size = sizeof(status);
2167 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2168 ok(ret, "failed to query status code %u\n", GetLastError());
2169 ok(status == 200, "request failed unexpectedly %u\n", status);
2171 supported = first = target = 0xdeadbeef;
2172 SetLastError(0xdeadbeef);
2173 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2174 error = GetLastError();
2175 ok(!ret, "unexpected success\n");
2176 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2177 ok(supported == 0xdeadbeef, "got %x\n", supported);
2178 ok(first == 0xdeadbeef, "got %x\n", first);
2179 ok(target == 0xdeadbeef, "got %x\n", target);
2181 size = sizeof(buffer2);
2182 memset(buffer2, 0, sizeof(buffer2));
2183 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL);
2184 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2185 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)),
2186 "WinHttpQueryHeaders returned invalid end of header string\n");
2188 size = sizeof(buffer2);
2189 memset(buffer2, 0, sizeof(buffer2));
2190 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL);
2191 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2192 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)),
2193 "WinHttpQueryHeaders returned invalid end of header string\n");
2194 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n");
2196 count = 0;
2197 memset(buffer, 0, sizeof(buffer));
2198 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
2199 ok(ret, "failed to read data %u\n", GetLastError());
2200 ok(count == sizeof page1 - 1, "count was wrong\n");
2201 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2203 WinHttpCloseHandle(req);
2204 WinHttpCloseHandle(con);
2205 WinHttpCloseHandle(ses);
2208 static void test_basic_authentication(int port)
2210 static const WCHAR authW[] = {'/','a','u','t','h',0};
2211 static WCHAR userW[] = {'u','s','e','r',0};
2212 static WCHAR passW[] = {'p','w','d',0};
2213 static WCHAR pass2W[] = {'p','w','d','2',0};
2214 HINTERNET ses, con, req;
2215 DWORD status, size, error, supported, first, target;
2216 BOOL ret;
2218 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2219 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2221 con = WinHttpConnect(ses, localhostW, port, 0);
2222 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2224 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2225 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2227 SetLastError(0xdeadbeef);
2228 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
2229 error = GetLastError();
2230 ok(!ret, "expected failure\n");
2231 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2233 SetLastError(0xdeadbeef);
2234 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
2235 error = GetLastError();
2236 ok(!ret, "expected failure\n");
2237 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2239 supported = 0xdeadbeef;
2240 SetLastError(0xdeadbeef);
2241 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2242 error = GetLastError();
2243 ok(!ret, "expected failure\n");
2244 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2245 ok(supported == 0xdeadbeef, "got %x\n", supported);
2247 supported = first = 0xdeadbeef;
2248 SetLastError(0xdeadbeef);
2249 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
2250 error = GetLastError();
2251 ok(!ret, "expected failure\n");
2252 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2253 ok(supported == 0xdeadbeef, "got %x\n", supported);
2254 ok(first == 0xdeadbeef, "got %x\n", first);
2256 supported = first = target = 0xdeadbeef;
2257 SetLastError(0xdeadbeef);
2258 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2259 error = GetLastError();
2260 ok(!ret, "expected failure\n");
2261 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2262 ok(supported == 0xdeadbeef, "got %x\n", supported);
2263 ok(first == 0xdeadbeef, "got %x\n", first);
2264 ok(target == 0xdeadbeef, "got %x\n", target);
2266 supported = first = target = 0xdeadbeef;
2267 SetLastError(0xdeadbeef);
2268 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2269 error = GetLastError();
2270 ok(!ret, "expected failure\n");
2271 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2272 ok(supported == 0xdeadbeef, "got %x\n", supported);
2273 ok(first == 0xdeadbeef, "got %x\n", first);
2274 ok(target == 0xdeadbeef, "got %x\n", target);
2276 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2277 ok(ret, "failed to send request %u\n", GetLastError());
2279 ret = WinHttpReceiveResponse(req, NULL);
2280 ok(ret, "failed to receive response %u\n", GetLastError());
2282 status = 0xdeadbeef;
2283 size = sizeof(status);
2284 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2285 ok(ret, "failed to query status code %u\n", GetLastError());
2286 ok(status == 401, "request failed unexpectedly %u\n", status);
2288 supported = first = target = 0xdeadbeef;
2289 SetLastError(0xdeadbeef);
2290 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2291 error = GetLastError();
2292 ok(ret, "failed to query authentication schemes %u\n", error);
2293 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2294 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2295 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2296 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2298 SetLastError(0xdeadbeef);
2299 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2300 error = GetLastError();
2301 ok(ret, "failed to set credentials %u\n", error);
2302 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2304 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2305 ok(ret, "failed to set credentials %u\n", GetLastError());
2307 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2308 ok(ret, "failed to set credentials %u\n", GetLastError());
2310 SetLastError(0xdeadbeef);
2311 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2312 error = GetLastError();
2313 ok(!ret, "expected failure\n");
2314 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2316 SetLastError(0xdeadbeef);
2317 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2318 error = GetLastError();
2319 ok(!ret, "expected failure\n");
2320 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2322 SetLastError(0xdeadbeef);
2323 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2324 error = GetLastError();
2325 ok(!ret, "expected failure\n");
2326 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2328 SetLastError(0xdeadbeef);
2329 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2330 error = GetLastError();
2331 ok(!ret, "expected failure\n");
2332 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2334 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2335 ok(ret, "failed to set credentials %u\n", GetLastError());
2337 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2338 ok(ret, "failed to send request %u\n", GetLastError());
2340 ret = WinHttpReceiveResponse(req, NULL);
2341 ok(ret, "failed to receive response %u\n", GetLastError());
2343 status = 0xdeadbeef;
2344 size = sizeof(status);
2345 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2346 ok(ret, "failed to query status code %u\n", GetLastError());
2347 ok(status == 200, "request failed unexpectedly %u\n", status);
2349 WinHttpCloseHandle(req);
2350 WinHttpCloseHandle(con);
2351 WinHttpCloseHandle(ses);
2353 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2355 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2356 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2358 con = WinHttpConnect(ses, localhostW, port, 0);
2359 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2361 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2362 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2364 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2365 ok(ret, "failed to set credentials %u\n", GetLastError());
2367 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2368 ok(ret, "failed to set username %u\n", GetLastError());
2370 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W));
2371 ok(ret, "failed to set password %u\n", GetLastError());
2373 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2374 ok(ret, "failed to send request %u\n", GetLastError());
2376 ret = WinHttpReceiveResponse(req, NULL);
2377 ok(ret, "failed to receive response %u\n", GetLastError());
2379 status = 0xdeadbeef;
2380 size = sizeof(status);
2381 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2382 ok(ret, "failed to query status code %u\n", GetLastError());
2383 ok(status == 200, "request failed unexpectedly %u\n", status);
2385 WinHttpCloseHandle(req);
2386 WinHttpCloseHandle(con);
2387 WinHttpCloseHandle(ses);
2389 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2390 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2392 con = WinHttpConnect(ses, localhostW, port, 0);
2393 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2395 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2396 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2398 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2399 ok(ret, "failed to set username %u\n", GetLastError());
2401 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(passW));
2402 ok(ret, "failed to set password %u\n", GetLastError());
2404 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, NULL);
2405 ok(ret, "failed to set credentials %u\n", GetLastError());
2407 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2408 ok(ret, "failed to send request %u\n", GetLastError());
2410 ret = WinHttpReceiveResponse(req, NULL);
2411 ok(ret, "failed to receive response %u\n", GetLastError());
2413 status = 0xdeadbeef;
2414 size = sizeof(status);
2415 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2416 ok(ret, "failed to query status code %u\n", GetLastError());
2417 ok(status == 401, "request failed unexpectedly %u\n", status);
2419 WinHttpCloseHandle(req);
2420 WinHttpCloseHandle(con);
2421 WinHttpCloseHandle(ses);
2424 static void test_no_headers(int port)
2426 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2427 HINTERNET ses, con, req;
2428 DWORD error;
2429 BOOL ret;
2431 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2432 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2434 con = WinHttpConnect(ses, localhostW, port, 0);
2435 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2437 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2438 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2440 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2441 if (!ret)
2443 error = GetLastError();
2444 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2446 else
2448 SetLastError(0xdeadbeef);
2449 ret = WinHttpReceiveResponse(req, NULL);
2450 error = GetLastError();
2451 ok(!ret, "expected failure\n");
2452 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2455 WinHttpCloseHandle(req);
2456 WinHttpCloseHandle(con);
2457 WinHttpCloseHandle(ses);
2460 static void test_no_content(int port)
2462 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2463 HINTERNET ses, con, req;
2464 char buf[128];
2465 DWORD size, len = sizeof(buf), bytes_read, status;
2466 BOOL ret;
2468 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2469 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2471 con = WinHttpConnect(ses, localhostW, port, 0);
2472 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2474 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0);
2475 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2477 size = 12345;
2478 SetLastError(0xdeadbeef);
2479 ret = WinHttpQueryDataAvailable(req, &size);
2480 todo_wine {
2481 ok(!ret, "expected error\n");
2482 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE,
2483 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2484 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
2485 "expected 12345, got %u\n", size);
2488 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2489 ok(ret, "expected success\n");
2491 ret = WinHttpReceiveResponse(req, NULL);
2492 ok(ret, "expected success\n");
2494 status = 0xdeadbeef;
2495 size = sizeof(status);
2496 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2497 NULL, &status, &size, NULL);
2498 ok(ret, "expected success\n");
2499 ok(status == 204, "expected status 204, got %d\n", status);
2501 SetLastError(0xdeadbeef);
2502 size = sizeof(status);
2503 status = 12345;
2504 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2505 NULL, &status, &size, 0);
2506 ok(!ret, "expected no content-length header\n");
2507 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError());
2508 ok(status == 12345, "expected 0, got %d\n", status);
2510 SetLastError(0xdeadbeef);
2511 size = 12345;
2512 ret = WinHttpQueryDataAvailable(req, &size);
2513 ok(ret, "expected success\n");
2514 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2515 "wrong error %u\n", GetLastError());
2516 ok(!size, "expected 0, got %u\n", size);
2518 SetLastError(0xdeadbeef);
2519 ret = WinHttpReadData(req, buf, len, &bytes_read);
2520 ok(ret, "expected success\n");
2521 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2522 "wrong error %u\n", GetLastError());
2523 ok(!bytes_read, "expected 0, got %u\n", bytes_read);
2525 size = 12345;
2526 ret = WinHttpQueryDataAvailable(req, &size);
2527 ok(ret, "expected success\n");
2528 ok(size == 0, "expected 0, got %d\n", size);
2530 WinHttpCloseHandle(req);
2532 size = 12345;
2533 SetLastError(0xdeadbeef);
2534 ret = WinHttpQueryDataAvailable(req, &size);
2535 ok(!ret, "expected error\n");
2536 ok(GetLastError() == ERROR_INVALID_HANDLE,
2537 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2538 ok(size == 12345, "expected 12345, got %u\n", size);
2540 WinHttpCloseHandle(con);
2541 WinHttpCloseHandle(ses);
2544 static void test_head_request(int port)
2546 static const WCHAR verbW[] = {'H','E','A','D',0};
2547 static const WCHAR headW[] = {'/','h','e','a','d',0};
2548 HINTERNET ses, con, req;
2549 char buf[128];
2550 DWORD size, len, count, status;
2551 BOOL ret;
2553 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2554 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2556 con = WinHttpConnect(ses, localhostW, port, 0);
2557 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2559 req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0);
2560 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2562 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2563 ok(ret, "failed to send request %u\n", GetLastError());
2565 ret = WinHttpReceiveResponse(req, NULL);
2566 ok(ret, "failed to receive response %u\n", GetLastError());
2568 status = 0xdeadbeef;
2569 size = sizeof(status);
2570 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2571 NULL, &status, &size, NULL);
2572 ok(ret, "failed to get status code %u\n", GetLastError());
2573 ok(status == 200, "got %u\n", status);
2575 len = 0xdeadbeef;
2576 size = sizeof(len);
2577 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2578 NULL, &len, &size, 0);
2579 ok(ret, "failed to get content-length header %u\n", GetLastError());
2580 ok(len == 100, "got %u\n", len);
2582 count = 0xdeadbeef;
2583 ret = WinHttpQueryDataAvailable(req, &count);
2584 ok(ret, "failed to query data available %u\n", GetLastError());
2585 ok(!count, "got %u\n", count);
2587 len = sizeof(buf);
2588 count = 0xdeadbeef;
2589 ret = WinHttpReadData(req, buf, len, &count);
2590 ok(ret, "failed to read data %u\n", GetLastError());
2591 ok(!count, "got %u\n", count);
2593 count = 0xdeadbeef;
2594 ret = WinHttpQueryDataAvailable(req, &count);
2595 ok(ret, "failed to query data available %u\n", GetLastError());
2596 ok(!count, "got %u\n", count);
2598 WinHttpCloseHandle(req);
2599 WinHttpCloseHandle(con);
2600 WinHttpCloseHandle(ses);
2603 static void test_not_modified(int port)
2605 static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2606 static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2607 static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2608 BOOL ret;
2609 HINTERNET session, request, connection;
2610 DWORD index, len, status, size, start = GetTickCount();
2611 SYSTEMTIME st;
2612 WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32];
2614 memcpy(today, ifmodifiedW, sizeof(ifmodifiedW));
2615 GetSystemTime(&st);
2616 WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]);
2618 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY,
2619 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
2620 ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError());
2622 connection = WinHttpConnect(session, localhostW, port, 0);
2623 ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError());
2625 request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER,
2626 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
2627 ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError());
2629 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0);
2630 ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError());
2632 ret = WinHttpReceiveResponse(request, NULL);
2633 ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2635 index = 0;
2636 len = sizeof(buffer);
2637 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2638 ifmodified2W, buffer, &len, &index);
2639 ok(ret, "failed to get header %u\n", GetLastError());
2641 status = 0xdeadbeef;
2642 size = sizeof(status);
2643 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
2644 NULL, &status, &size, NULL);
2645 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2646 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status);
2648 size = 0xdeadbeef;
2649 ret = WinHttpQueryDataAvailable(request, &size);
2650 ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2651 ok(!size, "got %u\n", size);
2653 WinHttpCloseHandle(request);
2654 WinHttpCloseHandle(connection);
2655 WinHttpCloseHandle(session);
2656 start = GetTickCount() - start;
2657 ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start);
2660 static void test_bad_header( int port )
2662 static const WCHAR bad_headerW[] =
2663 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2664 't','e','x','t','/','h','t','m','l','\n','\r',0};
2665 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
2666 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2667 WCHAR buffer[32];
2668 HINTERNET ses, con, req;
2669 DWORD index, len;
2670 BOOL ret;
2672 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2673 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2675 con = WinHttpConnect( ses, localhostW, port, 0 );
2676 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2678 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2679 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2681 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2682 ok( ret, "failed to add header %u\n", GetLastError() );
2684 index = 0;
2685 buffer[0] = 0;
2686 len = sizeof(buffer);
2687 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2688 content_typeW, buffer, &len, &index );
2689 ok( ret, "failed to query headers %u\n", GetLastError() );
2690 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2692 WinHttpCloseHandle( req );
2693 WinHttpCloseHandle( con );
2694 WinHttpCloseHandle( ses );
2697 static void test_multiple_reads(int port)
2699 static const WCHAR bigW[] = {'b','i','g',0};
2700 HINTERNET ses, con, req;
2701 DWORD total_len = 0;
2702 BOOL ret;
2704 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2705 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2707 con = WinHttpConnect(ses, localhostW, port, 0);
2708 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2710 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
2711 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2713 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2714 ok(ret, "failed to send request %u\n", GetLastError());
2716 ret = WinHttpReceiveResponse(req, NULL);
2717 ok(ret == TRUE, "expected success\n");
2719 for (;;)
2721 DWORD len = 0xdeadbeef;
2722 ret = WinHttpQueryDataAvailable( req, &len );
2723 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2724 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2725 if (len)
2727 DWORD bytes_read;
2728 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
2730 ret = WinHttpReadData( req, buf, len, &bytes_read );
2731 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
2733 HeapFree( GetProcessHeap(), 0, buf );
2734 if (!bytes_read) break;
2735 total_len += bytes_read;
2737 if (!len) break;
2739 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
2741 WinHttpCloseHandle(req);
2742 WinHttpCloseHandle(con);
2743 WinHttpCloseHandle(ses);
2746 static void test_cookies( int port )
2748 static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0};
2749 static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0};
2750 static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0};
2751 static const WCHAR cookieheaderW[] =
2752 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2753 HINTERNET ses, con, req;
2754 DWORD status, size;
2755 BOOL ret;
2757 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2758 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2760 con = WinHttpConnect( ses, localhostW, port, 0 );
2761 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2763 req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 );
2764 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2766 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2767 ok( ret, "failed to send request %u\n", GetLastError() );
2769 ret = WinHttpReceiveResponse( req, NULL );
2770 ok( ret, "failed to receive response %u\n", GetLastError() );
2772 status = 0xdeadbeef;
2773 size = sizeof(status);
2774 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2775 ok( ret, "failed to query status code %u\n", GetLastError() );
2776 ok( status == 200, "request failed unexpectedly %u\n", status );
2778 WinHttpCloseHandle( req );
2780 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2781 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2783 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2784 ok( ret, "failed to send request %u\n", GetLastError() );
2786 ret = WinHttpReceiveResponse( req, NULL );
2787 ok( ret, "failed to receive response %u\n", GetLastError() );
2789 status = 0xdeadbeef;
2790 size = sizeof(status);
2791 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2792 ok( ret, "failed to query status code %u\n", GetLastError() );
2793 ok( status == 200, "request failed unexpectedly %u\n", status );
2795 WinHttpCloseHandle( req );
2796 WinHttpCloseHandle( con );
2798 con = WinHttpConnect( ses, localhostW, port, 0 );
2799 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2801 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2802 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2804 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2805 ok( ret, "failed to send request %u\n", GetLastError() );
2807 ret = WinHttpReceiveResponse( req, NULL );
2808 ok( ret, "failed to receive response %u\n", GetLastError() );
2810 status = 0xdeadbeef;
2811 size = sizeof(status);
2812 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2813 ok( ret, "failed to query status code %u\n", GetLastError() );
2814 ok( status == 200, "request failed unexpectedly %u\n", status );
2816 WinHttpCloseHandle( req );
2818 req = WinHttpOpenRequest( con, NULL, cookie3W, NULL, NULL, NULL, 0 );
2819 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2821 ret = WinHttpSendRequest( req, cookieheaderW, ~0u, NULL, 0, 0, 0 );
2822 ok( ret, "failed to send request %u\n", GetLastError() );
2824 ret = WinHttpReceiveResponse( req, NULL );
2825 ok( ret, "failed to receive response %u\n", GetLastError() );
2827 status = 0xdeadbeef;
2828 size = sizeof(status);
2829 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2830 ok( ret, "failed to query status code %u\n", GetLastError() );
2831 ok( status == 200 || broken(status == 400), "request failed unexpectedly %u\n", status );
2833 WinHttpCloseHandle( req );
2834 WinHttpCloseHandle( con );
2835 WinHttpCloseHandle( ses );
2837 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2838 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2840 con = WinHttpConnect( ses, localhostW, port, 0 );
2841 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2843 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2844 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2846 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2847 ok( ret, "failed to send request %u\n", GetLastError() );
2849 ret = WinHttpReceiveResponse( req, NULL );
2850 ok( ret, "failed to receive response %u\n", GetLastError() );
2852 status = 0xdeadbeef;
2853 size = sizeof(status);
2854 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2855 ok( ret, "failed to query status code %u\n", GetLastError() );
2856 ok( status == 400, "request failed unexpectedly %u\n", status );
2858 WinHttpCloseHandle( req );
2859 WinHttpCloseHandle( con );
2860 WinHttpCloseHandle( ses );
2863 static void test_connection_info( int port )
2865 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2866 HINTERNET ses, con, req;
2867 WINHTTP_CONNECTION_INFO info;
2868 DWORD size, error;
2869 BOOL ret;
2871 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2872 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2874 con = WinHttpConnect( ses, localhostW, port, 0 );
2875 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2877 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
2878 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2880 size = sizeof(info);
2881 SetLastError( 0xdeadbeef );
2882 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2883 error = GetLastError();
2884 if (!ret && error == ERROR_INVALID_PARAMETER)
2886 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2887 return;
2889 ok( !ret, "unexpected success\n" );
2890 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
2892 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2893 ok( ret, "failed to send request %u\n", GetLastError() );
2895 size = 0;
2896 SetLastError( 0xdeadbeef );
2897 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2898 error = GetLastError();
2899 ok( !ret, "unexpected success\n" );
2900 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
2902 size = sizeof(info);
2903 memset( &info, 0, sizeof(info) );
2904 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2905 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2906 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2908 ret = WinHttpReceiveResponse( req, NULL );
2909 ok( ret, "failed to receive response %u\n", GetLastError() );
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), "wrong size %u\n", info.cbSize );
2917 WinHttpCloseHandle( req );
2918 WinHttpCloseHandle( con );
2919 WinHttpCloseHandle( ses );
2922 static void test_credentials(void)
2924 static WCHAR userW[] = {'u','s','e','r',0};
2925 static WCHAR passW[] = {'p','a','s','s',0};
2926 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2927 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2928 HINTERNET ses, con, req;
2929 DWORD size, error;
2930 WCHAR buffer[32];
2931 BOOL ret;
2933 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2934 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2936 con = WinHttpConnect(ses, localhostW, 0, 0);
2937 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2939 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2940 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2942 size = sizeof(buffer)/sizeof(WCHAR);
2943 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2944 ok(ret, "failed to query proxy username %u\n", GetLastError());
2945 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2946 ok(!size, "expected 0, got %u\n", size);
2948 size = sizeof(buffer)/sizeof(WCHAR);
2949 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2950 ok(ret, "failed to query proxy password %u\n", GetLastError());
2951 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2952 ok(!size, "expected 0, got %u\n", size);
2954 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2955 ok(ret, "failed to set username %u\n", GetLastError());
2957 size = sizeof(buffer)/sizeof(WCHAR);
2958 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2959 ok(ret, "failed to query proxy username %u\n", GetLastError());
2960 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2961 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2963 size = sizeof(buffer)/sizeof(WCHAR);
2964 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2965 ok(ret, "failed to query username %u\n", GetLastError());
2966 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2967 ok(!size, "expected 0, got %u\n", size);
2969 size = sizeof(buffer)/sizeof(WCHAR);
2970 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2971 ok(ret, "failed to query password %u\n", GetLastError());
2972 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2973 ok(!size, "expected 0, got %u\n", size);
2975 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2976 ok(ret, "failed to set proxy password %u\n", GetLastError());
2978 size = sizeof(buffer)/sizeof(WCHAR);
2979 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2980 ok(ret, "failed to query proxy password %u\n", GetLastError());
2981 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2982 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2984 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2985 ok(ret, "failed to set username %u\n", GetLastError());
2987 size = sizeof(buffer)/sizeof(WCHAR);
2988 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2989 ok(ret, "failed to query username %u\n", GetLastError());
2990 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2991 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2993 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2994 ok(ret, "failed to set password %u\n", GetLastError());
2996 size = sizeof(buffer)/sizeof(WCHAR);
2997 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2998 ok(ret, "failed to query password %u\n", GetLastError());
2999 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3000 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
3002 WinHttpCloseHandle(req);
3004 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
3005 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3007 SetLastError(0xdeadbeef);
3008 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
3009 error = GetLastError();
3010 ok(!ret, "expected failure\n");
3011 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3013 SetLastError(0xdeadbeef);
3014 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
3015 error = GetLastError();
3016 ok(!ret, "expected failure\n");
3017 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3019 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
3020 ok(ret, "failed to set credentials %u\n", GetLastError());
3022 size = sizeof(buffer)/sizeof(WCHAR);
3023 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3024 ok(ret, "failed to query username %u\n", GetLastError());
3025 todo_wine {
3026 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3027 ok(!size, "expected 0, got %u\n", size);
3030 size = sizeof(buffer)/sizeof(WCHAR);
3031 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3032 ok(ret, "failed to query password %u\n", GetLastError());
3033 todo_wine {
3034 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3035 ok(!size, "expected 0, got %u\n", size);
3038 WinHttpCloseHandle(req);
3039 WinHttpCloseHandle(con);
3040 WinHttpCloseHandle(ses);
3043 static void test_IWinHttpRequest(void)
3045 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
3046 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
3047 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3048 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3049 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3050 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3051 static const WCHAR method1W[] = {'G','E','T',0};
3052 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
3053 static const WCHAR method3W[] = {'P','O','S','T',0};
3054 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3055 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
3056 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
3057 static const WCHAR dateW[] = {'D','a','t','e',0};
3058 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
3059 static const WCHAR utf8W[] = {'u','t','f','-','8',0};
3060 HRESULT hr;
3061 IWinHttpRequest *req;
3062 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
3063 BSTR date, today, connection, value = NULL;
3064 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp;
3065 VARIANT_BOOL succeeded;
3066 LONG status;
3067 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
3068 SYSTEMTIME st;
3069 IStream *stream, *stream2;
3070 LARGE_INTEGER pos;
3071 char buf[128];
3072 DWORD count;
3074 GetSystemTime( &st );
3075 WinHttpTimeFromSystemTime( &st, todayW );
3077 CoInitialize( NULL );
3078 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3079 ok( hr == S_OK, "got %08x\n", hr );
3081 V_VT( &empty ) = VT_ERROR;
3082 V_ERROR( &empty ) = 0xdeadbeef;
3084 V_VT( &async ) = VT_BOOL;
3085 V_BOOL( &async ) = VARIANT_FALSE;
3087 method = SysAllocString( method3W );
3088 url = SysAllocString( url3W );
3089 hr = IWinHttpRequest_Open( req, method, url, async );
3090 ok( hr == S_OK, "got %08x\n", hr );
3091 SysFreeString( method );
3092 SysFreeString( url );
3094 V_VT( &data ) = VT_BSTR;
3095 V_BSTR( &data ) = SysAllocString( test_dataW );
3096 hr = IWinHttpRequest_Send( req, data );
3097 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
3098 "got %08x\n", hr );
3099 SysFreeString( V_BSTR( &data ) );
3101 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
3102 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3104 method = SysAllocString( method1W );
3105 hr = IWinHttpRequest_Open( req, method, NULL, empty );
3106 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3108 hr = IWinHttpRequest_Open( req, method, NULL, async );
3109 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3111 url = SysAllocString( url1W );
3112 hr = IWinHttpRequest_Open( req, NULL, url, empty );
3113 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3115 hr = IWinHttpRequest_Abort( req );
3116 ok( hr == S_OK, "got %08x\n", hr );
3118 hr = IWinHttpRequest_Open( req, method, url, empty );
3119 ok( hr == S_OK, "got %08x\n", hr );
3121 hr = IWinHttpRequest_Abort( req );
3122 ok( hr == S_OK, "got %08x\n", hr );
3124 IWinHttpRequest_Release( req );
3126 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3127 ok( hr == S_OK, "got %08x\n", hr );
3129 SysFreeString( url );
3130 url = SysAllocString( url2W );
3131 hr = IWinHttpRequest_Open( req, method, url, async );
3132 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3134 SysFreeString( method );
3135 method = SysAllocString( method2W );
3136 hr = IWinHttpRequest_Open( req, method, url, async );
3137 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3139 SysFreeString( method );
3140 method = SysAllocString( method1W );
3141 SysFreeString( url );
3142 url = SysAllocString( url1W );
3143 V_VT( &async ) = VT_ERROR;
3144 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND;
3145 hr = IWinHttpRequest_Open( req, method, url, async );
3146 ok( hr == S_OK, "got %08x\n", hr );
3148 V_VT( &cp ) = VT_ERROR;
3149 V_ERROR( &cp ) = 0xdeadbeef;
3150 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3151 ok( hr == S_OK, "got %08x\n", hr );
3152 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3153 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3155 V_VT( &cp ) = VT_UI4;
3156 V_UI4( &cp ) = CP_ACP;
3157 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3158 ok( hr == S_OK, "got %08x\n", hr );
3160 V_VT( &cp ) = VT_ERROR;
3161 V_ERROR( &cp ) = 0xdeadbeef;
3162 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3163 ok( hr == S_OK, "got %08x\n", hr );
3164 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3165 ok( V_I4( &cp ) == CP_ACP, "got %u\n", V_I4( &cp ) );
3167 value = SysAllocString( utf8W );
3168 V_VT( &cp ) = VT_BSTR;
3169 V_BSTR( &cp ) = value;
3170 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3171 ok( hr == S_OK, "got %08x\n", hr );
3172 SysFreeString( value );
3174 V_VT( &cp ) = VT_ERROR;
3175 V_ERROR( &cp ) = 0xdeadbeef;
3176 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3177 ok( hr == S_OK, "got %08x\n", hr );
3178 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3179 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3181 hr = IWinHttpRequest_Abort( req );
3182 ok( hr == S_OK, "got %08x\n", hr );
3184 hr = IWinHttpRequest_Send( req, empty );
3185 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3187 hr = IWinHttpRequest_Abort( req );
3188 ok( hr == S_OK, "got %08x\n", hr );
3190 IWinHttpRequest_Release( req );
3192 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3193 ok( hr == S_OK, "got %08x\n", hr );
3195 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3196 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3198 hr = IWinHttpRequest_get_ResponseText( req, &response );
3199 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3201 hr = IWinHttpRequest_get_Status( req, NULL );
3202 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3204 hr = IWinHttpRequest_get_Status( req, &status );
3205 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3207 hr = IWinHttpRequest_get_StatusText( req, NULL );
3208 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3210 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3211 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3213 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3214 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3216 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3217 ok( hr == S_OK, "got %08x\n", hr );
3219 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3220 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3222 VariantInit( &proxy_server );
3223 V_VT( &proxy_server ) = VT_ERROR;
3224 VariantInit( &bypass_list );
3225 V_VT( &bypass_list ) = VT_ERROR;
3226 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3227 ok( hr == S_OK, "got %08x\n", hr );
3229 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3230 ok( hr == S_OK, "got %08x\n", hr );
3232 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3233 ok( hr == S_OK, "got %08x\n", hr );
3235 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3236 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3238 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3239 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3241 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3242 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3244 connection = SysAllocString( connectionW );
3245 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3246 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3248 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3249 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3251 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
3252 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3254 date = SysAllocString( dateW );
3255 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3256 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3258 today = SysAllocString( todayW );
3259 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3260 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3262 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
3263 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3265 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3266 ok( hr == S_OK, "got %08x\n", hr );
3268 SysFreeString( method );
3269 method = SysAllocString( method1W );
3270 SysFreeString( url );
3271 url = SysAllocString( url1W );
3272 hr = IWinHttpRequest_Open( req, method, url, async );
3273 ok( hr == S_OK, "got %08x\n", hr );
3275 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3276 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3278 hr = IWinHttpRequest_get_ResponseText( req, &response );
3279 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3281 hr = IWinHttpRequest_get_Status( req, &status );
3282 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3284 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3285 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3287 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3288 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3290 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3291 ok( hr == S_OK, "got %08x\n", hr );
3293 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3294 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3296 username = SysAllocString( usernameW );
3297 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
3298 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3300 password = SysAllocString( passwordW );
3301 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
3302 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3304 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
3305 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3307 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3308 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3310 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3311 ok( hr == S_OK, "got %08x\n", hr );
3313 V_VT( &proxy_server ) = VT_BSTR;
3314 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
3315 V_VT( &bypass_list ) = VT_BSTR;
3316 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
3317 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3318 ok( hr == S_OK, "got %08x\n", hr );
3320 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
3321 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3323 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3324 ok( hr == S_OK, "got %08x\n", hr );
3326 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3327 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3329 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3330 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3332 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3333 ok( hr == S_OK, "got %08x\n", hr );
3335 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3336 ok( hr == S_OK, "got %08x\n", hr );
3338 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3339 ok( hr == S_OK, "got %08x\n", hr );
3341 hr = IWinHttpRequest_Send( req, empty );
3342 ok( hr == S_OK, "got %08x\n", hr );
3344 hr = IWinHttpRequest_Send( req, empty );
3345 ok( hr == S_OK, "got %08x\n", hr );
3347 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3348 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3350 hr = IWinHttpRequest_get_ResponseText( req, &response );
3351 ok( hr == S_OK, "got %08x\n", hr );
3352 SysFreeString( response );
3354 hr = IWinHttpRequest_get_Status( req, NULL );
3355 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3357 status = 0;
3358 hr = IWinHttpRequest_get_Status( req, &status );
3359 ok( hr == S_OK, "got %08x\n", hr );
3360 trace("Status=%d\n", status);
3362 hr = IWinHttpRequest_get_StatusText( req, NULL );
3363 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3365 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3366 ok( hr == S_OK, "got %08x\n", hr );
3367 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
3368 SysFreeString( status_text );
3370 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3371 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3373 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3374 ok( hr == S_OK, "got %08x\n", hr );
3376 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3377 ok( hr == S_OK, "got %08x\n", hr );
3379 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3380 ok( hr == S_OK, "got %08x\n", hr );
3382 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3383 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3385 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3386 ok( hr == S_OK, "got %08x\n", hr );
3387 SysFreeString( headers );
3389 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3390 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3392 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3393 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3395 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3396 ok( hr == S_OK, "got %08x\n", hr );
3397 SysFreeString( value );
3399 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3400 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
3402 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3403 ok( hr == S_OK, "got %08x\n", hr );
3405 VariantInit( &timeout );
3406 V_VT( &timeout ) = VT_I4;
3407 V_I4( &timeout ) = 10;
3408 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
3409 ok( hr == S_OK, "got %08x\n", hr );
3411 hr = IWinHttpRequest_get_Status( req, &status );
3412 ok( hr == S_OK, "got %08x\n", hr );
3414 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3415 ok( hr == S_OK, "got %08x\n", hr );
3416 SysFreeString( status_text );
3418 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3419 ok( hr == S_OK, "got %08x\n", hr );
3421 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3422 ok( hr == S_OK, "got %08x\n", hr );
3424 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3425 ok( hr == S_OK, "got %08x\n", hr );
3427 hr = IWinHttpRequest_Send( req, empty );
3428 ok( hr == S_OK, "got %08x\n", hr );
3430 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3431 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3433 hr = IWinHttpRequest_get_ResponseText( req, &response );
3434 ok( hr == S_OK, "got %08x\n", hr );
3435 SysFreeString( response );
3437 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3438 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3440 VariantInit( &body );
3441 V_VT( &body ) = VT_ERROR;
3442 hr = IWinHttpRequest_get_ResponseBody( req, &body );
3443 ok( hr == S_OK, "got %08x\n", hr );
3444 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
3446 hr = VariantClear( &body );
3447 ok( hr == S_OK, "got %08x\n", hr );
3449 VariantInit( &body );
3450 V_VT( &body ) = VT_ERROR;
3451 hr = IWinHttpRequest_get_ResponseStream( req, &body );
3452 ok( hr == S_OK, "got %08x\n", hr );
3453 ok( V_VT( &body ) == VT_UNKNOWN, "got %08x\n", V_VT( &body ) );
3455 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream );
3456 ok( hr == S_OK, "got %08x\n", hr );
3457 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" );
3459 buf[0] = 0;
3460 count = 0xdeadbeef;
3461 hr = IStream_Read( stream, buf, 128, &count );
3462 ok( hr == S_OK, "got %08x\n", hr );
3463 ok( count != 0xdeadbeef, "count not set\n" );
3464 ok( buf[0], "no data\n" );
3466 VariantInit( &body2 );
3467 V_VT( &body2 ) = VT_ERROR;
3468 hr = IWinHttpRequest_get_ResponseStream( req, &body2 );
3469 ok( hr == S_OK, "got %08x\n", hr );
3470 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %08x\n", V_VT( &body2 ) );
3471 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" );
3473 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 );
3474 ok( hr == S_OK, "got %08x\n", hr );
3475 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" );
3476 IStream_Release( stream2 );
3478 hr = VariantClear( &body );
3479 ok( hr == S_OK, "got %08x\n", hr );
3481 hr = VariantClear( &body2 );
3482 ok( hr == S_OK, "got %08x\n", hr );
3484 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3485 ok( hr == S_OK, "got %08x\n", hr );
3487 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3488 ok( hr == S_OK, "got %08x\n", hr );
3490 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3491 ok( hr == S_OK, "got %08x\n", hr );
3492 SysFreeString( headers );
3494 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3495 ok( hr == S_OK, "got %08x\n", hr );
3496 SysFreeString( value );
3498 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3499 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
3501 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3502 ok( hr == S_OK, "got %08x\n", hr );
3504 hr = IWinHttpRequest_Send( req, empty );
3505 ok( hr == S_OK, "got %08x\n", hr );
3507 hr = IWinHttpRequest_Abort( req );
3508 ok( hr == S_OK, "got %08x\n", hr );
3510 hr = IWinHttpRequest_Abort( req );
3511 ok( hr == S_OK, "got %08x\n", hr );
3513 IWinHttpRequest_Release( req );
3515 pos.QuadPart = 0;
3516 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL );
3517 ok( hr == S_OK, "got %08x\n", hr );
3519 buf[0] = 0;
3520 count = 0xdeadbeef;
3521 hr = IStream_Read( stream, buf, 128, &count );
3522 ok( hr == S_OK, "got %08x\n", hr );
3523 ok( count != 0xdeadbeef, "count not set\n" );
3524 ok( buf[0], "no data\n" );
3525 IStream_Release( stream );
3527 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3528 ok( hr == S_OK, "got %08x\n", hr );
3530 V_VT( &async ) = VT_I4;
3531 V_I4( &async ) = 1;
3532 hr = IWinHttpRequest_Open( req, method, url, async );
3533 ok( hr == S_OK, "got %08x\n", hr );
3535 hr = IWinHttpRequest_Send( req, empty );
3536 ok( hr == S_OK, "got %08x\n", hr );
3538 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
3539 ok( hr == S_OK, "got %08x\n", hr );
3541 IWinHttpRequest_Release( req );
3543 SysFreeString( method );
3544 SysFreeString( url );
3545 SysFreeString( username );
3546 SysFreeString( password );
3547 SysFreeString( connection );
3548 SysFreeString( date );
3549 SysFreeString( today );
3550 VariantClear( &proxy_server );
3551 VariantClear( &bypass_list );
3552 CoUninitialize();
3555 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret)
3557 DISPPARAMS params;
3558 VARIANT arg;
3559 HRESULT hr;
3561 memset(&params, 0, sizeof(params));
3562 params.cNamedArgs = 0;
3563 params.rgdispidNamedArgs = NULL;
3564 params.cArgs = 1;
3565 params.rgvarg = &arg;
3566 VariantInit(&arg);
3567 V_VT(&arg) = VT_I4;
3568 V_I4(&arg) = property;
3569 VariantInit(ret);
3570 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3571 DISPATCH_PROPERTYGET, &params, ret, NULL, NULL);
3572 ok(hr == S_OK, "error %#x\n", hr);
3575 static void test_IWinHttpRequest_Invoke(void)
3577 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
3578 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};
3579 WCHAR openW[] = {'O','p','e','n',0};
3580 WCHAR optionW[] = {'O','p','t','i','o','n',0};
3581 OLECHAR *open = openW, *option = optionW;
3582 BSTR utf8;
3583 CLSID clsid;
3584 IWinHttpRequest *request;
3585 IDispatch *dispatch;
3586 DISPID id;
3587 DISPPARAMS params;
3588 VARIANT arg[3], ret;
3589 UINT err;
3590 BOOL bret;
3591 HRESULT hr;
3593 CoInitialize(NULL);
3595 hr = CLSIDFromProgID(regid, &clsid);
3596 ok(hr == S_OK, "CLSIDFromProgID error %#x\n", hr);
3597 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest);
3598 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid));
3600 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request);
3601 ok(hr == S_OK, "error %#x\n", hr);
3603 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch);
3604 ok(hr == S_OK, "error %#x\n", hr);
3605 IDispatch_Release(dispatch);
3607 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id);
3608 ok(hr == S_OK, "error %#x\n", hr);
3609 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id);
3611 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id);
3612 ok(hr == S_OK, "error %#x\n", hr);
3613 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id);
3615 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3616 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3617 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3619 memset(&params, 0, sizeof(params));
3620 params.cArgs = 2;
3621 params.cNamedArgs = 0;
3622 params.rgvarg = arg;
3623 V_VT(&arg[0]) = VT_I4;
3624 V_I4(&arg[0]) = 1252;
3625 V_VT(&arg[1]) = VT_R8;
3626 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3627 VariantInit(&ret);
3628 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3629 DISPATCH_METHOD, &params, NULL, NULL, &err);
3630 ok(hr == S_OK, "error %#x\n", hr);
3632 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3633 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3634 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3636 memset(&params, 0, sizeof(params));
3637 params.cArgs = 2;
3638 params.cNamedArgs = 0;
3639 params.rgvarg = arg;
3640 V_VT(&arg[0]) = VT_I4;
3641 V_I4(&arg[0]) = 1252;
3642 V_VT(&arg[1]) = VT_R8;
3643 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3644 VariantInit(&ret);
3645 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3646 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
3647 ok(hr == S_OK, "error %#x\n", hr);
3649 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3650 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3651 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3653 memset(&params, 0, sizeof(params));
3654 params.cArgs = 2;
3655 params.cNamedArgs = 0;
3656 params.rgvarg = arg;
3657 V_VT(&arg[0]) = VT_I4;
3658 V_I4(&arg[0]) = 1252;
3659 V_VT(&arg[1]) = VT_R8;
3660 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3661 VariantInit(&ret);
3662 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3663 DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
3664 ok(hr == S_OK, "error %#x\n", hr);
3666 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3667 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3668 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3670 memset(&params, 0, sizeof(params));
3671 params.cArgs = 2;
3672 params.cNamedArgs = 0;
3673 params.rgvarg = arg;
3674 V_VT(&arg[0]) = VT_BSTR;
3675 utf8 = SysAllocString(utf8W);
3676 V_BSTR(&arg[0]) = utf8;
3677 V_VT(&arg[1]) = VT_R8;
3678 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3679 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, &err);
3680 ok(hr == S_OK, "error %#x\n", hr);
3682 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3683 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3684 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3686 VariantInit(&ret);
3687 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, &err);
3688 ok(hr == S_OK, "error %#x\n", hr);
3690 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3691 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3692 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3694 VariantInit(&ret);
3695 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3696 ok(hr == S_OK, "error %#x\n", hr);
3698 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3699 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3700 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3702 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
3703 ok(hr == S_OK, "error %#x\n", hr);
3705 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
3706 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#x\n", hr);
3708 VariantInit(&ret);
3709 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3710 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
3712 VariantInit(&ret);
3713 if (0) /* crashes */
3714 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err);
3716 params.cArgs = 1;
3717 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3718 ok(hr == DISP_E_TYPEMISMATCH, "error %#x\n", hr);
3720 VariantInit(&arg[2]);
3721 params.cArgs = 3;
3722 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3723 todo_wine
3724 ok(hr == S_OK, "error %#x\n", hr);
3726 VariantInit(&arg[0]);
3727 VariantInit(&arg[1]);
3728 VariantInit(&arg[2]);
3730 params.cArgs = 1;
3731 V_VT(&arg[0]) = VT_I4;
3732 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage;
3733 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3734 ok(hr == S_OK, "error %#x\n", hr);
3736 V_VT(&ret) = 0xdead;
3737 V_I4(&ret) = 0xbeef;
3738 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, &ret, NULL, NULL);
3739 ok(hr == S_OK, "error %#x\n", hr);
3740 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3741 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3743 V_VT(&ret) = 0xdead;
3744 V_I4(&ret) = 0xbeef;
3745 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, NULL);
3746 ok(hr == S_OK, "error %#x\n", hr);
3747 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3748 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3750 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3751 ok(hr == S_OK, "error %#x\n", hr);
3753 V_VT(&ret) = 0xdead;
3754 V_I4(&ret) = 0xbeef;
3755 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, &ret, NULL, NULL);
3756 ok(hr == S_OK, "error %#x\n", hr);
3757 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %d\n", V_VT(&ret));
3758 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret));
3760 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, NULL, NULL, NULL);
3761 ok(hr == S_OK, "error %#x\n", hr);
3763 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3764 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
3766 params.cArgs = 2;
3767 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3768 todo_wine
3769 ok(hr == S_OK, "error %#x\n", hr);
3771 params.cArgs = 0;
3772 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3773 ok(hr == DISP_E_PARAMNOTFOUND, "error %#x\n", hr);
3775 SysFreeString(utf8);
3777 params.cArgs = 1;
3778 V_VT(&arg[0]) = VT_I4;
3779 V_I4(&arg[0]) = AutoLogonPolicy_Never;
3780 VariantInit(&ret);
3781 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0,
3782 DISPATCH_METHOD, &params, &ret, NULL, NULL);
3783 ok(hr == S_OK, "error %#x\n", hr);
3785 IWinHttpRequest_Release(request);
3787 CoUninitialize();
3790 static void test_WinHttpDetectAutoProxyConfigUrl(void)
3792 BOOL ret;
3793 WCHAR *url;
3794 DWORD error;
3796 if (0) /* crashes on some win2k systems */
3798 SetLastError(0xdeadbeef);
3799 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
3800 error = GetLastError();
3801 ok( !ret, "expected failure\n" );
3802 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3804 url = NULL;
3805 SetLastError(0xdeadbeef);
3806 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
3807 error = GetLastError();
3808 ok( !ret, "expected failure\n" );
3809 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3811 if (0) /* crashes on some win2k systems */
3813 SetLastError(0xdeadbeef);
3814 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
3815 error = GetLastError();
3816 ok( !ret, "expected failure\n" );
3817 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3819 url = (WCHAR *)0xdeadbeef;
3820 SetLastError(0xdeadbeef);
3821 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
3822 error = GetLastError();
3823 if (!ret)
3825 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
3826 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
3828 else
3830 trace("%s\n", wine_dbgstr_w(url));
3831 GlobalFree( url );
3834 url = (WCHAR *)0xdeadbeef;
3835 SetLastError(0xdeadbeef);
3836 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
3837 error = GetLastError();
3838 if (!ret)
3840 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
3841 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
3843 else
3845 ok( error == ERROR_SUCCESS, "got %u\n", error );
3846 trace("%s\n", wine_dbgstr_w(url));
3847 GlobalFree( url );
3851 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
3853 BOOL ret;
3854 DWORD error;
3855 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
3857 memset( &cfg, 0, sizeof(cfg) );
3859 SetLastError(0xdeadbeef);
3860 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
3861 error = GetLastError();
3862 ok( !ret, "expected failure\n" );
3863 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3865 SetLastError(0xdeadbeef);
3866 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
3867 error = GetLastError();
3868 ok( ret, "expected success\n" );
3869 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error );
3871 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
3872 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
3873 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
3874 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
3875 GlobalFree( cfg.lpszAutoConfigUrl );
3876 GlobalFree( cfg.lpszProxy );
3877 GlobalFree( cfg.lpszProxyBypass );
3880 static void test_WinHttpGetProxyForUrl(void)
3882 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
3883 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
3884 static const WCHAR emptyW[] = {0};
3885 BOOL ret;
3886 DWORD error;
3887 HINTERNET session;
3888 WINHTTP_AUTOPROXY_OPTIONS options;
3889 WINHTTP_PROXY_INFO info;
3891 memset( &options, 0, sizeof(options) );
3893 SetLastError(0xdeadbeef);
3894 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
3895 error = GetLastError();
3896 ok( !ret, "expected failure\n" );
3897 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
3899 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
3900 ok( session != NULL, "failed to open session %u\n", GetLastError() );
3902 SetLastError(0xdeadbeef);
3903 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
3904 error = GetLastError();
3905 ok( !ret, "expected failure\n" );
3906 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3908 SetLastError(0xdeadbeef);
3909 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
3910 error = GetLastError();
3911 ok( !ret, "expected failure\n" );
3912 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3914 SetLastError(0xdeadbeef);
3915 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
3916 error = GetLastError();
3917 ok( !ret, "expected failure\n" );
3918 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3920 SetLastError(0xdeadbeef);
3921 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3922 error = GetLastError();
3923 ok( !ret, "expected failure\n" );
3924 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3926 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3927 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3929 SetLastError(0xdeadbeef);
3930 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
3931 error = GetLastError();
3932 ok( !ret, "expected failure\n" );
3933 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3935 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3936 options.dwAutoDetectFlags = 0;
3938 SetLastError(0xdeadbeef);
3939 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3940 error = GetLastError();
3941 ok( !ret, "expected failure\n" );
3942 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3944 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
3945 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3947 SetLastError(0xdeadbeef);
3948 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3949 error = GetLastError();
3950 ok( !ret, "expected failure\n" );
3951 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3953 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
3954 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
3956 memset( &info, 0, sizeof(info) );
3957 SetLastError(0xdeadbeef);
3958 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3959 error = GetLastError();
3960 if (ret)
3962 ok( error == ERROR_SUCCESS, "got %u\n", error );
3963 trace("Proxy.AccessType=%u\n", info.dwAccessType);
3964 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
3965 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
3966 GlobalFree( info.lpszProxy );
3967 GlobalFree( info.lpszProxyBypass );
3970 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
3971 options.dwAutoDetectFlags = 0;
3972 options.lpszAutoConfigUrl = wpadW;
3974 memset( &info, 0, sizeof(info) );
3975 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
3976 if (ret)
3978 trace("Proxy.AccessType=%u\n", info.dwAccessType);
3979 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
3980 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
3981 GlobalFree( info.lpszProxy );
3982 GlobalFree( info.lpszProxyBypass );
3984 WinHttpCloseHandle( session );
3987 static void test_chunked_read(void)
3989 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
3990 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
3991 WCHAR header[32];
3992 DWORD len, err;
3993 HINTERNET ses, con = NULL, req = NULL;
3994 BOOL ret;
3996 trace( "starting chunked read test\n" );
3998 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
3999 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
4000 if (!ses) goto done;
4002 con = WinHttpConnect( ses, test_winehq, 0, 0 );
4003 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
4004 if (!con) goto done;
4006 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
4007 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4008 if (!req) goto done;
4010 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4011 err = GetLastError();
4012 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
4014 skip("connection failed, skipping\n");
4015 goto done;
4017 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4019 ret = WinHttpReceiveResponse( req, NULL );
4020 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4022 header[0] = 0;
4023 len = sizeof(header);
4024 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
4025 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4026 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
4027 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
4029 header[0] = 0;
4030 len = sizeof(header);
4031 SetLastError( 0xdeadbeef );
4032 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
4033 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
4034 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
4036 trace( "entering query loop\n" );
4037 for (;;)
4039 len = 0xdeadbeef;
4040 ret = WinHttpQueryDataAvailable( req, &len );
4041 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4042 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4043 trace( "got %u available\n", len );
4044 if (len)
4046 DWORD bytes_read;
4047 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
4049 ret = WinHttpReadData( req, buf, len, &bytes_read );
4051 buf[bytes_read] = 0;
4052 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
4053 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
4054 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
4056 HeapFree( GetProcessHeap(), 0, buf );
4057 if (!bytes_read) break;
4059 if (!len) break;
4061 trace( "done\n" );
4063 done:
4064 if (req) WinHttpCloseHandle( req );
4065 if (con) WinHttpCloseHandle( con );
4066 if (ses) WinHttpCloseHandle( ses );
4069 START_TEST (winhttp)
4071 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
4072 static const WCHAR quitW[] = {'/','q','u','i','t',0};
4073 struct server_info si;
4074 HANDLE thread;
4075 DWORD ret;
4077 test_OpenRequest();
4078 test_SendRequest();
4079 test_WinHttpTimeFromSystemTime();
4080 test_WinHttpTimeToSystemTime();
4081 test_WinHttpAddHeaders();
4082 test_secure_connection();
4083 test_request_parameter_defaults();
4084 test_QueryOption();
4085 test_set_default_proxy_config();
4086 test_empty_headers_param();
4087 test_Timeouts();
4088 test_resolve_timeout();
4089 test_credentials();
4090 test_IWinHttpRequest();
4091 test_IWinHttpRequest_Invoke();
4092 test_WinHttpDetectAutoProxyConfigUrl();
4093 test_WinHttpGetIEProxyConfigForCurrentUser();
4094 test_WinHttpGetProxyForUrl();
4095 test_chunked_read();
4097 si.event = CreateEventW(NULL, 0, 0, NULL);
4098 si.port = 7532;
4100 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
4101 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
4103 ret = WaitForSingleObject(si.event, 10000);
4104 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
4105 if (ret != WAIT_OBJECT_0)
4106 return;
4108 test_connection_info(si.port);
4109 test_basic_request(si.port, NULL, basicW);
4110 test_no_headers(si.port);
4111 test_no_content(si.port);
4112 test_head_request(si.port);
4113 test_not_modified(si.port);
4114 test_basic_authentication(si.port);
4115 test_bad_header(si.port);
4116 test_multiple_reads(si.port);
4117 test_cookies(si.port);
4119 /* send the basic request again to shutdown the server thread */
4120 test_basic_request(si.port, NULL, quitW);
4122 WaitForSingleObject(thread, 3000);