ole32: Add a test showing IStorage_CopyTo ignores open objects in the source.
[wine/multimedia.git] / dlls / winhttp / tests / winhttp.c
blob94346e258ecf1bf0c649e1a7688bfc82cb24ec77
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 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winhttp.h>
26 #include <wincrypt.h>
27 #include <winreg.h>
29 #include "wine/test.h"
31 static const WCHAR test_useragent[] =
32 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
33 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
35 static void test_QueryOption(void)
37 BOOL ret;
38 HINTERNET session, request, connection;
39 DWORD feature, size;
41 SetLastError(0xdeadbeef);
42 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
43 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
45 SetLastError(0xdeadbeef);
46 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
47 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
48 ok(GetLastError() == ERROR_INVALID_PARAMETER,
49 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
51 size = 0xdeadbeef;
52 SetLastError(0xdeadbeef);
53 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
54 ok(!ret, "should fail to query option\n");
55 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
56 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
57 ok(size == 4, "expected 4, got %u\n", size);
59 feature = 0xdeadbeef;
60 size = sizeof(feature) - 1;
61 SetLastError(0xdeadbeef);
62 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
63 ok(!ret, "should fail to query option\n");
64 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
65 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
66 ok(size == 4, "expected 4, got %u\n", size);
68 feature = 0xdeadbeef;
69 size = sizeof(feature) + 1;
70 SetLastError(0xdeadbeef);
71 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
72 ok(ret, "failed to query option %u\n", GetLastError());
73 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
74 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
75 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
77 SetLastError(0xdeadbeef);
78 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
79 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
80 ok(GetLastError() == ERROR_INVALID_PARAMETER,
81 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
83 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
84 SetLastError(0xdeadbeef);
85 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
86 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
90 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
91 SetLastError(0xdeadbeef);
92 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
93 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
94 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
95 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
97 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
98 SetLastError(0xdeadbeef);
99 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
100 ok(ret, "failed to set redirect policy %u\n", GetLastError());
102 feature = 0xdeadbeef;
103 size = sizeof(feature);
104 SetLastError(0xdeadbeef);
105 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
106 ok(ret, "failed to query option %u\n", GetLastError());
107 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
108 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
110 feature = WINHTTP_DISABLE_COOKIES;
111 SetLastError(0xdeadbeef);
112 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
113 ok(!ret, "should fail to set disable feature for a session\n");
114 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
115 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
117 SetLastError(0xdeadbeef);
118 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
119 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
121 feature = WINHTTP_DISABLE_COOKIES;
122 SetLastError(0xdeadbeef);
123 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
124 ok(!ret, "should fail to set disable feature for a connection\n");
125 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
126 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
128 SetLastError(0xdeadbeef);
129 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
130 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
131 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
133 skip("Network unreachable, skipping the test\n");
134 goto done;
137 feature = 0xdeadbeef;
138 size = sizeof(feature);
139 SetLastError(0xdeadbeef);
140 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
141 ok(!ret, "should fail to query disable feature for a request\n");
142 ok(GetLastError() == ERROR_INVALID_PARAMETER,
143 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
145 feature = 0;
146 size = sizeof(feature);
147 SetLastError(0xdeadbeef);
148 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
149 ok(ret, "failed to set feature %u\n", GetLastError());
151 feature = 0xffffffff;
152 size = sizeof(feature);
153 SetLastError(0xdeadbeef);
154 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
155 ok(ret, "failed to set feature %u\n", GetLastError());
157 feature = WINHTTP_DISABLE_COOKIES;
158 size = sizeof(feature);
159 SetLastError(0xdeadbeef);
160 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
161 ok(ret, "failed to set feature %u\n", GetLastError());
163 size = 0;
164 SetLastError(0xdeadbeef);
165 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
166 ok(!ret, "should fail to query disable feature for a request\n");
167 ok(GetLastError() == ERROR_INVALID_PARAMETER,
168 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
170 SetLastError(0xdeadbeef);
171 ret = WinHttpCloseHandle(request);
172 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
174 done:
175 SetLastError(0xdeadbeef);
176 ret = WinHttpCloseHandle(connection);
177 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
178 SetLastError(0xdeadbeef);
179 ret = WinHttpCloseHandle(session);
180 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
183 static void test_OpenRequest (void)
185 BOOL ret;
186 HINTERNET session, request, connection;
188 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
189 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
190 ok(session != NULL, "WinHttpOpen failed to open session.\n");
192 /* Test with a bad server name */
193 SetLastError(0xdeadbeef);
194 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
195 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
196 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
198 /* Test with a valid server name */
199 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
200 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
202 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
203 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
204 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
206 skip("Network unreachable, skipping.\n");
207 goto done;
209 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
211 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
212 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
213 ret = WinHttpCloseHandle(request);
214 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
216 done:
217 ret = WinHttpCloseHandle(connection);
218 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
219 ret = WinHttpCloseHandle(session);
220 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
224 static void test_empty_headers_param(void)
226 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
227 static const WCHAR empty[] = {0};
228 HANDLE ses, con, req;
229 BOOL ret;
231 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
232 ok(ses != NULL, "failed to open session %u\n", GetLastError());
234 con = WinHttpConnect(ses, winehq, 80, 0);
235 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
237 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
238 ok(req != NULL, "failed to open a request %u\n", GetLastError());
240 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
241 ok(ret, "failed to send request %u\n", GetLastError());
243 WinHttpCloseHandle(req);
244 WinHttpCloseHandle(con);
245 WinHttpCloseHandle(ses);
248 static void test_SendRequest (void)
250 HINTERNET session, request, connection;
251 DWORD header_len, optional_len, total_len, bytes_rw, size;
252 DWORD_PTR context;
253 BOOL ret;
254 CHAR buffer[256];
255 int i;
257 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
258 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
259 static const WCHAR content_type[] =
260 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
261 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
262 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
263 static const WCHAR test_verb[] = {'P','O','S','T',0};
264 static CHAR post_data[] = "mode=Test";
265 static CHAR test_post[] = "mode => Test\\0\n";
267 header_len = -1L;
268 total_len = optional_len = sizeof(post_data);
269 memset(buffer, 0xff, sizeof(buffer));
271 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
272 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
273 ok(session != NULL, "WinHttpOpen failed to open session.\n");
275 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
276 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
278 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
279 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
280 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
282 skip("Network unreachable, skipping.\n");
283 goto done;
285 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
286 if (!request) goto done;
288 context = 0xdeadbeef;
289 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
290 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
292 context++;
293 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
294 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
296 context = 0;
297 size = sizeof(context);
298 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
299 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
300 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
302 for (i = 3; post_data[i]; i++)
304 bytes_rw = -1;
305 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
306 if (ret)
307 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
308 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
310 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
311 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
315 ret = WinHttpReceiveResponse(request, NULL);
316 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
318 bytes_rw = -1;
319 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
320 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
322 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
323 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
325 ret = WinHttpCloseHandle(request);
326 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
327 done:
328 ret = WinHttpCloseHandle(connection);
329 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
330 ret = WinHttpCloseHandle(session);
331 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
334 static void test_WinHttpTimeFromSystemTime(void)
336 BOOL ret;
337 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
338 static const WCHAR expected_string[] =
339 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
340 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
341 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
343 ret = WinHttpTimeFromSystemTime(&time, time_string);
344 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
345 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
346 "Time string returned did not match expected time string.\n");
349 static void test_WinHttpTimeToSystemTime(void)
351 BOOL ret;
352 SYSTEMTIME time;
353 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
354 static const WCHAR time_string1[] =
355 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
356 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
357 static const WCHAR time_string2[] =
358 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
359 '1','0',' ','0','5',' ','5','2','\n',0};
361 ret = WinHttpTimeToSystemTime(time_string1, &time);
362 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
363 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
364 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
366 ret = WinHttpTimeToSystemTime(time_string2, &time);
367 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
368 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
369 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
372 static void test_WinHttpAddHeaders(void)
374 HINTERNET session, request, connection;
375 BOOL ret, reverse;
376 WCHAR buffer[MAX_PATH];
377 WCHAR check_buffer[MAX_PATH];
378 DWORD index, len, oldlen;
380 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
381 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
382 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
383 static const WCHAR test_verb[] = {'P','O','S','T',0};
385 static const WCHAR test_header_begin[] =
386 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
387 static const WCHAR full_path_test_header_begin[] =
388 {'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'};
389 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
390 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
392 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
393 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
394 static const WCHAR test_flag_coalesce_comma[] =
395 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
396 static const WCHAR test_flag_coalesce_comma_reverse[] =
397 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
398 static const WCHAR test_flag_coalesce_semicolon[] =
399 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
400 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
401 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
403 static const WCHAR field[] = {'f','i','e','l','d',0};
404 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
405 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
407 static const WCHAR test_headers[][14] =
409 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
410 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
411 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
412 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
413 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
414 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
415 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
416 {0},
417 {':',0},
418 {'a',':',0},
419 {':','b',0},
420 {'c','d',0},
421 {' ','e',' ',':','f',0},
422 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
424 static const WCHAR test_indices[][6] =
426 {'t','e','s','t','1',0},
427 {'t','e','s','t','2',0},
428 {'t','e','s','t','3',0},
429 {'t','e','s','t','4',0}
432 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
433 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
434 ok(session != NULL, "WinHttpOpen failed to open session.\n");
436 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
437 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
439 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
440 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
441 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
443 skip("Network unreachable, skipping.\n");
444 goto done;
446 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
448 index = 0;
449 len = sizeof(buffer);
450 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
451 test_header_name, buffer, &len, &index);
452 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
453 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
454 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
456 index = 0;
457 len = sizeof(buffer);
458 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
459 test_header_name, buffer, &len, &index);
460 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
461 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
462 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
463 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
465 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
466 test_header_name, buffer, &len, &index);
467 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
469 /* Try to fetch the header info with a buffer that's big enough to fit the
470 * string but not the NULL terminator.
472 index = 0;
473 len = 5*sizeof(WCHAR);
474 memset(check_buffer, 0xab, sizeof(check_buffer));
475 memcpy(buffer, check_buffer, sizeof(buffer));
476 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
477 test_header_name, buffer, &len, &index);
478 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
479 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
480 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
481 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
483 /* Try with a NULL buffer */
484 index = 0;
485 len = sizeof(buffer);
486 SetLastError(0xdeadbeef);
487 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
488 test_header_name, NULL, &len, &index);
489 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
490 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
491 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
492 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
494 /* Try with a NULL buffer and a length that's too small */
495 index = 0;
496 len = 10;
497 SetLastError(0xdeadbeef);
498 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
499 test_header_name, NULL, &len, &index);
500 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
501 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
502 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
503 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
504 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
506 index = 0;
507 len = 0;
508 SetLastError(0xdeadbeef);
509 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
510 test_header_name, NULL, &len, &index);
511 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
512 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
513 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
514 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
515 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
517 /* valid query */
518 oldlen = len;
519 index = 0;
520 len = sizeof(buffer);
521 memset(buffer, 0xff, sizeof(buffer));
522 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
523 test_header_name, buffer, &len, &index);
524 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
525 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
526 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
527 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
528 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
529 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
530 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
531 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
532 "WinHttpQueryHeaders returned invalid end of header string.\n");
533 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
535 index = 0;
536 len = 0;
537 SetLastError(0xdeadbeef);
538 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | 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 oldlen = len;
547 index = 0;
548 len = sizeof(buffer);
549 memset(buffer, 0xff, sizeof(buffer));
550 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
551 test_header_name, buffer, &len, &index);
552 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
553 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
554 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
555 "no double NULL terminator\n");
556 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
557 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
558 "invalid beginning of header string.\n");
559 ok(index == 0, "header index was incremented\n");
561 /* tests for more indices */
562 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
563 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
565 index = 0;
566 len = sizeof(buffer);
567 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
568 test_header_name, buffer, &len, &index);
569 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
570 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
571 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
573 len = sizeof(buffer);
574 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
575 test_header_name, buffer, &len, &index);
576 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
577 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
578 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
580 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
581 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
583 index = 0;
584 len = sizeof(buffer);
585 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
586 test_header_name, buffer, &len, &index);
587 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
588 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
589 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
590 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
592 len = sizeof(buffer);
593 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
594 test_header_name, buffer, &len, &index);
595 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
596 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
597 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
599 /* add if new flag */
600 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
601 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
603 index = 0;
604 len = sizeof(buffer);
605 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
606 test_header_name, buffer, &len, &index);
607 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
608 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
609 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
611 len = sizeof(buffer);
612 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
613 test_header_name, buffer, &len, &index);
614 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
615 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
616 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
618 len = sizeof(buffer);
619 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
620 test_header_name, buffer, &len, &index);
621 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
623 /* coalesce flag */
624 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
625 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
627 index = 0;
628 len = sizeof(buffer);
629 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
630 test_header_name, buffer, &len, &index);
631 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
632 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
633 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");
635 len = sizeof(buffer);
636 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
637 test_header_name, buffer, &len, &index);
638 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
639 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
640 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
642 len = sizeof(buffer);
643 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
644 test_header_name, buffer, &len, &index);
645 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
647 /* coalesce with comma flag */
648 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
649 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
651 index = 0;
652 len = sizeof(buffer);
653 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
654 test_header_name, buffer, &len, &index);
655 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
656 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
657 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,
658 "WinHttpQueryHeaders returned incorrect string.\n");
660 len = sizeof(buffer);
661 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
662 test_header_name, buffer, &len, &index);
663 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
664 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
665 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
667 len = sizeof(buffer);
668 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
669 test_header_name, buffer, &len, &index);
670 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
673 /* coalesce with semicolon flag */
674 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
675 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
677 index = 0;
678 len = sizeof(buffer);
679 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
680 test_header_name, buffer, &len, &index);
681 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
682 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
683 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,
684 "WinHttpQueryHeaders returned incorrect string.\n");
686 len = sizeof(buffer);
687 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
688 test_header_name, buffer, &len, &index);
689 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
690 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
691 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
693 len = sizeof(buffer);
694 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
695 test_header_name, buffer, &len, &index);
696 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
698 /* add and replace flags */
699 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
700 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
702 index = 0;
703 len = sizeof(buffer);
704 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
705 test_header_name, buffer, &len, &index);
706 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
707 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
708 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
710 len = sizeof(buffer);
711 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
712 test_header_name, buffer, &len, &index);
713 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
714 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
717 len = sizeof(buffer);
718 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
719 test_header_name, buffer, &len, &index);
720 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
722 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
723 ok(!ret, "WinHttpAddRequestHeaders failed\n");
725 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
726 ok(ret, "WinHttpAddRequestHeaders failed\n");
728 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
729 ok(!ret, "WinHttpAddRequestHeaders failed\n");
731 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
732 ok(!ret, "WinHttpAddRequestHeaders failed\n");
734 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
735 ok(!ret, "WinHttpAddRequestHeaders failed\n");
737 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
738 ok(ret, "WinHttpAddRequestHeaders failed\n");
740 index = 0;
741 buffer[0] = 0;
742 len = sizeof(buffer);
743 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
744 field, buffer, &len, &index);
745 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
746 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
748 ret = WinHttpCloseHandle(request);
749 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
750 done:
751 ret = WinHttpCloseHandle(connection);
752 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
753 ret = WinHttpCloseHandle(session);
754 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
758 static void test_secure_connection(void)
760 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
762 HANDLE ses, con, req;
763 DWORD size, status, policy, bitness;
764 BOOL ret;
765 CERT_CONTEXT *cert;
767 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
768 ok(ses != NULL, "failed to open session %u\n", GetLastError());
770 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
771 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
772 ok(ret, "failed to set redirect policy %u\n", GetLastError());
774 con = WinHttpConnect(ses, google, 443, 0);
775 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
777 /* try without setting WINHTTP_FLAG_SECURE */
778 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
779 ok(req != NULL, "failed to open a request %u\n", GetLastError());
781 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
782 ok(ret, "failed to send request %u\n", GetLastError());
784 ret = WinHttpReceiveResponse(req, NULL);
785 ok(!ret, "succeeded unexpectedly\n");
787 size = 0;
788 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
789 ok(!ret, "succeeded unexpectedly\n");
791 WinHttpCloseHandle(req);
793 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
794 ok(req != NULL, "failed to open a request %u\n", GetLastError());
796 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
797 ok(ret, "failed to send request %u\n", GetLastError());
798 if (!ret)
800 skip("secure connection failed, skipping remaining secure tests\n");
801 goto cleanup;
804 size = sizeof(cert);
805 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
806 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
807 if (ret)
808 CertFreeCertificateContext(cert);
810 size = sizeof(bitness);
811 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
812 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
814 ret = WinHttpReceiveResponse(req, NULL);
815 ok(ret, "failed to receive response %u\n", GetLastError());
817 size = sizeof(status);
818 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
819 ok(ret, "failed unexpectedly %u\n", GetLastError());
820 ok(status == 200, "request failed unexpectedly %u\n", status);
822 size = 0;
823 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
824 ok(!ret, "succeeded unexpectedly\n");
826 cleanup:
827 WinHttpCloseHandle(req);
828 WinHttpCloseHandle(con);
829 WinHttpCloseHandle(ses);
832 static void test_request_parameter_defaults(void)
834 static const WCHAR empty[] = {0};
835 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
837 HANDLE ses, con, req;
838 DWORD size, status, error;
839 WCHAR *version;
840 BOOL ret;
842 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
843 ok(ses != NULL, "failed to open session %u\n", GetLastError());
845 con = WinHttpConnect(ses, codeweavers, 0, 0);
846 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
848 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
849 ok(req != NULL, "failed to open a request %u\n", GetLastError());
851 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
852 ok(ret, "failed to send request %u\n", GetLastError());
854 ret = WinHttpReceiveResponse(req, NULL);
855 ok(ret, "failed to receive response %u\n", GetLastError());
857 size = sizeof(status);
858 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
859 ok(ret, "failed unexpectedly %u\n", GetLastError());
860 ok(status == 200, "request failed unexpectedly %u\n", status);
862 WinHttpCloseHandle(req);
864 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
865 ok(req != NULL, "failed to open a request %u\n", GetLastError());
867 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
868 ok(ret, "failed to send request %u\n", GetLastError());
870 ret = WinHttpReceiveResponse(req, NULL);
871 ok(ret, "failed to receive response %u\n", GetLastError());
873 size = 0;
874 SetLastError(0xdeadbeef);
875 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
876 error = GetLastError();
877 ok(!ret, "succeeded unexpectedly\n");
878 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
880 version = HeapAlloc(GetProcessHeap(), 0, size);
881 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
882 ok(ret, "failed unexpectedly %u\n", GetLastError());
883 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
884 HeapFree(GetProcessHeap(), 0, version);
886 size = sizeof(status);
887 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
888 ok(ret, "failed unexpectedly %u\n", GetLastError());
889 ok(status == 200, "request failed unexpectedly %u\n", status);
891 WinHttpCloseHandle(req);
892 WinHttpCloseHandle(con);
893 WinHttpCloseHandle(ses);
896 static const WCHAR Connections[] = {
897 'S','o','f','t','w','a','r','e','\\',
898 'M','i','c','r','o','s','o','f','t','\\',
899 'W','i','n','d','o','w','s','\\',
900 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
901 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
902 'C','o','n','n','e','c','t','i','o','n','s',0 };
903 static const WCHAR WinHttpSettings[] = {
904 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
906 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
908 LONG l;
909 HKEY key;
910 DWORD ret = 0;
912 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
913 if (!l)
915 DWORD size = 0;
917 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
918 if (!l)
920 if (size <= len)
921 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
922 &size );
923 if (!l)
924 ret = size;
926 RegCloseKey( key );
928 return ret;
931 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
933 LONG l;
934 HKEY key;
936 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
937 KEY_WRITE, NULL, &key, NULL );
938 if (!l)
940 if (len)
941 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
942 else
943 RegDeleteValueW( key, WinHttpSettings );
944 RegCloseKey( key );
948 static void test_set_default_proxy_config(void)
950 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
951 static const WCHAR normalString[] = { 'f','o','o',0 };
952 DWORD type, len;
953 BYTE *saved_proxy_settings = NULL;
954 WINHTTP_PROXY_INFO info;
955 BOOL ret;
957 /* FIXME: it would be simpler to read the current settings using
958 * WinHttpGetDefaultProxyConfiguration and save them using
959 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
961 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
962 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
963 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
964 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
965 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
966 * the lpszProxy and lpszProxyBypass values are ignored.
967 * Thus, if a proxy is set with proxycfg, then calling
968 * WinHttpGetDefaultProxyConfiguration followed by
969 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
970 * getting deleted from the registry.
972 * Instead I read the current registry value and restore it directly.
974 len = get_default_proxy_reg_value( NULL, 0, &type );
975 if (len)
977 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
978 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
981 if (0)
983 /* Crashes on Vista and higher */
984 SetLastError(0xdeadbeef);
985 ret = WinHttpSetDefaultProxyConfiguration(NULL);
986 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
987 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
990 /* test with invalid access type */
991 info.dwAccessType = 0xdeadbeef;
992 info.lpszProxy = info.lpszProxyBypass = NULL;
993 SetLastError(0xdeadbeef);
994 ret = WinHttpSetDefaultProxyConfiguration(&info);
995 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
996 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
998 /* at a minimum, the proxy server must be set */
999 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1000 info.lpszProxy = info.lpszProxyBypass = NULL;
1001 SetLastError(0xdeadbeef);
1002 ret = WinHttpSetDefaultProxyConfiguration(&info);
1003 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1004 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1005 info.lpszProxyBypass = normalString;
1006 SetLastError(0xdeadbeef);
1007 ret = WinHttpSetDefaultProxyConfiguration(&info);
1008 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1009 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1011 /* the proxy server can't have wide characters */
1012 info.lpszProxy = wideString;
1013 SetLastError(0xdeadbeef);
1014 ret = WinHttpSetDefaultProxyConfiguration(&info);
1015 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1016 broken(ret), /* Earlier winhttp versions on W2K/XP */
1017 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1019 info.lpszProxy = normalString;
1020 SetLastError(0xdeadbeef);
1021 ret = WinHttpSetDefaultProxyConfiguration(&info);
1022 if (ret)
1024 ok(ret, "always true\n");
1025 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1027 else if (GetLastError() == ERROR_ACCESS_DENIED)
1028 skip("couldn't set default proxy configuration: access denied\n");
1029 else
1030 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1031 GetLastError());
1034 static void test_Timeouts (void)
1036 BOOL ret;
1037 DWORD value, size;
1038 HINTERNET ses, req, con;
1039 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1042 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1043 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1045 SetLastError(0xdeadbeef);
1046 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1047 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1048 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1050 SetLastError(0xdeadbeef);
1051 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1052 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1053 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1055 SetLastError(0xdeadbeef);
1056 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1057 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1058 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1060 SetLastError(0xdeadbeef);
1061 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1062 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1063 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1065 SetLastError(0xdeadbeef);
1066 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1067 ok(ret, "%u\n", GetLastError());
1069 SetLastError(0xdeadbeef);
1070 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1071 ok(ret, "%u\n", GetLastError());
1073 SetLastError(0xdeadbeef);
1074 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1075 ok(ret, "%u\n", GetLastError());
1077 SetLastError(0xdeadbeef);
1078 value = 0xdeadbeef;
1079 size = sizeof(DWORD);
1080 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1081 ok(ret, "%u\n", GetLastError());
1082 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1084 SetLastError(0xdeadbeef);
1085 value = 0xdeadbeef;
1086 size = sizeof(DWORD);
1087 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1088 ok(ret, "%u\n", GetLastError());
1089 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1091 SetLastError(0xdeadbeef);
1092 value = 0xdeadbeef;
1093 size = sizeof(DWORD);
1094 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1095 ok(ret, "%u\n", GetLastError());
1096 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1098 SetLastError(0xdeadbeef);
1099 value = 0xdeadbeef;
1100 size = sizeof(DWORD);
1101 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1102 ok(ret, "%u\n", GetLastError());
1103 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1105 SetLastError(0xdeadbeef);
1106 value = 0;
1107 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1108 ok(ret, "%u\n", GetLastError());
1110 SetLastError(0xdeadbeef);
1111 value = 0xdeadbeef;
1112 size = sizeof(DWORD);
1113 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1114 ok(ret, "%u\n", GetLastError());
1115 ok(value == 0, "Expected 0, got %u\n", value);
1117 SetLastError(0xdeadbeef);
1118 value = 0;
1119 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1120 ok(ret, "%u\n", GetLastError());
1122 SetLastError(0xdeadbeef);
1123 value = 0xdeadbeef;
1124 size = sizeof(DWORD);
1125 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1126 ok(ret, "%u\n", GetLastError());
1127 ok(value == 0, "Expected 0, got %u\n", value);
1129 SetLastError(0xdeadbeef);
1130 value = 0;
1131 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1132 ok(ret, "%u\n", GetLastError());
1134 SetLastError(0xdeadbeef);
1135 value = 0xdeadbeef;
1136 size = sizeof(DWORD);
1137 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1138 ok(ret, "%u\n", GetLastError());
1139 ok(value == 0, "Expected 0, got %u\n", value);
1141 SetLastError(0xdeadbeef);
1142 value = 0;
1143 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1144 ok(ret, "%u\n", GetLastError());
1146 SetLastError(0xdeadbeef);
1147 value = 0xdeadbeef;
1148 size = sizeof(DWORD);
1149 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1150 ok(ret, "%u\n", GetLastError());
1151 ok(value == 0, "Expected 0, got %u\n", value);
1153 SetLastError(0xdeadbeef);
1154 value = 0xbeefdead;
1155 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1156 ok(ret, "%u\n", GetLastError());
1158 SetLastError(0xdeadbeef);
1159 value = 0xdeadbeef;
1160 size = sizeof(DWORD);
1161 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1162 ok(ret, "%u\n", GetLastError());
1163 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1165 SetLastError(0xdeadbeef);
1166 value = 0xbeefdead;
1167 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1168 ok(ret, "%u\n", GetLastError());
1170 SetLastError(0xdeadbeef);
1171 value = 0xdeadbeef;
1172 size = sizeof(DWORD);
1173 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1174 ok(ret, "%u\n", GetLastError());
1175 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1177 SetLastError(0xdeadbeef);
1178 value = 0xbeefdead;
1179 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1180 ok(ret, "%u\n", GetLastError());
1182 SetLastError(0xdeadbeef);
1183 value = 0xdeadbeef;
1184 size = sizeof(DWORD);
1185 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1186 ok(ret, "%u\n", GetLastError());
1187 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1189 SetLastError(0xdeadbeef);
1190 value = 0xbeefdead;
1191 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1192 ok(ret, "%u\n", GetLastError());
1194 SetLastError(0xdeadbeef);
1195 value = 0xdeadbeef;
1196 size = sizeof(DWORD);
1197 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1198 ok(ret, "%u\n", GetLastError());
1199 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1201 con = WinHttpConnect(ses, codeweavers, 0, 0);
1202 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1204 /* Timeout values should match the last one set for session */
1205 SetLastError(0xdeadbeef);
1206 value = 0xdeadbeef;
1207 size = sizeof(DWORD);
1208 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1209 ok(ret, "%u\n", GetLastError());
1210 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1212 SetLastError(0xdeadbeef);
1213 value = 0xdeadbeef;
1214 size = sizeof(DWORD);
1215 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1216 ok(ret, "%u\n", GetLastError());
1217 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1219 SetLastError(0xdeadbeef);
1220 value = 0xdeadbeef;
1221 size = sizeof(DWORD);
1222 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1223 ok(ret, "%u\n", GetLastError());
1224 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1226 SetLastError(0xdeadbeef);
1227 value = 0xdeadbeef;
1228 size = sizeof(DWORD);
1229 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1230 ok(ret, "%u\n", GetLastError());
1231 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1233 SetLastError(0xdeadbeef);
1234 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1235 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1236 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1238 SetLastError(0xdeadbeef);
1239 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1240 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1241 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1243 SetLastError(0xdeadbeef);
1244 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1245 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1246 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1248 SetLastError(0xdeadbeef);
1249 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1250 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1251 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1253 SetLastError(0xdeadbeef);
1254 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1255 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1256 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1258 SetLastError(0xdeadbeef);
1259 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1260 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1261 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1263 SetLastError(0xdeadbeef);
1264 value = 0;
1265 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1266 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1267 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1269 SetLastError(0xdeadbeef);
1270 value = 0;
1271 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1272 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1273 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1275 SetLastError(0xdeadbeef);
1276 value = 0;
1277 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1278 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1279 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1281 SetLastError(0xdeadbeef);
1282 value = 0;
1283 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1284 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1285 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1287 /* Changing timeout values for session should affect the values for connection */
1288 SetLastError(0xdeadbeef);
1289 value = 0xdead;
1290 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1291 ok(ret, "%u\n", GetLastError());
1293 SetLastError(0xdeadbeef);
1294 value = 0xdeadbeef;
1295 size = sizeof(DWORD);
1296 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1297 ok(ret, "%u\n", GetLastError());
1298 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1300 SetLastError(0xdeadbeef);
1301 value = 0xdead;
1302 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1303 ok(ret, "%u\n", GetLastError());
1305 SetLastError(0xdeadbeef);
1306 value = 0xdeadbeef;
1307 size = sizeof(DWORD);
1308 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1309 ok(ret, "%u\n", GetLastError());
1310 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1312 SetLastError(0xdeadbeef);
1313 value = 0xdead;
1314 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1315 ok(ret, "%u\n", GetLastError());
1317 SetLastError(0xdeadbeef);
1318 value = 0xdeadbeef;
1319 size = sizeof(DWORD);
1320 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1321 ok(ret, "%u\n", GetLastError());
1322 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1324 SetLastError(0xdeadbeef);
1325 value = 0xdead;
1326 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1327 ok(ret, "%u\n", GetLastError());
1329 SetLastError(0xdeadbeef);
1330 value = 0xdeadbeef;
1331 size = sizeof(DWORD);
1332 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1333 ok(ret, "%u\n", GetLastError());
1334 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1336 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1337 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1339 /* Timeout values should match the last one set for session */
1340 SetLastError(0xdeadbeef);
1341 value = 0xdeadbeef;
1342 size = sizeof(DWORD);
1343 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1344 ok(ret, "%u\n", GetLastError());
1345 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1347 SetLastError(0xdeadbeef);
1348 value = 0xdeadbeef;
1349 size = sizeof(DWORD);
1350 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1351 ok(ret, "%u\n", GetLastError());
1352 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1354 SetLastError(0xdeadbeef);
1355 value = 0xdeadbeef;
1356 size = sizeof(DWORD);
1357 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1358 ok(ret, "%u\n", GetLastError());
1359 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1361 SetLastError(0xdeadbeef);
1362 value = 0xdeadbeef;
1363 size = sizeof(DWORD);
1364 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1365 ok(ret, "%u\n", GetLastError());
1366 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1368 SetLastError(0xdeadbeef);
1369 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1370 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1371 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1373 SetLastError(0xdeadbeef);
1374 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1375 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1376 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1378 SetLastError(0xdeadbeef);
1379 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1380 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1381 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1383 SetLastError(0xdeadbeef);
1384 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1385 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1386 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1388 SetLastError(0xdeadbeef);
1389 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1390 ok(ret, "%u\n", GetLastError());
1392 SetLastError(0xdeadbeef);
1393 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1394 ok(ret, "%u\n", GetLastError());
1396 SetLastError(0xdeadbeef);
1397 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1398 ok(ret, "%u\n", GetLastError());
1400 SetLastError(0xdeadbeef);
1401 value = 0xdeadbeef;
1402 size = sizeof(DWORD);
1403 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1404 ok(ret, "%u\n", GetLastError());
1405 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1407 SetLastError(0xdeadbeef);
1408 value = 0xdeadbeef;
1409 size = sizeof(DWORD);
1410 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1411 ok(ret, "%u\n", GetLastError());
1412 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1414 SetLastError(0xdeadbeef);
1415 value = 0xdeadbeef;
1416 size = sizeof(DWORD);
1417 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1418 ok(ret, "%u\n", GetLastError());
1419 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1421 SetLastError(0xdeadbeef);
1422 value = 0xdeadbeef;
1423 size = sizeof(DWORD);
1424 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1425 ok(ret, "%u\n", GetLastError());
1426 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1428 SetLastError(0xdeadbeef);
1429 value = 0;
1430 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1431 ok(ret, "%u\n", GetLastError());
1433 SetLastError(0xdeadbeef);
1434 value = 0xdeadbeef;
1435 size = sizeof(DWORD);
1436 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1437 ok(ret, "%u\n", GetLastError());
1438 ok(value == 0, "Expected 0, got %u\n", value);
1440 SetLastError(0xdeadbeef);
1441 value = 0;
1442 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1443 ok(ret, "%u\n", GetLastError());
1445 SetLastError(0xdeadbeef);
1446 value = 0xdeadbeef;
1447 size = sizeof(DWORD);
1448 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1449 ok(ret, "%u\n", GetLastError());
1450 ok(value == 0, "Expected 0, got %u\n", value);
1452 SetLastError(0xdeadbeef);
1453 value = 0;
1454 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1455 ok(ret, "%u\n", GetLastError());
1457 SetLastError(0xdeadbeef);
1458 value = 0xdeadbeef;
1459 size = sizeof(DWORD);
1460 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1461 ok(ret, "%u\n", GetLastError());
1462 ok(value == 0, "Expected 0, got %u\n", value);
1464 SetLastError(0xdeadbeef);
1465 value = 0;
1466 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1467 ok(ret, "%u\n", GetLastError());
1469 SetLastError(0xdeadbeef);
1470 value = 0xdeadbeef;
1471 size = sizeof(DWORD);
1472 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1473 ok(ret, "%u\n", GetLastError());
1474 ok(value == 0, "Expected 0, got %u\n", value);
1476 SetLastError(0xdeadbeef);
1477 value = 0xbeefdead;
1478 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1479 ok(ret, "%u\n", GetLastError());
1481 SetLastError(0xdeadbeef);
1482 value = 0xdeadbeef;
1483 size = sizeof(DWORD);
1484 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1485 ok(ret, "%u\n", GetLastError());
1486 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1488 SetLastError(0xdeadbeef);
1489 value = 0xbeefdead;
1490 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1491 ok(ret, "%u\n", GetLastError());
1493 SetLastError(0xdeadbeef);
1494 value = 0xdeadbeef;
1495 size = sizeof(DWORD);
1496 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1497 ok(ret, "%u\n", GetLastError());
1498 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1500 SetLastError(0xdeadbeef);
1501 value = 0xbeefdead;
1502 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1503 ok(ret, "%u\n", GetLastError());
1505 SetLastError(0xdeadbeef);
1506 value = 0xdeadbeef;
1507 size = sizeof(DWORD);
1508 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1509 ok(ret, "%u\n", GetLastError());
1510 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1512 SetLastError(0xdeadbeef);
1513 value = 0xbeefdead;
1514 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1515 ok(ret, "%u\n", GetLastError());
1517 SetLastError(0xdeadbeef);
1518 value = 0xdeadbeef;
1519 size = sizeof(DWORD);
1520 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1521 ok(ret, "%u\n", GetLastError());
1522 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1524 /* Changing timeout values for session should not affect the values for a request,
1525 * neither should the other way around.
1527 SetLastError(0xdeadbeef);
1528 value = 0xbeefdead;
1529 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1530 ok(ret, "%u\n", GetLastError());
1532 SetLastError(0xdeadbeef);
1533 value = 0xdeadbeef;
1534 size = sizeof(DWORD);
1535 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1536 ok(ret, "%u\n", GetLastError());
1537 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1539 SetLastError(0xdeadbeef);
1540 value = 0xbeefdead;
1541 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1542 ok(ret, "%u\n", GetLastError());
1544 SetLastError(0xdeadbeef);
1545 value = 0xdeadbeef;
1546 size = sizeof(DWORD);
1547 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1548 ok(ret, "%u\n", GetLastError());
1549 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1551 SetLastError(0xdeadbeef);
1552 value = 0xbeefdead;
1553 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1554 ok(ret, "%u\n", GetLastError());
1556 SetLastError(0xdeadbeef);
1557 value = 0xdeadbeef;
1558 size = sizeof(DWORD);
1559 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1560 ok(ret, "%u\n", GetLastError());
1561 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1563 SetLastError(0xdeadbeef);
1564 value = 0xbeefdead;
1565 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1566 ok(ret, "%u\n", GetLastError());
1568 SetLastError(0xdeadbeef);
1569 value = 0xdeadbeef;
1570 size = sizeof(DWORD);
1571 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1572 ok(ret, "%u\n", GetLastError());
1573 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1575 SetLastError(0xdeadbeef);
1576 value = 0xbeef;
1577 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1578 ok(ret, "%u\n", GetLastError());
1580 SetLastError(0xdeadbeef);
1581 value = 0xdeadbeef;
1582 size = sizeof(DWORD);
1583 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1584 ok(ret, "%u\n", GetLastError());
1585 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1587 SetLastError(0xdeadbeef);
1588 value = 0xbeef;
1589 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1590 ok(ret, "%u\n", GetLastError());
1592 SetLastError(0xdeadbeef);
1593 value = 0xdeadbeef;
1594 size = sizeof(DWORD);
1595 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1596 ok(ret, "%u\n", GetLastError());
1597 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1599 SetLastError(0xdeadbeef);
1600 value = 0xbeef;
1601 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1602 ok(ret, "%u\n", GetLastError());
1604 SetLastError(0xdeadbeef);
1605 value = 0xdeadbeef;
1606 size = sizeof(DWORD);
1607 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1608 ok(ret, "%u\n", GetLastError());
1609 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1611 SetLastError(0xdeadbeef);
1612 value = 0xbeef;
1613 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1614 ok(ret, "%u\n", GetLastError());
1616 SetLastError(0xdeadbeef);
1617 value = 0xdeadbeef;
1618 size = sizeof(DWORD);
1619 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1620 ok(ret, "%u\n", GetLastError());
1621 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1623 WinHttpCloseHandle(req);
1624 WinHttpCloseHandle(con);
1625 WinHttpCloseHandle(ses);
1628 static void test_resolve_timeout(void)
1630 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1631 static const WCHAR srevaewedoc[] = {'s','r','e','v','a','e','w','e','d','o','c','.','m','o','c',0};
1633 HANDLE ses, con, req;
1634 DWORD timeout;
1635 BOOL ret;
1637 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1638 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1640 timeout = 10000;
1641 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1642 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1644 con = WinHttpConnect(ses, srevaewedoc, 0, 0);
1645 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1647 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1648 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1650 SetLastError(0xdeadbeef);
1651 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1652 ok(!ret, "sent request\n");
1653 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED, "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", ret);
1655 WinHttpCloseHandle(req);
1656 WinHttpCloseHandle(con);
1657 WinHttpCloseHandle(ses);
1659 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1660 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1662 timeout = 10000;
1663 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1664 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1666 con = WinHttpConnect(ses, codeweavers, 0, 0);
1667 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1669 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1670 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1672 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1673 ok(ret, "failed to send request\n");
1675 WinHttpCloseHandle(req);
1676 WinHttpCloseHandle(con);
1677 WinHttpCloseHandle(ses);
1680 START_TEST (winhttp)
1682 test_OpenRequest();
1683 test_SendRequest();
1684 test_WinHttpTimeFromSystemTime();
1685 test_WinHttpTimeToSystemTime();
1686 test_WinHttpAddHeaders();
1687 test_secure_connection();
1688 test_request_parameter_defaults();
1689 test_QueryOption();
1690 test_set_default_proxy_config();
1691 test_empty_headers_param();
1692 test_Timeouts();
1693 test_resolve_timeout();