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 void test_QueryOption(void)
40 HINTERNET session, request, connection;
43 SetLastError(0xdeadbeef);
44 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
45 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
47 SetLastError(0xdeadbeef);
48 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
49 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
50 ok(GetLastError() == ERROR_INVALID_PARAMETER,
51 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
54 SetLastError(0xdeadbeef);
55 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
56 ok(!ret, "should fail to query option\n");
57 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
58 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
59 ok(size == 4, "expected 4, got %u\n", size);
62 size = sizeof(feature) - 1;
63 SetLastError(0xdeadbeef);
64 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
65 ok(!ret, "should fail to query option\n");
66 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
67 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
68 ok(size == 4, "expected 4, got %u\n", size);
71 size = sizeof(feature) + 1;
72 SetLastError(0xdeadbeef);
73 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
74 ok(ret, "failed to query option %u\n", GetLastError());
75 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
76 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
77 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
79 SetLastError(0xdeadbeef);
80 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
81 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
82 ok(GetLastError() == ERROR_INVALID_PARAMETER,
83 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
85 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
86 SetLastError(0xdeadbeef);
87 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
88 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
89 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
90 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
92 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
93 SetLastError(0xdeadbeef);
94 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
95 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
96 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
97 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
99 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
100 SetLastError(0xdeadbeef);
101 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
102 ok(ret, "failed to set redirect policy %u\n", GetLastError());
104 feature = 0xdeadbeef;
105 size = sizeof(feature);
106 SetLastError(0xdeadbeef);
107 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
108 ok(ret, "failed to query option %u\n", GetLastError());
109 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
110 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
112 feature = WINHTTP_DISABLE_COOKIES;
113 SetLastError(0xdeadbeef);
114 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
115 ok(!ret, "should fail to set disable feature for a session\n");
116 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
117 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
119 SetLastError(0xdeadbeef);
120 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
121 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
123 feature = WINHTTP_DISABLE_COOKIES;
124 SetLastError(0xdeadbeef);
125 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
126 ok(!ret, "should fail to set disable feature for a connection\n");
127 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
128 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
130 SetLastError(0xdeadbeef);
131 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
132 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
133 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
135 skip("Network unreachable, skipping the test\n");
139 feature = 0xdeadbeef;
140 size = sizeof(feature);
141 SetLastError(0xdeadbeef);
142 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
143 ok(!ret, "should fail to query disable feature for a request\n");
144 ok(GetLastError() == ERROR_INVALID_PARAMETER,
145 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
148 size = sizeof(feature);
149 SetLastError(0xdeadbeef);
150 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
151 ok(ret, "failed to set feature %u\n", GetLastError());
153 feature = 0xffffffff;
154 size = sizeof(feature);
155 SetLastError(0xdeadbeef);
156 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
157 ok(ret, "failed to set feature %u\n", GetLastError());
159 feature = WINHTTP_DISABLE_COOKIES;
160 size = sizeof(feature);
161 SetLastError(0xdeadbeef);
162 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
163 ok(ret, "failed to set feature %u\n", GetLastError());
166 SetLastError(0xdeadbeef);
167 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
168 ok(!ret, "should fail to query disable feature for a request\n");
169 ok(GetLastError() == ERROR_INVALID_PARAMETER,
170 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
172 SetLastError(0xdeadbeef);
173 ret = WinHttpCloseHandle(request);
174 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
177 SetLastError(0xdeadbeef);
178 ret = WinHttpCloseHandle(connection);
179 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
180 SetLastError(0xdeadbeef);
181 ret = WinHttpCloseHandle(session);
182 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
185 static void test_OpenRequest (void)
188 HINTERNET session, request, connection;
190 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
191 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
192 ok(session != NULL, "WinHttpOpen failed to open session.\n");
194 /* Test with a bad server name */
195 SetLastError(0xdeadbeef);
196 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
197 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
198 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
200 /* Test with a valid server name */
201 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
202 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
204 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
205 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
206 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
208 skip("Network unreachable, skipping.\n");
211 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
213 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
214 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
216 skip("Connection failed, skipping.\n");
219 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
220 ret = WinHttpCloseHandle(request);
221 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
224 ret = WinHttpCloseHandle(connection);
225 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
226 ret = WinHttpCloseHandle(session);
227 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
231 static void test_empty_headers_param(void)
233 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
234 static const WCHAR empty[] = {0};
235 HINTERNET ses, con, req;
238 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
239 ok(ses != NULL, "failed to open session %u\n", GetLastError());
241 con = WinHttpConnect(ses, winehq, 80, 0);
242 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
244 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
245 ok(req != NULL, "failed to open a request %u\n", GetLastError());
247 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
248 ok(ret, "failed to send request %u\n", GetLastError());
250 WinHttpCloseHandle(req);
251 WinHttpCloseHandle(con);
252 WinHttpCloseHandle(ses);
255 static void test_SendRequest (void)
257 HINTERNET session, request, connection;
258 DWORD header_len, optional_len, total_len, bytes_rw, size;
264 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
265 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
266 static const WCHAR content_type[] =
267 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
268 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
269 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
270 static const WCHAR test_verb[] = {'P','O','S','T',0};
271 static CHAR post_data[] = "mode=Test";
272 static CHAR test_post[] = "mode => Test\\0\n";
275 total_len = optional_len = sizeof(post_data);
276 memset(buffer, 0xff, sizeof(buffer));
278 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
279 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
280 ok(session != NULL, "WinHttpOpen failed to open session.\n");
282 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
283 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
285 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
286 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
287 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
289 skip("Network unreachable, skipping.\n");
292 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
293 if (!request) goto done;
295 context = 0xdeadbeef;
296 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
297 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
300 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
301 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
304 size = sizeof(context);
305 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
306 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
307 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
309 for (i = 3; post_data[i]; i++)
312 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
314 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
315 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
317 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
318 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
322 ret = WinHttpReceiveResponse(request, NULL);
323 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
326 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
327 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
329 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
330 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
332 ret = WinHttpCloseHandle(request);
333 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
335 ret = WinHttpCloseHandle(connection);
336 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
337 ret = WinHttpCloseHandle(session);
338 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
341 static void test_WinHttpTimeFromSystemTime(void)
344 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
345 static const WCHAR expected_string[] =
346 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
347 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
348 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
350 ret = WinHttpTimeFromSystemTime(&time, time_string);
351 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
352 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
353 "Time string returned did not match expected time string.\n");
356 static void test_WinHttpTimeToSystemTime(void)
360 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
361 static const WCHAR time_string1[] =
362 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
363 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
364 static const WCHAR time_string2[] =
365 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
366 '1','0',' ','0','5',' ','5','2','\n',0};
368 ret = WinHttpTimeToSystemTime(time_string1, &time);
369 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
370 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
371 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
373 ret = WinHttpTimeToSystemTime(time_string2, &time);
374 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
375 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
376 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
379 static void test_WinHttpAddHeaders(void)
381 HINTERNET session, request, connection;
383 WCHAR buffer[MAX_PATH];
384 WCHAR check_buffer[MAX_PATH];
385 DWORD index, len, oldlen;
387 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
388 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
389 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
390 static const WCHAR test_verb[] = {'P','O','S','T',0};
392 static const WCHAR test_header_begin[] =
393 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
394 static const WCHAR full_path_test_header_begin[] =
395 {'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'};
396 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
397 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
399 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
400 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
401 static const WCHAR test_flag_coalesce_comma[] =
402 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
403 static const WCHAR test_flag_coalesce_comma_reverse[] =
404 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
405 static const WCHAR test_flag_coalesce_semicolon[] =
406 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
407 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
408 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
410 static const WCHAR field[] = {'f','i','e','l','d',0};
411 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
412 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
414 static const WCHAR test_headers[][14] =
416 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
417 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
418 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
419 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
420 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
421 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
422 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
428 {' ','e',' ',':','f',0},
429 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
431 static const WCHAR test_indices[][6] =
433 {'t','e','s','t','1',0},
434 {'t','e','s','t','2',0},
435 {'t','e','s','t','3',0},
436 {'t','e','s','t','4',0}
439 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
440 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
441 ok(session != NULL, "WinHttpOpen failed to open session.\n");
443 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
444 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
446 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
447 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
448 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
450 skip("Network unreachable, skipping.\n");
453 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
456 len = sizeof(buffer);
457 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
458 test_header_name, buffer, &len, &index);
459 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
460 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
461 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
464 len = sizeof(buffer);
465 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
466 test_header_name, buffer, &len, &index);
467 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
468 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
469 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
470 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
472 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
473 test_header_name, buffer, &len, &index);
474 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
476 /* Try to fetch the header info with a buffer that's big enough to fit the
477 * string but not the NULL terminator.
480 len = 5*sizeof(WCHAR);
481 memset(check_buffer, 0xab, sizeof(check_buffer));
482 memcpy(buffer, check_buffer, sizeof(buffer));
483 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
484 test_header_name, buffer, &len, &index);
485 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
486 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
487 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
488 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
490 /* Try with a NULL buffer */
492 len = sizeof(buffer);
493 SetLastError(0xdeadbeef);
494 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
495 test_header_name, NULL, &len, &index);
496 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
497 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
498 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
499 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
501 /* Try with a NULL buffer and a length that's too small */
504 SetLastError(0xdeadbeef);
505 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
506 test_header_name, NULL, &len, &index);
507 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
508 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
509 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
510 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
511 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
515 SetLastError(0xdeadbeef);
516 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
517 test_header_name, NULL, &len, &index);
518 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
520 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
521 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
522 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
527 len = sizeof(buffer);
528 memset(buffer, 0xff, sizeof(buffer));
529 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
530 test_header_name, buffer, &len, &index);
531 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
532 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
533 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
534 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
535 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
536 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
537 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
538 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
539 "WinHttpQueryHeaders returned invalid end of header string.\n");
540 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
544 SetLastError(0xdeadbeef);
545 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
546 test_header_name, NULL, &len, &index);
547 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
548 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
549 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
550 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
551 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
555 len = sizeof(buffer);
556 memset(buffer, 0xff, sizeof(buffer));
557 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
558 test_header_name, buffer, &len, &index);
559 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
560 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
561 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
562 "no double NULL terminator\n");
563 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
564 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
565 "invalid beginning of header string.\n");
566 ok(index == 0, "header index was incremented\n");
568 /* tests for more indices */
569 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
570 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
573 len = sizeof(buffer);
574 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
575 test_header_name, buffer, &len, &index);
576 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
577 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
578 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
580 len = sizeof(buffer);
581 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
582 test_header_name, buffer, &len, &index);
583 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
584 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
585 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
587 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
588 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
591 len = sizeof(buffer);
592 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
593 test_header_name, buffer, &len, &index);
594 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
595 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
596 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
597 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 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[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
606 /* add if new flag */
607 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
608 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\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 == 1, "WinHttpQueryHeaders failed to increment index.\n");
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 len = sizeof(buffer);
626 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
627 test_header_name, buffer, &len, &index);
628 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
631 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
632 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\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 == 1, "WinHttpQueryHeaders failed to increment index.\n");
640 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");
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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
646 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
647 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
649 len = sizeof(buffer);
650 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
651 test_header_name, buffer, &len, &index);
652 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
654 /* coalesce with comma flag */
655 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
656 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
659 len = sizeof(buffer);
660 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
661 test_header_name, buffer, &len, &index);
662 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
663 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
664 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,
665 "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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
671 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
672 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
674 len = sizeof(buffer);
675 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
676 test_header_name, buffer, &len, &index);
677 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
680 /* coalesce with semicolon flag */
681 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
682 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
685 len = sizeof(buffer);
686 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
687 test_header_name, buffer, &len, &index);
688 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
689 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
690 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,
691 "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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
697 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
698 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
700 len = sizeof(buffer);
701 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
702 test_header_name, buffer, &len, &index);
703 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
705 /* add and replace flags */
706 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
707 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\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 == 1, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 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 == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
721 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
722 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
724 len = sizeof(buffer);
725 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
726 test_header_name, buffer, &len, &index);
727 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
729 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
730 ok(!ret, "WinHttpAddRequestHeaders failed\n");
732 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
733 ok(ret, "WinHttpAddRequestHeaders failed\n");
735 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
736 ok(!ret, "WinHttpAddRequestHeaders failed\n");
738 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
739 ok(!ret, "WinHttpAddRequestHeaders failed\n");
741 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
742 ok(!ret, "WinHttpAddRequestHeaders failed\n");
744 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
745 ok(ret, "WinHttpAddRequestHeaders failed\n");
749 len = sizeof(buffer);
750 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
751 field, buffer, &len, &index);
752 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
753 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
755 ret = WinHttpCloseHandle(request);
756 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
758 ret = WinHttpCloseHandle(connection);
759 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
760 ret = WinHttpCloseHandle(session);
761 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
765 static void test_secure_connection(void)
767 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
769 HINTERNET ses, con, req;
770 DWORD size, status, policy, bitness;
773 WINHTTP_CERTIFICATE_INFO info;
776 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
777 ok(ses != NULL, "failed to open session %u\n", GetLastError());
779 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
780 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
781 ok(ret, "failed to set redirect policy %u\n", GetLastError());
783 con = WinHttpConnect(ses, google, 443, 0);
784 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
786 /* try without setting WINHTTP_FLAG_SECURE */
787 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
788 ok(req != NULL, "failed to open a request %u\n", GetLastError());
790 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
791 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
793 skip("Connection failed, skipping.\n");
796 ok(ret, "failed to send request %u\n", GetLastError());
798 ret = WinHttpReceiveResponse(req, NULL);
799 ok(!ret, "succeeded unexpectedly\n");
802 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
803 ok(!ret, "succeeded unexpectedly\n");
805 WinHttpCloseHandle(req);
807 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
808 ok(req != NULL, "failed to open a request %u\n", GetLastError());
810 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
811 ok(ret, "failed to send request %u\n", GetLastError());
814 skip("secure connection failed, skipping remaining secure tests\n");
819 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
820 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
822 CertFreeCertificateContext(cert);
824 size = sizeof(bitness);
825 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
826 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
829 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
830 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
832 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
833 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
834 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
835 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
836 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
837 trace("dwKeySize %u\n", info.dwKeySize);
839 ret = WinHttpReceiveResponse(req, NULL);
840 ok(ret, "failed to receive response %u\n", GetLastError());
842 size = sizeof(status);
843 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
844 ok(ret, "failed unexpectedly %u\n", GetLastError());
845 ok(status == 200, "request failed unexpectedly %u\n", status);
848 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
849 ok(!ret, "succeeded unexpectedly\n");
854 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
859 WinHttpCloseHandle(req);
860 WinHttpCloseHandle(con);
861 WinHttpCloseHandle(ses);
864 static void test_request_parameter_defaults(void)
866 static const WCHAR empty[] = {0};
867 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
869 HINTERNET ses, con, req;
870 DWORD size, status, error;
874 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
875 ok(ses != NULL, "failed to open session %u\n", GetLastError());
877 con = WinHttpConnect(ses, codeweavers, 0, 0);
878 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
880 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
881 ok(req != NULL, "failed to open a request %u\n", GetLastError());
883 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
884 ok(ret, "failed to send request %u\n", GetLastError());
886 ret = WinHttpReceiveResponse(req, NULL);
887 ok(ret, "failed to receive response %u\n", GetLastError());
889 size = sizeof(status);
890 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
891 ok(ret, "failed unexpectedly %u\n", GetLastError());
892 ok(status == 200, "request failed unexpectedly %u\n", status);
894 WinHttpCloseHandle(req);
896 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
897 ok(req != NULL, "failed to open a request %u\n", GetLastError());
899 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
900 ok(ret, "failed to send request %u\n", GetLastError());
902 ret = WinHttpReceiveResponse(req, NULL);
903 ok(ret, "failed to receive response %u\n", GetLastError());
906 SetLastError(0xdeadbeef);
907 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
908 error = GetLastError();
909 ok(!ret, "succeeded unexpectedly\n");
910 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
912 version = HeapAlloc(GetProcessHeap(), 0, size);
913 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
914 ok(ret, "failed unexpectedly %u\n", GetLastError());
915 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
916 HeapFree(GetProcessHeap(), 0, version);
918 size = sizeof(status);
919 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
920 ok(ret, "failed unexpectedly %u\n", GetLastError());
921 ok(status == 200, "request failed unexpectedly %u\n", status);
923 WinHttpCloseHandle(req);
924 WinHttpCloseHandle(con);
925 WinHttpCloseHandle(ses);
928 static const WCHAR Connections[] = {
929 'S','o','f','t','w','a','r','e','\\',
930 'M','i','c','r','o','s','o','f','t','\\',
931 'W','i','n','d','o','w','s','\\',
932 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
933 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
934 'C','o','n','n','e','c','t','i','o','n','s',0 };
935 static const WCHAR WinHttpSettings[] = {
936 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
938 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
944 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
949 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
953 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
963 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
968 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
969 KEY_WRITE, NULL, &key, NULL );
973 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
975 RegDeleteValueW( key, WinHttpSettings );
980 static void test_set_default_proxy_config(void)
982 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
983 static const WCHAR normalString[] = { 'f','o','o',0 };
985 BYTE *saved_proxy_settings = NULL;
986 WINHTTP_PROXY_INFO info;
989 /* FIXME: it would be simpler to read the current settings using
990 * WinHttpGetDefaultProxyConfiguration and save them using
991 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
993 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
994 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
995 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
996 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
997 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
998 * the lpszProxy and lpszProxyBypass values are ignored.
999 * Thus, if a proxy is set with proxycfg, then calling
1000 * WinHttpGetDefaultProxyConfiguration followed by
1001 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1002 * getting deleted from the registry.
1004 * Instead I read the current registry value and restore it directly.
1006 len = get_default_proxy_reg_value( NULL, 0, &type );
1009 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1010 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1015 /* Crashes on Vista and higher */
1016 SetLastError(0xdeadbeef);
1017 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1018 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1019 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1022 /* test with invalid access type */
1023 info.dwAccessType = 0xdeadbeef;
1024 info.lpszProxy = info.lpszProxyBypass = NULL;
1025 SetLastError(0xdeadbeef);
1026 ret = WinHttpSetDefaultProxyConfiguration(&info);
1027 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1028 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1030 /* at a minimum, the proxy server must be set */
1031 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1032 info.lpszProxy = info.lpszProxyBypass = NULL;
1033 SetLastError(0xdeadbeef);
1034 ret = WinHttpSetDefaultProxyConfiguration(&info);
1035 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1036 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1037 info.lpszProxyBypass = normalString;
1038 SetLastError(0xdeadbeef);
1039 ret = WinHttpSetDefaultProxyConfiguration(&info);
1040 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1041 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1043 /* the proxy server can't have wide characters */
1044 info.lpszProxy = wideString;
1045 SetLastError(0xdeadbeef);
1046 ret = WinHttpSetDefaultProxyConfiguration(&info);
1047 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1048 broken(ret), /* Earlier winhttp versions on W2K/XP */
1049 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1051 info.lpszProxy = normalString;
1052 SetLastError(0xdeadbeef);
1053 ret = WinHttpSetDefaultProxyConfiguration(&info);
1056 ok(ret, "always true\n");
1057 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1059 else if (GetLastError() == ERROR_ACCESS_DENIED)
1060 skip("couldn't set default proxy configuration: access denied\n");
1062 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1066 static void test_Timeouts (void)
1070 HINTERNET ses, req, con;
1071 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1074 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1075 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1077 SetLastError(0xdeadbeef);
1078 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1079 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1080 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1082 SetLastError(0xdeadbeef);
1083 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1084 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1085 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1087 SetLastError(0xdeadbeef);
1088 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1089 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1090 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1092 SetLastError(0xdeadbeef);
1093 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1094 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1095 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1097 SetLastError(0xdeadbeef);
1098 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1099 ok(ret, "%u\n", GetLastError());
1101 SetLastError(0xdeadbeef);
1102 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1103 ok(ret, "%u\n", GetLastError());
1105 SetLastError(0xdeadbeef);
1106 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1107 ok(ret, "%u\n", GetLastError());
1109 SetLastError(0xdeadbeef);
1111 size = sizeof(DWORD);
1112 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1113 ok(ret, "%u\n", GetLastError());
1114 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1116 SetLastError(0xdeadbeef);
1118 size = sizeof(DWORD);
1119 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1120 ok(ret, "%u\n", GetLastError());
1121 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1123 SetLastError(0xdeadbeef);
1125 size = sizeof(DWORD);
1126 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1127 ok(ret, "%u\n", GetLastError());
1128 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1130 SetLastError(0xdeadbeef);
1132 size = sizeof(DWORD);
1133 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1134 ok(ret, "%u\n", GetLastError());
1135 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1137 SetLastError(0xdeadbeef);
1139 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1140 ok(ret, "%u\n", GetLastError());
1142 SetLastError(0xdeadbeef);
1144 size = sizeof(DWORD);
1145 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1146 ok(ret, "%u\n", GetLastError());
1147 ok(value == 0, "Expected 0, got %u\n", value);
1149 SetLastError(0xdeadbeef);
1151 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1152 ok(ret, "%u\n", GetLastError());
1154 SetLastError(0xdeadbeef);
1156 size = sizeof(DWORD);
1157 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1158 ok(ret, "%u\n", GetLastError());
1159 ok(value == 0, "Expected 0, got %u\n", value);
1161 SetLastError(0xdeadbeef);
1163 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1164 ok(ret, "%u\n", GetLastError());
1166 SetLastError(0xdeadbeef);
1168 size = sizeof(DWORD);
1169 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1170 ok(ret, "%u\n", GetLastError());
1171 ok(value == 0, "Expected 0, got %u\n", value);
1173 SetLastError(0xdeadbeef);
1175 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1176 ok(ret, "%u\n", GetLastError());
1178 SetLastError(0xdeadbeef);
1180 size = sizeof(DWORD);
1181 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1182 ok(ret, "%u\n", GetLastError());
1183 ok(value == 0, "Expected 0, got %u\n", value);
1185 SetLastError(0xdeadbeef);
1187 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1188 ok(ret, "%u\n", GetLastError());
1190 SetLastError(0xdeadbeef);
1192 size = sizeof(DWORD);
1193 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1194 ok(ret, "%u\n", GetLastError());
1195 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1197 SetLastError(0xdeadbeef);
1199 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1200 ok(ret, "%u\n", GetLastError());
1202 SetLastError(0xdeadbeef);
1204 size = sizeof(DWORD);
1205 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1206 ok(ret, "%u\n", GetLastError());
1207 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1209 SetLastError(0xdeadbeef);
1211 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1212 ok(ret, "%u\n", GetLastError());
1214 SetLastError(0xdeadbeef);
1216 size = sizeof(DWORD);
1217 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1218 ok(ret, "%u\n", GetLastError());
1219 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1221 SetLastError(0xdeadbeef);
1223 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1224 ok(ret, "%u\n", GetLastError());
1226 SetLastError(0xdeadbeef);
1228 size = sizeof(DWORD);
1229 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1230 ok(ret, "%u\n", GetLastError());
1231 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1233 con = WinHttpConnect(ses, codeweavers, 0, 0);
1234 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1236 /* Timeout values should match the last one set for session */
1237 SetLastError(0xdeadbeef);
1239 size = sizeof(DWORD);
1240 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1241 ok(ret, "%u\n", GetLastError());
1242 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1244 SetLastError(0xdeadbeef);
1246 size = sizeof(DWORD);
1247 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1248 ok(ret, "%u\n", GetLastError());
1249 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1251 SetLastError(0xdeadbeef);
1253 size = sizeof(DWORD);
1254 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1255 ok(ret, "%u\n", GetLastError());
1256 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1258 SetLastError(0xdeadbeef);
1260 size = sizeof(DWORD);
1261 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1262 ok(ret, "%u\n", GetLastError());
1263 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1265 SetLastError(0xdeadbeef);
1266 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1267 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1268 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1270 SetLastError(0xdeadbeef);
1271 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1272 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1273 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1275 SetLastError(0xdeadbeef);
1276 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1277 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1278 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1280 SetLastError(0xdeadbeef);
1281 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1282 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1283 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1285 SetLastError(0xdeadbeef);
1286 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1287 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1288 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1290 SetLastError(0xdeadbeef);
1291 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1292 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1293 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1295 SetLastError(0xdeadbeef);
1297 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1298 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1299 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1301 SetLastError(0xdeadbeef);
1303 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1304 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1305 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1307 SetLastError(0xdeadbeef);
1309 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1310 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1311 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1313 SetLastError(0xdeadbeef);
1315 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1316 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1317 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1319 /* Changing timeout values for session should affect the values for connection */
1320 SetLastError(0xdeadbeef);
1322 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1323 ok(ret, "%u\n", GetLastError());
1325 SetLastError(0xdeadbeef);
1327 size = sizeof(DWORD);
1328 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1329 ok(ret, "%u\n", GetLastError());
1330 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1332 SetLastError(0xdeadbeef);
1334 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1335 ok(ret, "%u\n", GetLastError());
1337 SetLastError(0xdeadbeef);
1339 size = sizeof(DWORD);
1340 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1341 ok(ret, "%u\n", GetLastError());
1342 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1344 SetLastError(0xdeadbeef);
1346 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1347 ok(ret, "%u\n", GetLastError());
1349 SetLastError(0xdeadbeef);
1351 size = sizeof(DWORD);
1352 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1353 ok(ret, "%u\n", GetLastError());
1354 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1356 SetLastError(0xdeadbeef);
1358 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1359 ok(ret, "%u\n", GetLastError());
1361 SetLastError(0xdeadbeef);
1363 size = sizeof(DWORD);
1364 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1365 ok(ret, "%u\n", GetLastError());
1366 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1368 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1369 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1371 /* Timeout values should match the last one set for session */
1372 SetLastError(0xdeadbeef);
1374 size = sizeof(DWORD);
1375 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1376 ok(ret, "%u\n", GetLastError());
1377 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1379 SetLastError(0xdeadbeef);
1381 size = sizeof(DWORD);
1382 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1383 ok(ret, "%u\n", GetLastError());
1384 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1386 SetLastError(0xdeadbeef);
1388 size = sizeof(DWORD);
1389 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1390 ok(ret, "%u\n", GetLastError());
1391 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1393 SetLastError(0xdeadbeef);
1395 size = sizeof(DWORD);
1396 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1397 ok(ret, "%u\n", GetLastError());
1398 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1400 SetLastError(0xdeadbeef);
1401 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1402 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1403 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1405 SetLastError(0xdeadbeef);
1406 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1407 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1408 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1410 SetLastError(0xdeadbeef);
1411 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1412 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1413 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1415 SetLastError(0xdeadbeef);
1416 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1417 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1418 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1420 SetLastError(0xdeadbeef);
1421 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1422 ok(ret, "%u\n", GetLastError());
1424 SetLastError(0xdeadbeef);
1425 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1426 ok(ret, "%u\n", GetLastError());
1428 SetLastError(0xdeadbeef);
1429 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1430 ok(ret, "%u\n", GetLastError());
1432 SetLastError(0xdeadbeef);
1434 size = sizeof(DWORD);
1435 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1436 ok(ret, "%u\n", GetLastError());
1437 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1439 SetLastError(0xdeadbeef);
1441 size = sizeof(DWORD);
1442 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1443 ok(ret, "%u\n", GetLastError());
1444 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1446 SetLastError(0xdeadbeef);
1448 size = sizeof(DWORD);
1449 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1450 ok(ret, "%u\n", GetLastError());
1451 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1453 SetLastError(0xdeadbeef);
1455 size = sizeof(DWORD);
1456 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1457 ok(ret, "%u\n", GetLastError());
1458 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1460 SetLastError(0xdeadbeef);
1462 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1463 ok(ret, "%u\n", GetLastError());
1465 SetLastError(0xdeadbeef);
1467 size = sizeof(DWORD);
1468 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1469 ok(ret, "%u\n", GetLastError());
1470 ok(value == 0, "Expected 0, got %u\n", value);
1472 SetLastError(0xdeadbeef);
1474 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1475 ok(ret, "%u\n", GetLastError());
1477 SetLastError(0xdeadbeef);
1479 size = sizeof(DWORD);
1480 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1481 ok(ret, "%u\n", GetLastError());
1482 ok(value == 0, "Expected 0, got %u\n", value);
1484 SetLastError(0xdeadbeef);
1486 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1487 ok(ret, "%u\n", GetLastError());
1489 SetLastError(0xdeadbeef);
1491 size = sizeof(DWORD);
1492 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1493 ok(ret, "%u\n", GetLastError());
1494 ok(value == 0, "Expected 0, got %u\n", value);
1496 SetLastError(0xdeadbeef);
1498 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1499 ok(ret, "%u\n", GetLastError());
1501 SetLastError(0xdeadbeef);
1503 size = sizeof(DWORD);
1504 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1505 ok(ret, "%u\n", GetLastError());
1506 ok(value == 0, "Expected 0, got %u\n", value);
1508 SetLastError(0xdeadbeef);
1510 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1511 ok(ret, "%u\n", GetLastError());
1513 SetLastError(0xdeadbeef);
1515 size = sizeof(DWORD);
1516 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1517 ok(ret, "%u\n", GetLastError());
1518 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1520 SetLastError(0xdeadbeef);
1522 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1523 ok(ret, "%u\n", GetLastError());
1525 SetLastError(0xdeadbeef);
1527 size = sizeof(DWORD);
1528 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1529 ok(ret, "%u\n", GetLastError());
1530 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1532 SetLastError(0xdeadbeef);
1534 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1535 ok(ret, "%u\n", GetLastError());
1537 SetLastError(0xdeadbeef);
1539 size = sizeof(DWORD);
1540 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1541 ok(ret, "%u\n", GetLastError());
1542 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1544 SetLastError(0xdeadbeef);
1546 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1547 ok(ret, "%u\n", GetLastError());
1549 SetLastError(0xdeadbeef);
1551 size = sizeof(DWORD);
1552 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1553 ok(ret, "%u\n", GetLastError());
1554 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1556 /* Changing timeout values for session should not affect the values for a request,
1557 * neither should the other way around.
1559 SetLastError(0xdeadbeef);
1561 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1562 ok(ret, "%u\n", GetLastError());
1564 SetLastError(0xdeadbeef);
1566 size = sizeof(DWORD);
1567 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1568 ok(ret, "%u\n", GetLastError());
1569 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1571 SetLastError(0xdeadbeef);
1573 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1574 ok(ret, "%u\n", GetLastError());
1576 SetLastError(0xdeadbeef);
1578 size = sizeof(DWORD);
1579 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1580 ok(ret, "%u\n", GetLastError());
1581 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1583 SetLastError(0xdeadbeef);
1585 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1586 ok(ret, "%u\n", GetLastError());
1588 SetLastError(0xdeadbeef);
1590 size = sizeof(DWORD);
1591 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1592 ok(ret, "%u\n", GetLastError());
1593 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1595 SetLastError(0xdeadbeef);
1597 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1598 ok(ret, "%u\n", GetLastError());
1600 SetLastError(0xdeadbeef);
1602 size = sizeof(DWORD);
1603 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1604 ok(ret, "%u\n", GetLastError());
1605 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1607 SetLastError(0xdeadbeef);
1609 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1610 ok(ret, "%u\n", GetLastError());
1612 SetLastError(0xdeadbeef);
1614 size = sizeof(DWORD);
1615 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1616 ok(ret, "%u\n", GetLastError());
1617 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1619 SetLastError(0xdeadbeef);
1621 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1622 ok(ret, "%u\n", GetLastError());
1624 SetLastError(0xdeadbeef);
1626 size = sizeof(DWORD);
1627 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1628 ok(ret, "%u\n", GetLastError());
1629 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1631 SetLastError(0xdeadbeef);
1633 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1634 ok(ret, "%u\n", GetLastError());
1636 SetLastError(0xdeadbeef);
1638 size = sizeof(DWORD);
1639 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1640 ok(ret, "%u\n", GetLastError());
1641 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1643 SetLastError(0xdeadbeef);
1645 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1646 ok(ret, "%u\n", GetLastError());
1648 SetLastError(0xdeadbeef);
1650 size = sizeof(DWORD);
1651 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1652 ok(ret, "%u\n", GetLastError());
1653 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1655 WinHttpCloseHandle(req);
1656 WinHttpCloseHandle(con);
1657 WinHttpCloseHandle(ses);
1660 static void test_resolve_timeout(void)
1662 static const WCHAR codeweavers[] =
1663 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1664 static const WCHAR nxdomain[] =
1665 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1667 HINTERNET ses, con, req;
1671 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1672 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1675 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1676 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1678 con = WinHttpConnect(ses, nxdomain, 0, 0);
1679 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1681 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1682 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1684 SetLastError(0xdeadbeef);
1685 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1686 ok(!ret, "sent request\n");
1687 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1688 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1690 WinHttpCloseHandle(req);
1691 WinHttpCloseHandle(con);
1692 WinHttpCloseHandle(ses);
1694 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1695 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1698 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1699 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1701 con = WinHttpConnect(ses, codeweavers, 0, 0);
1702 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1704 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1705 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1707 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1708 ok(ret, "failed to send request\n");
1710 WinHttpCloseHandle(req);
1711 WinHttpCloseHandle(con);
1712 WinHttpCloseHandle(ses);
1715 static const char page1[] =
1717 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1718 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1721 static const char okmsg[] =
1722 "HTTP/1.1 200 OK\r\n"
1723 "Server: winetest\r\n"
1726 static const char notokmsg[] =
1727 "HTTP/1.1 400 Bad Request\r\n"
1728 "Server: winetest\r\n"
1731 static const char noauthmsg[] =
1732 "HTTP/1.1 401 Unauthorized\r\n"
1733 "Server: winetest\r\n"
1734 "Connection: close\r\n"
1735 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1738 static const char proxymsg[] =
1739 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1740 "Server: winetest\r\n"
1741 "Proxy-Connection: close\r\n"
1742 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1751 static DWORD CALLBACK server_thread(LPVOID param)
1753 struct server_info *si = param;
1756 struct sockaddr_in sa;
1759 int last_request = 0;
1761 WSAStartup(MAKEWORD(1,1), &wsaData);
1763 s = socket(AF_INET, SOCK_STREAM, 0);
1764 if (s == INVALID_SOCKET)
1768 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1770 memset(&sa, 0, sizeof sa);
1771 sa.sin_family = AF_INET;
1772 sa.sin_port = htons(si->port);
1773 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1775 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1780 SetEvent(si->event);
1783 c = accept(s, NULL, NULL);
1785 memset(buffer, 0, sizeof buffer);
1786 for(i = 0; i < sizeof buffer - 1; i++)
1788 r = recv(c, &buffer[i], 1, 0);
1791 if (i < 4) continue;
1792 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1793 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1796 if (strstr(buffer, "GET /basic"))
1798 send(c, okmsg, sizeof okmsg - 1, 0);
1799 send(c, page1, sizeof page1 - 1, 0);
1801 if (strstr(buffer, "/auth"))
1803 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1804 send(c, okmsg, sizeof okmsg - 1, 0);
1806 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1808 if (strstr(buffer, "/no_headers"))
1810 send(c, page1, sizeof page1 - 1, 0);
1812 if (strstr(buffer, "GET /quit"))
1814 send(c, okmsg, sizeof okmsg - 1, 0);
1815 send(c, page1, sizeof page1 - 1, 0);
1821 } while (!last_request);
1827 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1829 HINTERNET ses, con, req;
1831 DWORD count, status, size;
1834 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1835 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1837 con = WinHttpConnect(ses, localhostW, port, 0);
1838 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1840 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1841 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1843 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1844 ok(ret, "failed to send request %u\n", GetLastError());
1846 ret = WinHttpReceiveResponse(req, NULL);
1847 ok(ret, "failed to receive response %u\n", GetLastError());
1849 size = sizeof(status);
1850 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1851 ok(ret, "failed to query status code %u\n", GetLastError());
1852 ok(status == 200, "request failed unexpectedly %u\n", status);
1855 memset(buffer, 0, sizeof(buffer));
1856 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1857 ok(ret, "failed to read data %u\n", GetLastError());
1858 ok(count == sizeof page1 - 1, "count was wrong\n");
1859 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1861 WinHttpCloseHandle(req);
1862 WinHttpCloseHandle(con);
1863 WinHttpCloseHandle(ses);
1866 static void test_basic_authentication(int port)
1868 static const WCHAR authW[] = {'/','a','u','t','h',0};
1869 static const WCHAR userW[] = {'u','s','e','r',0};
1870 static const WCHAR passW[] = {'p','w','d',0};
1871 HINTERNET ses, con, req;
1872 DWORD status, size, error;
1875 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1876 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1878 con = WinHttpConnect(ses, localhostW, port, 0);
1879 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1881 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1882 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1884 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1885 ok(ret, "failed to send request %u\n", GetLastError());
1887 ret = WinHttpReceiveResponse(req, NULL);
1888 ok(ret, "failed to receive response %u\n", GetLastError());
1890 size = sizeof(status);
1891 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1892 ok(ret, "failed to query status code %u\n", GetLastError());
1893 ok(status == 401, "request failed unexpectedly %u\n", status);
1895 SetLastError(0xdeadbeef);
1896 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1897 error = GetLastError();
1898 ok(!ret, "expected failure\n");
1899 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1901 SetLastError(0xdeadbeef);
1902 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1903 error = GetLastError();
1904 ok(!ret, "expected failure\n");
1905 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1907 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1908 ok(ret, "failed to set credentials %u\n", GetLastError());
1910 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1911 ok(ret, "failed to send request %u\n", GetLastError());
1913 ret = WinHttpReceiveResponse(req, NULL);
1914 ok(ret, "failed to receive response %u\n", GetLastError());
1916 size = sizeof(status);
1917 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1918 ok(ret, "failed to query status code %u\n", GetLastError());
1919 ok(status == 200, "request failed unexpectedly %u\n", status);
1921 WinHttpCloseHandle(req);
1922 WinHttpCloseHandle(con);
1923 WinHttpCloseHandle(ses);
1926 static void test_no_headers(int port)
1928 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1929 HINTERNET ses, con, req;
1932 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1933 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1935 con = WinHttpConnect(ses, localhostW, port, 0);
1936 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1938 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1939 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1941 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1942 ok(ret, "failed to send request %u\n", GetLastError());
1944 ret = WinHttpReceiveResponse(req, NULL);
1945 ok(!ret, "expected failure\n");
1947 WinHttpCloseHandle(req);
1948 WinHttpCloseHandle(con);
1949 WinHttpCloseHandle(ses);
1952 static void test_credentials(void)
1954 static WCHAR userW[] = {'u','s','e','r',0};
1955 static WCHAR passW[] = {'p','a','s','s',0};
1956 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
1957 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
1958 HINTERNET ses, con, req;
1963 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
1964 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1966 con = WinHttpConnect(ses, localhostW, 0, 0);
1967 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1969 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1970 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1972 size = sizeof(buffer)/sizeof(WCHAR);
1973 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
1974 ok(ret, "failed to query proxy username %u\n", GetLastError());
1975 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
1976 ok(!size, "expected 0, got %u\n", size);
1978 size = sizeof(buffer)/sizeof(WCHAR);
1979 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
1980 ok(ret, "failed to query proxy password %u\n", GetLastError());
1981 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
1982 ok(!size, "expected 0, got %u\n", size);
1984 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
1985 ok(ret, "failed to set username %u\n", GetLastError());
1987 size = sizeof(buffer)/sizeof(WCHAR);
1988 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
1989 ok(ret, "failed to query proxy username %u\n", GetLastError());
1990 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
1991 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
1993 size = sizeof(buffer)/sizeof(WCHAR);
1994 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
1995 ok(ret, "failed to query username %u\n", GetLastError());
1996 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
1997 ok(!size, "expected 0, got %u\n", size);
1999 size = sizeof(buffer)/sizeof(WCHAR);
2000 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2001 ok(ret, "failed to query password %u\n", GetLastError());
2002 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2003 ok(!size, "expected 0, got %u\n", size);
2005 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2006 ok(ret, "failed to set proxy password %u\n", GetLastError());
2008 size = sizeof(buffer)/sizeof(WCHAR);
2009 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2010 ok(ret, "failed to query proxy password %u\n", GetLastError());
2011 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2012 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2014 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2015 ok(ret, "failed to set username %u\n", GetLastError());
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(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2021 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2023 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2024 ok(ret, "failed to set password %u\n", GetLastError());
2026 size = sizeof(buffer)/sizeof(WCHAR);
2027 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2028 ok(ret, "failed to query password %u\n", GetLastError());
2029 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2030 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2032 WinHttpCloseHandle(req);
2034 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2035 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2037 SetLastError(0xdeadbeef);
2038 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2039 error = GetLastError();
2040 ok(!ret, "expected failure\n");
2041 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2043 SetLastError(0xdeadbeef);
2044 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2045 error = GetLastError();
2046 ok(!ret, "expected failure\n");
2047 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2049 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2050 ok(ret, "failed to set credentials %u\n", GetLastError());
2052 size = sizeof(buffer)/sizeof(WCHAR);
2053 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2054 ok(ret, "failed to query username %u\n", GetLastError());
2056 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2057 ok(!size, "expected 0, got %u\n", size);
2060 size = sizeof(buffer)/sizeof(WCHAR);
2061 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2062 ok(ret, "failed to query password %u\n", GetLastError());
2064 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2065 ok(!size, "expected 0, got %u\n", size);
2068 WinHttpCloseHandle(req);
2069 WinHttpCloseHandle(con);
2070 WinHttpCloseHandle(ses);
2073 START_TEST (winhttp)
2075 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2076 static const WCHAR quitW[] = {'/','q','u','i','t',0};
2077 struct server_info si;
2083 test_WinHttpTimeFromSystemTime();
2084 test_WinHttpTimeToSystemTime();
2085 test_WinHttpAddHeaders();
2086 test_secure_connection();
2087 test_request_parameter_defaults();
2089 test_set_default_proxy_config();
2090 test_empty_headers_param();
2092 test_resolve_timeout();
2095 si.event = CreateEvent(NULL, 0, 0, NULL);
2098 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2099 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2101 ret = WaitForSingleObject(si.event, 10000);
2102 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2103 if (ret != WAIT_OBJECT_0)
2106 test_basic_request(si.port, NULL, basicW);
2107 test_no_headers(si.port);
2108 test_basic_authentication(si.port);
2110 /* send the basic request again to shutdown the server thread */
2111 test_basic_request(si.port, NULL, quitW);
2113 WaitForSingleObject(thread, 3000);