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
30 #include "wine/test.h"
32 static const WCHAR test_useragent[] =
33 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
34 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
35 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
37 static BOOL proxy_active(void)
39 WINHTTP_PROXY_INFO proxy_info;
42 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
44 active = (proxy_info.lpszProxy != NULL);
46 GlobalFree((HGLOBAL) proxy_info.lpszProxy);
47 if (proxy_info.lpszProxyBypass != NULL)
48 GlobalFree((HGLOBAL) proxy_info.lpszProxyBypass);
56 static void test_QueryOption(void)
59 HINTERNET session, request, connection;
62 SetLastError(0xdeadbeef);
63 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
64 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
66 SetLastError(0xdeadbeef);
67 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
68 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
69 ok(GetLastError() == ERROR_INVALID_PARAMETER,
70 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
73 SetLastError(0xdeadbeef);
74 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
75 ok(!ret, "should fail to query option\n");
76 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
77 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
78 ok(size == 4, "expected 4, got %u\n", size);
81 size = sizeof(feature) - 1;
82 SetLastError(0xdeadbeef);
83 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
84 ok(!ret, "should fail to query option\n");
85 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
86 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
87 ok(size == 4, "expected 4, got %u\n", size);
90 size = sizeof(feature) + 1;
91 SetLastError(0xdeadbeef);
92 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
93 ok(ret, "failed to query option %u\n", GetLastError());
94 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
95 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
96 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
98 SetLastError(0xdeadbeef);
99 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
100 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
101 ok(GetLastError() == ERROR_INVALID_PARAMETER,
102 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
104 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
105 SetLastError(0xdeadbeef);
106 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
107 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
108 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
109 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
111 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
112 SetLastError(0xdeadbeef);
113 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
114 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
115 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
116 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
118 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
119 SetLastError(0xdeadbeef);
120 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
121 ok(ret, "failed to set redirect policy %u\n", GetLastError());
123 feature = 0xdeadbeef;
124 size = sizeof(feature);
125 SetLastError(0xdeadbeef);
126 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
127 ok(ret, "failed to query option %u\n", GetLastError());
128 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
129 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
131 feature = WINHTTP_DISABLE_COOKIES;
132 SetLastError(0xdeadbeef);
133 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
134 ok(!ret, "should fail to set disable feature for a session\n");
135 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
136 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
138 SetLastError(0xdeadbeef);
139 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
140 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
142 feature = WINHTTP_DISABLE_COOKIES;
143 SetLastError(0xdeadbeef);
144 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
145 ok(!ret, "should fail to set disable feature for a connection\n");
146 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
147 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
149 SetLastError(0xdeadbeef);
150 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
151 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
152 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
154 skip("Network unreachable, skipping the test\n");
158 feature = 0xdeadbeef;
159 size = sizeof(feature);
160 SetLastError(0xdeadbeef);
161 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
162 ok(!ret, "should fail to query disable feature for a request\n");
163 ok(GetLastError() == ERROR_INVALID_PARAMETER,
164 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
167 size = sizeof(feature);
168 SetLastError(0xdeadbeef);
169 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
170 ok(ret, "failed to set feature %u\n", GetLastError());
172 feature = 0xffffffff;
173 size = sizeof(feature);
174 SetLastError(0xdeadbeef);
175 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
176 ok(ret, "failed to set feature %u\n", GetLastError());
178 feature = WINHTTP_DISABLE_COOKIES;
179 size = sizeof(feature);
180 SetLastError(0xdeadbeef);
181 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
182 ok(ret, "failed to set feature %u\n", GetLastError());
185 SetLastError(0xdeadbeef);
186 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
187 ok(!ret, "should fail to query disable feature for a request\n");
188 ok(GetLastError() == ERROR_INVALID_PARAMETER,
189 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
191 SetLastError(0xdeadbeef);
192 ret = WinHttpCloseHandle(request);
193 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
196 SetLastError(0xdeadbeef);
197 ret = WinHttpCloseHandle(connection);
198 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
199 SetLastError(0xdeadbeef);
200 ret = WinHttpCloseHandle(session);
201 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
204 static void test_OpenRequest (void)
207 HINTERNET session, request, connection;
209 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
210 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
211 ok(session != NULL, "WinHttpOpen failed to open session.\n");
213 /* Test with a bad server name */
214 SetLastError(0xdeadbeef);
215 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
216 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
217 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
219 /* Test with a valid server name */
220 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
221 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
223 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
224 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
225 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
227 skip("Network unreachable, skipping.\n");
230 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
232 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
233 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
235 skip("Connection failed, skipping.\n");
238 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
239 ret = WinHttpCloseHandle(request);
240 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
243 ret = WinHttpCloseHandle(connection);
244 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
245 ret = WinHttpCloseHandle(session);
246 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
250 static void test_empty_headers_param(void)
252 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
253 static const WCHAR empty[] = {0};
254 HINTERNET ses, con, req;
257 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
258 ok(ses != NULL, "failed to open session %u\n", GetLastError());
260 con = WinHttpConnect(ses, winehq, 80, 0);
261 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
263 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
264 ok(req != NULL, "failed to open a request %u\n", GetLastError());
266 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
267 ok(ret, "failed to send request %u\n", GetLastError());
269 WinHttpCloseHandle(req);
270 WinHttpCloseHandle(con);
271 WinHttpCloseHandle(ses);
274 static void test_SendRequest (void)
276 HINTERNET session, request, connection;
277 DWORD header_len, optional_len, total_len, bytes_rw, size;
283 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
284 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
285 static const WCHAR content_type[] =
286 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
287 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
288 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
289 static const WCHAR test_verb[] = {'P','O','S','T',0};
290 static CHAR post_data[] = "mode=Test";
291 static CHAR test_post[] = "mode => Test\\0\n";
294 total_len = optional_len = sizeof(post_data);
295 memset(buffer, 0xff, sizeof(buffer));
297 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
298 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
299 ok(session != NULL, "WinHttpOpen failed to open session.\n");
301 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
302 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
304 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
305 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
306 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
308 skip("Network unreachable, skipping.\n");
311 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
312 if (!request) goto done;
314 context = 0xdeadbeef;
315 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
316 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
319 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
320 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
323 size = sizeof(context);
324 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
325 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
326 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
328 for (i = 3; post_data[i]; i++)
331 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
333 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
334 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
336 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
337 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
341 ret = WinHttpReceiveResponse(request, NULL);
342 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
345 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
346 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
348 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
349 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
351 ret = WinHttpCloseHandle(request);
352 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
354 ret = WinHttpCloseHandle(connection);
355 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
356 ret = WinHttpCloseHandle(session);
357 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
360 static void test_WinHttpTimeFromSystemTime(void)
363 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
364 static const WCHAR expected_string[] =
365 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
366 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
367 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
369 ret = WinHttpTimeFromSystemTime(&time, time_string);
370 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
371 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
372 "Time string returned did not match expected time string.\n");
375 static void test_WinHttpTimeToSystemTime(void)
379 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
380 static const WCHAR time_string1[] =
381 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
382 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
383 static const WCHAR time_string2[] =
384 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
385 '1','0',' ','0','5',' ','5','2','\n',0};
387 ret = WinHttpTimeToSystemTime(time_string1, &time);
388 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
389 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
390 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
392 ret = WinHttpTimeToSystemTime(time_string2, &time);
393 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
394 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
395 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
398 static void test_WinHttpAddHeaders(void)
400 HINTERNET session, request, connection;
402 WCHAR buffer[MAX_PATH];
403 WCHAR check_buffer[MAX_PATH];
404 DWORD index, len, oldlen;
406 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
407 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
408 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
409 static const WCHAR test_verb[] = {'P','O','S','T',0};
411 static const WCHAR test_header_begin[] =
412 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
413 static const WCHAR full_path_test_header_begin[] =
414 {'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'};
415 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
416 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
418 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
419 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
420 static const WCHAR test_flag_coalesce_comma[] =
421 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
422 static const WCHAR test_flag_coalesce_comma_reverse[] =
423 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
424 static const WCHAR test_flag_coalesce_semicolon[] =
425 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
426 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
427 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429 static const WCHAR field[] = {'f','i','e','l','d',0};
430 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
431 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
433 static const WCHAR test_headers[][14] =
435 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
436 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
437 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
438 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
439 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
440 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
441 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
447 {' ','e',' ',':','f',0},
448 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
450 static const WCHAR test_indices[][6] =
452 {'t','e','s','t','1',0},
453 {'t','e','s','t','2',0},
454 {'t','e','s','t','3',0},
455 {'t','e','s','t','4',0}
458 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
459 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
460 ok(session != NULL, "WinHttpOpen failed to open session.\n");
462 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
463 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
465 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
466 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
467 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
469 skip("Network unreachable, skipping.\n");
472 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
475 len = 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, found 'Warning' header.\n");
479 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
480 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
483 len = sizeof(buffer);
484 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
485 test_header_name, buffer, &len, &index);
486 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
487 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
488 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
489 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
491 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
492 test_header_name, buffer, &len, &index);
493 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
495 /* Try to fetch the header info with a buffer that's big enough to fit the
496 * string but not the NULL terminator.
499 len = 5*sizeof(WCHAR);
500 memset(check_buffer, 0xab, sizeof(check_buffer));
501 memcpy(buffer, check_buffer, sizeof(buffer));
502 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
503 test_header_name, buffer, &len, &index);
504 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
505 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
506 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
507 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
509 /* Try with a NULL buffer */
511 len = sizeof(buffer);
512 SetLastError(0xdeadbeef);
513 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
514 test_header_name, NULL, &len, &index);
515 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
516 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
517 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
518 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
520 /* Try with a NULL buffer and a length that's too small */
523 SetLastError(0xdeadbeef);
524 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
525 test_header_name, NULL, &len, &index);
526 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
527 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
528 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
529 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
530 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
534 SetLastError(0xdeadbeef);
535 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
536 test_header_name, NULL, &len, &index);
537 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
538 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
539 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
540 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
541 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
546 len = sizeof(buffer);
547 memset(buffer, 0xff, sizeof(buffer));
548 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
549 test_header_name, buffer, &len, &index);
550 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
551 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
552 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
553 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
554 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
555 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
556 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
557 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
558 "WinHttpQueryHeaders returned invalid end of header string.\n");
559 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
563 SetLastError(0xdeadbeef);
564 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
565 test_header_name, NULL, &len, &index);
566 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
567 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
568 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
569 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
570 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
574 len = sizeof(buffer);
575 memset(buffer, 0xff, sizeof(buffer));
576 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
577 test_header_name, buffer, &len, &index);
578 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
579 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
580 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
581 "no double NULL terminator\n");
582 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
583 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
584 "invalid beginning of header string.\n");
585 ok(index == 0, "header index was incremented\n");
587 /* tests for more indices */
588 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
589 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
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 == 1, "WinHttpQueryHeaders failed to increment index.\n");
597 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
599 len = sizeof(buffer);
600 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
601 test_header_name, buffer, &len, &index);
602 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
603 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
604 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
606 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
607 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
610 len = sizeof(buffer);
611 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
612 test_header_name, buffer, &len, &index);
613 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
614 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
615 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
616 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
622 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
623 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
625 /* add if new flag */
626 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
627 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
630 len = sizeof(buffer);
631 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
632 test_header_name, buffer, &len, &index);
633 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
634 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
635 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
637 len = sizeof(buffer);
638 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
639 test_header_name, buffer, &len, &index);
640 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
641 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
642 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
644 len = sizeof(buffer);
645 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
646 test_header_name, buffer, &len, &index);
647 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
650 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
651 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
654 len = sizeof(buffer);
655 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
656 test_header_name, buffer, &len, &index);
657 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
658 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
659 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");
661 len = sizeof(buffer);
662 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
663 test_header_name, buffer, &len, &index);
664 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
665 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
666 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
668 len = sizeof(buffer);
669 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
670 test_header_name, buffer, &len, &index);
671 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
673 /* coalesce with comma flag */
674 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
675 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
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_comma_reverse : test_flag_coalesce_comma, sizeof(reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma)) == 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");
699 /* coalesce with semicolon flag */
700 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
701 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
704 len = sizeof(buffer);
705 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
706 test_header_name, buffer, &len, &index);
707 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
708 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
709 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,
710 "WinHttpQueryHeaders returned incorrect string.\n");
712 len = sizeof(buffer);
713 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
714 test_header_name, buffer, &len, &index);
715 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
716 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
717 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
719 len = sizeof(buffer);
720 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
721 test_header_name, buffer, &len, &index);
722 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
724 /* add and replace flags */
725 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
726 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
729 len = sizeof(buffer);
730 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
731 test_header_name, buffer, &len, &index);
732 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
733 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
734 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
736 len = sizeof(buffer);
737 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
738 test_header_name, buffer, &len, &index);
739 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
740 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
741 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
743 len = sizeof(buffer);
744 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
745 test_header_name, buffer, &len, &index);
746 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
748 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
749 ok(!ret, "WinHttpAddRequestHeaders failed\n");
751 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
752 ok(ret, "WinHttpAddRequestHeaders failed\n");
754 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
755 ok(!ret, "WinHttpAddRequestHeaders failed\n");
757 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
758 ok(!ret, "WinHttpAddRequestHeaders failed\n");
760 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
761 ok(!ret, "WinHttpAddRequestHeaders failed\n");
763 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
764 ok(ret, "WinHttpAddRequestHeaders failed\n");
768 len = sizeof(buffer);
769 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
770 field, buffer, &len, &index);
771 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
772 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
774 ret = WinHttpCloseHandle(request);
775 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
777 ret = WinHttpCloseHandle(connection);
778 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
779 ret = WinHttpCloseHandle(session);
780 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
784 static void test_secure_connection(void)
786 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
788 HINTERNET ses, con, req;
789 DWORD size, status, policy, bitness;
792 WINHTTP_CERTIFICATE_INFO info;
795 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
796 ok(ses != NULL, "failed to open session %u\n", GetLastError());
798 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
799 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
800 ok(ret, "failed to set redirect policy %u\n", GetLastError());
802 con = WinHttpConnect(ses, google, 443, 0);
803 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
805 /* try without setting WINHTTP_FLAG_SECURE */
806 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
807 ok(req != NULL, "failed to open a request %u\n", GetLastError());
809 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
810 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
812 skip("Connection failed, skipping.\n");
815 ok(ret, "failed to send request %u\n", GetLastError());
817 ret = WinHttpReceiveResponse(req, NULL);
818 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
821 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
822 ok(!ret, "succeeded unexpectedly\n");
824 WinHttpCloseHandle(req);
826 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
827 ok(req != NULL, "failed to open a request %u\n", GetLastError());
829 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
830 ok(ret, "failed to send request %u\n", GetLastError());
833 skip("secure connection failed, skipping remaining secure tests\n");
838 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
839 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
841 CertFreeCertificateContext(cert);
843 size = sizeof(bitness);
844 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
845 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
848 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
849 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
851 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
852 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
853 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
854 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
855 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
856 trace("dwKeySize %u\n", info.dwKeySize);
858 ret = WinHttpReceiveResponse(req, NULL);
859 ok(ret, "failed to receive response %u\n", GetLastError());
861 size = sizeof(status);
862 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
863 ok(ret, "failed unexpectedly %u\n", GetLastError());
864 ok(status == 200, "request failed unexpectedly %u\n", status);
867 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
868 ok(!ret, "succeeded unexpectedly\n");
873 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
878 WinHttpCloseHandle(req);
879 WinHttpCloseHandle(con);
880 WinHttpCloseHandle(ses);
883 static void test_request_parameter_defaults(void)
885 static const WCHAR empty[] = {0};
886 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
888 HINTERNET ses, con, req;
889 DWORD size, status, error;
893 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
894 ok(ses != NULL, "failed to open session %u\n", GetLastError());
896 con = WinHttpConnect(ses, codeweavers, 0, 0);
897 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
899 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
900 ok(req != NULL, "failed to open a request %u\n", GetLastError());
902 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
903 ok(ret, "failed to send request %u\n", GetLastError());
905 ret = WinHttpReceiveResponse(req, NULL);
906 ok(ret, "failed to receive response %u\n", GetLastError());
908 size = sizeof(status);
909 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
910 ok(ret, "failed unexpectedly %u\n", GetLastError());
911 ok(status == 200, "request failed unexpectedly %u\n", status);
913 WinHttpCloseHandle(req);
915 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
916 ok(req != NULL, "failed to open a request %u\n", GetLastError());
918 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
919 ok(ret, "failed to send request %u\n", GetLastError());
921 ret = WinHttpReceiveResponse(req, NULL);
922 ok(ret, "failed to receive response %u\n", GetLastError());
925 SetLastError(0xdeadbeef);
926 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
927 error = GetLastError();
928 ok(!ret, "succeeded unexpectedly\n");
929 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
931 version = HeapAlloc(GetProcessHeap(), 0, size);
932 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
933 ok(ret, "failed unexpectedly %u\n", GetLastError());
934 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
935 HeapFree(GetProcessHeap(), 0, version);
937 size = sizeof(status);
938 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
939 ok(ret, "failed unexpectedly %u\n", GetLastError());
940 ok(status == 200, "request failed unexpectedly %u\n", status);
942 WinHttpCloseHandle(req);
943 WinHttpCloseHandle(con);
944 WinHttpCloseHandle(ses);
947 static const WCHAR Connections[] = {
948 'S','o','f','t','w','a','r','e','\\',
949 'M','i','c','r','o','s','o','f','t','\\',
950 'W','i','n','d','o','w','s','\\',
951 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
952 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
953 'C','o','n','n','e','c','t','i','o','n','s',0 };
954 static const WCHAR WinHttpSettings[] = {
955 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
957 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
963 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
968 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
972 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
982 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
987 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
988 KEY_WRITE, NULL, &key, NULL );
992 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
994 RegDeleteValueW( key, WinHttpSettings );
999 static void test_set_default_proxy_config(void)
1001 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1002 static const WCHAR normalString[] = { 'f','o','o',0 };
1004 BYTE *saved_proxy_settings = NULL;
1005 WINHTTP_PROXY_INFO info;
1008 /* FIXME: it would be simpler to read the current settings using
1009 * WinHttpGetDefaultProxyConfiguration and save them using
1010 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1012 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1013 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1014 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1015 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1016 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1017 * the lpszProxy and lpszProxyBypass values are ignored.
1018 * Thus, if a proxy is set with proxycfg, then calling
1019 * WinHttpGetDefaultProxyConfiguration followed by
1020 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1021 * getting deleted from the registry.
1023 * Instead I read the current registry value and restore it directly.
1025 len = get_default_proxy_reg_value( NULL, 0, &type );
1028 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1029 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1034 /* Crashes on Vista and higher */
1035 SetLastError(0xdeadbeef);
1036 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1037 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1038 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1041 /* test with invalid access type */
1042 info.dwAccessType = 0xdeadbeef;
1043 info.lpszProxy = info.lpszProxyBypass = NULL;
1044 SetLastError(0xdeadbeef);
1045 ret = WinHttpSetDefaultProxyConfiguration(&info);
1046 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1047 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1049 /* at a minimum, the proxy server must be set */
1050 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1051 info.lpszProxy = info.lpszProxyBypass = NULL;
1052 SetLastError(0xdeadbeef);
1053 ret = WinHttpSetDefaultProxyConfiguration(&info);
1054 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1055 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1056 info.lpszProxyBypass = normalString;
1057 SetLastError(0xdeadbeef);
1058 ret = WinHttpSetDefaultProxyConfiguration(&info);
1059 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1060 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1062 /* the proxy server can't have wide characters */
1063 info.lpszProxy = wideString;
1064 SetLastError(0xdeadbeef);
1065 ret = WinHttpSetDefaultProxyConfiguration(&info);
1066 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1067 broken(ret), /* Earlier winhttp versions on W2K/XP */
1068 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1070 info.lpszProxy = normalString;
1071 SetLastError(0xdeadbeef);
1072 ret = WinHttpSetDefaultProxyConfiguration(&info);
1075 ok(ret, "always true\n");
1076 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1078 else if (GetLastError() == ERROR_ACCESS_DENIED)
1079 skip("couldn't set default proxy configuration: access denied\n");
1081 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1085 static void test_Timeouts (void)
1089 HINTERNET ses, req, con;
1090 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1093 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1094 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1096 SetLastError(0xdeadbeef);
1097 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1098 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1099 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1101 SetLastError(0xdeadbeef);
1102 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1103 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1104 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1106 SetLastError(0xdeadbeef);
1107 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1108 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1109 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1111 SetLastError(0xdeadbeef);
1112 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1113 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1114 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1116 SetLastError(0xdeadbeef);
1117 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1118 ok(ret, "%u\n", GetLastError());
1120 SetLastError(0xdeadbeef);
1121 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1122 ok(ret, "%u\n", GetLastError());
1124 SetLastError(0xdeadbeef);
1125 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1126 ok(ret, "%u\n", GetLastError());
1128 SetLastError(0xdeadbeef);
1130 size = sizeof(DWORD);
1131 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1132 ok(ret, "%u\n", GetLastError());
1133 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1135 SetLastError(0xdeadbeef);
1137 size = sizeof(DWORD);
1138 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1139 ok(ret, "%u\n", GetLastError());
1140 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1142 SetLastError(0xdeadbeef);
1144 size = sizeof(DWORD);
1145 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1146 ok(ret, "%u\n", GetLastError());
1147 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1149 SetLastError(0xdeadbeef);
1151 size = sizeof(DWORD);
1152 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1153 ok(ret, "%u\n", GetLastError());
1154 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1156 SetLastError(0xdeadbeef);
1158 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1159 ok(ret, "%u\n", GetLastError());
1161 SetLastError(0xdeadbeef);
1163 size = sizeof(DWORD);
1164 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1165 ok(ret, "%u\n", GetLastError());
1166 ok(value == 0, "Expected 0, got %u\n", value);
1168 SetLastError(0xdeadbeef);
1170 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1171 ok(ret, "%u\n", GetLastError());
1173 SetLastError(0xdeadbeef);
1175 size = sizeof(DWORD);
1176 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1177 ok(ret, "%u\n", GetLastError());
1178 ok(value == 0, "Expected 0, got %u\n", value);
1180 SetLastError(0xdeadbeef);
1182 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1183 ok(ret, "%u\n", GetLastError());
1185 SetLastError(0xdeadbeef);
1187 size = sizeof(DWORD);
1188 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1189 ok(ret, "%u\n", GetLastError());
1190 ok(value == 0, "Expected 0, got %u\n", value);
1192 SetLastError(0xdeadbeef);
1194 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1195 ok(ret, "%u\n", GetLastError());
1197 SetLastError(0xdeadbeef);
1199 size = sizeof(DWORD);
1200 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1201 ok(ret, "%u\n", GetLastError());
1202 ok(value == 0, "Expected 0, got %u\n", value);
1204 SetLastError(0xdeadbeef);
1206 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1207 ok(ret, "%u\n", GetLastError());
1209 SetLastError(0xdeadbeef);
1211 size = sizeof(DWORD);
1212 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1213 ok(ret, "%u\n", GetLastError());
1214 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1216 SetLastError(0xdeadbeef);
1218 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1219 ok(ret, "%u\n", GetLastError());
1221 SetLastError(0xdeadbeef);
1223 size = sizeof(DWORD);
1224 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1225 ok(ret, "%u\n", GetLastError());
1226 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1228 SetLastError(0xdeadbeef);
1230 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1231 ok(ret, "%u\n", GetLastError());
1233 SetLastError(0xdeadbeef);
1235 size = sizeof(DWORD);
1236 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1237 ok(ret, "%u\n", GetLastError());
1238 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1240 SetLastError(0xdeadbeef);
1242 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1243 ok(ret, "%u\n", GetLastError());
1245 SetLastError(0xdeadbeef);
1247 size = sizeof(DWORD);
1248 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1249 ok(ret, "%u\n", GetLastError());
1250 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1252 con = WinHttpConnect(ses, codeweavers, 0, 0);
1253 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1255 /* Timeout values should match the last one set for session */
1256 SetLastError(0xdeadbeef);
1258 size = sizeof(DWORD);
1259 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1260 ok(ret, "%u\n", GetLastError());
1261 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1263 SetLastError(0xdeadbeef);
1265 size = sizeof(DWORD);
1266 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1267 ok(ret, "%u\n", GetLastError());
1268 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1270 SetLastError(0xdeadbeef);
1272 size = sizeof(DWORD);
1273 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1274 ok(ret, "%u\n", GetLastError());
1275 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1277 SetLastError(0xdeadbeef);
1279 size = sizeof(DWORD);
1280 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1281 ok(ret, "%u\n", GetLastError());
1282 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1284 SetLastError(0xdeadbeef);
1285 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1286 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1287 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1289 SetLastError(0xdeadbeef);
1290 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1291 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1292 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1294 SetLastError(0xdeadbeef);
1295 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1296 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1297 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1299 SetLastError(0xdeadbeef);
1300 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1301 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1302 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1304 SetLastError(0xdeadbeef);
1305 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1306 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1307 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1309 SetLastError(0xdeadbeef);
1310 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1311 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1312 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1314 SetLastError(0xdeadbeef);
1316 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1317 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1318 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1320 SetLastError(0xdeadbeef);
1322 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1323 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1324 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1326 SetLastError(0xdeadbeef);
1328 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1329 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1330 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1332 SetLastError(0xdeadbeef);
1334 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1335 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1336 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1338 /* Changing timeout values for session should affect the values for connection */
1339 SetLastError(0xdeadbeef);
1341 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1342 ok(ret, "%u\n", GetLastError());
1344 SetLastError(0xdeadbeef);
1346 size = sizeof(DWORD);
1347 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1348 ok(ret, "%u\n", GetLastError());
1349 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1351 SetLastError(0xdeadbeef);
1353 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1354 ok(ret, "%u\n", GetLastError());
1356 SetLastError(0xdeadbeef);
1358 size = sizeof(DWORD);
1359 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1360 ok(ret, "%u\n", GetLastError());
1361 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1363 SetLastError(0xdeadbeef);
1365 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1366 ok(ret, "%u\n", GetLastError());
1368 SetLastError(0xdeadbeef);
1370 size = sizeof(DWORD);
1371 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1372 ok(ret, "%u\n", GetLastError());
1373 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1375 SetLastError(0xdeadbeef);
1377 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1378 ok(ret, "%u\n", GetLastError());
1380 SetLastError(0xdeadbeef);
1382 size = sizeof(DWORD);
1383 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1384 ok(ret, "%u\n", GetLastError());
1385 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1387 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1388 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1390 /* Timeout values should match the last one set for session */
1391 SetLastError(0xdeadbeef);
1393 size = sizeof(DWORD);
1394 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1395 ok(ret, "%u\n", GetLastError());
1396 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1398 SetLastError(0xdeadbeef);
1400 size = sizeof(DWORD);
1401 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1402 ok(ret, "%u\n", GetLastError());
1403 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1405 SetLastError(0xdeadbeef);
1407 size = sizeof(DWORD);
1408 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1409 ok(ret, "%u\n", GetLastError());
1410 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1412 SetLastError(0xdeadbeef);
1414 size = sizeof(DWORD);
1415 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1416 ok(ret, "%u\n", GetLastError());
1417 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1419 SetLastError(0xdeadbeef);
1420 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1421 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1422 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1424 SetLastError(0xdeadbeef);
1425 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1426 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1427 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1429 SetLastError(0xdeadbeef);
1430 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1431 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1432 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1434 SetLastError(0xdeadbeef);
1435 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1436 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1437 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1439 SetLastError(0xdeadbeef);
1440 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1441 ok(ret, "%u\n", GetLastError());
1443 SetLastError(0xdeadbeef);
1444 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1445 ok(ret, "%u\n", GetLastError());
1447 SetLastError(0xdeadbeef);
1448 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1449 ok(ret, "%u\n", GetLastError());
1451 SetLastError(0xdeadbeef);
1453 size = sizeof(DWORD);
1454 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1455 ok(ret, "%u\n", GetLastError());
1456 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1458 SetLastError(0xdeadbeef);
1460 size = sizeof(DWORD);
1461 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1462 ok(ret, "%u\n", GetLastError());
1463 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1465 SetLastError(0xdeadbeef);
1467 size = sizeof(DWORD);
1468 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1469 ok(ret, "%u\n", GetLastError());
1470 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1472 SetLastError(0xdeadbeef);
1474 size = sizeof(DWORD);
1475 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1476 ok(ret, "%u\n", GetLastError());
1477 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1479 SetLastError(0xdeadbeef);
1481 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1482 ok(ret, "%u\n", GetLastError());
1484 SetLastError(0xdeadbeef);
1486 size = sizeof(DWORD);
1487 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1488 ok(ret, "%u\n", GetLastError());
1489 ok(value == 0, "Expected 0, got %u\n", value);
1491 SetLastError(0xdeadbeef);
1493 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1494 ok(ret, "%u\n", GetLastError());
1496 SetLastError(0xdeadbeef);
1498 size = sizeof(DWORD);
1499 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1500 ok(ret, "%u\n", GetLastError());
1501 ok(value == 0, "Expected 0, got %u\n", value);
1503 SetLastError(0xdeadbeef);
1505 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1506 ok(ret, "%u\n", GetLastError());
1508 SetLastError(0xdeadbeef);
1510 size = sizeof(DWORD);
1511 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1512 ok(ret, "%u\n", GetLastError());
1513 ok(value == 0, "Expected 0, got %u\n", value);
1515 SetLastError(0xdeadbeef);
1517 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1518 ok(ret, "%u\n", GetLastError());
1520 SetLastError(0xdeadbeef);
1522 size = sizeof(DWORD);
1523 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1524 ok(ret, "%u\n", GetLastError());
1525 ok(value == 0, "Expected 0, got %u\n", value);
1527 SetLastError(0xdeadbeef);
1529 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1530 ok(ret, "%u\n", GetLastError());
1532 SetLastError(0xdeadbeef);
1534 size = sizeof(DWORD);
1535 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1536 ok(ret, "%u\n", GetLastError());
1537 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1539 SetLastError(0xdeadbeef);
1541 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1542 ok(ret, "%u\n", GetLastError());
1544 SetLastError(0xdeadbeef);
1546 size = sizeof(DWORD);
1547 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1548 ok(ret, "%u\n", GetLastError());
1549 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1551 SetLastError(0xdeadbeef);
1553 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1554 ok(ret, "%u\n", GetLastError());
1556 SetLastError(0xdeadbeef);
1558 size = sizeof(DWORD);
1559 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1560 ok(ret, "%u\n", GetLastError());
1561 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1563 SetLastError(0xdeadbeef);
1565 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1566 ok(ret, "%u\n", GetLastError());
1568 SetLastError(0xdeadbeef);
1570 size = sizeof(DWORD);
1571 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1572 ok(ret, "%u\n", GetLastError());
1573 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1575 /* Changing timeout values for session should not affect the values for a request,
1576 * neither should the other way around.
1578 SetLastError(0xdeadbeef);
1580 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1581 ok(ret, "%u\n", GetLastError());
1583 SetLastError(0xdeadbeef);
1585 size = sizeof(DWORD);
1586 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1587 ok(ret, "%u\n", GetLastError());
1588 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1590 SetLastError(0xdeadbeef);
1592 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1593 ok(ret, "%u\n", GetLastError());
1595 SetLastError(0xdeadbeef);
1597 size = sizeof(DWORD);
1598 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1599 ok(ret, "%u\n", GetLastError());
1600 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1602 SetLastError(0xdeadbeef);
1604 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1605 ok(ret, "%u\n", GetLastError());
1607 SetLastError(0xdeadbeef);
1609 size = sizeof(DWORD);
1610 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1611 ok(ret, "%u\n", GetLastError());
1612 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1614 SetLastError(0xdeadbeef);
1616 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1617 ok(ret, "%u\n", GetLastError());
1619 SetLastError(0xdeadbeef);
1621 size = sizeof(DWORD);
1622 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1623 ok(ret, "%u\n", GetLastError());
1624 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1626 SetLastError(0xdeadbeef);
1628 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1629 ok(ret, "%u\n", GetLastError());
1631 SetLastError(0xdeadbeef);
1633 size = sizeof(DWORD);
1634 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1635 ok(ret, "%u\n", GetLastError());
1636 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1638 SetLastError(0xdeadbeef);
1640 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1641 ok(ret, "%u\n", GetLastError());
1643 SetLastError(0xdeadbeef);
1645 size = sizeof(DWORD);
1646 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1647 ok(ret, "%u\n", GetLastError());
1648 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1650 SetLastError(0xdeadbeef);
1652 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1653 ok(ret, "%u\n", GetLastError());
1655 SetLastError(0xdeadbeef);
1657 size = sizeof(DWORD);
1658 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1659 ok(ret, "%u\n", GetLastError());
1660 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1662 SetLastError(0xdeadbeef);
1664 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1665 ok(ret, "%u\n", GetLastError());
1667 SetLastError(0xdeadbeef);
1669 size = sizeof(DWORD);
1670 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1671 ok(ret, "%u\n", GetLastError());
1672 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1674 WinHttpCloseHandle(req);
1675 WinHttpCloseHandle(con);
1676 WinHttpCloseHandle(ses);
1679 static void test_resolve_timeout(void)
1681 static const WCHAR codeweavers[] =
1682 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1683 static const WCHAR nxdomain[] =
1684 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1686 HINTERNET ses, con, req;
1690 if (! proxy_active())
1692 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1693 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1696 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1697 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1699 con = WinHttpConnect(ses, nxdomain, 0, 0);
1700 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1702 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1703 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1705 SetLastError(0xdeadbeef);
1706 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1707 ok(!ret, "sent request\n");
1708 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1709 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1711 WinHttpCloseHandle(req);
1712 WinHttpCloseHandle(con);
1713 WinHttpCloseHandle(ses);
1716 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1718 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1719 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1722 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1723 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1725 con = WinHttpConnect(ses, codeweavers, 0, 0);
1726 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1728 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1729 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1731 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1732 ok(ret, "failed to send request\n");
1734 WinHttpCloseHandle(req);
1735 WinHttpCloseHandle(con);
1736 WinHttpCloseHandle(ses);
1739 static const char page1[] =
1741 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1742 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1745 static const char okmsg[] =
1746 "HTTP/1.1 200 OK\r\n"
1747 "Server: winetest\r\n"
1750 static const char notokmsg[] =
1751 "HTTP/1.1 400 Bad Request\r\n"
1752 "Server: winetest\r\n"
1755 static const char noauthmsg[] =
1756 "HTTP/1.1 401 Unauthorized\r\n"
1757 "Server: winetest\r\n"
1758 "Connection: close\r\n"
1759 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1762 static const char proxymsg[] =
1763 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1764 "Server: winetest\r\n"
1765 "Proxy-Connection: close\r\n"
1766 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1775 static DWORD CALLBACK server_thread(LPVOID param)
1777 struct server_info *si = param;
1780 struct sockaddr_in sa;
1783 int last_request = 0;
1785 WSAStartup(MAKEWORD(1,1), &wsaData);
1787 s = socket(AF_INET, SOCK_STREAM, 0);
1788 if (s == INVALID_SOCKET)
1792 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1794 memset(&sa, 0, sizeof sa);
1795 sa.sin_family = AF_INET;
1796 sa.sin_port = htons(si->port);
1797 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1799 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1804 SetEvent(si->event);
1807 c = accept(s, NULL, NULL);
1809 memset(buffer, 0, sizeof buffer);
1810 for(i = 0; i < sizeof buffer - 1; i++)
1812 r = recv(c, &buffer[i], 1, 0);
1815 if (i < 4) continue;
1816 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1817 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1820 if (strstr(buffer, "GET /basic"))
1822 send(c, okmsg, sizeof okmsg - 1, 0);
1823 send(c, page1, sizeof page1 - 1, 0);
1825 if (strstr(buffer, "/auth"))
1827 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1828 send(c, okmsg, sizeof okmsg - 1, 0);
1830 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1832 if (strstr(buffer, "/no_headers"))
1834 send(c, page1, sizeof page1 - 1, 0);
1836 if (strstr(buffer, "GET /quit"))
1838 send(c, okmsg, sizeof okmsg - 1, 0);
1839 send(c, page1, sizeof page1 - 1, 0);
1845 } while (!last_request);
1851 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1853 HINTERNET ses, con, req;
1855 DWORD count, status, size;
1858 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1859 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1861 con = WinHttpConnect(ses, localhostW, port, 0);
1862 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1864 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1865 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1867 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1868 ok(ret, "failed to send request %u\n", GetLastError());
1870 ret = WinHttpReceiveResponse(req, NULL);
1871 ok(ret, "failed to receive response %u\n", GetLastError());
1873 size = sizeof(status);
1874 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1875 ok(ret, "failed to query status code %u\n", GetLastError());
1876 ok(status == 200, "request failed unexpectedly %u\n", status);
1879 memset(buffer, 0, sizeof(buffer));
1880 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1881 ok(ret, "failed to read data %u\n", GetLastError());
1882 ok(count == sizeof page1 - 1, "count was wrong\n");
1883 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1885 WinHttpCloseHandle(req);
1886 WinHttpCloseHandle(con);
1887 WinHttpCloseHandle(ses);
1890 static void test_basic_authentication(int port)
1892 static const WCHAR authW[] = {'/','a','u','t','h',0};
1893 static const WCHAR userW[] = {'u','s','e','r',0};
1894 static const WCHAR passW[] = {'p','w','d',0};
1895 HINTERNET ses, con, req;
1896 DWORD status, size, error;
1899 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1900 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1902 con = WinHttpConnect(ses, localhostW, port, 0);
1903 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1905 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1906 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1908 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1909 ok(ret, "failed to send request %u\n", GetLastError());
1911 ret = WinHttpReceiveResponse(req, NULL);
1912 ok(ret, "failed to receive response %u\n", GetLastError());
1914 size = sizeof(status);
1915 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1916 ok(ret, "failed to query status code %u\n", GetLastError());
1917 ok(status == 401, "request failed unexpectedly %u\n", status);
1919 SetLastError(0xdeadbeef);
1920 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1921 error = GetLastError();
1922 ok(!ret, "expected failure\n");
1923 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1925 SetLastError(0xdeadbeef);
1926 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1927 error = GetLastError();
1928 ok(!ret, "expected failure\n");
1929 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1931 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1932 ok(ret, "failed to set credentials %u\n", GetLastError());
1934 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1935 ok(ret, "failed to send request %u\n", GetLastError());
1937 ret = WinHttpReceiveResponse(req, NULL);
1938 ok(ret, "failed to receive response %u\n", GetLastError());
1940 size = sizeof(status);
1941 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1942 ok(ret, "failed to query status code %u\n", GetLastError());
1943 ok(status == 200, "request failed unexpectedly %u\n", status);
1945 WinHttpCloseHandle(req);
1946 WinHttpCloseHandle(con);
1947 WinHttpCloseHandle(ses);
1950 static void test_no_headers(int port)
1952 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1953 HINTERNET ses, con, req;
1956 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1957 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1959 con = WinHttpConnect(ses, localhostW, port, 0);
1960 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1962 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1963 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1965 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1966 ok(ret, "failed to send request %u\n", GetLastError());
1968 ret = WinHttpReceiveResponse(req, NULL);
1969 ok(!ret, "expected failure\n");
1971 WinHttpCloseHandle(req);
1972 WinHttpCloseHandle(con);
1973 WinHttpCloseHandle(ses);
1976 static void test_credentials(void)
1978 static WCHAR userW[] = {'u','s','e','r',0};
1979 static WCHAR passW[] = {'p','a','s','s',0};
1980 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
1981 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
1982 HINTERNET ses, con, req;
1987 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
1988 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1990 con = WinHttpConnect(ses, localhostW, 0, 0);
1991 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1993 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1994 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1996 size = sizeof(buffer)/sizeof(WCHAR);
1997 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
1998 ok(ret, "failed to query proxy username %u\n", GetLastError());
1999 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2000 ok(!size, "expected 0, got %u\n", size);
2002 size = sizeof(buffer)/sizeof(WCHAR);
2003 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2004 ok(ret, "failed to query proxy password %u\n", GetLastError());
2005 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2006 ok(!size, "expected 0, got %u\n", size);
2008 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2009 ok(ret, "failed to set username %u\n", GetLastError());
2011 size = sizeof(buffer)/sizeof(WCHAR);
2012 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2013 ok(ret, "failed to query proxy username %u\n", GetLastError());
2014 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2015 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2017 size = sizeof(buffer)/sizeof(WCHAR);
2018 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2019 ok(ret, "failed to query username %u\n", GetLastError());
2020 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2021 ok(!size, "expected 0, got %u\n", size);
2023 size = sizeof(buffer)/sizeof(WCHAR);
2024 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2025 ok(ret, "failed to query password %u\n", GetLastError());
2026 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2027 ok(!size, "expected 0, got %u\n", size);
2029 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2030 ok(ret, "failed to set proxy password %u\n", GetLastError());
2032 size = sizeof(buffer)/sizeof(WCHAR);
2033 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2034 ok(ret, "failed to query proxy password %u\n", GetLastError());
2035 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2036 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2038 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2039 ok(ret, "failed to set username %u\n", GetLastError());
2041 size = sizeof(buffer)/sizeof(WCHAR);
2042 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2043 ok(ret, "failed to query username %u\n", GetLastError());
2044 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2045 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2047 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2048 ok(ret, "failed to set password %u\n", GetLastError());
2050 size = sizeof(buffer)/sizeof(WCHAR);
2051 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2052 ok(ret, "failed to query password %u\n", GetLastError());
2053 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2054 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2056 WinHttpCloseHandle(req);
2058 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2059 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2061 SetLastError(0xdeadbeef);
2062 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2063 error = GetLastError();
2064 ok(!ret, "expected failure\n");
2065 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2067 SetLastError(0xdeadbeef);
2068 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2069 error = GetLastError();
2070 ok(!ret, "expected failure\n");
2071 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2073 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2074 ok(ret, "failed to set credentials %u\n", GetLastError());
2076 size = sizeof(buffer)/sizeof(WCHAR);
2077 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2078 ok(ret, "failed to query username %u\n", GetLastError());
2080 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2081 ok(!size, "expected 0, got %u\n", size);
2084 size = sizeof(buffer)/sizeof(WCHAR);
2085 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2086 ok(ret, "failed to query password %u\n", GetLastError());
2088 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2089 ok(!size, "expected 0, got %u\n", size);
2092 WinHttpCloseHandle(req);
2093 WinHttpCloseHandle(con);
2094 WinHttpCloseHandle(ses);
2097 START_TEST (winhttp)
2099 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2100 static const WCHAR quitW[] = {'/','q','u','i','t',0};
2101 struct server_info si;
2107 test_WinHttpTimeFromSystemTime();
2108 test_WinHttpTimeToSystemTime();
2109 test_WinHttpAddHeaders();
2110 test_secure_connection();
2111 test_request_parameter_defaults();
2113 test_set_default_proxy_config();
2114 test_empty_headers_param();
2116 test_resolve_timeout();
2119 si.event = CreateEvent(NULL, 0, 0, NULL);
2122 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2123 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2125 ret = WaitForSingleObject(si.event, 10000);
2126 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2127 if (ret != WAIT_OBJECT_0)
2130 test_basic_request(si.port, NULL, basicW);
2131 test_no_headers(si.port);
2132 test_basic_authentication(si.port);
2134 /* send the basic request again to shutdown the server thread */
2135 test_basic_request(si.port, NULL, quitW);
2137 WaitForSingleObject(thread, 3000);