d3d11: Validate "ViewDimension" field in D3D11_RENDER_TARGET_VIEW_DESC.
[wine.git] / dlls / winhttp / tests / winhttp.c
blobf81c07c705996bcc0d425b871b73630082349a39
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 <stdio.h>
31 #include <initguid.h>
32 #include <httprequest.h>
33 #include <httprequestid.h>
35 #include "wine/test.h"
37 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
39 static const WCHAR test_useragent[] =
40 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
41 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
42 static const WCHAR test_winehq_https[] = {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','4','4','3',0};
43 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
45 static BOOL proxy_active(void)
47 WINHTTP_PROXY_INFO proxy_info;
48 BOOL active = FALSE;
50 SetLastError(0xdeadbeef);
51 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
53 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
54 "got %u\n", GetLastError());
55 active = (proxy_info.lpszProxy != NULL);
56 if (active)
57 GlobalFree(proxy_info.lpszProxy);
58 if (proxy_info.lpszProxyBypass != NULL)
59 GlobalFree(proxy_info.lpszProxyBypass);
61 else
62 active = FALSE;
64 return active;
67 static void test_QueryOption(void)
69 BOOL ret;
70 HINTERNET session, request, connection;
71 DWORD feature, size;
73 SetLastError(0xdeadbeef);
74 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
75 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
77 SetLastError(0xdeadbeef);
78 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
79 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
80 ok(GetLastError() == ERROR_INVALID_PARAMETER,
81 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
83 size = 0xdeadbeef;
84 SetLastError(0xdeadbeef);
85 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
86 ok(!ret, "should fail to query option\n");
87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
89 ok(size == 4, "expected 4, got %u\n", size);
91 feature = 0xdeadbeef;
92 size = sizeof(feature) - 1;
93 SetLastError(0xdeadbeef);
94 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
95 ok(!ret, "should fail to query option\n");
96 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
97 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
98 ok(size == 4, "expected 4, got %u\n", size);
100 feature = 0xdeadbeef;
101 size = sizeof(feature) + 1;
102 SetLastError(0xdeadbeef);
103 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
104 ok(ret, "failed to query option %u\n", GetLastError());
105 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
106 "got %u\n", GetLastError());
107 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
108 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
109 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
111 SetLastError(0xdeadbeef);
112 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
113 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
114 ok(GetLastError() == ERROR_INVALID_PARAMETER,
115 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
117 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
118 SetLastError(0xdeadbeef);
119 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
120 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
121 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
122 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
124 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
125 SetLastError(0xdeadbeef);
126 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
127 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
128 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
129 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
131 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
132 SetLastError(0xdeadbeef);
133 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
134 ok(ret, "failed to set redirect policy %u\n", GetLastError());
136 feature = 0xdeadbeef;
137 size = sizeof(feature);
138 SetLastError(0xdeadbeef);
139 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
140 ok(ret, "failed to query option %u\n", GetLastError());
141 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
142 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
144 feature = WINHTTP_DISABLE_COOKIES;
145 SetLastError(0xdeadbeef);
146 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
147 ok(!ret, "should fail to set disable feature for a session\n");
148 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
149 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151 SetLastError(0xdeadbeef);
152 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
153 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
155 feature = WINHTTP_DISABLE_COOKIES;
156 SetLastError(0xdeadbeef);
157 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
158 ok(!ret, "should fail to set disable feature for a connection\n");
159 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
160 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
162 SetLastError(0xdeadbeef);
163 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
164 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
165 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
167 skip("Network unreachable, skipping the test\n");
168 goto done;
171 feature = 0xdeadbeef;
172 size = sizeof(feature);
173 SetLastError(0xdeadbeef);
174 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
175 ok(!ret, "should fail to query disable feature for a request\n");
176 ok(GetLastError() == ERROR_INVALID_PARAMETER,
177 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
179 feature = 0;
180 size = sizeof(feature);
181 SetLastError(0xdeadbeef);
182 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
183 ok(ret, "failed to set feature %u\n", GetLastError());
185 feature = 0xffffffff;
186 size = sizeof(feature);
187 SetLastError(0xdeadbeef);
188 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
189 ok(ret, "failed to set feature %u\n", GetLastError());
191 feature = WINHTTP_DISABLE_COOKIES;
192 size = sizeof(feature);
193 SetLastError(0xdeadbeef);
194 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
195 ok(ret, "failed to set feature %u\n", GetLastError());
197 size = 0;
198 SetLastError(0xdeadbeef);
199 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
200 ok(!ret, "should fail to query disable feature for a request\n");
201 ok(GetLastError() == ERROR_INVALID_PARAMETER,
202 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
204 SetLastError(0xdeadbeef);
205 ret = WinHttpCloseHandle(request);
206 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
208 done:
209 SetLastError(0xdeadbeef);
210 ret = WinHttpCloseHandle(connection);
211 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
212 SetLastError(0xdeadbeef);
213 ret = WinHttpCloseHandle(session);
214 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
217 static void test_OpenRequest (void)
219 BOOL ret;
220 HINTERNET session, request, connection;
221 DWORD err;
223 SetLastError(0xdeadbeef);
224 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
225 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
226 err = GetLastError();
227 ok(session != NULL, "WinHttpOpen failed to open session.\n");
228 ok(err == ERROR_SUCCESS, "got %u\n", err);
230 /* Test with a bad server name */
231 SetLastError(0xdeadbeef);
232 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
233 err = GetLastError();
234 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
235 ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err);
237 /* Test with a valid server name */
238 SetLastError(0xdeadbeef);
239 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
240 err = GetLastError();
241 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err);
242 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err);
244 SetLastError(0xdeadbeef);
245 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
246 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
247 err = GetLastError();
248 if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED)
250 skip("Network unreachable, skipping.\n");
251 goto done;
253 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err);
254 ok(err == ERROR_SUCCESS, "got %u\n", err);
256 SetLastError(0xdeadbeef);
257 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
258 err = GetLastError();
259 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
261 skip("Connection failed, skipping.\n");
262 goto done;
264 ok(ret, "WinHttpSendRequest failed: %u\n", err);
265 ok(err == ERROR_SUCCESS, "got %u\n", err);
267 SetLastError(0xdeadbeef);
268 ret = WinHttpCloseHandle(request);
269 err = GetLastError();
270 ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err);
271 ok(err == ERROR_SUCCESS, "got %u\n", err);
273 done:
274 ret = WinHttpCloseHandle(connection);
275 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
276 ret = WinHttpCloseHandle(session);
277 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
281 static void test_empty_headers_param(void)
283 static const WCHAR empty[] = {0};
284 HINTERNET ses, con, req;
285 DWORD err;
286 BOOL ret;
288 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
289 ok(ses != NULL, "failed to open session %u\n", GetLastError());
291 con = WinHttpConnect(ses, test_winehq, 80, 0);
292 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
294 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
295 ok(req != NULL, "failed to open a request %u\n", GetLastError());
297 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
298 err = GetLastError();
299 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
301 skip("connection failed, skipping\n");
302 goto done;
304 ok(ret, "failed to send request %u\n", GetLastError());
306 done:
307 WinHttpCloseHandle(req);
308 WinHttpCloseHandle(con);
309 WinHttpCloseHandle(ses);
312 static void test_SendRequest (void)
314 static const WCHAR content_type[] =
315 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
316 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
317 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
318 static const WCHAR test_verb[] = {'P','O','S','T',0};
319 static CHAR post_data[] = "mode=Test";
320 static const char test_post[] = "mode => Test\0\n";
321 HINTERNET session, request, connection;
322 DWORD header_len, optional_len, total_len, bytes_rw, size, err;
323 DWORD_PTR context;
324 BOOL ret;
325 CHAR buffer[256];
326 int i;
328 header_len = -1L;
329 total_len = optional_len = sizeof(post_data);
330 memset(buffer, 0xff, sizeof(buffer));
332 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
333 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
334 ok(session != NULL, "WinHttpOpen failed to open session.\n");
336 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
337 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
339 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
340 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
341 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
343 skip("Network unreachable, skipping.\n");
344 goto done;
346 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
347 if (!request) goto done;
349 context = 0xdeadbeef;
350 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
351 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
353 context++;
354 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
355 err = GetLastError();
356 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
358 skip("connection failed, skipping\n");
359 goto done;
361 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
363 context = 0;
364 size = sizeof(context);
365 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
366 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
367 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
369 for (i = 3; post_data[i]; i++)
371 bytes_rw = -1;
372 SetLastError(0xdeadbeef);
373 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
374 if (ret)
376 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
377 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
379 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
381 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
382 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
386 SetLastError(0xdeadbeef);
387 ret = WinHttpReceiveResponse(request, NULL);
388 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */,
389 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
390 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
392 bytes_rw = -1;
393 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
394 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
396 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw);
397 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
399 done:
400 ret = WinHttpCloseHandle(request);
401 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
402 ret = WinHttpCloseHandle(connection);
403 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
404 ret = WinHttpCloseHandle(session);
405 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
408 static void test_WinHttpTimeFromSystemTime(void)
410 BOOL ret;
411 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
412 static const WCHAR expected_string[] =
413 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
414 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
415 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
416 DWORD err;
418 SetLastError(0xdeadbeef);
419 ret = WinHttpTimeFromSystemTime(&time, NULL);
420 err = GetLastError();
421 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
422 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
424 SetLastError(0xdeadbeef);
425 ret = WinHttpTimeFromSystemTime(NULL, time_string);
426 err = GetLastError();
427 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
428 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
430 SetLastError(0xdeadbeef);
431 ret = WinHttpTimeFromSystemTime(&time, time_string);
432 err = GetLastError();
433 ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err);
434 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
435 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
436 "Time string returned did not match expected time string.\n");
439 static void test_WinHttpTimeToSystemTime(void)
441 BOOL ret;
442 SYSTEMTIME time;
443 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
444 static const WCHAR time_string1[] =
445 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
446 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
447 static const WCHAR time_string2[] =
448 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
449 '1','0',' ','0','5',' ','5','2','\n',0};
450 DWORD err;
452 SetLastError(0xdeadbeef);
453 ret = WinHttpTimeToSystemTime(time_string1, NULL);
454 err = GetLastError();
455 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
456 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
458 SetLastError(0xdeadbeef);
459 ret = WinHttpTimeToSystemTime(NULL, &time);
460 err = GetLastError();
461 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
462 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
464 SetLastError(0xdeadbeef);
465 ret = WinHttpTimeToSystemTime(time_string1, &time);
466 err = GetLastError();
467 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
468 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
469 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
470 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
472 SetLastError(0xdeadbeef);
473 ret = WinHttpTimeToSystemTime(time_string2, &time);
474 err = GetLastError();
475 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
476 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
477 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
478 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
481 static void test_WinHttpAddHeaders(void)
483 HINTERNET session, request, connection;
484 BOOL ret, reverse;
485 WCHAR buffer[MAX_PATH];
486 WCHAR check_buffer[MAX_PATH];
487 DWORD err, index, len, oldlen;
489 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
490 static const WCHAR test_verb[] = {'P','O','S','T',0};
491 static const WCHAR test_header_begin[] =
492 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
493 static const WCHAR full_path_test_header_begin[] =
494 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
495 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
496 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
497 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
498 static const WCHAR test_header_name2[] = {'n','a','m','e',0};
499 static const WCHAR test_header_name3[] = {'a',0};
500 static const WCHAR test_header_range[] = {'R','a','n','g','e',0};
501 static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
502 static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
504 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
505 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
506 static const WCHAR test_flag_coalesce_comma[] =
507 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
508 static const WCHAR test_flag_coalesce_comma_reverse[] =
509 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
510 static const WCHAR test_flag_coalesce_semicolon[] =
511 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
512 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
513 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
515 static const WCHAR field[] = {'f','i','e','l','d',0};
516 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
517 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
518 static const WCHAR empty[] = {0};
520 static const WCHAR test_headers[][14] =
522 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
523 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
524 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
525 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
526 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
527 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
528 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
529 {0},
530 {':',0},
531 {'a',':',0},
532 {':','b',0},
533 {'c','d',0},
534 {' ','e',' ',':','f',0},
535 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
536 {'n','a','m','e',':',' ','v','a','l','u','e',0},
537 {'n','a','m','e',':',0}
539 static const WCHAR test_indices[][6] =
541 {'t','e','s','t','1',0},
542 {'t','e','s','t','2',0},
543 {'t','e','s','t','3',0},
544 {'t','e','s','t','4',0}
547 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
548 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
549 ok(session != NULL, "WinHttpOpen failed to open session.\n");
551 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
552 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
554 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
555 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
556 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
558 skip("Network unreachable, skipping.\n");
559 goto done;
561 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
563 index = 0;
564 len = sizeof(buffer);
565 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
566 test_header_name, buffer, &len, &index);
567 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
568 SetLastError(0xdeadbeef);
569 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
570 err = GetLastError();
571 ok(ret, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, err);
572 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
574 index = 0;
575 len = sizeof(buffer);
576 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
577 test_header_name, buffer, &len, &index);
578 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
579 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
580 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
581 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
583 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
584 test_header_name, buffer, &len, &index);
585 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
587 /* Try to fetch the header info with a buffer that's big enough to fit the
588 * string but not the NULL terminator.
590 index = 0;
591 len = 5*sizeof(WCHAR);
592 memset(check_buffer, 0xab, sizeof(check_buffer));
593 memcpy(buffer, check_buffer, sizeof(buffer));
594 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
595 test_header_name, buffer, &len, &index);
596 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
597 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
598 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
599 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
601 /* Try with a NULL buffer */
602 index = 0;
603 len = sizeof(buffer);
604 SetLastError(0xdeadbeef);
605 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
606 test_header_name, NULL, &len, &index);
607 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
608 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
609 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
610 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
612 /* Try with a NULL buffer and a length that's too small */
613 index = 0;
614 len = 10;
615 SetLastError(0xdeadbeef);
616 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
617 test_header_name, NULL, &len, &index);
618 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
619 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
620 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
621 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
622 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
624 index = 0;
625 len = 0;
626 SetLastError(0xdeadbeef);
627 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
628 test_header_name, NULL, &len, &index);
629 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
630 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
631 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
632 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
633 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
635 /* valid query */
636 oldlen = len;
637 index = 0;
638 len = sizeof(buffer);
639 memset(buffer, 0xff, sizeof(buffer));
640 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
641 test_header_name, buffer, &len, &index);
642 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
643 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
644 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
645 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
646 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
647 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
648 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
649 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
650 "WinHttpQueryHeaders returned invalid end of header string.\n");
651 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
653 index = 0;
654 len = 0;
655 SetLastError(0xdeadbeef);
656 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
657 test_header_name, NULL, &len, &index);
658 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
659 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
660 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
661 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
662 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
664 oldlen = len;
665 index = 0;
666 len = sizeof(buffer);
667 memset(buffer, 0xff, sizeof(buffer));
668 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
669 test_header_name, buffer, &len, &index);
670 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
671 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
672 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
673 "no double NULL terminator\n");
674 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
675 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
676 "invalid beginning of header string.\n");
677 ok(index == 0, "header index was incremented\n");
679 /* tests for more indices */
680 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
681 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
683 index = 0;
684 len = sizeof(buffer);
685 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
686 test_header_name, buffer, &len, &index);
687 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
688 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
689 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
691 len = sizeof(buffer);
692 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
693 test_header_name, buffer, &len, &index);
694 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
698 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
699 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
701 index = 0;
702 len = sizeof(buffer);
703 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
704 test_header_name, buffer, &len, &index);
705 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
706 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
707 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
708 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
710 len = sizeof(buffer);
711 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
712 test_header_name, buffer, &len, &index);
713 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
714 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
717 /* add if new flag */
718 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
719 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
721 index = 0;
722 len = sizeof(buffer);
723 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
724 test_header_name, buffer, &len, &index);
725 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
726 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
727 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
729 len = sizeof(buffer);
730 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
731 test_header_name, buffer, &len, &index);
732 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
733 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
734 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
736 len = sizeof(buffer);
737 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
738 test_header_name, buffer, &len, &index);
739 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
741 /* coalesce flag */
742 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
743 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
745 index = 0;
746 len = sizeof(buffer);
747 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
748 test_header_name, buffer, &len, &index);
749 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
750 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
751 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
752 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
754 len = sizeof(buffer);
755 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
756 test_header_name, buffer, &len, &index);
757 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
758 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
759 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
761 len = sizeof(buffer);
762 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
763 test_header_name, buffer, &len, &index);
764 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
766 /* coalesce with comma flag */
767 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
768 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
770 index = 0;
771 len = sizeof(buffer);
772 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
773 test_header_name, buffer, &len, &index);
774 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
775 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
776 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
777 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
778 "WinHttpQueryHeaders returned incorrect string.\n");
780 len = sizeof(buffer);
781 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
782 test_header_name, buffer, &len, &index);
783 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
784 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
785 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
787 len = sizeof(buffer);
788 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
789 test_header_name, buffer, &len, &index);
790 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
793 /* coalesce with semicolon flag */
794 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
795 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
797 index = 0;
798 len = sizeof(buffer);
799 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
800 test_header_name, buffer, &len, &index);
801 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
802 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
803 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
804 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
805 "WinHttpQueryHeaders returned incorrect string.\n");
807 len = sizeof(buffer);
808 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
809 test_header_name, buffer, &len, &index);
810 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
811 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
812 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
814 len = sizeof(buffer);
815 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
816 test_header_name, buffer, &len, &index);
817 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
819 /* add and replace flags */
820 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
821 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
823 index = 0;
824 len = sizeof(buffer);
825 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
826 test_header_name, buffer, &len, &index);
827 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
828 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
829 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
831 len = sizeof(buffer);
832 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
833 test_header_name, buffer, &len, &index);
834 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
835 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
836 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
838 len = sizeof(buffer);
839 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
840 test_header_name, buffer, &len, &index);
841 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
843 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
844 ok(!ret, "WinHttpAddRequestHeaders failed\n");
846 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
847 ok(ret, "WinHttpAddRequestHeaders failed\n");
849 index = 0;
850 memset(buffer, 0xff, sizeof(buffer));
851 len = sizeof(buffer);
852 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
853 test_header_name3, buffer, &len, &index);
854 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
855 ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n");
857 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
858 ok(!ret, "WinHttpAddRequestHeaders failed\n");
860 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
861 ok(!ret, "WinHttpAddRequestHeaders failed\n");
863 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
864 ok(!ret, "WinHttpAddRequestHeaders failed\n");
866 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
867 ok(ret, "WinHttpAddRequestHeaders failed\n");
869 index = 0;
870 buffer[0] = 0;
871 len = sizeof(buffer);
872 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
873 field, buffer, &len, &index);
874 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
875 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
877 SetLastError(0xdeadbeef);
878 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, 0,
879 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
880 err = GetLastError();
881 ok(!ret, "unexpected success\n");
882 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
884 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, ~0u,
885 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
886 ok(ret, "failed to add header: %u\n", GetLastError());
888 index = 0;
889 len = sizeof(buffer);
890 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
891 test_header_range, buffer, &len, &index);
892 ok(ret, "failed to get range header %u\n", GetLastError());
893 ok(!memcmp(buffer, test_header_bytes, sizeof(test_header_bytes)), "incorrect string returned\n");
894 ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len);
895 ok(index == 1, "wrong index %u\n", index);
897 index = 0;
898 len = sizeof(buffer);
899 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
900 test_header_name2, buffer, &len, &index);
901 ok(!ret, "unexpected success\n");
903 SetLastError(0xdeadbeef);
904 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
905 err = GetLastError();
906 ok(!ret, "unexpected success\n");
907 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
909 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
910 ok(ret, "got %u\n", GetLastError());
912 index = 0;
913 len = sizeof(buffer);
914 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
915 test_header_name2, buffer, &len, &index);
916 ok(ret, "got %u\n", GetLastError());
917 ok(index == 1, "wrong index %u\n", index);
918 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
920 ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
921 ok(ret, "got %u\n", GetLastError());
923 index = 0;
924 len = sizeof(buffer);
925 SetLastError(0xdeadbeef);
926 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
927 test_header_name2, buffer, &len, &index);
928 err = GetLastError();
929 ok(!ret, "unexpected success\n");
930 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
932 ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0);
933 ok(ret, "got %u\n", GetLastError());
935 index = 0;
936 len = sizeof(buffer);
937 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
938 test_header_name2, buffer, &len, &index);
939 ok(ret, "got %u\n", GetLastError());
940 ok(index == 1, "wrong index %u\n", index);
941 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
943 ret = WinHttpCloseHandle(request);
944 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
945 done:
946 ret = WinHttpCloseHandle(connection);
947 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
948 ret = WinHttpCloseHandle(session);
949 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
953 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len)
955 DWORD flags = *(DWORD *)buf;
957 if (!flags)
959 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
960 return;
962 #define X(x) if (flags & x) trace("%s\n", #x);
963 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
964 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
965 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
966 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
967 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
968 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
969 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
970 #undef X
973 static void test_secure_connection(void)
975 static const char data_start[] = "<!DOCTYPE html PUBLIC";
976 HINTERNET ses, con, req;
977 DWORD size, status, policy, bitness, read_size, err, available_size;
978 BOOL ret;
979 CERT_CONTEXT *cert;
980 WINHTTP_CERTIFICATE_INFO info;
981 char buffer[32];
983 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
984 ok(ses != NULL, "failed to open session %u\n", GetLastError());
986 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
987 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
988 ok(ret, "failed to set redirect policy %u\n", GetLastError());
990 con = WinHttpConnect(ses, test_winehq, 443, 0);
991 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
993 /* try without setting WINHTTP_FLAG_SECURE */
994 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
995 ok(req != NULL, "failed to open a request %u\n", GetLastError());
997 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
998 err = GetLastError();
999 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
1001 skip("Connection failed, skipping.\n");
1002 goto cleanup;
1004 ok(ret, "failed to send request %u\n", GetLastError());
1006 ret = WinHttpReceiveResponse(req, NULL);
1007 ok(ret, "failed to receive response %u\n", GetLastError());
1009 status = 0xdeadbeef;
1010 size = sizeof(status);
1011 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1012 ok(ret, "header query failed %u\n", GetLastError());
1013 ok(status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status);
1015 WinHttpCloseHandle(req);
1017 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
1018 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1020 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
1022 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1023 err = GetLastError();
1024 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT ||
1025 err == ERROR_WINHTTP_TIMEOUT))
1027 skip("secure connection failed, skipping remaining secure tests\n");
1028 goto cleanup;
1030 ok(ret, "failed to send request %u\n", GetLastError());
1032 size = sizeof(cert);
1033 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
1034 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1035 if (ret) CertFreeCertificateContext(cert);
1037 size = sizeof(bitness);
1038 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
1039 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
1041 size = sizeof(info);
1042 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
1043 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
1045 if (ret)
1047 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
1048 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
1049 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
1050 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
1051 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
1052 trace("dwKeySize %u\n", info.dwKeySize);
1055 ret = WinHttpReceiveResponse(req, NULL);
1056 ok(ret, "failed to receive response %u\n", GetLastError());
1058 available_size = 0;
1059 ret = WinHttpQueryDataAvailable(req, &available_size);
1060 ok(ret, "failed to query available data %u\n", GetLastError());
1061 ok(available_size > 2014, "available_size = %u\n", available_size);
1063 status = 0xdeadbeef;
1064 size = sizeof(status);
1065 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1066 ok(ret, "failed unexpectedly %u\n", GetLastError());
1067 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1069 size = 0;
1070 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1071 ok(!ret, "succeeded unexpectedly\n");
1073 read_size = 0;
1074 for (;;)
1076 size = 0;
1077 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
1078 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
1079 if (!size) break;
1080 read_size += size;
1082 if (read_size <= 32)
1083 ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer);
1085 ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size);
1087 cleanup:
1088 WinHttpCloseHandle(req);
1089 WinHttpCloseHandle(con);
1090 WinHttpCloseHandle(ses);
1093 static void test_request_parameter_defaults(void)
1095 static const WCHAR empty[] = {0};
1096 HINTERNET ses, con, req;
1097 DWORD size, status, error;
1098 WCHAR *version;
1099 BOOL ret;
1101 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1102 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1104 con = WinHttpConnect(ses, test_winehq, 0, 0);
1105 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1107 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1108 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1110 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1111 error = GetLastError();
1112 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1114 skip("connection failed, skipping\n");
1115 goto done;
1117 ok(ret, "failed to send request %u\n", GetLastError());
1119 ret = WinHttpReceiveResponse(req, NULL);
1120 if (!ret && GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE) /* win2k */
1122 win_skip("invalid response\n");
1123 goto done;
1125 ok(ret, "failed to receive response %u\n", GetLastError());
1127 status = 0xdeadbeef;
1128 size = sizeof(status);
1129 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1130 ok(ret, "failed unexpectedly %u\n", GetLastError());
1131 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1133 WinHttpCloseHandle(req);
1135 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
1136 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1138 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1139 error = GetLastError();
1140 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1142 skip("connection failed, skipping\n");
1143 goto done;
1145 ok(ret, "failed to send request %u\n", GetLastError());
1147 ret = WinHttpReceiveResponse(req, NULL);
1148 ok(ret, "failed to receive response %u\n", GetLastError());
1150 size = 0;
1151 SetLastError(0xdeadbeef);
1152 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
1153 error = GetLastError();
1154 ok(!ret, "succeeded unexpectedly\n");
1155 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
1157 version = HeapAlloc(GetProcessHeap(), 0, size);
1158 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
1159 ok(ret, "failed unexpectedly %u\n", GetLastError());
1160 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
1161 HeapFree(GetProcessHeap(), 0, version);
1163 status = 0xdeadbeef;
1164 size = sizeof(status);
1165 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1166 ok(ret, "failed unexpectedly %u\n", GetLastError());
1167 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1169 done:
1170 WinHttpCloseHandle(req);
1171 WinHttpCloseHandle(con);
1172 WinHttpCloseHandle(ses);
1175 static const WCHAR Connections[] = {
1176 'S','o','f','t','w','a','r','e','\\',
1177 'M','i','c','r','o','s','o','f','t','\\',
1178 'W','i','n','d','o','w','s','\\',
1179 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1180 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1181 'C','o','n','n','e','c','t','i','o','n','s',0 };
1182 static const WCHAR WinHttpSettings[] = {
1183 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1185 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
1187 LONG l;
1188 HKEY key;
1189 DWORD ret = 0;
1191 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
1192 if (!l)
1194 DWORD size = 0;
1196 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
1197 if (!l)
1199 if (size <= len)
1200 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1201 &size );
1202 if (!l)
1203 ret = size;
1205 RegCloseKey( key );
1207 return ret;
1210 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1212 LONG l;
1213 HKEY key;
1215 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
1216 KEY_WRITE, NULL, &key, NULL );
1217 if (!l)
1219 if (len)
1220 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1221 else
1222 RegDeleteValueW( key, WinHttpSettings );
1223 RegCloseKey( key );
1227 static void test_set_default_proxy_config(void)
1229 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1230 static WCHAR normalString[] = { 'f','o','o',0 };
1231 DWORD type, len;
1232 BYTE *saved_proxy_settings = NULL;
1233 WINHTTP_PROXY_INFO info;
1234 BOOL ret;
1236 /* FIXME: it would be simpler to read the current settings using
1237 * WinHttpGetDefaultProxyConfiguration and save them using
1238 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1240 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1241 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1242 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1243 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1244 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1245 * the lpszProxy and lpszProxyBypass values are ignored.
1246 * Thus, if a proxy is set with proxycfg, then calling
1247 * WinHttpGetDefaultProxyConfiguration followed by
1248 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1249 * getting deleted from the registry.
1251 * Instead I read the current registry value and restore it directly.
1253 len = get_default_proxy_reg_value( NULL, 0, &type );
1254 if (len)
1256 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1257 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1260 if (0)
1262 /* Crashes on Vista and higher */
1263 SetLastError(0xdeadbeef);
1264 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1265 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1266 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1269 /* test with invalid access type */
1270 info.dwAccessType = 0xdeadbeef;
1271 info.lpszProxy = info.lpszProxyBypass = NULL;
1272 SetLastError(0xdeadbeef);
1273 ret = WinHttpSetDefaultProxyConfiguration(&info);
1274 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1275 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1277 /* at a minimum, the proxy server must be set */
1278 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1279 info.lpszProxy = info.lpszProxyBypass = NULL;
1280 SetLastError(0xdeadbeef);
1281 ret = WinHttpSetDefaultProxyConfiguration(&info);
1282 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1283 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1284 info.lpszProxyBypass = normalString;
1285 SetLastError(0xdeadbeef);
1286 ret = WinHttpSetDefaultProxyConfiguration(&info);
1287 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1288 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1290 /* the proxy server can't have wide characters */
1291 info.lpszProxy = wideString;
1292 SetLastError(0xdeadbeef);
1293 ret = WinHttpSetDefaultProxyConfiguration(&info);
1294 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1295 skip("couldn't set default proxy configuration: access denied\n");
1296 else
1297 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1298 broken(ret), /* Earlier winhttp versions on W2K/XP */
1299 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1301 info.lpszProxy = normalString;
1302 SetLastError(0xdeadbeef);
1303 ret = WinHttpSetDefaultProxyConfiguration(&info);
1304 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1305 skip("couldn't set default proxy configuration: access denied\n");
1306 else
1308 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1309 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1310 "got %u\n", GetLastError());
1312 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1315 static void test_Timeouts (void)
1317 BOOL ret;
1318 DWORD value, size;
1319 HINTERNET ses, req, con;
1321 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1322 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1324 SetLastError(0xdeadbeef);
1325 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1326 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1327 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1329 SetLastError(0xdeadbeef);
1330 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1331 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1332 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1334 SetLastError(0xdeadbeef);
1335 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1336 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1337 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1339 SetLastError(0xdeadbeef);
1340 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1341 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1342 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1344 SetLastError(0xdeadbeef);
1345 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1346 ok(ret, "%u\n", GetLastError());
1347 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1348 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1350 SetLastError(0xdeadbeef);
1351 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1352 ok(ret, "%u\n", GetLastError());
1354 SetLastError(0xdeadbeef);
1355 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1356 ok(ret, "%u\n", GetLastError());
1358 SetLastError(0xdeadbeef);
1359 value = 0xdeadbeef;
1360 size = sizeof(DWORD);
1361 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1362 ok(ret, "%u\n", GetLastError());
1363 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1365 SetLastError(0xdeadbeef);
1366 value = 0xdeadbeef;
1367 size = sizeof(DWORD);
1368 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1369 ok(ret, "%u\n", GetLastError());
1370 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1372 SetLastError(0xdeadbeef);
1373 value = 0xdeadbeef;
1374 size = sizeof(DWORD);
1375 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1376 ok(ret, "%u\n", GetLastError());
1377 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1379 SetLastError(0xdeadbeef);
1380 value = 0xdeadbeef;
1381 size = sizeof(DWORD);
1382 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1383 ok(ret, "%u\n", GetLastError());
1384 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1386 SetLastError(0xdeadbeef);
1387 value = 0;
1388 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1389 ok(ret, "%u\n", GetLastError());
1391 SetLastError(0xdeadbeef);
1392 value = 0xdeadbeef;
1393 size = sizeof(DWORD);
1394 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1395 ok(ret, "%u\n", GetLastError());
1396 ok(value == 0, "Expected 0, got %u\n", value);
1398 SetLastError(0xdeadbeef);
1399 value = 0;
1400 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1401 ok(ret, "%u\n", GetLastError());
1403 SetLastError(0xdeadbeef);
1404 value = 0xdeadbeef;
1405 size = sizeof(DWORD);
1406 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1407 ok(ret, "%u\n", GetLastError());
1408 ok(value == 0, "Expected 0, got %u\n", value);
1410 SetLastError(0xdeadbeef);
1411 value = 0;
1412 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1413 ok(ret, "%u\n", GetLastError());
1415 SetLastError(0xdeadbeef);
1416 value = 0xdeadbeef;
1417 size = sizeof(DWORD);
1418 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1419 ok(ret, "%u\n", GetLastError());
1420 ok(value == 0, "Expected 0, got %u\n", value);
1422 SetLastError(0xdeadbeef);
1423 value = 0;
1424 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1425 ok(ret, "%u\n", GetLastError());
1427 SetLastError(0xdeadbeef);
1428 value = 0xdeadbeef;
1429 size = sizeof(DWORD);
1430 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1431 ok(ret, "%u\n", GetLastError());
1432 ok(value == 0, "Expected 0, got %u\n", value);
1434 SetLastError(0xdeadbeef);
1435 value = 0xbeefdead;
1436 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1437 ok(ret, "%u\n", GetLastError());
1439 SetLastError(0xdeadbeef);
1440 value = 0xdeadbeef;
1441 size = sizeof(DWORD);
1442 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1443 ok(ret, "%u\n", GetLastError());
1444 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1446 SetLastError(0xdeadbeef);
1447 value = 0xbeefdead;
1448 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1449 ok(ret, "%u\n", GetLastError());
1451 SetLastError(0xdeadbeef);
1452 value = 0xdeadbeef;
1453 size = sizeof(DWORD);
1454 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1455 ok(ret, "%u\n", GetLastError());
1456 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1458 SetLastError(0xdeadbeef);
1459 value = 0xbeefdead;
1460 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1461 ok(ret, "%u\n", GetLastError());
1463 SetLastError(0xdeadbeef);
1464 value = 0xdeadbeef;
1465 size = sizeof(DWORD);
1466 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1467 ok(ret, "%u\n", GetLastError());
1468 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1470 SetLastError(0xdeadbeef);
1471 value = 0xbeefdead;
1472 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1473 ok(ret, "%u\n", GetLastError());
1475 SetLastError(0xdeadbeef);
1476 value = 0xdeadbeef;
1477 size = sizeof(DWORD);
1478 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1479 ok(ret, "%u\n", GetLastError());
1480 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1482 con = WinHttpConnect(ses, test_winehq, 0, 0);
1483 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1485 /* Timeout values should match the last one set for session */
1486 SetLastError(0xdeadbeef);
1487 value = 0xdeadbeef;
1488 size = sizeof(DWORD);
1489 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1490 ok(ret, "%u\n", GetLastError());
1491 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1493 SetLastError(0xdeadbeef);
1494 value = 0xdeadbeef;
1495 size = sizeof(DWORD);
1496 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1497 ok(ret, "%u\n", GetLastError());
1498 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1500 SetLastError(0xdeadbeef);
1501 value = 0xdeadbeef;
1502 size = sizeof(DWORD);
1503 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1504 ok(ret, "%u\n", GetLastError());
1505 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1507 SetLastError(0xdeadbeef);
1508 value = 0xdeadbeef;
1509 size = sizeof(DWORD);
1510 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1511 ok(ret, "%u\n", GetLastError());
1512 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1514 SetLastError(0xdeadbeef);
1515 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1516 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1517 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1519 SetLastError(0xdeadbeef);
1520 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1521 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1522 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1524 SetLastError(0xdeadbeef);
1525 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1526 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1527 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1529 SetLastError(0xdeadbeef);
1530 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1531 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1532 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1534 SetLastError(0xdeadbeef);
1535 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1536 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1537 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1539 SetLastError(0xdeadbeef);
1540 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1541 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1542 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1544 SetLastError(0xdeadbeef);
1545 value = 0;
1546 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1547 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1548 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1550 SetLastError(0xdeadbeef);
1551 value = 0;
1552 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1553 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1554 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1556 SetLastError(0xdeadbeef);
1557 value = 0;
1558 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1559 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1560 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1562 SetLastError(0xdeadbeef);
1563 value = 0;
1564 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1565 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1566 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1568 /* Changing timeout values for session should affect the values for connection */
1569 SetLastError(0xdeadbeef);
1570 value = 0xdead;
1571 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1572 ok(ret, "%u\n", GetLastError());
1574 SetLastError(0xdeadbeef);
1575 value = 0xdeadbeef;
1576 size = sizeof(DWORD);
1577 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1578 ok(ret, "%u\n", GetLastError());
1579 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1581 SetLastError(0xdeadbeef);
1582 value = 0xdead;
1583 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1584 ok(ret, "%u\n", GetLastError());
1586 SetLastError(0xdeadbeef);
1587 value = 0xdeadbeef;
1588 size = sizeof(DWORD);
1589 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1590 ok(ret, "%u\n", GetLastError());
1591 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1593 SetLastError(0xdeadbeef);
1594 value = 0xdead;
1595 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1596 ok(ret, "%u\n", GetLastError());
1598 SetLastError(0xdeadbeef);
1599 value = 0xdeadbeef;
1600 size = sizeof(DWORD);
1601 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1602 ok(ret, "%u\n", GetLastError());
1603 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1605 SetLastError(0xdeadbeef);
1606 value = 0xdead;
1607 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1608 ok(ret, "%u\n", GetLastError());
1610 SetLastError(0xdeadbeef);
1611 value = 0xdeadbeef;
1612 size = sizeof(DWORD);
1613 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1614 ok(ret, "%u\n", GetLastError());
1615 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1617 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1618 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1620 /* Timeout values should match the last one set for session */
1621 SetLastError(0xdeadbeef);
1622 value = 0xdeadbeef;
1623 size = sizeof(DWORD);
1624 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1625 ok(ret, "%u\n", GetLastError());
1626 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1628 SetLastError(0xdeadbeef);
1629 value = 0xdeadbeef;
1630 size = sizeof(DWORD);
1631 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1632 ok(ret, "%u\n", GetLastError());
1633 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1635 SetLastError(0xdeadbeef);
1636 value = 0xdeadbeef;
1637 size = sizeof(DWORD);
1638 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1639 ok(ret, "%u\n", GetLastError());
1640 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1642 SetLastError(0xdeadbeef);
1643 value = 0xdeadbeef;
1644 size = sizeof(DWORD);
1645 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1646 ok(ret, "%u\n", GetLastError());
1647 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1649 SetLastError(0xdeadbeef);
1650 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1651 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1652 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1654 SetLastError(0xdeadbeef);
1655 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1656 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1657 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1659 SetLastError(0xdeadbeef);
1660 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1661 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1662 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1664 SetLastError(0xdeadbeef);
1665 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1666 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1667 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1669 SetLastError(0xdeadbeef);
1670 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1671 ok(ret, "%u\n", GetLastError());
1673 SetLastError(0xdeadbeef);
1674 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1675 ok(ret, "%u\n", GetLastError());
1677 SetLastError(0xdeadbeef);
1678 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1679 ok(ret, "%u\n", GetLastError());
1681 SetLastError(0xdeadbeef);
1682 value = 0xdeadbeef;
1683 size = sizeof(DWORD);
1684 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1685 ok(ret, "%u\n", GetLastError());
1686 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1688 SetLastError(0xdeadbeef);
1689 value = 0xdeadbeef;
1690 size = sizeof(DWORD);
1691 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1692 ok(ret, "%u\n", GetLastError());
1693 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1695 SetLastError(0xdeadbeef);
1696 value = 0xdeadbeef;
1697 size = sizeof(DWORD);
1698 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1699 ok(ret, "%u\n", GetLastError());
1700 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1702 SetLastError(0xdeadbeef);
1703 value = 0xdeadbeef;
1704 size = sizeof(DWORD);
1705 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1706 ok(ret, "%u\n", GetLastError());
1707 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1709 SetLastError(0xdeadbeef);
1710 value = 0;
1711 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1712 ok(ret, "%u\n", GetLastError());
1714 SetLastError(0xdeadbeef);
1715 value = 0xdeadbeef;
1716 size = sizeof(DWORD);
1717 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1718 ok(ret, "%u\n", GetLastError());
1719 ok(value == 0, "Expected 0, got %u\n", value);
1721 SetLastError(0xdeadbeef);
1722 value = 0;
1723 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1724 ok(ret, "%u\n", GetLastError());
1726 SetLastError(0xdeadbeef);
1727 value = 0xdeadbeef;
1728 size = sizeof(DWORD);
1729 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1730 ok(ret, "%u\n", GetLastError());
1731 ok(value == 0, "Expected 0, got %u\n", value);
1733 SetLastError(0xdeadbeef);
1734 value = 0;
1735 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1736 ok(ret, "%u\n", GetLastError());
1738 SetLastError(0xdeadbeef);
1739 value = 0xdeadbeef;
1740 size = sizeof(DWORD);
1741 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1742 ok(ret, "%u\n", GetLastError());
1743 ok(value == 0, "Expected 0, got %u\n", value);
1745 SetLastError(0xdeadbeef);
1746 value = 0;
1747 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1748 ok(ret, "%u\n", GetLastError());
1750 SetLastError(0xdeadbeef);
1751 value = 0xdeadbeef;
1752 size = sizeof(DWORD);
1753 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1754 ok(ret, "%u\n", GetLastError());
1755 ok(value == 0, "Expected 0, got %u\n", value);
1757 SetLastError(0xdeadbeef);
1758 value = 0xbeefdead;
1759 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1760 ok(ret, "%u\n", GetLastError());
1762 SetLastError(0xdeadbeef);
1763 value = 0xdeadbeef;
1764 size = sizeof(DWORD);
1765 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1766 ok(ret, "%u\n", GetLastError());
1767 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1769 SetLastError(0xdeadbeef);
1770 value = 0xbeefdead;
1771 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1772 ok(ret, "%u\n", GetLastError());
1774 SetLastError(0xdeadbeef);
1775 value = 0xdeadbeef;
1776 size = sizeof(DWORD);
1777 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1778 ok(ret, "%u\n", GetLastError());
1779 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1781 SetLastError(0xdeadbeef);
1782 value = 0xbeefdead;
1783 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1784 ok(ret, "%u\n", GetLastError());
1786 SetLastError(0xdeadbeef);
1787 value = 0xdeadbeef;
1788 size = sizeof(DWORD);
1789 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1790 ok(ret, "%u\n", GetLastError());
1791 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1793 SetLastError(0xdeadbeef);
1794 value = 0xbeefdead;
1795 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1796 ok(ret, "%u\n", GetLastError());
1798 SetLastError(0xdeadbeef);
1799 value = 0xdeadbeef;
1800 size = sizeof(DWORD);
1801 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1802 ok(ret, "%u\n", GetLastError());
1803 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1805 /* Changing timeout values for session should not affect the values for a request,
1806 * neither should the other way around.
1808 SetLastError(0xdeadbeef);
1809 value = 0xbeefdead;
1810 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1811 ok(ret, "%u\n", GetLastError());
1813 SetLastError(0xdeadbeef);
1814 value = 0xdeadbeef;
1815 size = sizeof(DWORD);
1816 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1817 ok(ret, "%u\n", GetLastError());
1818 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1820 SetLastError(0xdeadbeef);
1821 value = 0xbeefdead;
1822 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1823 ok(ret, "%u\n", GetLastError());
1825 SetLastError(0xdeadbeef);
1826 value = 0xdeadbeef;
1827 size = sizeof(DWORD);
1828 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1829 ok(ret, "%u\n", GetLastError());
1830 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1832 SetLastError(0xdeadbeef);
1833 value = 0xbeefdead;
1834 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1835 ok(ret, "%u\n", GetLastError());
1837 SetLastError(0xdeadbeef);
1838 value = 0xdeadbeef;
1839 size = sizeof(DWORD);
1840 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1841 ok(ret, "%u\n", GetLastError());
1842 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1844 SetLastError(0xdeadbeef);
1845 value = 0xbeefdead;
1846 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1847 ok(ret, "%u\n", GetLastError());
1849 SetLastError(0xdeadbeef);
1850 value = 0xdeadbeef;
1851 size = sizeof(DWORD);
1852 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1853 ok(ret, "%u\n", GetLastError());
1854 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1856 SetLastError(0xdeadbeef);
1857 value = 0xbeef;
1858 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1859 ok(ret, "%u\n", GetLastError());
1861 SetLastError(0xdeadbeef);
1862 value = 0xdeadbeef;
1863 size = sizeof(DWORD);
1864 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1865 ok(ret, "%u\n", GetLastError());
1866 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1868 SetLastError(0xdeadbeef);
1869 value = 0xbeef;
1870 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1871 ok(ret, "%u\n", GetLastError());
1873 SetLastError(0xdeadbeef);
1874 value = 0xdeadbeef;
1875 size = sizeof(DWORD);
1876 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1877 ok(ret, "%u\n", GetLastError());
1878 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1880 SetLastError(0xdeadbeef);
1881 value = 0xbeef;
1882 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1883 ok(ret, "%u\n", GetLastError());
1885 SetLastError(0xdeadbeef);
1886 value = 0xdeadbeef;
1887 size = sizeof(DWORD);
1888 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1889 ok(ret, "%u\n", GetLastError());
1890 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1892 SetLastError(0xdeadbeef);
1893 value = 0xbeef;
1894 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1895 ok(ret, "%u\n", GetLastError());
1897 SetLastError(0xdeadbeef);
1898 value = 0xdeadbeef;
1899 size = sizeof(DWORD);
1900 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1901 ok(ret, "%u\n", GetLastError());
1902 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1904 WinHttpCloseHandle(req);
1905 WinHttpCloseHandle(con);
1906 WinHttpCloseHandle(ses);
1909 static void test_resolve_timeout(void)
1911 static const WCHAR nxdomain[] =
1912 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1913 HINTERNET ses, con, req;
1914 DWORD timeout;
1915 BOOL ret;
1917 if (! proxy_active())
1919 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1920 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1922 timeout = 10000;
1923 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1924 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1926 con = WinHttpConnect(ses, nxdomain, 0, 0);
1927 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1929 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1930 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1932 SetLastError(0xdeadbeef);
1933 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1934 if (ret)
1936 skip("nxdomain returned success. Broken ISP redirects?\n");
1937 goto done;
1939 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1940 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1942 WinHttpCloseHandle(req);
1943 WinHttpCloseHandle(con);
1944 WinHttpCloseHandle(ses);
1946 else
1947 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1949 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1950 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1952 timeout = 10000;
1953 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1954 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1956 con = WinHttpConnect(ses, test_winehq, 0, 0);
1957 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1959 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1960 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1962 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1963 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
1965 skip("connection failed, skipping\n");
1966 goto done;
1968 ok(ret, "failed to send request\n");
1970 done:
1971 WinHttpCloseHandle(req);
1972 WinHttpCloseHandle(con);
1973 WinHttpCloseHandle(ses);
1976 static const char page1[] =
1977 "<HTML>\r\n"
1978 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1979 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1980 "</HTML>\r\n\r\n";
1982 static const char okmsg[] =
1983 "HTTP/1.1 200 OK\r\n"
1984 "Server: winetest\r\n"
1985 "\r\n";
1987 static const char notokmsg[] =
1988 "HTTP/1.1 400 Bad Request\r\n"
1989 "\r\n";
1991 static const char cookiemsg[] =
1992 "HTTP/1.1 200 OK\r\n"
1993 "Set-Cookie: name = value \r\n"
1994 "Set-Cookie: NAME = value \r\n"
1995 "\r\n";
1997 static const char nocontentmsg[] =
1998 "HTTP/1.1 204 No Content\r\n"
1999 "Server: winetest\r\n"
2000 "\r\n";
2002 static const char notmodified[] =
2003 "HTTP/1.1 304 Not Modified\r\n"
2004 "\r\n";
2006 static const char noauthmsg[] =
2007 "HTTP/1.1 401 Unauthorized\r\n"
2008 "Server: winetest\r\n"
2009 "Connection: close\r\n"
2010 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2011 "Content-Length: 12\r\n"
2012 "Content-Type: text/plain\r\n"
2013 "\r\n";
2015 static const char okauthmsg[] =
2016 "HTTP/1.1 200 OK\r\n"
2017 "Server: winetest\r\n"
2018 "Connection: close\r\n"
2019 "Content-Length: 11\r\n"
2020 "Content-Type: text/plain\r\n"
2021 "\r\n";
2023 static const char headmsg[] =
2024 "HTTP/1.1 200 OK\r\n"
2025 "Content-Length: 100\r\n"
2026 "\r\n";
2028 static const char unauthorized[] = "Unauthorized";
2029 static const char hello_world[] = "Hello World";
2031 struct server_info
2033 HANDLE event;
2034 int port;
2037 #define BIG_BUFFER_LEN 0x2250
2039 static DWORD CALLBACK server_thread(LPVOID param)
2041 struct server_info *si = param;
2042 int r, c = -1, i, on;
2043 SOCKET s;
2044 struct sockaddr_in sa;
2045 char buffer[0x100];
2046 WSADATA wsaData;
2047 int last_request = 0;
2049 WSAStartup(MAKEWORD(1,1), &wsaData);
2051 s = socket(AF_INET, SOCK_STREAM, 0);
2052 if (s == INVALID_SOCKET)
2053 return 1;
2055 on = 1;
2056 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2058 memset(&sa, 0, sizeof sa);
2059 sa.sin_family = AF_INET;
2060 sa.sin_port = htons(si->port);
2061 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2063 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
2064 if (r < 0)
2065 return 1;
2067 listen(s, 0);
2068 SetEvent(si->event);
2071 if (c == -1) c = accept(s, NULL, NULL);
2073 memset(buffer, 0, sizeof buffer);
2074 for(i = 0; i < sizeof buffer - 1; i++)
2076 r = recv(c, &buffer[i], 1, 0);
2077 if (r != 1)
2078 break;
2079 if (i < 4) continue;
2080 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
2081 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
2082 break;
2084 if (strstr(buffer, "GET /basic"))
2086 send(c, okmsg, sizeof okmsg - 1, 0);
2087 send(c, page1, sizeof page1 - 1, 0);
2089 if (strstr(buffer, "/auth"))
2091 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2093 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2094 send(c, hello_world, sizeof hello_world - 1, 0);
2096 else
2098 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
2099 send(c, unauthorized, sizeof unauthorized - 1, 0);
2101 continue;
2103 if (strstr(buffer, "/big"))
2105 char msg[BIG_BUFFER_LEN];
2106 memset(msg, 'm', sizeof(msg));
2107 send(c, okmsg, sizeof(okmsg) - 1, 0);
2108 send(c, msg, sizeof(msg), 0);
2110 if (strstr(buffer, "/no_headers"))
2112 send(c, page1, sizeof page1 - 1, 0);
2114 if (strstr(buffer, "GET /no_content"))
2116 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
2117 continue;
2119 if (strstr(buffer, "GET /not_modified"))
2121 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0);
2122 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2123 continue;
2125 if (strstr(buffer, "HEAD /head"))
2127 send(c, headmsg, sizeof headmsg - 1, 0);
2128 continue;
2130 if (strstr(buffer, "GET /cookie3"))
2132 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2133 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL))
2134 send(c, okmsg, sizeof(okmsg) - 1, 0);
2135 else
2136 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2138 if (strstr(buffer, "GET /cookie2"))
2140 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") ||
2141 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL))
2142 send(c, okmsg, sizeof(okmsg) - 1, 0);
2143 else
2144 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2146 else if (strstr(buffer, "GET /cookie"))
2148 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
2149 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2151 if (strstr(buffer, "GET /quit"))
2153 send(c, okmsg, sizeof okmsg - 1, 0);
2154 send(c, page1, sizeof page1 - 1, 0);
2155 last_request = 1;
2157 shutdown(c, 2);
2158 closesocket(c);
2159 c = -1;
2161 } while (!last_request);
2163 closesocket(s);
2164 return 0;
2167 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
2169 static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0};
2170 static const WCHAR test_header_end_raw[] = {0,0};
2171 HINTERNET ses, con, req;
2172 char buffer[0x100];
2173 WCHAR buffer2[0x100];
2174 DWORD count, status, size, error, supported, first, target;
2175 BOOL ret;
2177 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2178 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2180 con = WinHttpConnect(ses, localhostW, port, 0);
2181 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2183 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
2184 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2186 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2187 ok(ret, "failed to send request %u\n", GetLastError());
2189 ret = WinHttpReceiveResponse(req, NULL);
2190 ok(ret, "failed to receive response %u\n", GetLastError());
2192 status = 0xdeadbeef;
2193 size = sizeof(status);
2194 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2195 ok(ret, "failed to query status code %u\n", GetLastError());
2196 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2198 supported = first = target = 0xdeadbeef;
2199 SetLastError(0xdeadbeef);
2200 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2201 error = GetLastError();
2202 ok(!ret, "unexpected success\n");
2203 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2204 ok(supported == 0xdeadbeef, "got %x\n", supported);
2205 ok(first == 0xdeadbeef, "got %x\n", first);
2206 ok(target == 0xdeadbeef, "got %x\n", target);
2208 size = sizeof(buffer2);
2209 memset(buffer2, 0, sizeof(buffer2));
2210 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL);
2211 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2212 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)),
2213 "WinHttpQueryHeaders returned invalid end of header string\n");
2215 size = sizeof(buffer2);
2216 memset(buffer2, 0, sizeof(buffer2));
2217 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL);
2218 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2219 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)),
2220 "WinHttpQueryHeaders returned invalid end of header string\n");
2221 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n");
2223 count = 0;
2224 memset(buffer, 0, sizeof(buffer));
2225 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
2226 ok(ret, "failed to read data %u\n", GetLastError());
2227 ok(count == sizeof page1 - 1, "count was wrong\n");
2228 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2230 WinHttpCloseHandle(req);
2231 WinHttpCloseHandle(con);
2232 WinHttpCloseHandle(ses);
2235 static void test_basic_authentication(int port)
2237 static const WCHAR authW[] = {'/','a','u','t','h',0};
2238 static WCHAR userW[] = {'u','s','e','r',0};
2239 static WCHAR passW[] = {'p','w','d',0};
2240 static WCHAR pass2W[] = {'p','w','d','2',0};
2241 HINTERNET ses, con, req;
2242 DWORD status, size, error, supported, first, target;
2243 char buffer[32];
2244 BOOL ret;
2246 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2247 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2249 con = WinHttpConnect(ses, localhostW, port, 0);
2250 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2252 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2253 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2255 SetLastError(0xdeadbeef);
2256 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
2257 error = GetLastError();
2258 ok(!ret, "expected failure\n");
2259 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2261 SetLastError(0xdeadbeef);
2262 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
2263 error = GetLastError();
2264 ok(!ret, "expected failure\n");
2265 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2267 supported = 0xdeadbeef;
2268 SetLastError(0xdeadbeef);
2269 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2270 error = GetLastError();
2271 ok(!ret, "expected failure\n");
2272 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2273 ok(supported == 0xdeadbeef, "got %x\n", supported);
2275 supported = first = 0xdeadbeef;
2276 SetLastError(0xdeadbeef);
2277 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
2278 error = GetLastError();
2279 ok(!ret, "expected failure\n");
2280 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2281 ok(supported == 0xdeadbeef, "got %x\n", supported);
2282 ok(first == 0xdeadbeef, "got %x\n", first);
2284 supported = first = target = 0xdeadbeef;
2285 SetLastError(0xdeadbeef);
2286 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2287 error = GetLastError();
2288 ok(!ret, "expected failure\n");
2289 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2290 ok(supported == 0xdeadbeef, "got %x\n", supported);
2291 ok(first == 0xdeadbeef, "got %x\n", first);
2292 ok(target == 0xdeadbeef, "got %x\n", target);
2294 supported = first = target = 0xdeadbeef;
2295 SetLastError(0xdeadbeef);
2296 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2297 error = GetLastError();
2298 ok(!ret, "expected failure\n");
2299 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2300 ok(supported == 0xdeadbeef, "got %x\n", supported);
2301 ok(first == 0xdeadbeef, "got %x\n", first);
2302 ok(target == 0xdeadbeef, "got %x\n", target);
2304 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2305 ok(ret, "failed to send request %u\n", GetLastError());
2307 ret = WinHttpReceiveResponse(req, NULL);
2308 ok(ret, "failed to receive response %u\n", GetLastError());
2310 status = 0xdeadbeef;
2311 size = sizeof(status);
2312 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2313 ok(ret, "failed to query status code %u\n", GetLastError());
2314 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status);
2316 size = 0;
2317 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2318 error = GetLastError();
2319 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2320 if (ret)
2322 ok(size == 12, "expected 12, got %u\n", size);
2323 ok(!memcmp(buffer, unauthorized, 12), "got %s\n", buffer);
2326 supported = first = target = 0xdeadbeef;
2327 SetLastError(0xdeadbeef);
2328 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2329 error = GetLastError();
2330 ok(ret, "failed to query authentication schemes %u\n", error);
2331 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2332 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2333 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2334 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2336 SetLastError(0xdeadbeef);
2337 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2338 error = GetLastError();
2339 ok(ret, "failed to set credentials %u\n", error);
2340 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2342 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2343 ok(ret, "failed to set credentials %u\n", GetLastError());
2345 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2346 ok(ret, "failed to set credentials %u\n", GetLastError());
2348 SetLastError(0xdeadbeef);
2349 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2350 error = GetLastError();
2351 ok(!ret, "expected failure\n");
2352 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2354 SetLastError(0xdeadbeef);
2355 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2356 error = GetLastError();
2357 ok(!ret, "expected failure\n");
2358 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2360 SetLastError(0xdeadbeef);
2361 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2362 error = GetLastError();
2363 ok(!ret, "expected failure\n");
2364 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2366 SetLastError(0xdeadbeef);
2367 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2368 error = GetLastError();
2369 ok(!ret, "expected failure\n");
2370 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2372 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2373 ok(ret, "failed to set credentials %u\n", GetLastError());
2375 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2376 ok(ret, "failed to send request %u\n", GetLastError());
2378 ret = WinHttpReceiveResponse(req, NULL);
2379 ok(ret, "failed to receive response %u\n", GetLastError());
2381 status = 0xdeadbeef;
2382 size = sizeof(status);
2383 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2384 ok(ret, "failed to query status code %u\n", GetLastError());
2385 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2387 size = 0;
2388 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2389 error = GetLastError();
2390 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2391 if (ret)
2393 ok(size == 11, "expected 11, got %u\n", size);
2394 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2397 WinHttpCloseHandle(req);
2398 WinHttpCloseHandle(con);
2399 WinHttpCloseHandle(ses);
2401 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2403 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2404 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2406 con = WinHttpConnect(ses, localhostW, port, 0);
2407 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2409 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2410 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2412 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2413 ok(ret, "failed to set credentials %u\n", GetLastError());
2415 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2416 ok(ret, "failed to set username %u\n", GetLastError());
2418 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W));
2419 ok(ret, "failed to set password %u\n", GetLastError());
2421 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2422 ok(ret, "failed to send request %u\n", GetLastError());
2424 ret = WinHttpReceiveResponse(req, NULL);
2425 ok(ret, "failed to receive response %u\n", GetLastError());
2427 status = 0xdeadbeef;
2428 size = sizeof(status);
2429 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2430 ok(ret, "failed to query status code %u\n", GetLastError());
2431 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2433 WinHttpCloseHandle(req);
2434 WinHttpCloseHandle(con);
2435 WinHttpCloseHandle(ses);
2437 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2438 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2440 con = WinHttpConnect(ses, localhostW, port, 0);
2441 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2443 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2444 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2446 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2447 ok(ret, "failed to set username %u\n", GetLastError());
2449 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2450 ok(ret, "failed to set password %u\n", GetLastError());
2452 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, NULL);
2453 ok(ret, "failed to set credentials %u\n", GetLastError());
2455 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2456 ok(ret, "failed to send request %u\n", GetLastError());
2458 ret = WinHttpReceiveResponse(req, NULL);
2459 ok(ret, "failed to receive response %u\n", GetLastError());
2461 status = 0xdeadbeef;
2462 size = sizeof(status);
2463 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2464 ok(ret, "failed to query status code %u\n", GetLastError());
2465 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status);
2467 WinHttpCloseHandle(req);
2468 WinHttpCloseHandle(con);
2469 WinHttpCloseHandle(ses);
2472 static void test_no_headers(int port)
2474 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2475 HINTERNET ses, con, req;
2476 DWORD error;
2477 BOOL ret;
2479 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2480 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2482 con = WinHttpConnect(ses, localhostW, port, 0);
2483 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2485 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2486 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2488 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2489 if (!ret)
2491 error = GetLastError();
2492 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2494 else
2496 SetLastError(0xdeadbeef);
2497 ret = WinHttpReceiveResponse(req, NULL);
2498 error = GetLastError();
2499 ok(!ret, "expected failure\n");
2500 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2503 WinHttpCloseHandle(req);
2504 WinHttpCloseHandle(con);
2505 WinHttpCloseHandle(ses);
2508 static void test_no_content(int port)
2510 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2511 HINTERNET ses, con, req;
2512 char buf[128];
2513 DWORD size, len = sizeof(buf), bytes_read, status;
2514 BOOL ret;
2516 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2517 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2519 con = WinHttpConnect(ses, localhostW, port, 0);
2520 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2522 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0);
2523 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2525 size = 12345;
2526 SetLastError(0xdeadbeef);
2527 ret = WinHttpQueryDataAvailable(req, &size);
2528 todo_wine {
2529 ok(!ret, "expected error\n");
2530 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE,
2531 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2532 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
2533 "expected 12345, got %u\n", size);
2536 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2537 ok(ret, "expected success\n");
2539 ret = WinHttpReceiveResponse(req, NULL);
2540 ok(ret, "expected success\n");
2542 status = 0xdeadbeef;
2543 size = sizeof(status);
2544 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2545 NULL, &status, &size, NULL);
2546 ok(ret, "expected success\n");
2547 ok(status == HTTP_STATUS_NO_CONTENT, "expected status 204, got %d\n", status);
2549 SetLastError(0xdeadbeef);
2550 size = sizeof(status);
2551 status = 12345;
2552 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2553 NULL, &status, &size, 0);
2554 ok(!ret, "expected no content-length header\n");
2555 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError());
2556 ok(status == 12345, "expected 0, got %d\n", status);
2558 SetLastError(0xdeadbeef);
2559 size = 12345;
2560 ret = WinHttpQueryDataAvailable(req, &size);
2561 ok(ret, "expected success\n");
2562 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2563 "wrong error %u\n", GetLastError());
2564 ok(!size, "expected 0, got %u\n", size);
2566 SetLastError(0xdeadbeef);
2567 ret = WinHttpReadData(req, buf, len, &bytes_read);
2568 ok(ret, "expected success\n");
2569 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2570 "wrong error %u\n", GetLastError());
2571 ok(!bytes_read, "expected 0, got %u\n", bytes_read);
2573 size = 12345;
2574 ret = WinHttpQueryDataAvailable(req, &size);
2575 ok(ret, "expected success\n");
2576 ok(size == 0, "expected 0, got %d\n", size);
2578 WinHttpCloseHandle(req);
2580 size = 12345;
2581 SetLastError(0xdeadbeef);
2582 ret = WinHttpQueryDataAvailable(req, &size);
2583 ok(!ret, "expected error\n");
2584 ok(GetLastError() == ERROR_INVALID_HANDLE,
2585 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2586 ok(size == 12345, "expected 12345, got %u\n", size);
2588 WinHttpCloseHandle(con);
2589 WinHttpCloseHandle(ses);
2592 static void test_head_request(int port)
2594 static const WCHAR verbW[] = {'H','E','A','D',0};
2595 static const WCHAR headW[] = {'/','h','e','a','d',0};
2596 HINTERNET ses, con, req;
2597 char buf[128];
2598 DWORD size, len, count, status;
2599 BOOL ret;
2601 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2602 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2604 con = WinHttpConnect(ses, localhostW, port, 0);
2605 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2607 req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0);
2608 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2610 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2611 ok(ret, "failed to send request %u\n", GetLastError());
2613 ret = WinHttpReceiveResponse(req, NULL);
2614 ok(ret, "failed to receive response %u\n", GetLastError());
2616 status = 0xdeadbeef;
2617 size = sizeof(status);
2618 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
2619 NULL, &status, &size, NULL);
2620 ok(ret, "failed to get status code %u\n", GetLastError());
2621 ok(status == HTTP_STATUS_OK, "got %u\n", status);
2623 len = 0xdeadbeef;
2624 size = sizeof(len);
2625 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
2626 NULL, &len, &size, 0);
2627 ok(ret, "failed to get content-length header %u\n", GetLastError());
2628 ok(len == HTTP_STATUS_CONTINUE, "got %u\n", len);
2630 count = 0xdeadbeef;
2631 ret = WinHttpQueryDataAvailable(req, &count);
2632 ok(ret, "failed to query data available %u\n", GetLastError());
2633 ok(!count, "got %u\n", count);
2635 len = sizeof(buf);
2636 count = 0xdeadbeef;
2637 ret = WinHttpReadData(req, buf, len, &count);
2638 ok(ret, "failed to read data %u\n", GetLastError());
2639 ok(!count, "got %u\n", count);
2641 count = 0xdeadbeef;
2642 ret = WinHttpQueryDataAvailable(req, &count);
2643 ok(ret, "failed to query data available %u\n", GetLastError());
2644 ok(!count, "got %u\n", count);
2646 WinHttpCloseHandle(req);
2647 WinHttpCloseHandle(con);
2648 WinHttpCloseHandle(ses);
2651 static void test_not_modified(int port)
2653 static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2654 static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2655 static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2656 BOOL ret;
2657 HINTERNET session, request, connection;
2658 DWORD index, len, status, size, start = GetTickCount();
2659 SYSTEMTIME st;
2660 WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32];
2662 memcpy(today, ifmodifiedW, sizeof(ifmodifiedW));
2663 GetSystemTime(&st);
2664 WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]);
2666 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY,
2667 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
2668 ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError());
2670 connection = WinHttpConnect(session, localhostW, port, 0);
2671 ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError());
2673 request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER,
2674 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
2675 ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError());
2677 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0);
2678 ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError());
2680 ret = WinHttpReceiveResponse(request, NULL);
2681 ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2683 index = 0;
2684 len = sizeof(buffer);
2685 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2686 ifmodified2W, buffer, &len, &index);
2687 ok(ret, "failed to get header %u\n", GetLastError());
2689 status = 0xdeadbeef;
2690 size = sizeof(status);
2691 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
2692 NULL, &status, &size, NULL);
2693 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2694 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status);
2696 size = 0xdeadbeef;
2697 ret = WinHttpQueryDataAvailable(request, &size);
2698 ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2699 ok(!size, "got %u\n", size);
2701 WinHttpCloseHandle(request);
2702 WinHttpCloseHandle(connection);
2703 WinHttpCloseHandle(session);
2704 start = GetTickCount() - start;
2705 ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start);
2708 static void test_bad_header( int port )
2710 static const WCHAR bad_headerW[] =
2711 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2712 't','e','x','t','/','h','t','m','l','\n','\r',0};
2713 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
2714 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2715 WCHAR buffer[32];
2716 HINTERNET ses, con, req;
2717 DWORD index, len;
2718 BOOL ret;
2720 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2721 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2723 con = WinHttpConnect( ses, localhostW, port, 0 );
2724 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2726 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2727 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2729 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2730 ok( ret, "failed to add header %u\n", GetLastError() );
2732 index = 0;
2733 buffer[0] = 0;
2734 len = sizeof(buffer);
2735 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2736 content_typeW, buffer, &len, &index );
2737 ok( ret, "failed to query headers %u\n", GetLastError() );
2738 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2740 WinHttpCloseHandle( req );
2741 WinHttpCloseHandle( con );
2742 WinHttpCloseHandle( ses );
2745 static void test_multiple_reads(int port)
2747 static const WCHAR bigW[] = {'b','i','g',0};
2748 HINTERNET ses, con, req;
2749 DWORD total_len = 0;
2750 BOOL ret;
2752 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2753 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2755 con = WinHttpConnect(ses, localhostW, port, 0);
2756 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2758 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
2759 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2761 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2762 ok(ret, "failed to send request %u\n", GetLastError());
2764 ret = WinHttpReceiveResponse(req, NULL);
2765 ok(ret == TRUE, "expected success\n");
2767 for (;;)
2769 DWORD len = 0xdeadbeef;
2770 ret = WinHttpQueryDataAvailable( req, &len );
2771 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2772 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2773 if (len)
2775 DWORD bytes_read;
2776 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
2778 ret = WinHttpReadData( req, buf, len, &bytes_read );
2779 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
2781 HeapFree( GetProcessHeap(), 0, buf );
2782 if (!bytes_read) break;
2783 total_len += bytes_read;
2785 if (!len) break;
2787 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
2789 WinHttpCloseHandle(req);
2790 WinHttpCloseHandle(con);
2791 WinHttpCloseHandle(ses);
2794 static void test_cookies( int port )
2796 static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0};
2797 static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0};
2798 static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0};
2799 static const WCHAR cookieheaderW[] =
2800 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2801 HINTERNET ses, con, req;
2802 DWORD status, size;
2803 BOOL ret;
2805 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2806 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2808 con = WinHttpConnect( ses, localhostW, port, 0 );
2809 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2811 req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 );
2812 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2814 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2815 ok( ret, "failed to send request %u\n", GetLastError() );
2817 ret = WinHttpReceiveResponse( req, NULL );
2818 ok( ret, "failed to receive response %u\n", GetLastError() );
2820 status = 0xdeadbeef;
2821 size = sizeof(status);
2822 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2823 ok( ret, "failed to query status code %u\n", GetLastError() );
2824 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
2826 WinHttpCloseHandle( req );
2828 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2829 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2831 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2832 ok( ret, "failed to send request %u\n", GetLastError() );
2834 ret = WinHttpReceiveResponse( req, NULL );
2835 ok( ret, "failed to receive response %u\n", GetLastError() );
2837 status = 0xdeadbeef;
2838 size = sizeof(status);
2839 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2840 ok( ret, "failed to query status code %u\n", GetLastError() );
2841 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
2843 WinHttpCloseHandle( req );
2844 WinHttpCloseHandle( con );
2846 con = WinHttpConnect( ses, localhostW, port, 0 );
2847 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2849 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2850 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2852 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2853 ok( ret, "failed to send request %u\n", GetLastError() );
2855 ret = WinHttpReceiveResponse( req, NULL );
2856 ok( ret, "failed to receive response %u\n", GetLastError() );
2858 status = 0xdeadbeef;
2859 size = sizeof(status);
2860 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2861 ok( ret, "failed to query status code %u\n", GetLastError() );
2862 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
2864 WinHttpCloseHandle( req );
2866 req = WinHttpOpenRequest( con, NULL, cookie3W, NULL, NULL, NULL, 0 );
2867 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2869 ret = WinHttpSendRequest( req, cookieheaderW, ~0u, NULL, 0, 0, 0 );
2870 ok( ret, "failed to send request %u\n", GetLastError() );
2872 ret = WinHttpReceiveResponse( req, NULL );
2873 ok( ret, "failed to receive response %u\n", GetLastError() );
2875 status = 0xdeadbeef;
2876 size = sizeof(status);
2877 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2878 ok( ret, "failed to query status code %u\n", GetLastError() );
2879 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST), "request failed unexpectedly %u\n", status );
2881 WinHttpCloseHandle( req );
2882 WinHttpCloseHandle( con );
2883 WinHttpCloseHandle( ses );
2885 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2886 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2888 con = WinHttpConnect( ses, localhostW, port, 0 );
2889 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2891 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
2892 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2894 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2895 ok( ret, "failed to send request %u\n", GetLastError() );
2897 ret = WinHttpReceiveResponse( req, NULL );
2898 ok( ret, "failed to receive response %u\n", GetLastError() );
2900 status = 0xdeadbeef;
2901 size = sizeof(status);
2902 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
2903 ok( ret, "failed to query status code %u\n", GetLastError() );
2904 ok( status == HTTP_STATUS_BAD_REQUEST, "request failed unexpectedly %u\n", status );
2906 WinHttpCloseHandle( req );
2907 WinHttpCloseHandle( con );
2908 WinHttpCloseHandle( ses );
2911 static void test_connection_info( int port )
2913 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2914 HINTERNET ses, con, req;
2915 WINHTTP_CONNECTION_INFO info;
2916 DWORD size, error;
2917 BOOL ret;
2919 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
2920 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2922 con = WinHttpConnect( ses, localhostW, port, 0 );
2923 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2925 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
2926 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2928 size = sizeof(info);
2929 SetLastError( 0xdeadbeef );
2930 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2931 error = GetLastError();
2932 if (!ret && error == ERROR_INVALID_PARAMETER)
2934 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2935 return;
2937 ok( !ret, "unexpected success\n" );
2938 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
2940 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2941 ok( ret, "failed to send request %u\n", GetLastError() );
2943 size = 0;
2944 SetLastError( 0xdeadbeef );
2945 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2946 error = GetLastError();
2947 ok( !ret, "unexpected success\n" );
2948 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
2950 size = sizeof(info);
2951 memset( &info, 0, sizeof(info) );
2952 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2953 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2954 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize );
2956 ret = WinHttpReceiveResponse( req, NULL );
2957 ok( ret, "failed to receive response %u\n", GetLastError() );
2959 size = sizeof(info);
2960 memset( &info, 0, sizeof(info) );
2961 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2962 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2963 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize );
2965 WinHttpCloseHandle( req );
2966 WinHttpCloseHandle( con );
2967 WinHttpCloseHandle( ses );
2970 static void test_credentials(void)
2972 static WCHAR userW[] = {'u','s','e','r',0};
2973 static WCHAR passW[] = {'p','a','s','s',0};
2974 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2975 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2976 HINTERNET ses, con, req;
2977 DWORD size, error;
2978 WCHAR buffer[32];
2979 BOOL ret;
2981 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2982 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2984 con = WinHttpConnect(ses, localhostW, 0, 0);
2985 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2987 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2988 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2990 size = sizeof(buffer)/sizeof(WCHAR);
2991 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2992 ok(ret, "failed to query proxy username %u\n", GetLastError());
2993 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2994 ok(!size, "expected 0, got %u\n", size);
2996 size = sizeof(buffer)/sizeof(WCHAR);
2997 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2998 ok(ret, "failed to query proxy password %u\n", GetLastError());
2999 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3000 ok(!size, "expected 0, got %u\n", size);
3002 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
3003 ok(ret, "failed to set username %u\n", GetLastError());
3005 size = sizeof(buffer)/sizeof(WCHAR);
3006 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
3007 ok(ret, "failed to query proxy username %u\n", GetLastError());
3008 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3009 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
3011 size = sizeof(buffer)/sizeof(WCHAR);
3012 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3013 ok(ret, "failed to query username %u\n", GetLastError());
3014 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3015 ok(!size, "expected 0, got %u\n", size);
3017 size = sizeof(buffer)/sizeof(WCHAR);
3018 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3019 ok(ret, "failed to query password %u\n", GetLastError());
3020 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3021 ok(!size, "expected 0, got %u\n", size);
3023 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
3024 ok(ret, "failed to set proxy password %u\n", GetLastError());
3026 size = sizeof(buffer)/sizeof(WCHAR);
3027 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
3028 ok(ret, "failed to query proxy password %u\n", GetLastError());
3029 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3030 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
3032 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
3033 ok(ret, "failed to set username %u\n", GetLastError());
3035 size = sizeof(buffer)/sizeof(WCHAR);
3036 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3037 ok(ret, "failed to query username %u\n", GetLastError());
3038 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3039 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
3041 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
3042 ok(ret, "failed to set password %u\n", GetLastError());
3044 size = sizeof(buffer)/sizeof(WCHAR);
3045 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3046 ok(ret, "failed to query password %u\n", GetLastError());
3047 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3048 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
3050 WinHttpCloseHandle(req);
3052 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
3053 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3055 SetLastError(0xdeadbeef);
3056 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
3057 error = GetLastError();
3058 ok(!ret, "expected failure\n");
3059 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3061 SetLastError(0xdeadbeef);
3062 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
3063 error = GetLastError();
3064 ok(!ret, "expected failure\n");
3065 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3067 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
3068 ok(ret, "failed to set credentials %u\n", GetLastError());
3070 size = sizeof(buffer)/sizeof(WCHAR);
3071 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3072 ok(ret, "failed to query username %u\n", GetLastError());
3073 todo_wine {
3074 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3075 ok(!size, "expected 0, got %u\n", size);
3078 size = sizeof(buffer)/sizeof(WCHAR);
3079 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3080 ok(ret, "failed to query password %u\n", GetLastError());
3081 todo_wine {
3082 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3083 ok(!size, "expected 0, got %u\n", size);
3086 WinHttpCloseHandle(req);
3087 WinHttpCloseHandle(con);
3088 WinHttpCloseHandle(ses);
3091 static void test_IWinHttpRequest(int port)
3093 static const WCHAR data_start[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3094 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
3095 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
3096 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3097 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3098 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3099 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3100 static const WCHAR method1W[] = {'G','E','T',0};
3101 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
3102 static const WCHAR method3W[] = {'P','O','S','T',0};
3103 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3104 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
3105 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
3106 static const WCHAR dateW[] = {'D','a','t','e',0};
3107 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
3108 static const WCHAR utf8W[] = {'u','t','f','-','8',0};
3109 static const WCHAR unauthW[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3110 HRESULT hr;
3111 IWinHttpRequest *req;
3112 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
3113 BSTR date, today, connection, value = NULL;
3114 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp;
3115 VARIANT_BOOL succeeded;
3116 LONG status;
3117 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
3118 SYSTEMTIME st;
3119 IStream *stream, *stream2;
3120 LARGE_INTEGER pos;
3121 char buf[128];
3122 WCHAR bufW[128];
3123 DWORD count;
3125 GetSystemTime( &st );
3126 WinHttpTimeFromSystemTime( &st, todayW );
3128 CoInitialize( NULL );
3129 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3130 ok( hr == S_OK, "got %08x\n", hr );
3132 V_VT( &empty ) = VT_ERROR;
3133 V_ERROR( &empty ) = 0xdeadbeef;
3135 V_VT( &async ) = VT_BOOL;
3136 V_BOOL( &async ) = VARIANT_FALSE;
3138 method = SysAllocString( method3W );
3139 url = SysAllocString( url3W );
3140 hr = IWinHttpRequest_Open( req, method, url, async );
3141 ok( hr == S_OK, "got %08x\n", hr );
3142 SysFreeString( method );
3143 SysFreeString( url );
3145 V_VT( &data ) = VT_BSTR;
3146 V_BSTR( &data ) = SysAllocString( test_dataW );
3147 hr = IWinHttpRequest_Send( req, data );
3148 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
3149 "got %08x\n", hr );
3150 SysFreeString( V_BSTR( &data ) );
3152 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
3153 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3155 method = SysAllocString( method1W );
3156 hr = IWinHttpRequest_Open( req, method, NULL, empty );
3157 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3159 hr = IWinHttpRequest_Open( req, method, NULL, async );
3160 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3162 url = SysAllocString( url1W );
3163 hr = IWinHttpRequest_Open( req, NULL, url, empty );
3164 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3166 hr = IWinHttpRequest_Abort( req );
3167 ok( hr == S_OK, "got %08x\n", hr );
3169 hr = IWinHttpRequest_Open( req, method, url, empty );
3170 ok( hr == S_OK, "got %08x\n", hr );
3172 hr = IWinHttpRequest_Abort( req );
3173 ok( hr == S_OK, "got %08x\n", hr );
3175 IWinHttpRequest_Release( req );
3177 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3178 ok( hr == S_OK, "got %08x\n", hr );
3180 SysFreeString( url );
3181 url = SysAllocString( url2W );
3182 hr = IWinHttpRequest_Open( req, method, url, async );
3183 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3185 SysFreeString( method );
3186 method = SysAllocString( method2W );
3187 hr = IWinHttpRequest_Open( req, method, url, async );
3188 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3190 SysFreeString( method );
3191 method = SysAllocString( method1W );
3192 SysFreeString( url );
3193 url = SysAllocString( url1W );
3194 V_VT( &async ) = VT_ERROR;
3195 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND;
3196 hr = IWinHttpRequest_Open( req, method, url, async );
3197 ok( hr == S_OK, "got %08x\n", hr );
3199 V_VT( &cp ) = VT_ERROR;
3200 V_ERROR( &cp ) = 0xdeadbeef;
3201 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3202 ok( hr == S_OK, "got %08x\n", hr );
3203 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3204 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3206 V_VT( &cp ) = VT_UI4;
3207 V_UI4( &cp ) = CP_ACP;
3208 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3209 ok( hr == S_OK, "got %08x\n", hr );
3211 V_VT( &cp ) = VT_ERROR;
3212 V_ERROR( &cp ) = 0xdeadbeef;
3213 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3214 ok( hr == S_OK, "got %08x\n", hr );
3215 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3216 ok( V_I4( &cp ) == CP_ACP, "got %u\n", V_I4( &cp ) );
3218 value = SysAllocString( utf8W );
3219 V_VT( &cp ) = VT_BSTR;
3220 V_BSTR( &cp ) = value;
3221 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3222 ok( hr == S_OK, "got %08x\n", hr );
3223 SysFreeString( value );
3225 V_VT( &cp ) = VT_ERROR;
3226 V_ERROR( &cp ) = 0xdeadbeef;
3227 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3228 ok( hr == S_OK, "got %08x\n", hr );
3229 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3230 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3232 hr = IWinHttpRequest_Abort( req );
3233 ok( hr == S_OK, "got %08x\n", hr );
3235 hr = IWinHttpRequest_Send( req, empty );
3236 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3238 hr = IWinHttpRequest_Abort( req );
3239 ok( hr == S_OK, "got %08x\n", hr );
3241 IWinHttpRequest_Release( req );
3243 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3244 ok( hr == S_OK, "got %08x\n", hr );
3246 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3247 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3249 hr = IWinHttpRequest_get_ResponseText( req, &response );
3250 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3252 hr = IWinHttpRequest_get_Status( req, NULL );
3253 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3255 hr = IWinHttpRequest_get_Status( req, &status );
3256 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3258 hr = IWinHttpRequest_get_StatusText( req, NULL );
3259 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3261 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3262 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3264 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3265 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3267 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3268 ok( hr == S_OK, "got %08x\n", hr );
3270 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3271 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3273 VariantInit( &proxy_server );
3274 V_VT( &proxy_server ) = VT_ERROR;
3275 VariantInit( &bypass_list );
3276 V_VT( &bypass_list ) = VT_ERROR;
3277 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3278 ok( hr == S_OK, "got %08x\n", hr );
3280 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3281 ok( hr == S_OK, "got %08x\n", hr );
3283 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3284 ok( hr == S_OK, "got %08x\n", hr );
3286 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3287 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3289 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3290 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3292 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3293 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3295 connection = SysAllocString( connectionW );
3296 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3297 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3299 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3300 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3302 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
3303 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3305 date = SysAllocString( dateW );
3306 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3307 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3309 today = SysAllocString( todayW );
3310 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3311 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3313 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
3314 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3316 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3317 ok( hr == S_OK, "got %08x\n", hr );
3319 SysFreeString( method );
3320 method = SysAllocString( method1W );
3321 SysFreeString( url );
3322 url = SysAllocString( url1W );
3323 hr = IWinHttpRequest_Open( req, method, url, async );
3324 ok( hr == S_OK, "got %08x\n", hr );
3326 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3327 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3329 hr = IWinHttpRequest_get_ResponseText( req, &response );
3330 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3332 hr = IWinHttpRequest_get_Status( req, &status );
3333 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3335 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3336 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3338 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3339 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3341 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3342 ok( hr == S_OK, "got %08x\n", hr );
3344 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3345 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3347 username = SysAllocString( usernameW );
3348 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
3349 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3351 password = SysAllocString( passwordW );
3352 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
3353 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3355 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
3356 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3358 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3359 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3361 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3362 ok( hr == S_OK, "got %08x\n", hr );
3364 V_VT( &proxy_server ) = VT_BSTR;
3365 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
3366 V_VT( &bypass_list ) = VT_BSTR;
3367 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
3368 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3369 ok( hr == S_OK, "got %08x\n", hr );
3371 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
3372 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3374 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3375 ok( hr == S_OK, "got %08x\n", hr );
3377 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3378 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3380 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3381 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3383 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3384 ok( hr == S_OK, "got %08x\n", hr );
3386 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3387 ok( hr == S_OK, "got %08x\n", hr );
3389 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3390 ok( hr == S_OK, "got %08x\n", hr );
3392 hr = IWinHttpRequest_Send( req, empty );
3393 ok( hr == S_OK, "got %08x\n", hr );
3395 hr = IWinHttpRequest_Send( req, empty );
3396 ok( hr == S_OK, "got %08x\n", hr );
3398 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3399 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3401 hr = IWinHttpRequest_get_ResponseText( req, &response );
3402 ok( hr == S_OK, "got %08x\n", hr );
3403 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
3404 SysFreeString( response );
3406 hr = IWinHttpRequest_get_Status( req, NULL );
3407 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3409 status = 0;
3410 hr = IWinHttpRequest_get_Status( req, &status );
3411 ok( hr == S_OK, "got %08x\n", hr );
3412 trace("Status=%d\n", status);
3414 hr = IWinHttpRequest_get_StatusText( req, NULL );
3415 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3417 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3418 ok( hr == S_OK, "got %08x\n", hr );
3419 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
3420 SysFreeString( status_text );
3422 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3423 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3425 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3426 ok( hr == S_OK, "got %08x\n", hr );
3428 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3429 ok( hr == S_OK, "got %08x\n", hr );
3431 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3432 ok( hr == S_OK, "got %08x\n", hr );
3434 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3435 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3437 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3438 ok( hr == S_OK, "got %08x\n", hr );
3439 SysFreeString( headers );
3441 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3442 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3444 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3445 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3447 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3448 ok( hr == S_OK, "got %08x\n", hr );
3449 SysFreeString( value );
3451 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3452 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
3454 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3455 ok( hr == S_OK, "got %08x\n", hr );
3457 VariantInit( &timeout );
3458 V_VT( &timeout ) = VT_I4;
3459 V_I4( &timeout ) = 10;
3460 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
3461 ok( hr == S_OK, "got %08x\n", hr );
3463 hr = IWinHttpRequest_get_Status( req, &status );
3464 ok( hr == S_OK, "got %08x\n", hr );
3466 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3467 ok( hr == S_OK, "got %08x\n", hr );
3468 SysFreeString( status_text );
3470 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
3471 ok( hr == S_OK, "got %08x\n", hr );
3473 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3474 ok( hr == S_OK, "got %08x\n", hr );
3476 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3477 ok( hr == S_OK, "got %08x\n", hr );
3479 hr = IWinHttpRequest_Send( req, empty );
3480 ok( hr == S_OK, "got %08x\n", hr );
3482 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3483 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3485 hr = IWinHttpRequest_get_ResponseText( req, &response );
3486 ok( hr == S_OK, "got %08x\n", hr );
3487 SysFreeString( response );
3489 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3490 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3492 VariantInit( &body );
3493 V_VT( &body ) = VT_ERROR;
3494 hr = IWinHttpRequest_get_ResponseBody( req, &body );
3495 ok( hr == S_OK, "got %08x\n", hr );
3496 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
3498 hr = VariantClear( &body );
3499 ok( hr == S_OK, "got %08x\n", hr );
3501 VariantInit( &body );
3502 V_VT( &body ) = VT_ERROR;
3503 hr = IWinHttpRequest_get_ResponseStream( req, &body );
3504 ok( hr == S_OK, "got %08x\n", hr );
3505 ok( V_VT( &body ) == VT_UNKNOWN, "got %08x\n", V_VT( &body ) );
3507 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream );
3508 ok( hr == S_OK, "got %08x\n", hr );
3509 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" );
3511 buf[0] = 0;
3512 count = 0xdeadbeef;
3513 hr = IStream_Read( stream, buf, 128, &count );
3514 ok( hr == S_OK, "got %08x\n", hr );
3515 ok( count != 0xdeadbeef, "count not set\n" );
3516 ok( buf[0], "no data\n" );
3518 VariantInit( &body2 );
3519 V_VT( &body2 ) = VT_ERROR;
3520 hr = IWinHttpRequest_get_ResponseStream( req, &body2 );
3521 ok( hr == S_OK, "got %08x\n", hr );
3522 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %08x\n", V_VT( &body2 ) );
3523 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" );
3525 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 );
3526 ok( hr == S_OK, "got %08x\n", hr );
3527 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" );
3528 IStream_Release( stream2 );
3530 hr = VariantClear( &body );
3531 ok( hr == S_OK, "got %08x\n", hr );
3533 hr = VariantClear( &body2 );
3534 ok( hr == S_OK, "got %08x\n", hr );
3536 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3537 ok( hr == S_OK, "got %08x\n", hr );
3539 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3540 ok( hr == S_OK, "got %08x\n", hr );
3542 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3543 ok( hr == S_OK, "got %08x\n", hr );
3544 SysFreeString( headers );
3546 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3547 ok( hr == S_OK, "got %08x\n", hr );
3548 SysFreeString( value );
3550 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3551 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
3553 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3554 ok( hr == S_OK, "got %08x\n", hr );
3556 hr = IWinHttpRequest_Send( req, empty );
3557 ok( hr == S_OK, "got %08x\n", hr );
3559 hr = IWinHttpRequest_Abort( req );
3560 ok( hr == S_OK, "got %08x\n", hr );
3562 hr = IWinHttpRequest_Abort( req );
3563 ok( hr == S_OK, "got %08x\n", hr );
3565 IWinHttpRequest_Release( req );
3567 pos.QuadPart = 0;
3568 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL );
3569 ok( hr == S_OK, "got %08x\n", hr );
3571 buf[0] = 0;
3572 count = 0xdeadbeef;
3573 hr = IStream_Read( stream, buf, 128, &count );
3574 ok( hr == S_OK, "got %08x\n", hr );
3575 ok( count != 0xdeadbeef, "count not set\n" );
3576 ok( buf[0], "no data\n" );
3577 IStream_Release( stream );
3579 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3580 ok( hr == S_OK, "got %08x\n", hr );
3582 V_VT( &async ) = VT_I4;
3583 V_I4( &async ) = 1;
3584 hr = IWinHttpRequest_Open( req, method, url, async );
3585 ok( hr == S_OK, "got %08x\n", hr );
3587 hr = IWinHttpRequest_Send( req, empty );
3588 ok( hr == S_OK, "got %08x\n", hr );
3590 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
3591 ok( hr == S_OK, "got %08x\n", hr );
3593 IWinHttpRequest_Release( req );
3595 SysFreeString( method );
3596 SysFreeString( url );
3597 SysFreeString( username );
3598 SysFreeString( password );
3599 SysFreeString( connection );
3600 SysFreeString( date );
3601 SysFreeString( today );
3602 VariantClear( &proxy_server );
3603 VariantClear( &bypass_list );
3605 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3606 ok( hr == S_OK, "got %08x\n", hr );
3608 url = SysAllocString( test_winehq_https );
3609 method = SysAllocString( method3W );
3610 V_VT( &async ) = VT_BOOL;
3611 V_BOOL( &async ) = VARIANT_FALSE;
3612 hr = IWinHttpRequest_Open( req, method, url, async );
3613 ok( hr == S_OK, "got %08x\n", hr );
3614 SysFreeString( method );
3615 SysFreeString( url );
3617 hr = IWinHttpRequest_Send( req, empty );
3618 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE )), "got %08x\n", hr );
3619 if (hr == S_OK)
3621 hr = IWinHttpRequest_get_ResponseText( req, &response );
3622 ok( hr == S_OK, "got %08x\n", hr );
3623 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
3624 SysFreeString( response );
3627 IWinHttpRequest_Release( req );
3629 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3630 ok( hr == S_OK, "got %08x\n", hr );
3632 sprintf( buf, "http://localhost:%d/auth", port );
3633 MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, sizeof(bufW)/sizeof(bufW[0]) );
3634 url = SysAllocString( bufW );
3635 method = SysAllocString( method3W );
3636 V_VT( &async ) = VT_BOOL;
3637 V_BOOL( &async ) = VARIANT_FALSE;
3638 hr = IWinHttpRequest_Open( req, method, url, async );
3639 ok( hr == S_OK, "got %08x\n", hr );
3640 SysFreeString( method );
3641 SysFreeString( url );
3643 hr = IWinHttpRequest_get_Status( req, &status );
3644 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3646 V_VT( &data ) = VT_BSTR;
3647 V_BSTR( &data ) = SysAllocString( test_dataW );
3648 hr = IWinHttpRequest_Send( req, data );
3649 ok( hr == S_OK, "got %08x\n", hr );
3650 SysFreeString( V_BSTR( &data ) );
3652 hr = IWinHttpRequest_get_ResponseText( req, &response );
3653 ok( hr == S_OK, "got %08x\n", hr );
3654 ok( !memcmp( response, unauthW, sizeof(unauthW) ), "got %s\n", wine_dbgstr_w(response) );
3655 SysFreeString( response );
3657 status = 0xdeadbeef;
3658 hr = IWinHttpRequest_get_Status( req, &status );
3659 ok( hr == S_OK, "got %08x\n", hr );
3660 ok( status == HTTP_STATUS_DENIED, "got %d\n", status );
3662 IWinHttpRequest_Release( req );
3664 CoUninitialize();
3667 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret)
3669 DISPPARAMS params;
3670 VARIANT arg;
3671 HRESULT hr;
3673 memset(&params, 0, sizeof(params));
3674 params.cNamedArgs = 0;
3675 params.rgdispidNamedArgs = NULL;
3676 params.cArgs = 1;
3677 params.rgvarg = &arg;
3678 VariantInit(&arg);
3679 V_VT(&arg) = VT_I4;
3680 V_I4(&arg) = property;
3681 VariantInit(ret);
3682 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3683 DISPATCH_PROPERTYGET, &params, ret, NULL, NULL);
3684 ok(hr == S_OK, "error %#x\n", hr);
3687 static void test_IWinHttpRequest_Invoke(void)
3689 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
3690 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};
3691 WCHAR openW[] = {'O','p','e','n',0};
3692 WCHAR optionW[] = {'O','p','t','i','o','n',0};
3693 OLECHAR *open = openW, *option = optionW;
3694 BSTR utf8;
3695 CLSID clsid;
3696 IWinHttpRequest *request;
3697 IDispatch *dispatch;
3698 DISPID id;
3699 DISPPARAMS params;
3700 VARIANT arg[3], ret;
3701 UINT err;
3702 BOOL bret;
3703 HRESULT hr;
3705 CoInitialize(NULL);
3707 hr = CLSIDFromProgID(regid, &clsid);
3708 ok(hr == S_OK, "CLSIDFromProgID error %#x\n", hr);
3709 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest);
3710 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid));
3712 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request);
3713 ok(hr == S_OK, "error %#x\n", hr);
3715 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch);
3716 ok(hr == S_OK, "error %#x\n", hr);
3717 IDispatch_Release(dispatch);
3719 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id);
3720 ok(hr == S_OK, "error %#x\n", hr);
3721 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id);
3723 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id);
3724 ok(hr == S_OK, "error %#x\n", hr);
3725 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id);
3727 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3728 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3729 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3731 memset(&params, 0, sizeof(params));
3732 params.cArgs = 2;
3733 params.cNamedArgs = 0;
3734 params.rgvarg = arg;
3735 V_VT(&arg[0]) = VT_I4;
3736 V_I4(&arg[0]) = 1252;
3737 V_VT(&arg[1]) = VT_R8;
3738 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3739 VariantInit(&ret);
3740 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3741 DISPATCH_METHOD, &params, NULL, NULL, &err);
3742 ok(hr == S_OK, "error %#x\n", hr);
3744 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3745 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3746 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3748 memset(&params, 0, sizeof(params));
3749 params.cArgs = 2;
3750 params.cNamedArgs = 0;
3751 params.rgvarg = arg;
3752 V_VT(&arg[0]) = VT_I4;
3753 V_I4(&arg[0]) = 1252;
3754 V_VT(&arg[1]) = VT_R8;
3755 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3756 VariantInit(&ret);
3757 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3758 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
3759 ok(hr == S_OK, "error %#x\n", hr);
3761 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3762 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3763 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3765 memset(&params, 0, sizeof(params));
3766 params.cArgs = 2;
3767 params.cNamedArgs = 0;
3768 params.rgvarg = arg;
3769 V_VT(&arg[0]) = VT_I4;
3770 V_I4(&arg[0]) = 1252;
3771 V_VT(&arg[1]) = VT_R8;
3772 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3773 VariantInit(&ret);
3774 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
3775 DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
3776 ok(hr == S_OK, "error %#x\n", hr);
3778 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3779 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3780 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3782 memset(&params, 0, sizeof(params));
3783 params.cArgs = 2;
3784 params.cNamedArgs = 0;
3785 params.rgvarg = arg;
3786 V_VT(&arg[0]) = VT_BSTR;
3787 utf8 = SysAllocString(utf8W);
3788 V_BSTR(&arg[0]) = utf8;
3789 V_VT(&arg[1]) = VT_R8;
3790 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3791 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, &err);
3792 ok(hr == S_OK, "error %#x\n", hr);
3794 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3795 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3796 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3798 VariantInit(&ret);
3799 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, &err);
3800 ok(hr == S_OK, "error %#x\n", hr);
3802 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3803 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3804 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
3806 VariantInit(&ret);
3807 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3808 ok(hr == S_OK, "error %#x\n", hr);
3810 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
3811 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3812 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3814 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
3815 ok(hr == S_OK, "error %#x\n", hr);
3817 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
3818 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#x\n", hr);
3820 VariantInit(&ret);
3821 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3822 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
3824 VariantInit(&ret);
3825 if (0) /* crashes */
3826 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err);
3828 params.cArgs = 1;
3829 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3830 ok(hr == DISP_E_TYPEMISMATCH, "error %#x\n", hr);
3832 VariantInit(&arg[2]);
3833 params.cArgs = 3;
3834 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
3835 todo_wine
3836 ok(hr == S_OK, "error %#x\n", hr);
3838 VariantInit(&arg[0]);
3839 VariantInit(&arg[1]);
3840 VariantInit(&arg[2]);
3842 params.cArgs = 1;
3843 V_VT(&arg[0]) = VT_I4;
3844 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage;
3845 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3846 ok(hr == S_OK, "error %#x\n", hr);
3848 V_VT(&ret) = 0xdead;
3849 V_I4(&ret) = 0xbeef;
3850 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, &ret, NULL, NULL);
3851 ok(hr == S_OK, "error %#x\n", hr);
3852 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3853 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3855 V_VT(&ret) = 0xdead;
3856 V_I4(&ret) = 0xbeef;
3857 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, NULL);
3858 ok(hr == S_OK, "error %#x\n", hr);
3859 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
3860 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
3862 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3863 ok(hr == S_OK, "error %#x\n", hr);
3865 V_VT(&ret) = 0xdead;
3866 V_I4(&ret) = 0xbeef;
3867 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, &ret, NULL, NULL);
3868 ok(hr == S_OK, "error %#x\n", hr);
3869 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %d\n", V_VT(&ret));
3870 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret));
3872 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, NULL, NULL, NULL);
3873 ok(hr == S_OK, "error %#x\n", hr);
3875 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3876 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
3878 params.cArgs = 2;
3879 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3880 todo_wine
3881 ok(hr == S_OK, "error %#x\n", hr);
3883 params.cArgs = 0;
3884 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
3885 ok(hr == DISP_E_PARAMNOTFOUND, "error %#x\n", hr);
3887 SysFreeString(utf8);
3889 params.cArgs = 1;
3890 V_VT(&arg[0]) = VT_I4;
3891 V_I4(&arg[0]) = AutoLogonPolicy_Never;
3892 VariantInit(&ret);
3893 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0,
3894 DISPATCH_METHOD, &params, &ret, NULL, NULL);
3895 ok(hr == S_OK, "error %#x\n", hr);
3897 IWinHttpRequest_Release(request);
3899 CoUninitialize();
3902 static void test_WinHttpDetectAutoProxyConfigUrl(void)
3904 BOOL ret;
3905 WCHAR *url;
3906 DWORD error;
3908 if (0) /* crashes on some win2k systems */
3910 SetLastError(0xdeadbeef);
3911 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
3912 error = GetLastError();
3913 ok( !ret, "expected failure\n" );
3914 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3916 url = NULL;
3917 SetLastError(0xdeadbeef);
3918 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
3919 error = GetLastError();
3920 ok( !ret, "expected failure\n" );
3921 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3923 if (0) /* crashes on some win2k systems */
3925 SetLastError(0xdeadbeef);
3926 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
3927 error = GetLastError();
3928 ok( !ret, "expected failure\n" );
3929 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3931 url = (WCHAR *)0xdeadbeef;
3932 SetLastError(0xdeadbeef);
3933 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
3934 error = GetLastError();
3935 if (!ret)
3937 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
3938 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
3940 else
3942 trace("%s\n", wine_dbgstr_w(url));
3943 GlobalFree( url );
3946 url = (WCHAR *)0xdeadbeef;
3947 SetLastError(0xdeadbeef);
3948 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
3949 error = GetLastError();
3950 if (!ret)
3952 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
3953 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
3955 else
3957 ok( error == ERROR_SUCCESS, "got %u\n", error );
3958 trace("%s\n", wine_dbgstr_w(url));
3959 GlobalFree( url );
3963 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
3965 BOOL ret;
3966 DWORD error;
3967 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
3969 memset( &cfg, 0, sizeof(cfg) );
3971 SetLastError(0xdeadbeef);
3972 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
3973 error = GetLastError();
3974 ok( !ret, "expected failure\n" );
3975 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
3977 SetLastError(0xdeadbeef);
3978 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
3979 error = GetLastError();
3980 ok( ret, "expected success\n" );
3981 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error );
3983 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
3984 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
3985 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
3986 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
3987 GlobalFree( cfg.lpszAutoConfigUrl );
3988 GlobalFree( cfg.lpszProxy );
3989 GlobalFree( cfg.lpszProxyBypass );
3992 static void test_WinHttpGetProxyForUrl(void)
3994 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
3995 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
3996 static const WCHAR emptyW[] = {0};
3997 BOOL ret;
3998 DWORD error;
3999 HINTERNET session;
4000 WINHTTP_AUTOPROXY_OPTIONS options;
4001 WINHTTP_PROXY_INFO info;
4003 memset( &options, 0, sizeof(options) );
4005 SetLastError(0xdeadbeef);
4006 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
4007 error = GetLastError();
4008 ok( !ret, "expected failure\n" );
4009 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
4011 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
4012 ok( session != NULL, "failed to open session %u\n", GetLastError() );
4014 SetLastError(0xdeadbeef);
4015 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
4016 error = GetLastError();
4017 ok( !ret, "expected failure\n" );
4018 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4020 SetLastError(0xdeadbeef);
4021 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
4022 error = GetLastError();
4023 ok( !ret, "expected failure\n" );
4024 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4026 SetLastError(0xdeadbeef);
4027 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
4028 error = GetLastError();
4029 ok( !ret, "expected failure\n" );
4030 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4032 SetLastError(0xdeadbeef);
4033 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4034 error = GetLastError();
4035 ok( !ret, "expected failure\n" );
4036 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4038 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
4039 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
4041 SetLastError(0xdeadbeef);
4042 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
4043 error = GetLastError();
4044 ok( !ret, "expected failure\n" );
4045 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4047 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
4048 options.dwAutoDetectFlags = 0;
4050 SetLastError(0xdeadbeef);
4051 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4052 error = GetLastError();
4053 ok( !ret, "expected failure\n" );
4054 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4056 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
4057 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
4059 SetLastError(0xdeadbeef);
4060 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4061 error = GetLastError();
4062 ok( !ret, "expected failure\n" );
4063 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4065 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
4066 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
4068 memset( &info, 0, sizeof(info) );
4069 SetLastError(0xdeadbeef);
4070 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4071 error = GetLastError();
4072 if (ret)
4074 ok( error == ERROR_SUCCESS, "got %u\n", error );
4075 trace("Proxy.AccessType=%u\n", info.dwAccessType);
4076 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
4077 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
4078 GlobalFree( info.lpszProxy );
4079 GlobalFree( info.lpszProxyBypass );
4082 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
4083 options.dwAutoDetectFlags = 0;
4084 options.lpszAutoConfigUrl = wpadW;
4086 memset( &info, 0, sizeof(info) );
4087 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4088 if (ret)
4090 trace("Proxy.AccessType=%u\n", info.dwAccessType);
4091 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
4092 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
4093 GlobalFree( info.lpszProxy );
4094 GlobalFree( info.lpszProxyBypass );
4096 WinHttpCloseHandle( session );
4099 static void test_chunked_read(void)
4101 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4102 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
4103 WCHAR header[32];
4104 DWORD len, err;
4105 HINTERNET ses, con = NULL, req = NULL;
4106 BOOL ret;
4108 trace( "starting chunked read test\n" );
4110 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
4111 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
4112 if (!ses) goto done;
4114 con = WinHttpConnect( ses, test_winehq, 0, 0 );
4115 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
4116 if (!con) goto done;
4118 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
4119 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4120 if (!req) goto done;
4122 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4123 err = GetLastError();
4124 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
4126 skip("connection failed, skipping\n");
4127 goto done;
4129 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4131 ret = WinHttpReceiveResponse( req, NULL );
4132 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4134 header[0] = 0;
4135 len = sizeof(header);
4136 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
4137 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4138 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
4139 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
4141 header[0] = 0;
4142 len = sizeof(header);
4143 SetLastError( 0xdeadbeef );
4144 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
4145 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
4146 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
4148 trace( "entering query loop\n" );
4149 for (;;)
4151 len = 0xdeadbeef;
4152 ret = WinHttpQueryDataAvailable( req, &len );
4153 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4154 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4155 trace( "got %u available\n", len );
4156 if (len)
4158 DWORD bytes_read;
4159 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
4161 ret = WinHttpReadData( req, buf, len, &bytes_read );
4163 buf[bytes_read] = 0;
4164 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
4165 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
4166 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
4168 HeapFree( GetProcessHeap(), 0, buf );
4169 if (!bytes_read) break;
4171 if (!len) break;
4173 trace( "done\n" );
4175 done:
4176 if (req) WinHttpCloseHandle( req );
4177 if (con) WinHttpCloseHandle( con );
4178 if (ses) WinHttpCloseHandle( ses );
4181 START_TEST (winhttp)
4183 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
4184 static const WCHAR quitW[] = {'/','q','u','i','t',0};
4185 struct server_info si;
4186 HANDLE thread;
4187 DWORD ret;
4189 test_OpenRequest();
4190 test_SendRequest();
4191 test_WinHttpTimeFromSystemTime();
4192 test_WinHttpTimeToSystemTime();
4193 test_WinHttpAddHeaders();
4194 test_secure_connection();
4195 test_request_parameter_defaults();
4196 test_QueryOption();
4197 test_set_default_proxy_config();
4198 test_empty_headers_param();
4199 test_Timeouts();
4200 test_resolve_timeout();
4201 test_credentials();
4202 test_IWinHttpRequest_Invoke();
4203 test_WinHttpDetectAutoProxyConfigUrl();
4204 test_WinHttpGetIEProxyConfigForCurrentUser();
4205 test_WinHttpGetProxyForUrl();
4206 test_chunked_read();
4208 si.event = CreateEventW(NULL, 0, 0, NULL);
4209 si.port = 7532;
4211 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
4212 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
4214 ret = WaitForSingleObject(si.event, 10000);
4215 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
4216 if (ret != WAIT_OBJECT_0)
4217 return;
4219 test_IWinHttpRequest(si.port);
4220 test_connection_info(si.port);
4221 test_basic_request(si.port, NULL, basicW);
4222 test_no_headers(si.port);
4223 test_no_content(si.port);
4224 test_head_request(si.port);
4225 test_not_modified(si.port);
4226 test_basic_authentication(si.port);
4227 test_bad_header(si.port);
4228 test_multiple_reads(si.port);
4229 test_cookies(si.port);
4231 /* send the basic request again to shutdown the server thread */
4232 test_basic_request(si.port, NULL, quitW);
4234 WaitForSingleObject(thread, 3000);