quartz: Free two assert calls from having side effects.
[wine/testsucceed.git] / dlls / winhttp / tests / winhttp.c
blob24478ad8308c090ae692013c022f6056868b317f
1 /*
2 * WinHTTP - tests
4 * Copyright 2008 Google (Zac Brown)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winhttp.h>
27 #include <wincrypt.h>
28 #include <winreg.h>
29 #include <winsock.h>
30 #include "initguid.h"
31 #include <httprequest.h>
33 #include "wine/test.h"
35 static const WCHAR test_useragent[] =
36 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
37 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
38 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
40 static BOOL proxy_active(void)
42 WINHTTP_PROXY_INFO proxy_info;
43 BOOL active = FALSE;
45 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
47 active = (proxy_info.lpszProxy != NULL);
48 if (active)
49 GlobalFree((HGLOBAL) proxy_info.lpszProxy);
50 if (proxy_info.lpszProxyBypass != NULL)
51 GlobalFree((HGLOBAL) proxy_info.lpszProxyBypass);
53 else
54 active = FALSE;
56 return active;
59 static void test_QueryOption(void)
61 BOOL ret;
62 HINTERNET session, request, connection;
63 DWORD feature, size;
65 SetLastError(0xdeadbeef);
66 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
67 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
69 SetLastError(0xdeadbeef);
70 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
71 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
72 ok(GetLastError() == ERROR_INVALID_PARAMETER,
73 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
75 size = 0xdeadbeef;
76 SetLastError(0xdeadbeef);
77 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
78 ok(!ret, "should fail to query option\n");
79 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
80 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
81 ok(size == 4, "expected 4, got %u\n", size);
83 feature = 0xdeadbeef;
84 size = sizeof(feature) - 1;
85 SetLastError(0xdeadbeef);
86 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
87 ok(!ret, "should fail to query option\n");
88 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
89 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
90 ok(size == 4, "expected 4, got %u\n", size);
92 feature = 0xdeadbeef;
93 size = sizeof(feature) + 1;
94 SetLastError(0xdeadbeef);
95 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
96 ok(ret, "failed to query option %u\n", GetLastError());
97 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
98 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
99 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
101 SetLastError(0xdeadbeef);
102 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
103 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
104 ok(GetLastError() == ERROR_INVALID_PARAMETER,
105 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
107 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
108 SetLastError(0xdeadbeef);
109 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
110 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
111 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
112 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
114 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
115 SetLastError(0xdeadbeef);
116 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
117 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
118 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
119 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
121 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
122 SetLastError(0xdeadbeef);
123 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
124 ok(ret, "failed to set redirect policy %u\n", GetLastError());
126 feature = 0xdeadbeef;
127 size = sizeof(feature);
128 SetLastError(0xdeadbeef);
129 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
130 ok(ret, "failed to query option %u\n", GetLastError());
131 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
132 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
134 feature = WINHTTP_DISABLE_COOKIES;
135 SetLastError(0xdeadbeef);
136 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
137 ok(!ret, "should fail to set disable feature for a session\n");
138 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
139 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
141 SetLastError(0xdeadbeef);
142 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
143 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
145 feature = WINHTTP_DISABLE_COOKIES;
146 SetLastError(0xdeadbeef);
147 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
148 ok(!ret, "should fail to set disable feature for a connection\n");
149 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
150 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
152 SetLastError(0xdeadbeef);
153 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
154 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
155 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
157 skip("Network unreachable, skipping the test\n");
158 goto done;
161 feature = 0xdeadbeef;
162 size = sizeof(feature);
163 SetLastError(0xdeadbeef);
164 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
165 ok(!ret, "should fail to query disable feature for a request\n");
166 ok(GetLastError() == ERROR_INVALID_PARAMETER,
167 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
169 feature = 0;
170 size = sizeof(feature);
171 SetLastError(0xdeadbeef);
172 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
173 ok(ret, "failed to set feature %u\n", GetLastError());
175 feature = 0xffffffff;
176 size = sizeof(feature);
177 SetLastError(0xdeadbeef);
178 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
179 ok(ret, "failed to set feature %u\n", GetLastError());
181 feature = WINHTTP_DISABLE_COOKIES;
182 size = sizeof(feature);
183 SetLastError(0xdeadbeef);
184 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
185 ok(ret, "failed to set feature %u\n", GetLastError());
187 size = 0;
188 SetLastError(0xdeadbeef);
189 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
190 ok(!ret, "should fail to query disable feature for a request\n");
191 ok(GetLastError() == ERROR_INVALID_PARAMETER,
192 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
194 SetLastError(0xdeadbeef);
195 ret = WinHttpCloseHandle(request);
196 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
198 done:
199 SetLastError(0xdeadbeef);
200 ret = WinHttpCloseHandle(connection);
201 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
202 SetLastError(0xdeadbeef);
203 ret = WinHttpCloseHandle(session);
204 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
207 static void test_OpenRequest (void)
209 BOOL ret;
210 HINTERNET session, request, connection;
212 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
213 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
214 ok(session != NULL, "WinHttpOpen failed to open session.\n");
216 /* Test with a bad server name */
217 SetLastError(0xdeadbeef);
218 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
219 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
220 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
222 /* Test with a valid server name */
223 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
224 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
226 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
227 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
228 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
230 skip("Network unreachable, skipping.\n");
231 goto done;
233 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
235 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
236 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
238 skip("Connection failed, skipping.\n");
239 goto done;
241 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
242 ret = WinHttpCloseHandle(request);
243 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
245 done:
246 ret = WinHttpCloseHandle(connection);
247 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
248 ret = WinHttpCloseHandle(session);
249 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
253 static void test_empty_headers_param(void)
255 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
256 static const WCHAR empty[] = {0};
257 HINTERNET ses, con, req;
258 BOOL ret;
260 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
261 ok(ses != NULL, "failed to open session %u\n", GetLastError());
263 con = WinHttpConnect(ses, winehq, 80, 0);
264 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
266 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
267 ok(req != NULL, "failed to open a request %u\n", GetLastError());
269 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
270 ok(ret, "failed to send request %u\n", GetLastError());
272 WinHttpCloseHandle(req);
273 WinHttpCloseHandle(con);
274 WinHttpCloseHandle(ses);
277 static void test_SendRequest (void)
279 HINTERNET session, request, connection;
280 DWORD header_len, optional_len, total_len, bytes_rw, size;
281 DWORD_PTR context;
282 BOOL ret;
283 CHAR buffer[256];
284 int i;
286 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
287 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
288 static const WCHAR content_type[] =
289 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
290 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
291 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
292 static const WCHAR test_verb[] = {'P','O','S','T',0};
293 static CHAR post_data[] = "mode=Test";
294 static CHAR test_post[] = "mode => Test\\0\n";
296 header_len = -1L;
297 total_len = optional_len = sizeof(post_data);
298 memset(buffer, 0xff, sizeof(buffer));
300 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
301 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
302 ok(session != NULL, "WinHttpOpen failed to open session.\n");
304 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
305 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
307 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
308 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
309 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
311 skip("Network unreachable, skipping.\n");
312 goto done;
314 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
315 if (!request) goto done;
317 context = 0xdeadbeef;
318 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
319 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
321 context++;
322 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
323 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
325 context = 0;
326 size = sizeof(context);
327 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
328 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
329 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
331 for (i = 3; post_data[i]; i++)
333 bytes_rw = -1;
334 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
335 if (ret)
336 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
337 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
339 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
340 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
344 ret = WinHttpReceiveResponse(request, NULL);
345 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
347 bytes_rw = -1;
348 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
349 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
351 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
352 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
354 ret = WinHttpCloseHandle(request);
355 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
356 done:
357 ret = WinHttpCloseHandle(connection);
358 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
359 ret = WinHttpCloseHandle(session);
360 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
363 static void test_WinHttpTimeFromSystemTime(void)
365 BOOL ret;
366 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
367 static const WCHAR expected_string[] =
368 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
369 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
370 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
372 ret = WinHttpTimeFromSystemTime(&time, time_string);
373 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
374 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
375 "Time string returned did not match expected time string.\n");
378 static void test_WinHttpTimeToSystemTime(void)
380 BOOL ret;
381 SYSTEMTIME time;
382 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
383 static const WCHAR time_string1[] =
384 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
385 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
386 static const WCHAR time_string2[] =
387 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
388 '1','0',' ','0','5',' ','5','2','\n',0};
390 ret = WinHttpTimeToSystemTime(time_string1, &time);
391 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
392 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
393 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
395 ret = WinHttpTimeToSystemTime(time_string2, &time);
396 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
397 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
398 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
401 static void test_WinHttpAddHeaders(void)
403 HINTERNET session, request, connection;
404 BOOL ret, reverse;
405 WCHAR buffer[MAX_PATH];
406 WCHAR check_buffer[MAX_PATH];
407 DWORD index, len, oldlen;
409 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
410 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
411 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
412 static const WCHAR test_verb[] = {'P','O','S','T',0};
414 static const WCHAR test_header_begin[] =
415 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
416 static const WCHAR full_path_test_header_begin[] =
417 {'P','O','S','T',' ','h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',':','8','0','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
418 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
419 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
421 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
422 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
423 static const WCHAR test_flag_coalesce_comma[] =
424 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
425 static const WCHAR test_flag_coalesce_comma_reverse[] =
426 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
427 static const WCHAR test_flag_coalesce_semicolon[] =
428 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
430 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
432 static const WCHAR field[] = {'f','i','e','l','d',0};
433 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
434 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
436 static const WCHAR test_headers[][14] =
438 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
439 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
440 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
441 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
442 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
443 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
444 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
445 {0},
446 {':',0},
447 {'a',':',0},
448 {':','b',0},
449 {'c','d',0},
450 {' ','e',' ',':','f',0},
451 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
453 static const WCHAR test_indices[][6] =
455 {'t','e','s','t','1',0},
456 {'t','e','s','t','2',0},
457 {'t','e','s','t','3',0},
458 {'t','e','s','t','4',0}
461 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
462 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
463 ok(session != NULL, "WinHttpOpen failed to open session.\n");
465 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
466 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
468 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
469 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
470 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
472 skip("Network unreachable, skipping.\n");
473 goto done;
475 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
477 index = 0;
478 len = sizeof(buffer);
479 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
480 test_header_name, buffer, &len, &index);
481 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
482 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
483 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
485 index = 0;
486 len = sizeof(buffer);
487 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
488 test_header_name, buffer, &len, &index);
489 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
490 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
491 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
492 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
494 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
495 test_header_name, buffer, &len, &index);
496 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
498 /* Try to fetch the header info with a buffer that's big enough to fit the
499 * string but not the NULL terminator.
501 index = 0;
502 len = 5*sizeof(WCHAR);
503 memset(check_buffer, 0xab, sizeof(check_buffer));
504 memcpy(buffer, check_buffer, sizeof(buffer));
505 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
506 test_header_name, buffer, &len, &index);
507 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
508 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
509 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
510 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
512 /* Try with a NULL buffer */
513 index = 0;
514 len = sizeof(buffer);
515 SetLastError(0xdeadbeef);
516 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
517 test_header_name, NULL, &len, &index);
518 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
520 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
521 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
523 /* Try with a NULL buffer and a length that's too small */
524 index = 0;
525 len = 10;
526 SetLastError(0xdeadbeef);
527 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
528 test_header_name, NULL, &len, &index);
529 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
530 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
531 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
532 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
533 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
535 index = 0;
536 len = 0;
537 SetLastError(0xdeadbeef);
538 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
539 test_header_name, NULL, &len, &index);
540 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
541 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
542 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
543 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
544 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
546 /* valid query */
547 oldlen = len;
548 index = 0;
549 len = sizeof(buffer);
550 memset(buffer, 0xff, sizeof(buffer));
551 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
552 test_header_name, buffer, &len, &index);
553 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
554 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
555 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
556 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
557 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
558 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
559 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
560 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
561 "WinHttpQueryHeaders returned invalid end of header string.\n");
562 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
564 index = 0;
565 len = 0;
566 SetLastError(0xdeadbeef);
567 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
568 test_header_name, NULL, &len, &index);
569 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
570 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
571 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
572 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
573 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
575 oldlen = len;
576 index = 0;
577 len = sizeof(buffer);
578 memset(buffer, 0xff, sizeof(buffer));
579 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
580 test_header_name, buffer, &len, &index);
581 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
582 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
583 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
584 "no double NULL terminator\n");
585 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
586 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
587 "invalid beginning of header string.\n");
588 ok(index == 0, "header index was incremented\n");
590 /* tests for more indices */
591 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
592 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
594 index = 0;
595 len = sizeof(buffer);
596 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
597 test_header_name, buffer, &len, &index);
598 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
599 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
600 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
602 len = sizeof(buffer);
603 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
604 test_header_name, buffer, &len, &index);
605 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
606 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
607 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
609 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
610 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
612 index = 0;
613 len = sizeof(buffer);
614 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
615 test_header_name, buffer, &len, &index);
616 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
617 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
618 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
619 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
621 len = sizeof(buffer);
622 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
623 test_header_name, buffer, &len, &index);
624 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
625 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
626 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
628 /* add if new flag */
629 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
630 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
632 index = 0;
633 len = sizeof(buffer);
634 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
635 test_header_name, buffer, &len, &index);
636 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
637 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
638 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
640 len = sizeof(buffer);
641 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
642 test_header_name, buffer, &len, &index);
643 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
644 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
645 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
647 len = sizeof(buffer);
648 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
649 test_header_name, buffer, &len, &index);
650 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
652 /* coalesce flag */
653 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
654 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
656 index = 0;
657 len = sizeof(buffer);
658 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
659 test_header_name, buffer, &len, &index);
660 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
661 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
662 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce, sizeof(reverse ? test_flag_coalesce_reverse : test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
664 len = sizeof(buffer);
665 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
666 test_header_name, buffer, &len, &index);
667 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
668 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
669 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
671 len = sizeof(buffer);
672 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
673 test_header_name, buffer, &len, &index);
674 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
676 /* coalesce with comma flag */
677 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
678 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
680 index = 0;
681 len = sizeof(buffer);
682 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
683 test_header_name, buffer, &len, &index);
684 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
685 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
686 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma, sizeof(reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma)) == 0,
687 "WinHttpQueryHeaders returned incorrect string.\n");
689 len = sizeof(buffer);
690 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
691 test_header_name, buffer, &len, &index);
692 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
693 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
694 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
696 len = sizeof(buffer);
697 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
698 test_header_name, buffer, &len, &index);
699 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
702 /* coalesce with semicolon flag */
703 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
704 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
706 index = 0;
707 len = sizeof(buffer);
708 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
709 test_header_name, buffer, &len, &index);
710 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
711 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
712 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon, sizeof(reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon)) == 0,
713 "WinHttpQueryHeaders returned incorrect string.\n");
715 len = sizeof(buffer);
716 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
717 test_header_name, buffer, &len, &index);
718 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
719 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
720 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
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 == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
727 /* add and replace flags */
728 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
729 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
731 index = 0;
732 len = sizeof(buffer);
733 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
734 test_header_name, buffer, &len, &index);
735 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
736 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
737 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
739 len = sizeof(buffer);
740 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
741 test_header_name, buffer, &len, &index);
742 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
743 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
744 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
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 == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
751 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
752 ok(!ret, "WinHttpAddRequestHeaders failed\n");
754 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
755 ok(ret, "WinHttpAddRequestHeaders failed\n");
757 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
758 ok(!ret, "WinHttpAddRequestHeaders failed\n");
760 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
761 ok(!ret, "WinHttpAddRequestHeaders failed\n");
763 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
764 ok(!ret, "WinHttpAddRequestHeaders failed\n");
766 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
767 ok(ret, "WinHttpAddRequestHeaders failed\n");
769 index = 0;
770 buffer[0] = 0;
771 len = sizeof(buffer);
772 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
773 field, buffer, &len, &index);
774 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
775 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
777 ret = WinHttpCloseHandle(request);
778 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
779 done:
780 ret = WinHttpCloseHandle(connection);
781 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
782 ret = WinHttpCloseHandle(session);
783 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
787 static void test_secure_connection(void)
789 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
791 HINTERNET ses, con, req;
792 DWORD size, status, policy, bitness;
793 BOOL ret;
794 CERT_CONTEXT *cert;
795 WINHTTP_CERTIFICATE_INFO info;
796 char buffer[32];
798 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
799 ok(ses != NULL, "failed to open session %u\n", GetLastError());
801 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
802 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
803 ok(ret, "failed to set redirect policy %u\n", GetLastError());
805 con = WinHttpConnect(ses, google, 443, 0);
806 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
808 /* try without setting WINHTTP_FLAG_SECURE */
809 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
810 ok(req != NULL, "failed to open a request %u\n", GetLastError());
812 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
813 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
815 skip("Connection failed, skipping.\n");
816 goto cleanup;
818 ok(ret, "failed to send request %u\n", GetLastError());
820 ret = WinHttpReceiveResponse(req, NULL);
821 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
823 size = 0;
824 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
825 ok(!ret, "succeeded unexpectedly\n");
827 WinHttpCloseHandle(req);
829 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
830 ok(req != NULL, "failed to open a request %u\n", GetLastError());
832 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
833 ok(ret, "failed to send request %u\n", GetLastError());
834 if (!ret)
836 skip("secure connection failed, skipping remaining secure tests\n");
837 goto cleanup;
840 size = sizeof(cert);
841 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
842 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
843 if (ret)
844 CertFreeCertificateContext(cert);
846 size = sizeof(bitness);
847 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
848 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
850 size = sizeof(info);
851 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
852 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
854 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
855 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
856 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
857 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
858 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
859 trace("dwKeySize %u\n", info.dwKeySize);
861 ret = WinHttpReceiveResponse(req, NULL);
862 ok(ret, "failed to receive response %u\n", GetLastError());
864 size = sizeof(status);
865 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
866 ok(ret, "failed unexpectedly %u\n", GetLastError());
867 ok(status == 200, "request failed unexpectedly %u\n", status);
869 size = 0;
870 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
871 ok(!ret, "succeeded unexpectedly\n");
873 for (;;)
875 size = 0;
876 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
877 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
878 if (!size) break;
881 cleanup:
882 WinHttpCloseHandle(req);
883 WinHttpCloseHandle(con);
884 WinHttpCloseHandle(ses);
887 static void test_request_parameter_defaults(void)
889 static const WCHAR empty[] = {0};
890 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
892 HINTERNET ses, con, req;
893 DWORD size, status, error;
894 WCHAR *version;
895 BOOL ret;
897 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
898 ok(ses != NULL, "failed to open session %u\n", GetLastError());
900 con = WinHttpConnect(ses, codeweavers, 0, 0);
901 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
903 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
904 ok(req != NULL, "failed to open a request %u\n", GetLastError());
906 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
907 ok(ret, "failed to send request %u\n", GetLastError());
909 ret = WinHttpReceiveResponse(req, NULL);
910 ok(ret, "failed to receive response %u\n", GetLastError());
912 size = sizeof(status);
913 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
914 ok(ret, "failed unexpectedly %u\n", GetLastError());
915 ok(status == 200, "request failed unexpectedly %u\n", status);
917 WinHttpCloseHandle(req);
919 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
920 ok(req != NULL, "failed to open a request %u\n", GetLastError());
922 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
923 ok(ret, "failed to send request %u\n", GetLastError());
925 ret = WinHttpReceiveResponse(req, NULL);
926 ok(ret, "failed to receive response %u\n", GetLastError());
928 size = 0;
929 SetLastError(0xdeadbeef);
930 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
931 error = GetLastError();
932 ok(!ret, "succeeded unexpectedly\n");
933 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
935 version = HeapAlloc(GetProcessHeap(), 0, size);
936 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
937 ok(ret, "failed unexpectedly %u\n", GetLastError());
938 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
939 HeapFree(GetProcessHeap(), 0, version);
941 size = sizeof(status);
942 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
943 ok(ret, "failed unexpectedly %u\n", GetLastError());
944 ok(status == 200, "request failed unexpectedly %u\n", status);
946 WinHttpCloseHandle(req);
947 WinHttpCloseHandle(con);
948 WinHttpCloseHandle(ses);
951 static const WCHAR Connections[] = {
952 'S','o','f','t','w','a','r','e','\\',
953 'M','i','c','r','o','s','o','f','t','\\',
954 'W','i','n','d','o','w','s','\\',
955 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
956 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
957 'C','o','n','n','e','c','t','i','o','n','s',0 };
958 static const WCHAR WinHttpSettings[] = {
959 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
961 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
963 LONG l;
964 HKEY key;
965 DWORD ret = 0;
967 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
968 if (!l)
970 DWORD size = 0;
972 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
973 if (!l)
975 if (size <= len)
976 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
977 &size );
978 if (!l)
979 ret = size;
981 RegCloseKey( key );
983 return ret;
986 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
988 LONG l;
989 HKEY key;
991 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
992 KEY_WRITE, NULL, &key, NULL );
993 if (!l)
995 if (len)
996 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
997 else
998 RegDeleteValueW( key, WinHttpSettings );
999 RegCloseKey( key );
1003 static void test_set_default_proxy_config(void)
1005 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1006 static const WCHAR normalString[] = { 'f','o','o',0 };
1007 DWORD type, len;
1008 BYTE *saved_proxy_settings = NULL;
1009 WINHTTP_PROXY_INFO info;
1010 BOOL ret;
1012 /* FIXME: it would be simpler to read the current settings using
1013 * WinHttpGetDefaultProxyConfiguration and save them using
1014 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1016 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1017 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1018 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1019 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1020 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1021 * the lpszProxy and lpszProxyBypass values are ignored.
1022 * Thus, if a proxy is set with proxycfg, then calling
1023 * WinHttpGetDefaultProxyConfiguration followed by
1024 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1025 * getting deleted from the registry.
1027 * Instead I read the current registry value and restore it directly.
1029 len = get_default_proxy_reg_value( NULL, 0, &type );
1030 if (len)
1032 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1033 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1036 if (0)
1038 /* Crashes on Vista and higher */
1039 SetLastError(0xdeadbeef);
1040 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1041 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1042 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1045 /* test with invalid access type */
1046 info.dwAccessType = 0xdeadbeef;
1047 info.lpszProxy = info.lpszProxyBypass = NULL;
1048 SetLastError(0xdeadbeef);
1049 ret = WinHttpSetDefaultProxyConfiguration(&info);
1050 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1051 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1053 /* at a minimum, the proxy server must be set */
1054 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1055 info.lpszProxy = info.lpszProxyBypass = NULL;
1056 SetLastError(0xdeadbeef);
1057 ret = WinHttpSetDefaultProxyConfiguration(&info);
1058 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1059 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1060 info.lpszProxyBypass = normalString;
1061 SetLastError(0xdeadbeef);
1062 ret = WinHttpSetDefaultProxyConfiguration(&info);
1063 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1064 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1066 /* the proxy server can't have wide characters */
1067 info.lpszProxy = wideString;
1068 SetLastError(0xdeadbeef);
1069 ret = WinHttpSetDefaultProxyConfiguration(&info);
1070 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1071 broken(ret), /* Earlier winhttp versions on W2K/XP */
1072 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1074 info.lpszProxy = normalString;
1075 SetLastError(0xdeadbeef);
1076 ret = WinHttpSetDefaultProxyConfiguration(&info);
1077 if (ret)
1079 ok(ret, "always true\n");
1080 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1082 else if (GetLastError() == ERROR_ACCESS_DENIED)
1083 skip("couldn't set default proxy configuration: access denied\n");
1084 else
1085 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1086 GetLastError());
1089 static void test_Timeouts (void)
1091 BOOL ret;
1092 DWORD value, size;
1093 HINTERNET ses, req, con;
1094 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1097 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1098 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1100 SetLastError(0xdeadbeef);
1101 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1102 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1103 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1105 SetLastError(0xdeadbeef);
1106 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1107 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1108 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1110 SetLastError(0xdeadbeef);
1111 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1112 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1113 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1115 SetLastError(0xdeadbeef);
1116 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1117 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1118 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1120 SetLastError(0xdeadbeef);
1121 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1122 ok(ret, "%u\n", GetLastError());
1124 SetLastError(0xdeadbeef);
1125 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1126 ok(ret, "%u\n", GetLastError());
1128 SetLastError(0xdeadbeef);
1129 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1130 ok(ret, "%u\n", GetLastError());
1132 SetLastError(0xdeadbeef);
1133 value = 0xdeadbeef;
1134 size = sizeof(DWORD);
1135 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1136 ok(ret, "%u\n", GetLastError());
1137 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1139 SetLastError(0xdeadbeef);
1140 value = 0xdeadbeef;
1141 size = sizeof(DWORD);
1142 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1143 ok(ret, "%u\n", GetLastError());
1144 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1146 SetLastError(0xdeadbeef);
1147 value = 0xdeadbeef;
1148 size = sizeof(DWORD);
1149 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1150 ok(ret, "%u\n", GetLastError());
1151 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1153 SetLastError(0xdeadbeef);
1154 value = 0xdeadbeef;
1155 size = sizeof(DWORD);
1156 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1157 ok(ret, "%u\n", GetLastError());
1158 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1160 SetLastError(0xdeadbeef);
1161 value = 0;
1162 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1163 ok(ret, "%u\n", GetLastError());
1165 SetLastError(0xdeadbeef);
1166 value = 0xdeadbeef;
1167 size = sizeof(DWORD);
1168 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1169 ok(ret, "%u\n", GetLastError());
1170 ok(value == 0, "Expected 0, got %u\n", value);
1172 SetLastError(0xdeadbeef);
1173 value = 0;
1174 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1175 ok(ret, "%u\n", GetLastError());
1177 SetLastError(0xdeadbeef);
1178 value = 0xdeadbeef;
1179 size = sizeof(DWORD);
1180 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1181 ok(ret, "%u\n", GetLastError());
1182 ok(value == 0, "Expected 0, got %u\n", value);
1184 SetLastError(0xdeadbeef);
1185 value = 0;
1186 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1187 ok(ret, "%u\n", GetLastError());
1189 SetLastError(0xdeadbeef);
1190 value = 0xdeadbeef;
1191 size = sizeof(DWORD);
1192 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1193 ok(ret, "%u\n", GetLastError());
1194 ok(value == 0, "Expected 0, got %u\n", value);
1196 SetLastError(0xdeadbeef);
1197 value = 0;
1198 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1199 ok(ret, "%u\n", GetLastError());
1201 SetLastError(0xdeadbeef);
1202 value = 0xdeadbeef;
1203 size = sizeof(DWORD);
1204 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1205 ok(ret, "%u\n", GetLastError());
1206 ok(value == 0, "Expected 0, got %u\n", value);
1208 SetLastError(0xdeadbeef);
1209 value = 0xbeefdead;
1210 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1211 ok(ret, "%u\n", GetLastError());
1213 SetLastError(0xdeadbeef);
1214 value = 0xdeadbeef;
1215 size = sizeof(DWORD);
1216 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1217 ok(ret, "%u\n", GetLastError());
1218 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1220 SetLastError(0xdeadbeef);
1221 value = 0xbeefdead;
1222 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1223 ok(ret, "%u\n", GetLastError());
1225 SetLastError(0xdeadbeef);
1226 value = 0xdeadbeef;
1227 size = sizeof(DWORD);
1228 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1229 ok(ret, "%u\n", GetLastError());
1230 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1232 SetLastError(0xdeadbeef);
1233 value = 0xbeefdead;
1234 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1235 ok(ret, "%u\n", GetLastError());
1237 SetLastError(0xdeadbeef);
1238 value = 0xdeadbeef;
1239 size = sizeof(DWORD);
1240 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1241 ok(ret, "%u\n", GetLastError());
1242 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1244 SetLastError(0xdeadbeef);
1245 value = 0xbeefdead;
1246 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1247 ok(ret, "%u\n", GetLastError());
1249 SetLastError(0xdeadbeef);
1250 value = 0xdeadbeef;
1251 size = sizeof(DWORD);
1252 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1253 ok(ret, "%u\n", GetLastError());
1254 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1256 con = WinHttpConnect(ses, codeweavers, 0, 0);
1257 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1259 /* Timeout values should match the last one set for session */
1260 SetLastError(0xdeadbeef);
1261 value = 0xdeadbeef;
1262 size = sizeof(DWORD);
1263 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1264 ok(ret, "%u\n", GetLastError());
1265 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1267 SetLastError(0xdeadbeef);
1268 value = 0xdeadbeef;
1269 size = sizeof(DWORD);
1270 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1271 ok(ret, "%u\n", GetLastError());
1272 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1274 SetLastError(0xdeadbeef);
1275 value = 0xdeadbeef;
1276 size = sizeof(DWORD);
1277 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1278 ok(ret, "%u\n", GetLastError());
1279 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1281 SetLastError(0xdeadbeef);
1282 value = 0xdeadbeef;
1283 size = sizeof(DWORD);
1284 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1285 ok(ret, "%u\n", GetLastError());
1286 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1288 SetLastError(0xdeadbeef);
1289 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1290 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1291 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1293 SetLastError(0xdeadbeef);
1294 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1295 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1296 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1298 SetLastError(0xdeadbeef);
1299 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1300 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1301 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1303 SetLastError(0xdeadbeef);
1304 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1305 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1306 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1308 SetLastError(0xdeadbeef);
1309 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1310 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1311 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1313 SetLastError(0xdeadbeef);
1314 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1315 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1316 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1318 SetLastError(0xdeadbeef);
1319 value = 0;
1320 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1321 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1322 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1324 SetLastError(0xdeadbeef);
1325 value = 0;
1326 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1327 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1328 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1330 SetLastError(0xdeadbeef);
1331 value = 0;
1332 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1333 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1334 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1336 SetLastError(0xdeadbeef);
1337 value = 0;
1338 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1339 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1340 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1342 /* Changing timeout values for session should affect the values for connection */
1343 SetLastError(0xdeadbeef);
1344 value = 0xdead;
1345 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1346 ok(ret, "%u\n", GetLastError());
1348 SetLastError(0xdeadbeef);
1349 value = 0xdeadbeef;
1350 size = sizeof(DWORD);
1351 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1352 ok(ret, "%u\n", GetLastError());
1353 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1355 SetLastError(0xdeadbeef);
1356 value = 0xdead;
1357 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1358 ok(ret, "%u\n", GetLastError());
1360 SetLastError(0xdeadbeef);
1361 value = 0xdeadbeef;
1362 size = sizeof(DWORD);
1363 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1364 ok(ret, "%u\n", GetLastError());
1365 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1367 SetLastError(0xdeadbeef);
1368 value = 0xdead;
1369 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1370 ok(ret, "%u\n", GetLastError());
1372 SetLastError(0xdeadbeef);
1373 value = 0xdeadbeef;
1374 size = sizeof(DWORD);
1375 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1376 ok(ret, "%u\n", GetLastError());
1377 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1379 SetLastError(0xdeadbeef);
1380 value = 0xdead;
1381 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1382 ok(ret, "%u\n", GetLastError());
1384 SetLastError(0xdeadbeef);
1385 value = 0xdeadbeef;
1386 size = sizeof(DWORD);
1387 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1388 ok(ret, "%u\n", GetLastError());
1389 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1391 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1392 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1394 /* Timeout values should match the last one set for session */
1395 SetLastError(0xdeadbeef);
1396 value = 0xdeadbeef;
1397 size = sizeof(DWORD);
1398 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1399 ok(ret, "%u\n", GetLastError());
1400 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1402 SetLastError(0xdeadbeef);
1403 value = 0xdeadbeef;
1404 size = sizeof(DWORD);
1405 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1406 ok(ret, "%u\n", GetLastError());
1407 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1409 SetLastError(0xdeadbeef);
1410 value = 0xdeadbeef;
1411 size = sizeof(DWORD);
1412 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1413 ok(ret, "%u\n", GetLastError());
1414 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1416 SetLastError(0xdeadbeef);
1417 value = 0xdeadbeef;
1418 size = sizeof(DWORD);
1419 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1420 ok(ret, "%u\n", GetLastError());
1421 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1423 SetLastError(0xdeadbeef);
1424 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1425 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1426 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1428 SetLastError(0xdeadbeef);
1429 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1430 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1431 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1433 SetLastError(0xdeadbeef);
1434 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1435 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1436 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1438 SetLastError(0xdeadbeef);
1439 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1440 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1441 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1443 SetLastError(0xdeadbeef);
1444 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1445 ok(ret, "%u\n", GetLastError());
1447 SetLastError(0xdeadbeef);
1448 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1449 ok(ret, "%u\n", GetLastError());
1451 SetLastError(0xdeadbeef);
1452 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1453 ok(ret, "%u\n", GetLastError());
1455 SetLastError(0xdeadbeef);
1456 value = 0xdeadbeef;
1457 size = sizeof(DWORD);
1458 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1459 ok(ret, "%u\n", GetLastError());
1460 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1462 SetLastError(0xdeadbeef);
1463 value = 0xdeadbeef;
1464 size = sizeof(DWORD);
1465 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1466 ok(ret, "%u\n", GetLastError());
1467 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1469 SetLastError(0xdeadbeef);
1470 value = 0xdeadbeef;
1471 size = sizeof(DWORD);
1472 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1473 ok(ret, "%u\n", GetLastError());
1474 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1476 SetLastError(0xdeadbeef);
1477 value = 0xdeadbeef;
1478 size = sizeof(DWORD);
1479 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1480 ok(ret, "%u\n", GetLastError());
1481 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1483 SetLastError(0xdeadbeef);
1484 value = 0;
1485 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1486 ok(ret, "%u\n", GetLastError());
1488 SetLastError(0xdeadbeef);
1489 value = 0xdeadbeef;
1490 size = sizeof(DWORD);
1491 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1492 ok(ret, "%u\n", GetLastError());
1493 ok(value == 0, "Expected 0, got %u\n", value);
1495 SetLastError(0xdeadbeef);
1496 value = 0;
1497 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1498 ok(ret, "%u\n", GetLastError());
1500 SetLastError(0xdeadbeef);
1501 value = 0xdeadbeef;
1502 size = sizeof(DWORD);
1503 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1504 ok(ret, "%u\n", GetLastError());
1505 ok(value == 0, "Expected 0, got %u\n", value);
1507 SetLastError(0xdeadbeef);
1508 value = 0;
1509 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1510 ok(ret, "%u\n", GetLastError());
1512 SetLastError(0xdeadbeef);
1513 value = 0xdeadbeef;
1514 size = sizeof(DWORD);
1515 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1516 ok(ret, "%u\n", GetLastError());
1517 ok(value == 0, "Expected 0, got %u\n", value);
1519 SetLastError(0xdeadbeef);
1520 value = 0;
1521 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1522 ok(ret, "%u\n", GetLastError());
1524 SetLastError(0xdeadbeef);
1525 value = 0xdeadbeef;
1526 size = sizeof(DWORD);
1527 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1528 ok(ret, "%u\n", GetLastError());
1529 ok(value == 0, "Expected 0, got %u\n", value);
1531 SetLastError(0xdeadbeef);
1532 value = 0xbeefdead;
1533 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1534 ok(ret, "%u\n", GetLastError());
1536 SetLastError(0xdeadbeef);
1537 value = 0xdeadbeef;
1538 size = sizeof(DWORD);
1539 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1540 ok(ret, "%u\n", GetLastError());
1541 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1543 SetLastError(0xdeadbeef);
1544 value = 0xbeefdead;
1545 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1546 ok(ret, "%u\n", GetLastError());
1548 SetLastError(0xdeadbeef);
1549 value = 0xdeadbeef;
1550 size = sizeof(DWORD);
1551 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1552 ok(ret, "%u\n", GetLastError());
1553 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1555 SetLastError(0xdeadbeef);
1556 value = 0xbeefdead;
1557 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1558 ok(ret, "%u\n", GetLastError());
1560 SetLastError(0xdeadbeef);
1561 value = 0xdeadbeef;
1562 size = sizeof(DWORD);
1563 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1564 ok(ret, "%u\n", GetLastError());
1565 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1567 SetLastError(0xdeadbeef);
1568 value = 0xbeefdead;
1569 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1570 ok(ret, "%u\n", GetLastError());
1572 SetLastError(0xdeadbeef);
1573 value = 0xdeadbeef;
1574 size = sizeof(DWORD);
1575 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1576 ok(ret, "%u\n", GetLastError());
1577 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1579 /* Changing timeout values for session should not affect the values for a request,
1580 * neither should the other way around.
1582 SetLastError(0xdeadbeef);
1583 value = 0xbeefdead;
1584 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1585 ok(ret, "%u\n", GetLastError());
1587 SetLastError(0xdeadbeef);
1588 value = 0xdeadbeef;
1589 size = sizeof(DWORD);
1590 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1591 ok(ret, "%u\n", GetLastError());
1592 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1594 SetLastError(0xdeadbeef);
1595 value = 0xbeefdead;
1596 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1597 ok(ret, "%u\n", GetLastError());
1599 SetLastError(0xdeadbeef);
1600 value = 0xdeadbeef;
1601 size = sizeof(DWORD);
1602 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1603 ok(ret, "%u\n", GetLastError());
1604 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1606 SetLastError(0xdeadbeef);
1607 value = 0xbeefdead;
1608 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1609 ok(ret, "%u\n", GetLastError());
1611 SetLastError(0xdeadbeef);
1612 value = 0xdeadbeef;
1613 size = sizeof(DWORD);
1614 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1615 ok(ret, "%u\n", GetLastError());
1616 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1618 SetLastError(0xdeadbeef);
1619 value = 0xbeefdead;
1620 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1621 ok(ret, "%u\n", GetLastError());
1623 SetLastError(0xdeadbeef);
1624 value = 0xdeadbeef;
1625 size = sizeof(DWORD);
1626 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1627 ok(ret, "%u\n", GetLastError());
1628 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1630 SetLastError(0xdeadbeef);
1631 value = 0xbeef;
1632 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1633 ok(ret, "%u\n", GetLastError());
1635 SetLastError(0xdeadbeef);
1636 value = 0xdeadbeef;
1637 size = sizeof(DWORD);
1638 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1639 ok(ret, "%u\n", GetLastError());
1640 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1642 SetLastError(0xdeadbeef);
1643 value = 0xbeef;
1644 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1645 ok(ret, "%u\n", GetLastError());
1647 SetLastError(0xdeadbeef);
1648 value = 0xdeadbeef;
1649 size = sizeof(DWORD);
1650 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1651 ok(ret, "%u\n", GetLastError());
1652 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1654 SetLastError(0xdeadbeef);
1655 value = 0xbeef;
1656 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1657 ok(ret, "%u\n", GetLastError());
1659 SetLastError(0xdeadbeef);
1660 value = 0xdeadbeef;
1661 size = sizeof(DWORD);
1662 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1663 ok(ret, "%u\n", GetLastError());
1664 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1666 SetLastError(0xdeadbeef);
1667 value = 0xbeef;
1668 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1669 ok(ret, "%u\n", GetLastError());
1671 SetLastError(0xdeadbeef);
1672 value = 0xdeadbeef;
1673 size = sizeof(DWORD);
1674 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1675 ok(ret, "%u\n", GetLastError());
1676 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1678 WinHttpCloseHandle(req);
1679 WinHttpCloseHandle(con);
1680 WinHttpCloseHandle(ses);
1683 static void test_resolve_timeout(void)
1685 static const WCHAR codeweavers[] =
1686 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1687 static const WCHAR nxdomain[] =
1688 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1690 HINTERNET ses, con, req;
1691 DWORD timeout;
1692 BOOL ret;
1694 if (! proxy_active())
1696 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1697 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1699 timeout = 10000;
1700 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1701 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1703 con = WinHttpConnect(ses, nxdomain, 0, 0);
1704 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1706 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1707 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1709 SetLastError(0xdeadbeef);
1710 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1711 ok(!ret, "sent request\n");
1712 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1713 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1715 WinHttpCloseHandle(req);
1716 WinHttpCloseHandle(con);
1717 WinHttpCloseHandle(ses);
1719 else
1720 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1722 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1723 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1725 timeout = 10000;
1726 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1727 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1729 con = WinHttpConnect(ses, codeweavers, 0, 0);
1730 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1732 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1733 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1735 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1736 ok(ret, "failed to send request\n");
1738 WinHttpCloseHandle(req);
1739 WinHttpCloseHandle(con);
1740 WinHttpCloseHandle(ses);
1743 static const char page1[] =
1744 "<HTML>\r\n"
1745 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1746 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1747 "</HTML>\r\n\r\n";
1749 static const char okmsg[] =
1750 "HTTP/1.1 200 OK\r\n"
1751 "Server: winetest\r\n"
1752 "\r\n";
1754 static const char notokmsg[] =
1755 "HTTP/1.1 400 Bad Request\r\n"
1756 "Server: winetest\r\n"
1757 "\r\n";
1759 static const char noauthmsg[] =
1760 "HTTP/1.1 401 Unauthorized\r\n"
1761 "Server: winetest\r\n"
1762 "Connection: close\r\n"
1763 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1764 "\r\n";
1766 static const char proxymsg[] =
1767 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1768 "Server: winetest\r\n"
1769 "Proxy-Connection: close\r\n"
1770 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1771 "\r\n";
1773 struct server_info
1775 HANDLE event;
1776 int port;
1779 static DWORD CALLBACK server_thread(LPVOID param)
1781 struct server_info *si = param;
1782 int r, c, i, on;
1783 SOCKET s;
1784 struct sockaddr_in sa;
1785 char buffer[0x100];
1786 WSADATA wsaData;
1787 int last_request = 0;
1789 WSAStartup(MAKEWORD(1,1), &wsaData);
1791 s = socket(AF_INET, SOCK_STREAM, 0);
1792 if (s == INVALID_SOCKET)
1793 return 1;
1795 on = 1;
1796 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1798 memset(&sa, 0, sizeof sa);
1799 sa.sin_family = AF_INET;
1800 sa.sin_port = htons(si->port);
1801 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1803 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1804 if (r < 0)
1805 return 1;
1807 listen(s, 0);
1808 SetEvent(si->event);
1811 c = accept(s, NULL, NULL);
1813 memset(buffer, 0, sizeof buffer);
1814 for(i = 0; i < sizeof buffer - 1; i++)
1816 r = recv(c, &buffer[i], 1, 0);
1817 if (r != 1)
1818 break;
1819 if (i < 4) continue;
1820 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1821 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1822 break;
1824 if (strstr(buffer, "GET /basic"))
1826 send(c, okmsg, sizeof okmsg - 1, 0);
1827 send(c, page1, sizeof page1 - 1, 0);
1829 if (strstr(buffer, "/auth"))
1831 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1832 send(c, okmsg, sizeof okmsg - 1, 0);
1833 else
1834 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1836 if (strstr(buffer, "/no_headers"))
1838 send(c, page1, sizeof page1 - 1, 0);
1840 if (strstr(buffer, "GET /quit"))
1842 send(c, okmsg, sizeof okmsg - 1, 0);
1843 send(c, page1, sizeof page1 - 1, 0);
1844 last_request = 1;
1846 shutdown(c, 2);
1847 closesocket(c);
1849 } while (!last_request);
1851 closesocket(s);
1852 return 0;
1855 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1857 HINTERNET ses, con, req;
1858 char buffer[0x100];
1859 DWORD count, status, size;
1860 BOOL ret;
1862 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1863 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1865 con = WinHttpConnect(ses, localhostW, port, 0);
1866 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1868 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1869 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1871 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1872 ok(ret, "failed to send request %u\n", GetLastError());
1874 ret = WinHttpReceiveResponse(req, NULL);
1875 ok(ret, "failed to receive response %u\n", GetLastError());
1877 size = sizeof(status);
1878 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1879 ok(ret, "failed to query status code %u\n", GetLastError());
1880 ok(status == 200, "request failed unexpectedly %u\n", status);
1882 count = 0;
1883 memset(buffer, 0, sizeof(buffer));
1884 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1885 ok(ret, "failed to read data %u\n", GetLastError());
1886 ok(count == sizeof page1 - 1, "count was wrong\n");
1887 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1889 WinHttpCloseHandle(req);
1890 WinHttpCloseHandle(con);
1891 WinHttpCloseHandle(ses);
1894 static void test_basic_authentication(int port)
1896 static const WCHAR authW[] = {'/','a','u','t','h',0};
1897 static const WCHAR userW[] = {'u','s','e','r',0};
1898 static const WCHAR passW[] = {'p','w','d',0};
1899 HINTERNET ses, con, req;
1900 DWORD status, size, error;
1901 BOOL ret;
1903 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1904 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1906 con = WinHttpConnect(ses, localhostW, port, 0);
1907 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1909 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1910 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1912 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1913 ok(ret, "failed to send request %u\n", GetLastError());
1915 ret = WinHttpReceiveResponse(req, NULL);
1916 ok(ret, "failed to receive response %u\n", GetLastError());
1918 size = sizeof(status);
1919 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1920 ok(ret, "failed to query status code %u\n", GetLastError());
1921 ok(status == 401, "request failed unexpectedly %u\n", status);
1923 SetLastError(0xdeadbeef);
1924 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1925 error = GetLastError();
1926 ok(!ret, "expected failure\n");
1927 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1929 SetLastError(0xdeadbeef);
1930 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1931 error = GetLastError();
1932 ok(!ret, "expected failure\n");
1933 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1935 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1936 ok(ret, "failed to set credentials %u\n", GetLastError());
1938 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1939 ok(ret, "failed to send request %u\n", GetLastError());
1941 ret = WinHttpReceiveResponse(req, NULL);
1942 ok(ret, "failed to receive response %u\n", GetLastError());
1944 size = sizeof(status);
1945 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1946 ok(ret, "failed to query status code %u\n", GetLastError());
1947 ok(status == 200, "request failed unexpectedly %u\n", status);
1949 WinHttpCloseHandle(req);
1950 WinHttpCloseHandle(con);
1951 WinHttpCloseHandle(ses);
1954 static void test_no_headers(int port)
1956 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1957 HINTERNET ses, con, req;
1958 DWORD error;
1959 BOOL ret;
1961 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1962 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1964 con = WinHttpConnect(ses, localhostW, port, 0);
1965 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1967 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1968 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1970 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1971 ok(ret, "failed to send request %u\n", GetLastError());
1973 SetLastError(0xdeadbeef);
1974 ret = WinHttpReceiveResponse(req, NULL);
1975 error = GetLastError();
1976 ok(!ret, "expected failure\n");
1977 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
1979 WinHttpCloseHandle(req);
1980 WinHttpCloseHandle(con);
1981 WinHttpCloseHandle(ses);
1984 static void test_credentials(void)
1986 static WCHAR userW[] = {'u','s','e','r',0};
1987 static WCHAR passW[] = {'p','a','s','s',0};
1988 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
1989 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
1990 HINTERNET ses, con, req;
1991 DWORD size, error;
1992 WCHAR buffer[32];
1993 BOOL ret;
1995 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
1996 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1998 con = WinHttpConnect(ses, localhostW, 0, 0);
1999 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2001 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2002 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2004 size = sizeof(buffer)/sizeof(WCHAR);
2005 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2006 ok(ret, "failed to query proxy username %u\n", GetLastError());
2007 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2008 ok(!size, "expected 0, got %u\n", size);
2010 size = sizeof(buffer)/sizeof(WCHAR);
2011 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2012 ok(ret, "failed to query proxy password %u\n", GetLastError());
2013 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2014 ok(!size, "expected 0, got %u\n", size);
2016 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2017 ok(ret, "failed to set username %u\n", GetLastError());
2019 size = sizeof(buffer)/sizeof(WCHAR);
2020 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2021 ok(ret, "failed to query proxy username %u\n", GetLastError());
2022 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2023 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2025 size = sizeof(buffer)/sizeof(WCHAR);
2026 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2027 ok(ret, "failed to query username %u\n", GetLastError());
2028 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2029 ok(!size, "expected 0, got %u\n", size);
2031 size = sizeof(buffer)/sizeof(WCHAR);
2032 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2033 ok(ret, "failed to query password %u\n", GetLastError());
2034 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2035 ok(!size, "expected 0, got %u\n", size);
2037 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2038 ok(ret, "failed to set proxy password %u\n", GetLastError());
2040 size = sizeof(buffer)/sizeof(WCHAR);
2041 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2042 ok(ret, "failed to query proxy password %u\n", GetLastError());
2043 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2044 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2046 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2047 ok(ret, "failed to set username %u\n", GetLastError());
2049 size = sizeof(buffer)/sizeof(WCHAR);
2050 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2051 ok(ret, "failed to query username %u\n", GetLastError());
2052 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2053 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2055 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2056 ok(ret, "failed to set password %u\n", GetLastError());
2058 size = sizeof(buffer)/sizeof(WCHAR);
2059 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2060 ok(ret, "failed to query password %u\n", GetLastError());
2061 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2062 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2064 WinHttpCloseHandle(req);
2066 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2067 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2069 SetLastError(0xdeadbeef);
2070 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2071 error = GetLastError();
2072 ok(!ret, "expected failure\n");
2073 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2075 SetLastError(0xdeadbeef);
2076 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2077 error = GetLastError();
2078 ok(!ret, "expected failure\n");
2079 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2081 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2082 ok(ret, "failed to set credentials %u\n", GetLastError());
2084 size = sizeof(buffer)/sizeof(WCHAR);
2085 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2086 ok(ret, "failed to query username %u\n", GetLastError());
2087 todo_wine {
2088 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2089 ok(!size, "expected 0, got %u\n", size);
2092 size = sizeof(buffer)/sizeof(WCHAR);
2093 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2094 ok(ret, "failed to query password %u\n", GetLastError());
2095 todo_wine {
2096 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2097 ok(!size, "expected 0, got %u\n", size);
2100 WinHttpCloseHandle(req);
2101 WinHttpCloseHandle(con);
2102 WinHttpCloseHandle(ses);
2105 static void test_IWinHttpRequest(void)
2107 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2108 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2109 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2110 static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
2111 static const WCHAR method1W[] = {'G','E','T',0};
2112 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2113 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2114 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2115 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2116 static const WCHAR dateW[] = {'D','a','t','e',0};
2117 HRESULT hr;
2118 IWinHttpRequest *req;
2119 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2120 BSTR date, today, connection, value = NULL;
2121 VARIANT async, empty, timeout, body, proxy_server, bypass_list;
2122 VARIANT_BOOL succeeded;
2123 LONG status;
2124 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2125 SYSTEMTIME st;
2127 GetSystemTime( &st );
2128 WinHttpTimeFromSystemTime( &st, todayW );
2130 CoInitialize( NULL );
2131 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2132 ok( hr == S_OK, "got %08x\n", hr );
2134 V_VT( &empty ) = VT_ERROR;
2135 V_ERROR( &empty ) = 0xdeadbeef;
2137 V_VT( &async ) = VT_BOOL;
2138 V_BOOL( &async ) = VARIANT_FALSE;
2140 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2141 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2143 method = SysAllocString( method1W );
2144 hr = IWinHttpRequest_Open( req, method, NULL, empty );
2145 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2147 hr = IWinHttpRequest_Open( req, method, NULL, async );
2148 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2150 url = SysAllocString( url1W );
2151 hr = IWinHttpRequest_Open( req, NULL, url, empty );
2152 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2154 hr = IWinHttpRequest_Abort( req );
2155 ok( hr == S_OK, "got %08x\n", hr );
2157 hr = IWinHttpRequest_Open( req, method, url, empty );
2158 ok( hr == S_OK, "got %08x\n", hr );
2160 hr = IWinHttpRequest_Abort( req );
2161 ok( hr == S_OK, "got %08x\n", hr );
2163 hr = IWinHttpRequest_Release( req );
2164 ok( hr == S_OK, "got %08x\n", hr );
2166 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2167 ok( hr == S_OK, "got %08x\n", hr );
2169 SysFreeString( url );
2170 url = SysAllocString( url2W );
2171 hr = IWinHttpRequest_Open( req, method, url, async );
2172 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2174 SysFreeString( method );
2175 method = SysAllocString( method2W );
2176 hr = IWinHttpRequest_Open( req, method, url, async );
2177 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2179 SysFreeString( method );
2180 method = SysAllocString( method1W );
2181 SysFreeString( url );
2182 url = SysAllocString( url1W );
2183 hr = IWinHttpRequest_Open( req, method, url, async );
2184 ok( hr == S_OK, "got %08x\n", hr );
2186 hr = IWinHttpRequest_Abort( req );
2187 ok( hr == S_OK, "got %08x\n", hr );
2189 hr = IWinHttpRequest_Send( req, empty );
2190 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2192 hr = IWinHttpRequest_Abort( req );
2193 ok( hr == S_OK, "got %08x\n", hr );
2195 hr = IWinHttpRequest_Release( req );
2196 ok( hr == S_OK, "got %08x\n", hr );
2198 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2199 ok( hr == S_OK, "got %08x\n", hr );
2201 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2202 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2204 hr = IWinHttpRequest_get_ResponseText( req, &response );
2205 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2207 hr = IWinHttpRequest_get_Status( req, NULL );
2208 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2210 hr = IWinHttpRequest_get_Status( req, &status );
2211 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2213 hr = IWinHttpRequest_get_StatusText( req, NULL );
2214 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2216 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2217 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2219 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2220 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2222 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2223 ok( hr == S_OK, "got %08x\n", hr );
2225 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2226 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2228 VariantInit( &proxy_server );
2229 V_VT( &proxy_server ) = VT_ERROR;
2230 VariantInit( &bypass_list );
2231 V_VT( &bypass_list ) = VT_ERROR;
2232 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2233 ok( hr == S_OK, "got %08x\n", hr );
2235 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2236 ok( hr == S_OK, "got %08x\n", hr );
2238 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2239 ok( hr == S_OK, "got %08x\n", hr );
2241 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2242 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2244 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2245 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2247 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2248 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2250 connection = SysAllocString( connectionW );
2251 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2252 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2254 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2255 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2257 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2258 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2260 date = SysAllocString( dateW );
2261 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2262 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2264 today = SysAllocString( todayW );
2265 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2266 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2268 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2269 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2271 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2272 ok( hr == S_OK, "got %08x\n", hr );
2274 SysFreeString( method );
2275 method = SysAllocString( method1W );
2276 SysFreeString( url );
2277 url = SysAllocString( url1W );
2278 hr = IWinHttpRequest_Open( req, method, url, async );
2279 ok( hr == S_OK, "got %08x\n", hr );
2281 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2282 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2284 hr = IWinHttpRequest_get_ResponseText( req, &response );
2285 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2287 hr = IWinHttpRequest_get_Status( req, &status );
2288 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2290 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2291 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2293 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2294 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2296 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2297 ok( hr == S_OK, "got %08x\n", hr );
2299 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2300 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2302 username = SysAllocString( usernameW );
2303 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2304 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2306 password = SysAllocString( passwordW );
2307 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2308 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2310 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2311 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2313 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2314 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2316 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2317 ok( hr == S_OK, "got %08x\n", hr );
2319 V_VT( &proxy_server ) = VT_BSTR;
2320 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2321 V_VT( &bypass_list ) = VT_BSTR;
2322 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2323 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2324 ok( hr == S_OK, "got %08x\n", hr );
2326 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2327 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2329 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2330 ok( hr == S_OK, "got %08x\n", hr );
2332 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2333 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2335 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2336 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2338 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2339 ok( hr == S_OK, "got %08x\n", hr );
2341 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2342 ok( hr == S_OK, "got %08x\n", hr );
2344 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2345 ok( hr == S_OK, "got %08x\n", hr );
2347 hr = IWinHttpRequest_Send( req, empty );
2348 ok( hr == S_OK, "got %08x\n", hr );
2350 hr = IWinHttpRequest_Send( req, empty );
2351 ok( hr == S_OK, "got %08x\n", hr );
2353 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2354 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2356 hr = IWinHttpRequest_get_ResponseText( req, &response );
2357 ok( hr == S_OK, "got %08x\n", hr );
2358 SysFreeString( response );
2360 hr = IWinHttpRequest_get_Status( req, NULL );
2361 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2363 status = 0;
2364 hr = IWinHttpRequest_get_Status( req, &status );
2365 ok( hr == S_OK, "got %08x\n", hr );
2366 trace("%d\n", status);
2368 hr = IWinHttpRequest_get_StatusText( req, NULL );
2369 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2371 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2372 ok( hr == S_OK, "got %08x\n", hr );
2373 trace("%s\n", wine_dbgstr_w(status_text));
2374 SysFreeString( status_text );
2376 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2377 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2379 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2380 ok( hr == S_OK, "got %08x\n", hr );
2382 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2383 ok( hr == S_OK, "got %08x\n", hr );
2385 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2386 ok( hr == S_OK, "got %08x\n", hr );
2388 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2389 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2391 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2392 ok( hr == S_OK, "got %08x\n", hr );
2393 SysFreeString( headers );
2395 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2396 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2398 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2399 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2401 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2402 ok( hr == S_OK, "got %08x\n", hr );
2403 SysFreeString( value );
2405 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2406 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2408 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2409 ok( hr == S_OK, "got %08x\n", hr );
2411 VariantInit( &timeout );
2412 V_VT( &timeout ) = VT_I4;
2413 V_I4( &timeout ) = 10;
2414 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2415 ok( hr == S_OK, "got %08x\n", hr );
2417 hr = IWinHttpRequest_get_Status( req, &status );
2418 ok( hr == S_OK, "got %08x\n", hr );
2420 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2421 ok( hr == S_OK, "got %08x\n", hr );
2422 SysFreeString( status_text );
2424 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2425 ok( hr == S_OK, "got %08x\n", hr );
2427 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2428 ok( hr == S_OK, "got %08x\n", hr );
2430 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2431 ok( hr == S_OK, "got %08x\n", hr );
2433 hr = IWinHttpRequest_Send( req, empty );
2434 ok( hr == S_OK, "got %08x\n", hr );
2436 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2437 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2439 hr = IWinHttpRequest_get_ResponseText( req, &response );
2440 ok( hr == S_OK, "got %08x\n", hr );
2441 SysFreeString( response );
2443 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2444 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2446 VariantInit( &body );
2447 V_VT( &body ) = VT_ERROR;
2448 hr = IWinHttpRequest_get_ResponseBody( req, &body );
2449 ok( hr == S_OK, "got %08x\n", hr );
2450 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2452 hr = VariantClear( &body );
2453 ok( hr == S_OK, "got %08x\n", hr );
2455 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2456 ok( hr == S_OK, "got %08x\n", hr );
2458 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2459 ok( hr == S_OK, "got %08x\n", hr );
2461 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2462 ok( hr == S_OK, "got %08x\n", hr );
2463 SysFreeString( headers );
2465 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2466 ok( hr == S_OK, "got %08x\n", hr );
2467 SysFreeString( value );
2469 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2470 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2472 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2473 ok( hr == S_OK, "got %08x\n", hr );
2475 hr = IWinHttpRequest_Send( req, empty );
2476 ok( hr == S_OK, "got %08x\n", hr );
2478 hr = IWinHttpRequest_Abort( req );
2479 ok( hr == S_OK, "got %08x\n", hr );
2481 hr = IWinHttpRequest_Abort( req );
2482 ok( hr == S_OK, "got %08x\n", hr );
2484 hr = IWinHttpRequest_Release( req );
2485 ok( hr == S_OK, "got %08x\n", hr );
2487 SysFreeString( method );
2488 SysFreeString( url );
2489 SysFreeString( username );
2490 SysFreeString( password );
2491 SysFreeString( connection );
2492 SysFreeString( date );
2493 SysFreeString( today );
2494 VariantClear( &proxy_server );
2495 VariantClear( &bypass_list );
2496 CoUninitialize();
2499 START_TEST (winhttp)
2501 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2502 static const WCHAR quitW[] = {'/','q','u','i','t',0};
2503 struct server_info si;
2504 HANDLE thread;
2505 DWORD ret;
2507 test_OpenRequest();
2508 test_SendRequest();
2509 test_WinHttpTimeFromSystemTime();
2510 test_WinHttpTimeToSystemTime();
2511 test_WinHttpAddHeaders();
2512 test_secure_connection();
2513 test_request_parameter_defaults();
2514 test_QueryOption();
2515 test_set_default_proxy_config();
2516 test_empty_headers_param();
2517 test_Timeouts();
2518 test_resolve_timeout();
2519 test_credentials();
2520 test_IWinHttpRequest();
2522 si.event = CreateEvent(NULL, 0, 0, NULL);
2523 si.port = 7532;
2525 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2526 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2528 ret = WaitForSingleObject(si.event, 10000);
2529 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2530 if (ret != WAIT_OBJECT_0)
2531 return;
2533 test_basic_request(si.port, NULL, basicW);
2534 test_no_headers(si.port);
2535 test_basic_authentication(si.port);
2537 /* send the basic request again to shutdown the server thread */
2538 test_basic_request(si.port, NULL, quitW);
2540 WaitForSingleObject(thread, 3000);