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
33 #include <httprequest.h>
35 #include "wine/test.h"
37 static const WCHAR test_useragent[] =
38 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
39 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
40 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
42 static BOOL proxy_active(void)
44 WINHTTP_PROXY_INFO proxy_info;
47 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
49 active = (proxy_info.lpszProxy != NULL);
51 GlobalFree(proxy_info.lpszProxy);
52 if (proxy_info.lpszProxyBypass != NULL)
53 GlobalFree(proxy_info.lpszProxyBypass);
61 static void test_QueryOption(void)
64 HINTERNET session, request, connection;
67 SetLastError(0xdeadbeef);
68 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
69 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
71 SetLastError(0xdeadbeef);
72 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
73 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
74 ok(GetLastError() == ERROR_INVALID_PARAMETER,
75 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
78 SetLastError(0xdeadbeef);
79 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
80 ok(!ret, "should fail to query option\n");
81 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
82 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
83 ok(size == 4, "expected 4, got %u\n", size);
86 size = sizeof(feature) - 1;
87 SetLastError(0xdeadbeef);
88 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
89 ok(!ret, "should fail to query option\n");
90 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
91 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
92 ok(size == 4, "expected 4, got %u\n", size);
95 size = sizeof(feature) + 1;
96 SetLastError(0xdeadbeef);
97 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
98 ok(ret, "failed to query option %u\n", GetLastError());
99 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
100 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
101 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
103 SetLastError(0xdeadbeef);
104 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
105 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
106 ok(GetLastError() == ERROR_INVALID_PARAMETER,
107 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
109 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
110 SetLastError(0xdeadbeef);
111 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
112 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
113 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
114 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
116 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
117 SetLastError(0xdeadbeef);
118 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
119 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
120 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
121 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
123 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
124 SetLastError(0xdeadbeef);
125 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
126 ok(ret, "failed to set redirect policy %u\n", GetLastError());
128 feature = 0xdeadbeef;
129 size = sizeof(feature);
130 SetLastError(0xdeadbeef);
131 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
132 ok(ret, "failed to query option %u\n", GetLastError());
133 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
134 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
136 feature = WINHTTP_DISABLE_COOKIES;
137 SetLastError(0xdeadbeef);
138 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
139 ok(!ret, "should fail to set disable feature for a session\n");
140 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
141 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
143 SetLastError(0xdeadbeef);
144 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
145 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
147 feature = WINHTTP_DISABLE_COOKIES;
148 SetLastError(0xdeadbeef);
149 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
150 ok(!ret, "should fail to set disable feature for a connection\n");
151 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
152 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
154 SetLastError(0xdeadbeef);
155 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
156 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
157 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
159 skip("Network unreachable, skipping the test\n");
163 feature = 0xdeadbeef;
164 size = sizeof(feature);
165 SetLastError(0xdeadbeef);
166 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
167 ok(!ret, "should fail to query disable feature for a request\n");
168 ok(GetLastError() == ERROR_INVALID_PARAMETER,
169 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
172 size = sizeof(feature);
173 SetLastError(0xdeadbeef);
174 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
175 ok(ret, "failed to set feature %u\n", GetLastError());
177 feature = 0xffffffff;
178 size = sizeof(feature);
179 SetLastError(0xdeadbeef);
180 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
181 ok(ret, "failed to set feature %u\n", GetLastError());
183 feature = WINHTTP_DISABLE_COOKIES;
184 size = sizeof(feature);
185 SetLastError(0xdeadbeef);
186 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
187 ok(ret, "failed to set feature %u\n", GetLastError());
190 SetLastError(0xdeadbeef);
191 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
192 ok(!ret, "should fail to query disable feature for a request\n");
193 ok(GetLastError() == ERROR_INVALID_PARAMETER,
194 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
196 SetLastError(0xdeadbeef);
197 ret = WinHttpCloseHandle(request);
198 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
201 SetLastError(0xdeadbeef);
202 ret = WinHttpCloseHandle(connection);
203 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
204 SetLastError(0xdeadbeef);
205 ret = WinHttpCloseHandle(session);
206 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
209 static void test_OpenRequest (void)
212 HINTERNET session, request, connection;
214 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
215 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
216 ok(session != NULL, "WinHttpOpen failed to open session.\n");
218 /* Test with a bad server name */
219 SetLastError(0xdeadbeef);
220 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
221 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
222 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
224 /* Test with a valid server name */
225 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
226 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
228 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
229 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
230 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
232 skip("Network unreachable, skipping.\n");
235 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
237 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
238 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
240 skip("Connection failed, skipping.\n");
243 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
244 ret = WinHttpCloseHandle(request);
245 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
248 ret = WinHttpCloseHandle(connection);
249 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
250 ret = WinHttpCloseHandle(session);
251 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
255 static void test_empty_headers_param(void)
257 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
258 static const WCHAR empty[] = {0};
259 HINTERNET ses, con, req;
262 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
263 ok(ses != NULL, "failed to open session %u\n", GetLastError());
265 con = WinHttpConnect(ses, winehq, 80, 0);
266 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
268 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
269 ok(req != NULL, "failed to open a request %u\n", GetLastError());
271 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
272 ok(ret, "failed to send request %u\n", GetLastError());
274 WinHttpCloseHandle(req);
275 WinHttpCloseHandle(con);
276 WinHttpCloseHandle(ses);
279 static void test_SendRequest (void)
281 HINTERNET session, request, connection;
282 DWORD header_len, optional_len, total_len, bytes_rw, size;
288 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
289 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
290 static const WCHAR content_type[] =
291 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
292 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
293 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
294 static const WCHAR test_verb[] = {'P','O','S','T',0};
295 static CHAR post_data[] = "mode=Test";
296 static CHAR test_post[] = "mode => Test\\0\n";
299 total_len = optional_len = sizeof(post_data);
300 memset(buffer, 0xff, sizeof(buffer));
302 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
303 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
304 ok(session != NULL, "WinHttpOpen failed to open session.\n");
306 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
307 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
309 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
310 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
311 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
313 skip("Network unreachable, skipping.\n");
316 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
317 if (!request) goto done;
319 context = 0xdeadbeef;
320 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
321 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
324 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
325 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
328 size = sizeof(context);
329 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
330 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
331 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
333 for (i = 3; post_data[i]; i++)
336 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
338 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
339 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
341 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
342 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
346 ret = WinHttpReceiveResponse(request, NULL);
347 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
350 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
351 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
353 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
354 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
356 ret = WinHttpCloseHandle(request);
357 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
359 ret = WinHttpCloseHandle(connection);
360 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
361 ret = WinHttpCloseHandle(session);
362 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
365 static void test_WinHttpTimeFromSystemTime(void)
368 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
369 static const WCHAR expected_string[] =
370 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
371 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
372 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
374 ret = WinHttpTimeFromSystemTime(&time, time_string);
375 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
376 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
377 "Time string returned did not match expected time string.\n");
380 static void test_WinHttpTimeToSystemTime(void)
384 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
385 static const WCHAR time_string1[] =
386 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
387 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
388 static const WCHAR time_string2[] =
389 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
390 '1','0',' ','0','5',' ','5','2','\n',0};
392 ret = WinHttpTimeToSystemTime(time_string1, &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");
397 ret = WinHttpTimeToSystemTime(time_string2, &time);
398 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
399 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
400 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
403 static void test_WinHttpAddHeaders(void)
405 HINTERNET session, request, connection;
407 WCHAR buffer[MAX_PATH];
408 WCHAR check_buffer[MAX_PATH];
409 DWORD index, len, oldlen;
411 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
412 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
413 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
414 static const WCHAR test_verb[] = {'P','O','S','T',0};
416 static const WCHAR test_header_begin[] =
417 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
418 static const WCHAR full_path_test_header_begin[] =
419 {'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'};
420 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
421 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
423 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
424 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
425 static const WCHAR test_flag_coalesce_comma[] =
426 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
427 static const WCHAR test_flag_coalesce_comma_reverse[] =
428 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
429 static const WCHAR test_flag_coalesce_semicolon[] =
430 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
431 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
432 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
434 static const WCHAR field[] = {'f','i','e','l','d',0};
435 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
436 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
438 static const WCHAR test_headers[][14] =
440 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
441 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
442 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
443 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
444 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
445 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
446 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
452 {' ','e',' ',':','f',0},
453 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
455 static const WCHAR test_indices[][6] =
457 {'t','e','s','t','1',0},
458 {'t','e','s','t','2',0},
459 {'t','e','s','t','3',0},
460 {'t','e','s','t','4',0}
463 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
464 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
465 ok(session != NULL, "WinHttpOpen failed to open session.\n");
467 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
468 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
470 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
471 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
472 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
474 skip("Network unreachable, skipping.\n");
477 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
480 len = sizeof(buffer);
481 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
482 test_header_name, buffer, &len, &index);
483 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
484 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
485 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
488 len = sizeof(buffer);
489 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
490 test_header_name, buffer, &len, &index);
491 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
492 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
493 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
494 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
496 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
497 test_header_name, buffer, &len, &index);
498 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
500 /* Try to fetch the header info with a buffer that's big enough to fit the
501 * string but not the NULL terminator.
504 len = 5*sizeof(WCHAR);
505 memset(check_buffer, 0xab, sizeof(check_buffer));
506 memcpy(buffer, check_buffer, sizeof(buffer));
507 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
508 test_header_name, buffer, &len, &index);
509 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
510 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
511 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
512 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
514 /* Try with a NULL buffer */
516 len = sizeof(buffer);
517 SetLastError(0xdeadbeef);
518 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
519 test_header_name, NULL, &len, &index);
520 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
521 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
522 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
523 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
525 /* Try with a NULL buffer and a length that's too small */
528 SetLastError(0xdeadbeef);
529 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
530 test_header_name, NULL, &len, &index);
531 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
532 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
533 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
534 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
535 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
539 SetLastError(0xdeadbeef);
540 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
541 test_header_name, NULL, &len, &index);
542 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
543 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
544 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
545 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
546 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
551 len = sizeof(buffer);
552 memset(buffer, 0xff, sizeof(buffer));
553 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
554 test_header_name, buffer, &len, &index);
555 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
556 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
557 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
558 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
559 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
560 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
561 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
562 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
563 "WinHttpQueryHeaders returned invalid end of header string.\n");
564 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
568 SetLastError(0xdeadbeef);
569 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
570 test_header_name, NULL, &len, &index);
571 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
572 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
573 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
574 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
575 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
579 len = sizeof(buffer);
580 memset(buffer, 0xff, sizeof(buffer));
581 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
582 test_header_name, buffer, &len, &index);
583 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
584 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
585 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
586 "no double NULL terminator\n");
587 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
588 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
589 "invalid beginning of header string.\n");
590 ok(index == 0, "header index was incremented\n");
592 /* tests for more indices */
593 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
594 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
597 len = sizeof(buffer);
598 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
599 test_header_name, buffer, &len, &index);
600 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
601 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
602 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
604 len = sizeof(buffer);
605 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
606 test_header_name, buffer, &len, &index);
607 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
608 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
609 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
611 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
612 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
615 len = sizeof(buffer);
616 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
617 test_header_name, buffer, &len, &index);
618 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
619 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
620 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
621 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
623 len = sizeof(buffer);
624 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
625 test_header_name, buffer, &len, &index);
626 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
627 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
628 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
630 /* add if new flag */
631 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
632 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\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, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 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");
655 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
656 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\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_reverse : test_flag_coalesce,
665 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
667 len = sizeof(buffer);
668 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
669 test_header_name, buffer, &len, &index);
670 ok(ret == 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");
679 /* coalesce with comma flag */
680 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
681 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
684 len = sizeof(buffer);
685 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
686 test_header_name, buffer, &len, &index);
687 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
688 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
689 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
690 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 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");
706 /* coalesce with semicolon flag */
707 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
708 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
711 len = sizeof(buffer);
712 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
713 test_header_name, buffer, &len, &index);
714 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
715 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
716 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
717 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
718 "WinHttpQueryHeaders returned incorrect string.\n");
720 len = sizeof(buffer);
721 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
722 test_header_name, buffer, &len, &index);
723 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
724 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
725 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
727 len = sizeof(buffer);
728 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
729 test_header_name, buffer, &len, &index);
730 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
732 /* add and replace flags */
733 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
734 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
737 len = sizeof(buffer);
738 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
739 test_header_name, buffer, &len, &index);
740 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
741 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
742 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
744 len = sizeof(buffer);
745 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
746 test_header_name, buffer, &len, &index);
747 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
748 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
749 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
751 len = sizeof(buffer);
752 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
753 test_header_name, buffer, &len, &index);
754 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
756 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
757 ok(!ret, "WinHttpAddRequestHeaders failed\n");
759 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
760 ok(ret, "WinHttpAddRequestHeaders failed\n");
762 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
763 ok(!ret, "WinHttpAddRequestHeaders failed\n");
765 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
766 ok(!ret, "WinHttpAddRequestHeaders failed\n");
768 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
769 ok(!ret, "WinHttpAddRequestHeaders failed\n");
771 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
772 ok(ret, "WinHttpAddRequestHeaders failed\n");
776 len = sizeof(buffer);
777 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
778 field, buffer, &len, &index);
779 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
780 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
782 ret = WinHttpCloseHandle(request);
783 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
785 ret = WinHttpCloseHandle(connection);
786 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
787 ret = WinHttpCloseHandle(session);
788 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
792 static void test_secure_connection(void)
794 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
796 HINTERNET ses, con, req;
797 DWORD size, status, policy, bitness, read_size;
800 WINHTTP_CERTIFICATE_INFO info;
803 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
804 ok(ses != NULL, "failed to open session %u\n", GetLastError());
806 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
807 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
808 ok(ret, "failed to set redirect policy %u\n", GetLastError());
810 con = WinHttpConnect(ses, google, 443, 0);
811 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
813 /* try without setting WINHTTP_FLAG_SECURE */
814 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
815 ok(req != NULL, "failed to open a request %u\n", GetLastError());
817 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
818 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
820 skip("Connection failed, skipping.\n");
823 ok(ret, "failed to send request %u\n", GetLastError());
825 ret = WinHttpReceiveResponse(req, NULL);
826 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
829 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
830 ok(!ret, "succeeded unexpectedly\n");
832 WinHttpCloseHandle(req);
834 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
835 ok(req != NULL, "failed to open a request %u\n", GetLastError());
837 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
838 ok(ret, "failed to send request %u\n", GetLastError());
841 skip("secure connection failed, skipping remaining secure tests\n");
846 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
847 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
849 CertFreeCertificateContext(cert);
851 size = sizeof(bitness);
852 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
853 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
856 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
857 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
859 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
860 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
861 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
862 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
863 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
864 trace("dwKeySize %u\n", info.dwKeySize);
866 ret = WinHttpReceiveResponse(req, NULL);
867 ok(ret, "failed to receive response %u\n", GetLastError());
869 size = sizeof(status);
870 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
871 ok(ret, "failed unexpectedly %u\n", GetLastError());
872 ok(status == 200, "request failed unexpectedly %u\n", status);
875 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
876 ok(!ret, "succeeded unexpectedly\n");
882 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
883 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
887 ok(read_size > 2014, "read_size = %u\n", read_size);
890 WinHttpCloseHandle(req);
891 WinHttpCloseHandle(con);
892 WinHttpCloseHandle(ses);
895 static void test_request_parameter_defaults(void)
897 static const WCHAR empty[] = {0};
898 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
900 HINTERNET ses, con, req;
901 DWORD size, status, error;
905 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
906 ok(ses != NULL, "failed to open session %u\n", GetLastError());
908 con = WinHttpConnect(ses, codeweavers, 0, 0);
909 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
911 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
912 ok(req != NULL, "failed to open a request %u\n", GetLastError());
914 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
915 ok(ret, "failed to send request %u\n", GetLastError());
917 ret = WinHttpReceiveResponse(req, NULL);
918 ok(ret, "failed to receive response %u\n", GetLastError());
920 size = sizeof(status);
921 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
922 ok(ret, "failed unexpectedly %u\n", GetLastError());
923 ok(status == 200, "request failed unexpectedly %u\n", status);
925 WinHttpCloseHandle(req);
927 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
928 ok(req != NULL, "failed to open a request %u\n", GetLastError());
930 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
931 ok(ret, "failed to send request %u\n", GetLastError());
933 ret = WinHttpReceiveResponse(req, NULL);
934 ok(ret, "failed to receive response %u\n", GetLastError());
937 SetLastError(0xdeadbeef);
938 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
939 error = GetLastError();
940 ok(!ret, "succeeded unexpectedly\n");
941 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
943 version = HeapAlloc(GetProcessHeap(), 0, size);
944 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
945 ok(ret, "failed unexpectedly %u\n", GetLastError());
946 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
947 HeapFree(GetProcessHeap(), 0, version);
949 size = sizeof(status);
950 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
951 ok(ret, "failed unexpectedly %u\n", GetLastError());
952 ok(status == 200, "request failed unexpectedly %u\n", status);
954 WinHttpCloseHandle(req);
955 WinHttpCloseHandle(con);
956 WinHttpCloseHandle(ses);
959 static const WCHAR Connections[] = {
960 'S','o','f','t','w','a','r','e','\\',
961 'M','i','c','r','o','s','o','f','t','\\',
962 'W','i','n','d','o','w','s','\\',
963 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
964 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
965 'C','o','n','n','e','c','t','i','o','n','s',0 };
966 static const WCHAR WinHttpSettings[] = {
967 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
969 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
975 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
980 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
984 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
994 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
999 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
1000 KEY_WRITE, NULL, &key, NULL );
1004 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1006 RegDeleteValueW( key, WinHttpSettings );
1011 static void test_set_default_proxy_config(void)
1013 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1014 static WCHAR normalString[] = { 'f','o','o',0 };
1016 BYTE *saved_proxy_settings = NULL;
1017 WINHTTP_PROXY_INFO info;
1020 /* FIXME: it would be simpler to read the current settings using
1021 * WinHttpGetDefaultProxyConfiguration and save them using
1022 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1024 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1025 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1026 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1027 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1028 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1029 * the lpszProxy and lpszProxyBypass values are ignored.
1030 * Thus, if a proxy is set with proxycfg, then calling
1031 * WinHttpGetDefaultProxyConfiguration followed by
1032 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1033 * getting deleted from the registry.
1035 * Instead I read the current registry value and restore it directly.
1037 len = get_default_proxy_reg_value( NULL, 0, &type );
1040 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1041 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1046 /* Crashes on Vista and higher */
1047 SetLastError(0xdeadbeef);
1048 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1049 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1050 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1053 /* test with invalid access type */
1054 info.dwAccessType = 0xdeadbeef;
1055 info.lpszProxy = info.lpszProxyBypass = NULL;
1056 SetLastError(0xdeadbeef);
1057 ret = WinHttpSetDefaultProxyConfiguration(&info);
1058 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1059 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1061 /* at a minimum, the proxy server must be set */
1062 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1063 info.lpszProxy = info.lpszProxyBypass = NULL;
1064 SetLastError(0xdeadbeef);
1065 ret = WinHttpSetDefaultProxyConfiguration(&info);
1066 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1067 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1068 info.lpszProxyBypass = normalString;
1069 SetLastError(0xdeadbeef);
1070 ret = WinHttpSetDefaultProxyConfiguration(&info);
1071 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1072 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1074 /* the proxy server can't have wide characters */
1075 info.lpszProxy = wideString;
1076 SetLastError(0xdeadbeef);
1077 ret = WinHttpSetDefaultProxyConfiguration(&info);
1078 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1079 skip("couldn't set default proxy configuration: access denied\n");
1081 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1082 broken(ret), /* Earlier winhttp versions on W2K/XP */
1083 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1085 info.lpszProxy = normalString;
1086 SetLastError(0xdeadbeef);
1087 ret = WinHttpSetDefaultProxyConfiguration(&info);
1088 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1089 skip("couldn't set default proxy configuration: access denied\n");
1091 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1094 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1097 static void test_Timeouts (void)
1101 HINTERNET ses, req, con;
1102 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1105 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1106 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1108 SetLastError(0xdeadbeef);
1109 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1110 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1111 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1113 SetLastError(0xdeadbeef);
1114 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1115 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1116 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1118 SetLastError(0xdeadbeef);
1119 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1120 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1121 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1123 SetLastError(0xdeadbeef);
1124 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1125 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1126 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1128 SetLastError(0xdeadbeef);
1129 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1130 ok(ret, "%u\n", GetLastError());
1132 SetLastError(0xdeadbeef);
1133 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1134 ok(ret, "%u\n", GetLastError());
1136 SetLastError(0xdeadbeef);
1137 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1138 ok(ret, "%u\n", GetLastError());
1140 SetLastError(0xdeadbeef);
1142 size = sizeof(DWORD);
1143 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1144 ok(ret, "%u\n", GetLastError());
1145 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1147 SetLastError(0xdeadbeef);
1149 size = sizeof(DWORD);
1150 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1151 ok(ret, "%u\n", GetLastError());
1152 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1154 SetLastError(0xdeadbeef);
1156 size = sizeof(DWORD);
1157 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1158 ok(ret, "%u\n", GetLastError());
1159 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1161 SetLastError(0xdeadbeef);
1163 size = sizeof(DWORD);
1164 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1165 ok(ret, "%u\n", GetLastError());
1166 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1168 SetLastError(0xdeadbeef);
1170 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1171 ok(ret, "%u\n", GetLastError());
1173 SetLastError(0xdeadbeef);
1175 size = sizeof(DWORD);
1176 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1183 ok(ret, "%u\n", GetLastError());
1185 SetLastError(0xdeadbeef);
1187 size = sizeof(DWORD);
1188 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1195 ok(ret, "%u\n", GetLastError());
1197 SetLastError(0xdeadbeef);
1199 size = sizeof(DWORD);
1200 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_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_RECEIVE_TIMEOUT, &value, sizeof(value));
1207 ok(ret, "%u\n", GetLastError());
1209 SetLastError(0xdeadbeef);
1211 size = sizeof(DWORD);
1212 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1213 ok(ret, "%u\n", GetLastError());
1214 ok(value == 0, "Expected 0, got %u\n", value);
1216 SetLastError(0xdeadbeef);
1218 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1219 ok(ret, "%u\n", GetLastError());
1221 SetLastError(0xdeadbeef);
1223 size = sizeof(DWORD);
1224 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1231 ok(ret, "%u\n", GetLastError());
1233 SetLastError(0xdeadbeef);
1235 size = sizeof(DWORD);
1236 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1243 ok(ret, "%u\n", GetLastError());
1245 SetLastError(0xdeadbeef);
1247 size = sizeof(DWORD);
1248 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1249 ok(ret, "%u\n", GetLastError());
1250 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1252 SetLastError(0xdeadbeef);
1254 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1255 ok(ret, "%u\n", GetLastError());
1257 SetLastError(0xdeadbeef);
1259 size = sizeof(DWORD);
1260 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1261 ok(ret, "%u\n", GetLastError());
1262 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1264 con = WinHttpConnect(ses, codeweavers, 0, 0);
1265 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1267 /* Timeout values should match the last one set for session */
1268 SetLastError(0xdeadbeef);
1270 size = sizeof(DWORD);
1271 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1272 ok(ret, "%u\n", GetLastError());
1273 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1275 SetLastError(0xdeadbeef);
1277 size = sizeof(DWORD);
1278 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1279 ok(ret, "%u\n", GetLastError());
1280 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1282 SetLastError(0xdeadbeef);
1284 size = sizeof(DWORD);
1285 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1286 ok(ret, "%u\n", GetLastError());
1287 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1289 SetLastError(0xdeadbeef);
1291 size = sizeof(DWORD);
1292 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1293 ok(ret, "%u\n", GetLastError());
1294 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1296 SetLastError(0xdeadbeef);
1297 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1298 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1299 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1301 SetLastError(0xdeadbeef);
1302 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1303 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1304 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1306 SetLastError(0xdeadbeef);
1307 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1308 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1309 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1311 SetLastError(0xdeadbeef);
1312 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1313 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1314 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1316 SetLastError(0xdeadbeef);
1317 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1318 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1319 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1321 SetLastError(0xdeadbeef);
1322 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
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_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1335 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1336 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1338 SetLastError(0xdeadbeef);
1340 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1341 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1342 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1344 SetLastError(0xdeadbeef);
1346 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1347 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1348 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1350 /* Changing timeout values for session should affect the values for connection */
1351 SetLastError(0xdeadbeef);
1353 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1354 ok(ret, "%u\n", GetLastError());
1356 SetLastError(0xdeadbeef);
1358 size = sizeof(DWORD);
1359 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1366 ok(ret, "%u\n", GetLastError());
1368 SetLastError(0xdeadbeef);
1370 size = sizeof(DWORD);
1371 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1378 ok(ret, "%u\n", GetLastError());
1380 SetLastError(0xdeadbeef);
1382 size = sizeof(DWORD);
1383 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1384 ok(ret, "%u\n", GetLastError());
1385 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1387 SetLastError(0xdeadbeef);
1389 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1390 ok(ret, "%u\n", GetLastError());
1392 SetLastError(0xdeadbeef);
1394 size = sizeof(DWORD);
1395 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1396 ok(ret, "%u\n", GetLastError());
1397 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1399 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1400 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1402 /* Timeout values should match the last one set for session */
1403 SetLastError(0xdeadbeef);
1405 size = sizeof(DWORD);
1406 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1407 ok(ret, "%u\n", GetLastError());
1408 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1410 SetLastError(0xdeadbeef);
1412 size = sizeof(DWORD);
1413 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1414 ok(ret, "%u\n", GetLastError());
1415 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1417 SetLastError(0xdeadbeef);
1419 size = sizeof(DWORD);
1420 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1421 ok(ret, "%u\n", GetLastError());
1422 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1424 SetLastError(0xdeadbeef);
1426 size = sizeof(DWORD);
1427 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1428 ok(ret, "%u\n", GetLastError());
1429 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1431 SetLastError(0xdeadbeef);
1432 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1433 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1434 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1436 SetLastError(0xdeadbeef);
1437 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1438 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1439 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1441 SetLastError(0xdeadbeef);
1442 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1443 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1444 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1446 SetLastError(0xdeadbeef);
1447 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1448 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1449 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1451 SetLastError(0xdeadbeef);
1452 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1453 ok(ret, "%u\n", GetLastError());
1455 SetLastError(0xdeadbeef);
1456 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1457 ok(ret, "%u\n", GetLastError());
1459 SetLastError(0xdeadbeef);
1460 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1461 ok(ret, "%u\n", GetLastError());
1463 SetLastError(0xdeadbeef);
1465 size = sizeof(DWORD);
1466 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1467 ok(ret, "%u\n", GetLastError());
1468 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1470 SetLastError(0xdeadbeef);
1472 size = sizeof(DWORD);
1473 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1474 ok(ret, "%u\n", GetLastError());
1475 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1477 SetLastError(0xdeadbeef);
1479 size = sizeof(DWORD);
1480 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1481 ok(ret, "%u\n", GetLastError());
1482 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1484 SetLastError(0xdeadbeef);
1486 size = sizeof(DWORD);
1487 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1488 ok(ret, "%u\n", GetLastError());
1489 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1491 SetLastError(0xdeadbeef);
1493 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1494 ok(ret, "%u\n", GetLastError());
1496 SetLastError(0xdeadbeef);
1498 size = sizeof(DWORD);
1499 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1506 ok(ret, "%u\n", GetLastError());
1508 SetLastError(0xdeadbeef);
1510 size = sizeof(DWORD);
1511 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1518 ok(ret, "%u\n", GetLastError());
1520 SetLastError(0xdeadbeef);
1522 size = sizeof(DWORD);
1523 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_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_RECEIVE_TIMEOUT, &value, sizeof(value));
1530 ok(ret, "%u\n", GetLastError());
1532 SetLastError(0xdeadbeef);
1534 size = sizeof(DWORD);
1535 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1536 ok(ret, "%u\n", GetLastError());
1537 ok(value == 0, "Expected 0, got %u\n", value);
1539 SetLastError(0xdeadbeef);
1541 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1542 ok(ret, "%u\n", GetLastError());
1544 SetLastError(0xdeadbeef);
1546 size = sizeof(DWORD);
1547 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1554 ok(ret, "%u\n", GetLastError());
1556 SetLastError(0xdeadbeef);
1558 size = sizeof(DWORD);
1559 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1566 ok(ret, "%u\n", GetLastError());
1568 SetLastError(0xdeadbeef);
1570 size = sizeof(DWORD);
1571 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1572 ok(ret, "%u\n", GetLastError());
1573 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1575 SetLastError(0xdeadbeef);
1577 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1578 ok(ret, "%u\n", GetLastError());
1580 SetLastError(0xdeadbeef);
1582 size = sizeof(DWORD);
1583 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1584 ok(ret, "%u\n", GetLastError());
1585 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1587 /* Changing timeout values for session should not affect the values for a request,
1588 * neither should the other way around.
1590 SetLastError(0xdeadbeef);
1592 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1593 ok(ret, "%u\n", GetLastError());
1595 SetLastError(0xdeadbeef);
1597 size = sizeof(DWORD);
1598 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1605 ok(ret, "%u\n", GetLastError());
1607 SetLastError(0xdeadbeef);
1609 size = sizeof(DWORD);
1610 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1617 ok(ret, "%u\n", GetLastError());
1619 SetLastError(0xdeadbeef);
1621 size = sizeof(DWORD);
1622 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_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(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1629 ok(ret, "%u\n", GetLastError());
1631 SetLastError(0xdeadbeef);
1633 size = sizeof(DWORD);
1634 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1635 ok(ret, "%u\n", GetLastError());
1636 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1638 SetLastError(0xdeadbeef);
1640 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1641 ok(ret, "%u\n", GetLastError());
1643 SetLastError(0xdeadbeef);
1645 size = sizeof(DWORD);
1646 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_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_CONNECT_TIMEOUT, &value, sizeof(value));
1653 ok(ret, "%u\n", GetLastError());
1655 SetLastError(0xdeadbeef);
1657 size = sizeof(DWORD);
1658 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_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_SEND_TIMEOUT, &value, sizeof(value));
1665 ok(ret, "%u\n", GetLastError());
1667 SetLastError(0xdeadbeef);
1669 size = sizeof(DWORD);
1670 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1671 ok(ret, "%u\n", GetLastError());
1672 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1674 SetLastError(0xdeadbeef);
1676 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1677 ok(ret, "%u\n", GetLastError());
1679 SetLastError(0xdeadbeef);
1681 size = sizeof(DWORD);
1682 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1683 ok(ret, "%u\n", GetLastError());
1684 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1686 WinHttpCloseHandle(req);
1687 WinHttpCloseHandle(con);
1688 WinHttpCloseHandle(ses);
1691 static void test_resolve_timeout(void)
1693 static const WCHAR codeweavers[] =
1694 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1695 static const WCHAR nxdomain[] =
1696 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1698 HINTERNET ses, con, req;
1702 if (! proxy_active())
1704 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1705 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1708 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1709 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1711 con = WinHttpConnect(ses, nxdomain, 0, 0);
1712 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1714 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1715 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1717 SetLastError(0xdeadbeef);
1718 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1719 ok(!ret, "sent request\n");
1720 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1721 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1723 WinHttpCloseHandle(req);
1724 WinHttpCloseHandle(con);
1725 WinHttpCloseHandle(ses);
1728 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1730 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1731 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1734 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1735 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1737 con = WinHttpConnect(ses, codeweavers, 0, 0);
1738 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1740 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1741 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1743 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1744 ok(ret, "failed to send request\n");
1746 WinHttpCloseHandle(req);
1747 WinHttpCloseHandle(con);
1748 WinHttpCloseHandle(ses);
1751 static const char page1[] =
1753 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1754 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1757 static const char okmsg[] =
1758 "HTTP/1.1 200 OK\r\n"
1759 "Server: winetest\r\n"
1762 static const char noauthmsg[] =
1763 "HTTP/1.1 401 Unauthorized\r\n"
1764 "Server: winetest\r\n"
1765 "Connection: close\r\n"
1766 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1769 static const char proxymsg[] =
1770 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1771 "Server: winetest\r\n"
1772 "Proxy-Connection: close\r\n"
1773 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1782 static DWORD CALLBACK server_thread(LPVOID param)
1784 struct server_info *si = param;
1787 struct sockaddr_in sa;
1790 int last_request = 0;
1792 WSAStartup(MAKEWORD(1,1), &wsaData);
1794 s = socket(AF_INET, SOCK_STREAM, 0);
1795 if (s == INVALID_SOCKET)
1799 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1801 memset(&sa, 0, sizeof sa);
1802 sa.sin_family = AF_INET;
1803 sa.sin_port = htons(si->port);
1804 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1806 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1811 SetEvent(si->event);
1814 c = accept(s, NULL, NULL);
1816 memset(buffer, 0, sizeof buffer);
1817 for(i = 0; i < sizeof buffer - 1; i++)
1819 r = recv(c, &buffer[i], 1, 0);
1822 if (i < 4) continue;
1823 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1824 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1827 if (strstr(buffer, "GET /basic"))
1829 send(c, okmsg, sizeof okmsg - 1, 0);
1830 send(c, page1, sizeof page1 - 1, 0);
1832 if (strstr(buffer, "/auth"))
1834 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1835 send(c, okmsg, sizeof okmsg - 1, 0);
1837 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1839 if (strstr(buffer, "/no_headers"))
1841 send(c, page1, sizeof page1 - 1, 0);
1843 if (strstr(buffer, "GET /quit"))
1845 send(c, okmsg, sizeof okmsg - 1, 0);
1846 send(c, page1, sizeof page1 - 1, 0);
1852 } while (!last_request);
1858 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1860 HINTERNET ses, con, req;
1862 DWORD count, status, size;
1865 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1866 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1868 con = WinHttpConnect(ses, localhostW, port, 0);
1869 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1871 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1872 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1874 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1875 ok(ret, "failed to send request %u\n", GetLastError());
1877 ret = WinHttpReceiveResponse(req, NULL);
1878 ok(ret, "failed to receive response %u\n", GetLastError());
1880 size = sizeof(status);
1881 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1882 ok(ret, "failed to query status code %u\n", GetLastError());
1883 ok(status == 200, "request failed unexpectedly %u\n", status);
1886 memset(buffer, 0, sizeof(buffer));
1887 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1888 ok(ret, "failed to read data %u\n", GetLastError());
1889 ok(count == sizeof page1 - 1, "count was wrong\n");
1890 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1892 WinHttpCloseHandle(req);
1893 WinHttpCloseHandle(con);
1894 WinHttpCloseHandle(ses);
1897 static void test_basic_authentication(int port)
1899 static const WCHAR authW[] = {'/','a','u','t','h',0};
1900 static const WCHAR userW[] = {'u','s','e','r',0};
1901 static const WCHAR passW[] = {'p','w','d',0};
1902 HINTERNET ses, con, req;
1903 DWORD status, size, error;
1906 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1907 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1909 con = WinHttpConnect(ses, localhostW, port, 0);
1910 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1912 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1913 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1915 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1916 ok(ret, "failed to send request %u\n", GetLastError());
1918 ret = WinHttpReceiveResponse(req, NULL);
1919 ok(ret, "failed to receive response %u\n", GetLastError());
1921 size = sizeof(status);
1922 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1923 ok(ret, "failed to query status code %u\n", GetLastError());
1924 ok(status == 401, "request failed unexpectedly %u\n", status);
1926 SetLastError(0xdeadbeef);
1927 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1928 error = GetLastError();
1929 ok(!ret, "expected failure\n");
1930 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1932 SetLastError(0xdeadbeef);
1933 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1934 error = GetLastError();
1935 ok(!ret, "expected failure\n");
1936 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1938 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1939 ok(ret, "failed to set credentials %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, "failed to receive response %u\n", GetLastError());
1947 size = sizeof(status);
1948 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1949 ok(ret, "failed to query status code %u\n", GetLastError());
1950 ok(status == 200, "request failed unexpectedly %u\n", status);
1952 WinHttpCloseHandle(req);
1953 WinHttpCloseHandle(con);
1954 WinHttpCloseHandle(ses);
1957 static void test_no_headers(int port)
1959 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1960 HINTERNET ses, con, req;
1964 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1965 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1967 con = WinHttpConnect(ses, localhostW, port, 0);
1968 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1970 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1971 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1973 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1974 ok(ret, "failed to send request %u\n", GetLastError());
1976 SetLastError(0xdeadbeef);
1977 ret = WinHttpReceiveResponse(req, NULL);
1978 error = GetLastError();
1979 ok(!ret, "expected failure\n");
1980 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
1982 WinHttpCloseHandle(req);
1983 WinHttpCloseHandle(con);
1984 WinHttpCloseHandle(ses);
1987 static void test_bad_header( int port )
1989 static const WCHAR bad_headerW[] =
1990 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
1991 't','e','x','t','/','h','t','m','l','\n','\r',0};
1992 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
1993 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
1995 HINTERNET ses, con, req;
1999 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2000 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2002 con = WinHttpConnect( ses, localhostW, port, 0 );
2003 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2005 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2006 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2008 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2009 ok( ret, "failed to add header %u\n", GetLastError() );
2013 len = sizeof(buffer);
2014 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2015 content_typeW, buffer, &len, &index );
2016 ok( ret, "failed to query headers %u\n", GetLastError() );
2017 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2019 WinHttpCloseHandle( req );
2020 WinHttpCloseHandle( con );
2021 WinHttpCloseHandle( ses );
2024 static void test_connection_info( int port )
2026 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2027 HINTERNET ses, con, req;
2028 WINHTTP_CONNECTION_INFO info;
2032 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2033 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2035 con = WinHttpConnect( ses, localhostW, port, 0 );
2036 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2038 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
2039 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2041 size = sizeof(info);
2042 SetLastError( 0xdeadbeef );
2043 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2044 error = GetLastError();
2045 if (!ret && error == ERROR_INVALID_PARAMETER)
2047 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2050 ok( !ret, "unexpected success\n" );
2051 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
2053 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2054 ok( ret, "failed to send request %u\n", GetLastError() );
2057 SetLastError( 0xdeadbeef );
2058 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2059 error = GetLastError();
2060 ok( !ret, "unexpected success\n" );
2061 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
2063 size = sizeof(info);
2064 memset( &info, 0, sizeof(info) );
2065 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2066 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2067 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2069 ret = WinHttpReceiveResponse( req, NULL );
2070 ok( ret, "failed to receive response %u\n", GetLastError() );
2072 size = sizeof(info);
2073 memset( &info, 0, sizeof(info) );
2074 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2075 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2076 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2078 WinHttpCloseHandle( req );
2079 WinHttpCloseHandle( con );
2080 WinHttpCloseHandle( ses );
2083 static void test_credentials(void)
2085 static WCHAR userW[] = {'u','s','e','r',0};
2086 static WCHAR passW[] = {'p','a','s','s',0};
2087 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2088 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2089 HINTERNET ses, con, req;
2094 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2095 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2097 con = WinHttpConnect(ses, localhostW, 0, 0);
2098 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2100 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2101 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2103 size = sizeof(buffer)/sizeof(WCHAR);
2104 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2105 ok(ret, "failed to query proxy username %u\n", GetLastError());
2106 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2107 ok(!size, "expected 0, got %u\n", size);
2109 size = sizeof(buffer)/sizeof(WCHAR);
2110 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2111 ok(ret, "failed to query proxy password %u\n", GetLastError());
2112 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2113 ok(!size, "expected 0, got %u\n", size);
2115 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2116 ok(ret, "failed to set username %u\n", GetLastError());
2118 size = sizeof(buffer)/sizeof(WCHAR);
2119 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2120 ok(ret, "failed to query proxy username %u\n", GetLastError());
2121 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2122 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2124 size = sizeof(buffer)/sizeof(WCHAR);
2125 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2126 ok(ret, "failed to query username %u\n", GetLastError());
2127 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2128 ok(!size, "expected 0, got %u\n", size);
2130 size = sizeof(buffer)/sizeof(WCHAR);
2131 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2132 ok(ret, "failed to query password %u\n", GetLastError());
2133 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2134 ok(!size, "expected 0, got %u\n", size);
2136 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2137 ok(ret, "failed to set proxy password %u\n", GetLastError());
2139 size = sizeof(buffer)/sizeof(WCHAR);
2140 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2141 ok(ret, "failed to query proxy password %u\n", GetLastError());
2142 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2143 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2145 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2146 ok(ret, "failed to set username %u\n", GetLastError());
2148 size = sizeof(buffer)/sizeof(WCHAR);
2149 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2150 ok(ret, "failed to query username %u\n", GetLastError());
2151 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2152 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2154 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2155 ok(ret, "failed to set password %u\n", GetLastError());
2157 size = sizeof(buffer)/sizeof(WCHAR);
2158 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2159 ok(ret, "failed to query password %u\n", GetLastError());
2160 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2161 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2163 WinHttpCloseHandle(req);
2165 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2166 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2168 SetLastError(0xdeadbeef);
2169 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2170 error = GetLastError();
2171 ok(!ret, "expected failure\n");
2172 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2174 SetLastError(0xdeadbeef);
2175 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2176 error = GetLastError();
2177 ok(!ret, "expected failure\n");
2178 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2180 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2181 ok(ret, "failed to set credentials %u\n", GetLastError());
2183 size = sizeof(buffer)/sizeof(WCHAR);
2184 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2185 ok(ret, "failed to query username %u\n", GetLastError());
2187 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2188 ok(!size, "expected 0, got %u\n", size);
2191 size = sizeof(buffer)/sizeof(WCHAR);
2192 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2193 ok(ret, "failed to query password %u\n", GetLastError());
2195 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2196 ok(!size, "expected 0, got %u\n", size);
2199 WinHttpCloseHandle(req);
2200 WinHttpCloseHandle(con);
2201 WinHttpCloseHandle(ses);
2204 static void test_IWinHttpRequest(void)
2206 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2207 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2208 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2209 static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
2210 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
2211 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
2212 'p','o','s','t','t','e','s','t','.','p','h','p',0};
2213 static const WCHAR method1W[] = {'G','E','T',0};
2214 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2215 static const WCHAR method3W[] = {'P','O','S','T',0};
2216 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2217 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2218 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2219 static const WCHAR dateW[] = {'D','a','t','e',0};
2220 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
2222 IWinHttpRequest *req;
2223 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2224 BSTR date, today, connection, value = NULL;
2225 VARIANT async, empty, timeout, body, proxy_server, bypass_list, data;
2226 VARIANT_BOOL succeeded;
2228 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2231 GetSystemTime( &st );
2232 WinHttpTimeFromSystemTime( &st, todayW );
2234 CoInitialize( NULL );
2235 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2236 ok( hr == S_OK, "got %08x\n", hr );
2238 V_VT( &empty ) = VT_ERROR;
2239 V_ERROR( &empty ) = 0xdeadbeef;
2241 V_VT( &async ) = VT_BOOL;
2242 V_BOOL( &async ) = VARIANT_FALSE;
2244 method = SysAllocString( method3W );
2245 url = SysAllocString( url3W );
2246 hr = IWinHttpRequest_Open( req, method, url, async );
2247 ok( hr == S_OK, "got %08x\n", hr );
2248 SysFreeString( method );
2249 SysFreeString( url );
2251 V_VT( &data ) = VT_BSTR;
2252 V_BSTR( &data ) = SysAllocString( test_dataW );
2253 hr = IWinHttpRequest_Send( req, data );
2254 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
2256 SysFreeString( V_BSTR( &data ) );
2258 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2259 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2261 method = SysAllocString( method1W );
2262 hr = IWinHttpRequest_Open( req, method, NULL, empty );
2263 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2265 hr = IWinHttpRequest_Open( req, method, NULL, async );
2266 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2268 url = SysAllocString( url1W );
2269 hr = IWinHttpRequest_Open( req, NULL, url, empty );
2270 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2272 hr = IWinHttpRequest_Abort( req );
2273 ok( hr == S_OK, "got %08x\n", hr );
2275 hr = IWinHttpRequest_Open( req, method, url, empty );
2276 ok( hr == S_OK, "got %08x\n", hr );
2278 hr = IWinHttpRequest_Abort( req );
2279 ok( hr == S_OK, "got %08x\n", hr );
2281 hr = IWinHttpRequest_Release( req );
2282 ok( hr == S_OK, "got %08x\n", hr );
2284 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2285 ok( hr == S_OK, "got %08x\n", hr );
2287 SysFreeString( url );
2288 url = SysAllocString( url2W );
2289 hr = IWinHttpRequest_Open( req, method, url, async );
2290 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2292 SysFreeString( method );
2293 method = SysAllocString( method2W );
2294 hr = IWinHttpRequest_Open( req, method, url, async );
2295 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2297 SysFreeString( method );
2298 method = SysAllocString( method1W );
2299 SysFreeString( url );
2300 url = SysAllocString( url1W );
2301 hr = IWinHttpRequest_Open( req, method, url, async );
2302 ok( hr == S_OK, "got %08x\n", hr );
2304 hr = IWinHttpRequest_Abort( req );
2305 ok( hr == S_OK, "got %08x\n", hr );
2307 hr = IWinHttpRequest_Send( req, empty );
2308 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2310 hr = IWinHttpRequest_Abort( req );
2311 ok( hr == S_OK, "got %08x\n", hr );
2313 hr = IWinHttpRequest_Release( req );
2314 ok( hr == S_OK, "got %08x\n", hr );
2316 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2317 ok( hr == S_OK, "got %08x\n", hr );
2319 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2320 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2322 hr = IWinHttpRequest_get_ResponseText( req, &response );
2323 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2325 hr = IWinHttpRequest_get_Status( req, NULL );
2326 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2328 hr = IWinHttpRequest_get_Status( req, &status );
2329 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2331 hr = IWinHttpRequest_get_StatusText( req, NULL );
2332 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2334 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2335 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2337 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2338 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2340 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2341 ok( hr == S_OK, "got %08x\n", hr );
2343 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2344 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2346 VariantInit( &proxy_server );
2347 V_VT( &proxy_server ) = VT_ERROR;
2348 VariantInit( &bypass_list );
2349 V_VT( &bypass_list ) = VT_ERROR;
2350 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2351 ok( hr == S_OK, "got %08x\n", hr );
2353 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2354 ok( hr == S_OK, "got %08x\n", hr );
2356 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2357 ok( hr == S_OK, "got %08x\n", hr );
2359 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2360 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2362 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2363 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2365 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2366 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2368 connection = SysAllocString( connectionW );
2369 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2370 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2372 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2373 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2375 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2376 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2378 date = SysAllocString( dateW );
2379 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2380 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2382 today = SysAllocString( todayW );
2383 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2384 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2386 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2387 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2389 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2390 ok( hr == S_OK, "got %08x\n", hr );
2392 SysFreeString( method );
2393 method = SysAllocString( method1W );
2394 SysFreeString( url );
2395 url = SysAllocString( url1W );
2396 hr = IWinHttpRequest_Open( req, method, url, async );
2397 ok( hr == S_OK, "got %08x\n", hr );
2399 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2400 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2402 hr = IWinHttpRequest_get_ResponseText( req, &response );
2403 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2405 hr = IWinHttpRequest_get_Status( req, &status );
2406 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2408 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2409 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2411 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2412 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2414 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2415 ok( hr == S_OK, "got %08x\n", hr );
2417 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2418 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2420 username = SysAllocString( usernameW );
2421 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2422 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2424 password = SysAllocString( passwordW );
2425 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2426 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2428 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2429 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2431 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2432 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2434 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2435 ok( hr == S_OK, "got %08x\n", hr );
2437 V_VT( &proxy_server ) = VT_BSTR;
2438 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2439 V_VT( &bypass_list ) = VT_BSTR;
2440 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2441 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2442 ok( hr == S_OK, "got %08x\n", hr );
2444 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2445 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2447 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2448 ok( hr == S_OK, "got %08x\n", hr );
2450 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2451 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2453 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2454 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2456 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2457 ok( hr == S_OK, "got %08x\n", hr );
2459 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2460 ok( hr == S_OK, "got %08x\n", hr );
2462 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2463 ok( hr == S_OK, "got %08x\n", hr );
2465 hr = IWinHttpRequest_Send( req, empty );
2466 ok( hr == S_OK, "got %08x\n", hr );
2468 hr = IWinHttpRequest_Send( req, empty );
2469 ok( hr == S_OK, "got %08x\n", hr );
2471 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2472 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2474 hr = IWinHttpRequest_get_ResponseText( req, &response );
2475 ok( hr == S_OK, "got %08x\n", hr );
2476 SysFreeString( response );
2478 hr = IWinHttpRequest_get_Status( req, NULL );
2479 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2482 hr = IWinHttpRequest_get_Status( req, &status );
2483 ok( hr == S_OK, "got %08x\n", hr );
2484 trace("Status=%d\n", status);
2486 hr = IWinHttpRequest_get_StatusText( req, NULL );
2487 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2489 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2490 ok( hr == S_OK, "got %08x\n", hr );
2491 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
2492 SysFreeString( status_text );
2494 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2495 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2497 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2498 ok( hr == S_OK, "got %08x\n", hr );
2500 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2501 ok( hr == S_OK, "got %08x\n", hr );
2503 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2504 ok( hr == S_OK, "got %08x\n", hr );
2506 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2507 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2509 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2510 ok( hr == S_OK, "got %08x\n", hr );
2511 SysFreeString( headers );
2513 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2514 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2516 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2517 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2519 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2520 ok( hr == S_OK, "got %08x\n", hr );
2521 SysFreeString( value );
2523 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2524 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2526 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2527 ok( hr == S_OK, "got %08x\n", hr );
2529 VariantInit( &timeout );
2530 V_VT( &timeout ) = VT_I4;
2531 V_I4( &timeout ) = 10;
2532 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2533 ok( hr == S_OK, "got %08x\n", hr );
2535 hr = IWinHttpRequest_get_Status( req, &status );
2536 ok( hr == S_OK, "got %08x\n", hr );
2538 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2539 ok( hr == S_OK, "got %08x\n", hr );
2540 SysFreeString( status_text );
2542 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2543 ok( hr == S_OK, "got %08x\n", hr );
2545 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2546 ok( hr == S_OK, "got %08x\n", hr );
2548 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2549 ok( hr == S_OK, "got %08x\n", hr );
2551 hr = IWinHttpRequest_Send( req, empty );
2552 ok( hr == S_OK, "got %08x\n", hr );
2554 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2555 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2557 hr = IWinHttpRequest_get_ResponseText( req, &response );
2558 ok( hr == S_OK, "got %08x\n", hr );
2559 SysFreeString( response );
2561 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2562 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2564 VariantInit( &body );
2565 V_VT( &body ) = VT_ERROR;
2566 hr = IWinHttpRequest_get_ResponseBody( req, &body );
2567 ok( hr == S_OK, "got %08x\n", hr );
2568 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2570 hr = VariantClear( &body );
2571 ok( hr == S_OK, "got %08x\n", hr );
2573 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2574 ok( hr == S_OK, "got %08x\n", hr );
2576 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2577 ok( hr == S_OK, "got %08x\n", hr );
2579 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2580 ok( hr == S_OK, "got %08x\n", hr );
2581 SysFreeString( headers );
2583 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2584 ok( hr == S_OK, "got %08x\n", hr );
2585 SysFreeString( value );
2587 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2588 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2590 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2591 ok( hr == S_OK, "got %08x\n", hr );
2593 hr = IWinHttpRequest_Send( req, empty );
2594 ok( hr == S_OK, "got %08x\n", hr );
2596 hr = IWinHttpRequest_Abort( req );
2597 ok( hr == S_OK, "got %08x\n", hr );
2599 hr = IWinHttpRequest_Abort( req );
2600 ok( hr == S_OK, "got %08x\n", hr );
2602 hr = IWinHttpRequest_Release( req );
2603 ok( hr == S_OK, "got %08x\n", hr );
2605 SysFreeString( method );
2606 SysFreeString( url );
2607 SysFreeString( username );
2608 SysFreeString( password );
2609 SysFreeString( connection );
2610 SysFreeString( date );
2611 SysFreeString( today );
2612 VariantClear( &proxy_server );
2613 VariantClear( &bypass_list );
2617 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2623 if (0) /* crashes on some win2k systems */
2625 SetLastError(0xdeadbeef);
2626 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
2627 error = GetLastError();
2628 ok( !ret, "expected failure\n" );
2629 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2632 SetLastError(0xdeadbeef);
2633 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
2634 error = GetLastError();
2635 ok( !ret, "expected failure\n" );
2636 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2638 if (0) /* crashes on some win2k systems */
2640 SetLastError(0xdeadbeef);
2641 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
2642 error = GetLastError();
2643 ok( !ret, "expected failure\n" );
2644 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2647 SetLastError(0xdeadbeef);
2648 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
2649 error = GetLastError();
2651 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2654 trace("%s\n", wine_dbgstr_w(url));
2659 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2663 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
2665 memset( &cfg, 0, sizeof(cfg) );
2667 SetLastError(0xdeadbeef);
2668 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
2669 error = GetLastError();
2670 ok( !ret, "expected failure\n" );
2671 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2673 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
2674 ok( ret, "expected success\n" );
2675 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
2676 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
2677 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
2678 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
2679 GlobalFree( cfg.lpszAutoConfigUrl );
2680 GlobalFree( cfg.lpszProxy );
2681 GlobalFree( cfg.lpszProxyBypass );
2684 static void test_WinHttpGetProxyForUrl(void)
2686 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2687 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
2688 static const WCHAR emptyW[] = {0};
2692 WINHTTP_AUTOPROXY_OPTIONS options;
2693 WINHTTP_PROXY_INFO info;
2695 memset( &options, 0, sizeof(options) );
2697 SetLastError(0xdeadbeef);
2698 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
2699 error = GetLastError();
2700 ok( !ret, "expected failure\n" );
2701 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
2703 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2704 ok( session != NULL, "failed to open session %u\n", GetLastError() );
2706 SetLastError(0xdeadbeef);
2707 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
2708 error = GetLastError();
2709 ok( !ret, "expected failure\n" );
2710 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2712 SetLastError(0xdeadbeef);
2713 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
2714 error = GetLastError();
2715 ok( !ret, "expected failure\n" );
2716 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2718 SetLastError(0xdeadbeef);
2719 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
2720 error = GetLastError();
2721 ok( !ret, "expected failure\n" );
2722 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2724 SetLastError(0xdeadbeef);
2725 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2726 error = GetLastError();
2727 ok( !ret, "expected failure\n" );
2728 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2730 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2731 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2733 SetLastError(0xdeadbeef);
2734 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
2735 error = GetLastError();
2736 ok( !ret, "expected failure\n" );
2737 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2739 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2740 options.dwAutoDetectFlags = 0;
2742 SetLastError(0xdeadbeef);
2743 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2744 error = GetLastError();
2745 ok( !ret, "expected failure\n" );
2746 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2748 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
2749 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2751 SetLastError(0xdeadbeef);
2752 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2753 error = GetLastError();
2754 ok( !ret, "expected failure\n" );
2755 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2757 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2758 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2760 memset( &info, 0, sizeof(info) );
2761 SetLastError(0xdeadbeef);
2762 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2763 error = GetLastError();
2764 if (!ret) ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED ||
2765 error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
2768 trace("Proxy.AccessType=%u\n", info.dwAccessType);
2769 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
2770 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2771 GlobalFree( info.lpszProxy );
2772 GlobalFree( info.lpszProxyBypass );
2775 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
2776 options.dwAutoDetectFlags = 0;
2777 options.lpszAutoConfigUrl = wpadW;
2779 memset( &info, 0, sizeof(info) );
2780 SetLastError(0xdeadbeef);
2781 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2782 error = GetLastError();
2783 if (!ret) ok( error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
2786 trace("Proxy.AccessType=%u\n", info.dwAccessType);
2787 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
2788 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2789 GlobalFree( info.lpszProxy );
2790 GlobalFree( info.lpszProxyBypass );
2792 WinHttpCloseHandle( session );
2795 static void test_chunked_read(void)
2797 static const WCHAR host[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2798 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
2799 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
2802 HINTERNET ses, con = NULL, req = NULL;
2805 trace( "starting chunked read test\n" );
2807 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2808 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
2809 if (!ses) goto done;
2811 con = WinHttpConnect( ses, host, 0, 0 );
2812 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
2813 if (!con) goto done;
2815 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
2816 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
2817 if (!req) goto done;
2819 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2820 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
2822 ret = WinHttpReceiveResponse( req, NULL );
2823 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
2826 len = sizeof(header);
2827 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
2828 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
2829 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
2830 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
2833 len = sizeof(header);
2834 SetLastError( 0xdeadbeef );
2835 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
2836 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
2837 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
2839 trace( "entering query loop\n" );
2843 ret = WinHttpQueryDataAvailable( req, &len );
2844 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2845 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2846 trace( "got %u available\n", len );
2850 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
2852 ret = WinHttpReadData( req, buf, len, &bytes_read );
2854 buf[bytes_read] = 0;
2855 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
2856 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
2857 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
2859 HeapFree( GetProcessHeap(), 0, buf );
2860 if (!bytes_read) break;
2867 if (req) WinHttpCloseHandle( req );
2868 if (con) WinHttpCloseHandle( con );
2869 if (ses) WinHttpCloseHandle( ses );
2872 START_TEST (winhttp)
2874 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2875 static const WCHAR quitW[] = {'/','q','u','i','t',0};
2876 struct server_info si;
2882 test_WinHttpTimeFromSystemTime();
2883 test_WinHttpTimeToSystemTime();
2884 test_WinHttpAddHeaders();
2885 test_secure_connection();
2886 test_request_parameter_defaults();
2888 test_set_default_proxy_config();
2889 test_empty_headers_param();
2891 test_resolve_timeout();
2893 test_IWinHttpRequest();
2894 test_WinHttpDetectAutoProxyConfigUrl();
2895 test_WinHttpGetIEProxyConfigForCurrentUser();
2896 test_WinHttpGetProxyForUrl();
2897 test_chunked_read();
2899 si.event = CreateEvent(NULL, 0, 0, NULL);
2902 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2903 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2905 ret = WaitForSingleObject(si.event, 10000);
2906 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2907 if (ret != WAIT_OBJECT_0)
2910 test_connection_info(si.port);
2911 test_basic_request(si.port, NULL, basicW);
2912 test_no_headers(si.port);
2913 test_basic_authentication(si.port);
2914 test_bad_header(si.port);
2916 /* send the basic request again to shutdown the server thread */
2917 test_basic_request(si.port, NULL, quitW);
2919 WaitForSingleObject(thread, 3000);