ddf0f1a3f997a46d0847b00fc110807b428847c8
[reactos.git] / rostests / winetests / winhttp / winhttp.c
1 /*
2 * WinHTTP - tests
3 *
4 * Copyright 2008 Google (Zac Brown)
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #define WIN32_NO_STATUS
22 #define _INC_WINDOWS
23 #define COM_NO_WINDOWS_H
24
25 #define COBJMACROS
26 #include <stdarg.h>
27 //#include <stdlib.h>
28 #include <windef.h>
29 #include <winbase.h>
30 #include <ole2.h>
31 #include <winsock2.h>
32 //#include <ws2tcpip.h>
33 #include <winhttp.h>
34 #include <wincrypt.h>
35 #include <winreg.h>
36 //#include <winsock.h>
37 //#include "initguid.h"
38 #include <httprequest.h>
39
40 #include <wine/test.h>
41
42 static const WCHAR test_useragent[] =
43 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
44 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
45 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
46
47 static BOOL proxy_active(void)
48 {
49 WINHTTP_PROXY_INFO proxy_info;
50 BOOL active = FALSE;
51
52 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
53 {
54 active = (proxy_info.lpszProxy != NULL);
55 if (active)
56 GlobalFree(proxy_info.lpszProxy);
57 if (proxy_info.lpszProxyBypass != NULL)
58 GlobalFree(proxy_info.lpszProxyBypass);
59 }
60 else
61 active = FALSE;
62
63 return active;
64 }
65
66 static void test_QueryOption(void)
67 {
68 BOOL ret;
69 HINTERNET session, request, connection;
70 DWORD feature, size;
71
72 SetLastError(0xdeadbeef);
73 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
74 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
75
76 SetLastError(0xdeadbeef);
77 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
78 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
79 ok(GetLastError() == ERROR_INVALID_PARAMETER,
80 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
81
82 size = 0xdeadbeef;
83 SetLastError(0xdeadbeef);
84 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
85 ok(!ret, "should fail to query option\n");
86 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
87 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
88 ok(size == 4, "expected 4, got %u\n", size);
89
90 feature = 0xdeadbeef;
91 size = sizeof(feature) - 1;
92 SetLastError(0xdeadbeef);
93 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
94 ok(!ret, "should fail to query option\n");
95 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
96 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
97 ok(size == 4, "expected 4, got %u\n", size);
98
99 feature = 0xdeadbeef;
100 size = sizeof(feature) + 1;
101 SetLastError(0xdeadbeef);
102 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
103 ok(ret, "failed to query option %u\n", GetLastError());
104 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
105 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
106 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
107
108 SetLastError(0xdeadbeef);
109 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
110 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
111 ok(GetLastError() == ERROR_INVALID_PARAMETER,
112 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
113
114 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
115 SetLastError(0xdeadbeef);
116 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
117 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
118 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
119 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
120
121 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
122 SetLastError(0xdeadbeef);
123 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
124 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
125 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
126 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
127
128 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
129 SetLastError(0xdeadbeef);
130 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
131 ok(ret, "failed to set redirect policy %u\n", GetLastError());
132
133 feature = 0xdeadbeef;
134 size = sizeof(feature);
135 SetLastError(0xdeadbeef);
136 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
137 ok(ret, "failed to query option %u\n", GetLastError());
138 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
139 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
140
141 feature = WINHTTP_DISABLE_COOKIES;
142 SetLastError(0xdeadbeef);
143 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
144 ok(!ret, "should fail to set disable feature for a session\n");
145 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
146 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
147
148 SetLastError(0xdeadbeef);
149 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
150 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
151
152 feature = WINHTTP_DISABLE_COOKIES;
153 SetLastError(0xdeadbeef);
154 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
155 ok(!ret, "should fail to set disable feature for a connection\n");
156 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
157 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
158
159 SetLastError(0xdeadbeef);
160 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
161 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
162 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
163 {
164 skip("Network unreachable, skipping the test\n");
165 goto done;
166 }
167
168 feature = 0xdeadbeef;
169 size = sizeof(feature);
170 SetLastError(0xdeadbeef);
171 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
172 ok(!ret, "should fail to query disable feature for a request\n");
173 ok(GetLastError() == ERROR_INVALID_PARAMETER,
174 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
175
176 feature = 0;
177 size = sizeof(feature);
178 SetLastError(0xdeadbeef);
179 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
180 ok(ret, "failed to set feature %u\n", GetLastError());
181
182 feature = 0xffffffff;
183 size = sizeof(feature);
184 SetLastError(0xdeadbeef);
185 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
186 ok(ret, "failed to set feature %u\n", GetLastError());
187
188 feature = WINHTTP_DISABLE_COOKIES;
189 size = sizeof(feature);
190 SetLastError(0xdeadbeef);
191 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
192 ok(ret, "failed to set feature %u\n", GetLastError());
193
194 size = 0;
195 SetLastError(0xdeadbeef);
196 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
197 ok(!ret, "should fail to query disable feature for a request\n");
198 ok(GetLastError() == ERROR_INVALID_PARAMETER,
199 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
200
201 SetLastError(0xdeadbeef);
202 ret = WinHttpCloseHandle(request);
203 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
204
205 done:
206 SetLastError(0xdeadbeef);
207 ret = WinHttpCloseHandle(connection);
208 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
209 SetLastError(0xdeadbeef);
210 ret = WinHttpCloseHandle(session);
211 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
212 }
213
214 static void test_OpenRequest (void)
215 {
216 BOOL ret;
217 HINTERNET session, request, connection;
218
219 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
220 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
221 ok(session != NULL, "WinHttpOpen failed to open session.\n");
222
223 /* Test with a bad server name */
224 SetLastError(0xdeadbeef);
225 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
226 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
227 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
228
229 /* Test with a valid server name */
230 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
231 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
232
233 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
234 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
235 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
236 {
237 skip("Network unreachable, skipping.\n");
238 goto done;
239 }
240 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
241
242 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
243 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
244 {
245 skip("Connection failed, skipping.\n");
246 goto done;
247 }
248 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
249 ret = WinHttpCloseHandle(request);
250 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
251
252 done:
253 ret = WinHttpCloseHandle(connection);
254 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
255 ret = WinHttpCloseHandle(session);
256 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
257
258 }
259
260 static void test_empty_headers_param(void)
261 {
262 static const WCHAR empty[] = {0};
263 HINTERNET ses, con, req;
264 BOOL ret;
265
266 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
267 ok(ses != NULL, "failed to open session %u\n", GetLastError());
268
269 con = WinHttpConnect(ses, test_winehq, 80, 0);
270 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
271
272 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
273 ok(req != NULL, "failed to open a request %u\n", GetLastError());
274
275 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
276 ok(ret, "failed to send request %u\n", GetLastError());
277
278 WinHttpCloseHandle(req);
279 WinHttpCloseHandle(con);
280 WinHttpCloseHandle(ses);
281 }
282
283 static void test_SendRequest (void)
284 {
285 static const WCHAR content_type[] =
286 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
287 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
288 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
289 static const WCHAR test_verb[] = {'P','O','S','T',0};
290 static CHAR post_data[] = "mode=Test";
291 static const char test_post[] = "mode => Test\0\n";
292 HINTERNET session, request, connection;
293 DWORD header_len, optional_len, total_len, bytes_rw, size;
294 DWORD_PTR context;
295 BOOL ret;
296 CHAR buffer[256];
297 int i;
298
299 header_len = -1L;
300 total_len = optional_len = sizeof(post_data);
301 memset(buffer, 0xff, sizeof(buffer));
302
303 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
304 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
305 ok(session != NULL, "WinHttpOpen failed to open session.\n");
306
307 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
308 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
309
310 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
311 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
312 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
313 {
314 skip("Network unreachable, skipping.\n");
315 goto done;
316 }
317 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
318 if (!request) goto done;
319
320 context = 0xdeadbeef;
321 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
322 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
323
324 context++;
325 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
326 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
327
328 context = 0;
329 size = sizeof(context);
330 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
331 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
332 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
333
334 for (i = 3; post_data[i]; i++)
335 {
336 bytes_rw = -1;
337 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
338 if (ret)
339 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
340 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
341 {
342 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
343 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
344 }
345 }
346
347 ret = WinHttpReceiveResponse(request, NULL);
348 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
349
350 bytes_rw = -1;
351 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
352 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
353
354 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw);
355 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
356
357 ret = WinHttpCloseHandle(request);
358 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
359 done:
360 ret = WinHttpCloseHandle(connection);
361 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
362 ret = WinHttpCloseHandle(session);
363 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
364 }
365
366 static void test_WinHttpTimeFromSystemTime(void)
367 {
368 BOOL ret;
369 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
370 static const WCHAR expected_string[] =
371 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
372 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
373 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
374
375 ret = WinHttpTimeFromSystemTime(&time, time_string);
376 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
377 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
378 "Time string returned did not match expected time string.\n");
379 }
380
381 static void test_WinHttpTimeToSystemTime(void)
382 {
383 BOOL ret;
384 SYSTEMTIME time;
385 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
386 static const WCHAR time_string1[] =
387 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
388 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
389 static const WCHAR time_string2[] =
390 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
391 '1','0',' ','0','5',' ','5','2','\n',0};
392
393 ret = WinHttpTimeToSystemTime(time_string1, &time);
394 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
395 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
396 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
397
398 ret = WinHttpTimeToSystemTime(time_string2, &time);
399 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
400 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
401 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
402 }
403
404 static void test_WinHttpAddHeaders(void)
405 {
406 HINTERNET session, request, connection;
407 BOOL ret, reverse;
408 WCHAR buffer[MAX_PATH];
409 WCHAR check_buffer[MAX_PATH];
410 DWORD index, len, oldlen;
411
412 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
413 static const WCHAR test_verb[] = {'P','O','S','T',0};
414 static const WCHAR test_header_begin[] =
415 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
416 static const WCHAR full_path_test_header_begin[] =
417 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0','/','p','o','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
418 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
419 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
420
421 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
422 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
423 static const WCHAR test_flag_coalesce_comma[] =
424 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
425 static const WCHAR test_flag_coalesce_comma_reverse[] =
426 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
427 static const WCHAR test_flag_coalesce_semicolon[] =
428 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
430 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
431
432 static const WCHAR field[] = {'f','i','e','l','d',0};
433 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
434 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
435
436 static const WCHAR test_headers[][14] =
437 {
438 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
439 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
440 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
441 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
442 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
443 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
444 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
445 {0},
446 {':',0},
447 {'a',':',0},
448 {':','b',0},
449 {'c','d',0},
450 {' ','e',' ',':','f',0},
451 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
452 };
453 static const WCHAR test_indices[][6] =
454 {
455 {'t','e','s','t','1',0},
456 {'t','e','s','t','2',0},
457 {'t','e','s','t','3',0},
458 {'t','e','s','t','4',0}
459 };
460
461 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
462 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
463 ok(session != NULL, "WinHttpOpen failed to open session.\n");
464
465 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
466 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
467
468 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
469 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
470 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
471 {
472 skip("Network unreachable, skipping.\n");
473 goto done;
474 }
475 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
476
477 index = 0;
478 len = sizeof(buffer);
479 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
480 test_header_name, buffer, &len, &index);
481 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
482 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
483 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
484
485 index = 0;
486 len = sizeof(buffer);
487 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
488 test_header_name, buffer, &len, &index);
489 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
490 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
491 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
492 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
493
494 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
495 test_header_name, buffer, &len, &index);
496 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
497
498 /* Try to fetch the header info with a buffer that's big enough to fit the
499 * string but not the NULL terminator.
500 */
501 index = 0;
502 len = 5*sizeof(WCHAR);
503 memset(check_buffer, 0xab, sizeof(check_buffer));
504 memcpy(buffer, check_buffer, sizeof(buffer));
505 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
506 test_header_name, buffer, &len, &index);
507 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
508 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
509 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
510 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
511
512 /* Try with a NULL buffer */
513 index = 0;
514 len = sizeof(buffer);
515 SetLastError(0xdeadbeef);
516 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
517 test_header_name, NULL, &len, &index);
518 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
520 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
521 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
522
523 /* Try with a NULL buffer and a length that's too small */
524 index = 0;
525 len = 10;
526 SetLastError(0xdeadbeef);
527 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
528 test_header_name, NULL, &len, &index);
529 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
530 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
531 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
532 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
533 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
534
535 index = 0;
536 len = 0;
537 SetLastError(0xdeadbeef);
538 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
539 test_header_name, NULL, &len, &index);
540 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
541 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
542 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
543 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
544 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
545
546 /* valid query */
547 oldlen = len;
548 index = 0;
549 len = sizeof(buffer);
550 memset(buffer, 0xff, sizeof(buffer));
551 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
552 test_header_name, buffer, &len, &index);
553 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
554 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
555 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
556 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
557 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
558 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
559 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
560 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
561 "WinHttpQueryHeaders returned invalid end of header string.\n");
562 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
563
564 index = 0;
565 len = 0;
566 SetLastError(0xdeadbeef);
567 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
568 test_header_name, NULL, &len, &index);
569 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
570 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
571 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
572 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
573 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
574
575 oldlen = len;
576 index = 0;
577 len = sizeof(buffer);
578 memset(buffer, 0xff, sizeof(buffer));
579 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
580 test_header_name, buffer, &len, &index);
581 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
582 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
583 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
584 "no double NULL terminator\n");
585 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
586 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
587 "invalid beginning of header string.\n");
588 ok(index == 0, "header index was incremented\n");
589
590 /* tests for more indices */
591 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
592 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
593
594 index = 0;
595 len = sizeof(buffer);
596 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
597 test_header_name, buffer, &len, &index);
598 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
599 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
600 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
601
602 len = sizeof(buffer);
603 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
604 test_header_name, buffer, &len, &index);
605 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
606 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
607 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
608
609 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
610 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
611
612 index = 0;
613 len = sizeof(buffer);
614 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
615 test_header_name, buffer, &len, &index);
616 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
617 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
618 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
619 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
620
621 len = sizeof(buffer);
622 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
623 test_header_name, buffer, &len, &index);
624 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
625 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
626 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
627
628 /* add if new flag */
629 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
630 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
631
632 index = 0;
633 len = sizeof(buffer);
634 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
635 test_header_name, buffer, &len, &index);
636 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
637 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
638 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
639
640 len = sizeof(buffer);
641 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
642 test_header_name, buffer, &len, &index);
643 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
644 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
645 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
646
647 len = sizeof(buffer);
648 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
649 test_header_name, buffer, &len, &index);
650 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
651
652 /* coalesce flag */
653 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
654 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
655
656 index = 0;
657 len = sizeof(buffer);
658 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
659 test_header_name, buffer, &len, &index);
660 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
661 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
662 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
663 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
664
665 len = sizeof(buffer);
666 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
667 test_header_name, buffer, &len, &index);
668 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
669 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
670 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
671
672 len = sizeof(buffer);
673 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
674 test_header_name, buffer, &len, &index);
675 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
676
677 /* coalesce with comma flag */
678 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
679 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
680
681 index = 0;
682 len = sizeof(buffer);
683 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
684 test_header_name, buffer, &len, &index);
685 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
686 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
687 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
688 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
689 "WinHttpQueryHeaders returned incorrect string.\n");
690
691 len = sizeof(buffer);
692 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
693 test_header_name, buffer, &len, &index);
694 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
697
698 len = sizeof(buffer);
699 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
700 test_header_name, buffer, &len, &index);
701 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
702
703
704 /* coalesce with semicolon flag */
705 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
706 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
707
708 index = 0;
709 len = sizeof(buffer);
710 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
711 test_header_name, buffer, &len, &index);
712 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
713 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
714 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
715 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
716 "WinHttpQueryHeaders returned incorrect string.\n");
717
718 len = sizeof(buffer);
719 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
720 test_header_name, buffer, &len, &index);
721 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
722 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
723 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
724
725 len = sizeof(buffer);
726 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
727 test_header_name, buffer, &len, &index);
728 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
729
730 /* add and replace flags */
731 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
732 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
733
734 index = 0;
735 len = sizeof(buffer);
736 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
737 test_header_name, buffer, &len, &index);
738 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
739 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
740 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
741
742 len = sizeof(buffer);
743 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
744 test_header_name, buffer, &len, &index);
745 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
746 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
747 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
748
749 len = sizeof(buffer);
750 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
751 test_header_name, buffer, &len, &index);
752 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
753
754 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
755 ok(!ret, "WinHttpAddRequestHeaders failed\n");
756
757 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
758 ok(ret, "WinHttpAddRequestHeaders failed\n");
759
760 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
761 ok(!ret, "WinHttpAddRequestHeaders failed\n");
762
763 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
764 ok(!ret, "WinHttpAddRequestHeaders failed\n");
765
766 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
767 ok(!ret, "WinHttpAddRequestHeaders failed\n");
768
769 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
770 ok(ret, "WinHttpAddRequestHeaders failed\n");
771
772 index = 0;
773 buffer[0] = 0;
774 len = sizeof(buffer);
775 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
776 field, buffer, &len, &index);
777 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
778 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
779
780 ret = WinHttpCloseHandle(request);
781 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
782 done:
783 ret = WinHttpCloseHandle(connection);
784 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
785 ret = WinHttpCloseHandle(session);
786 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
787
788 }
789
790 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len)
791 {
792 DWORD flags = *(DWORD *)buf;
793
794 if (!flags)
795 {
796 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
797 return;
798 }
799 #define X(x) if (flags & x) trace("%s\n", #x);
800 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
801 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
802 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
803 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
804 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
805 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
806 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
807 #undef X
808 }
809
810 static void test_secure_connection(void)
811 {
812 HINTERNET ses, con, req;
813 DWORD size, status, policy, bitness, read_size;
814 BOOL ret;
815 CERT_CONTEXT *cert;
816 WINHTTP_CERTIFICATE_INFO info;
817 char buffer[32];
818
819 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
820 ok(ses != NULL, "failed to open session %u\n", GetLastError());
821
822 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
823 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
824 ok(ret, "failed to set redirect policy %u\n", GetLastError());
825
826 con = WinHttpConnect(ses, test_winehq, 443, 0);
827 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
828
829 /* try without setting WINHTTP_FLAG_SECURE */
830 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
831 ok(req != NULL, "failed to open a request %u\n", GetLastError());
832
833 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
834 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
835 {
836 skip("Connection failed, skipping.\n");
837 goto cleanup;
838 }
839 ok(ret, "failed to send request %u\n", GetLastError());
840
841 ret = WinHttpReceiveResponse(req, NULL);
842 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
843
844 size = 0;
845 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
846 ok(!ret, "succeeded unexpectedly\n");
847
848 WinHttpCloseHandle(req);
849
850 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
851 ok(req != NULL, "failed to open a request %u\n", GetLastError());
852
853 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
854
855 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
856 ok(ret, "failed to send request %u\n", GetLastError());
857 if (!ret)
858 {
859 skip("secure connection failed, skipping remaining secure tests\n");
860 goto cleanup;
861 }
862
863 size = sizeof(cert);
864 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
865 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
866 if (ret)
867 CertFreeCertificateContext(cert);
868
869 size = sizeof(bitness);
870 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
871 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
872
873 size = sizeof(info);
874 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
875 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
876
877 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
878 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
879 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
880 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
881 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
882 trace("dwKeySize %u\n", info.dwKeySize);
883
884 ret = WinHttpReceiveResponse(req, NULL);
885 ok(ret, "failed to receive response %u\n", GetLastError());
886
887 size = sizeof(status);
888 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
889 ok(ret, "failed unexpectedly %u\n", GetLastError());
890 ok(status == 200, "request failed unexpectedly %u\n", status);
891
892 size = 0;
893 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
894 ok(!ret, "succeeded unexpectedly\n");
895
896 read_size = 0;
897 for (;;)
898 {
899 size = 0;
900 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
901 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
902 if (!size) break;
903 read_size += size;
904 }
905 ok(read_size > 2014, "read_size = %u\n", read_size);
906
907 cleanup:
908 WinHttpCloseHandle(req);
909 WinHttpCloseHandle(con);
910 WinHttpCloseHandle(ses);
911 }
912
913 static void test_request_parameter_defaults(void)
914 {
915 static const WCHAR empty[] = {0};
916 HINTERNET ses, con, req;
917 DWORD size, status, error;
918 WCHAR *version;
919 BOOL ret;
920
921 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
922 ok(ses != NULL, "failed to open session %u\n", GetLastError());
923
924 con = WinHttpConnect(ses, test_winehq, 0, 0);
925 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
926
927 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
928 ok(req != NULL, "failed to open a request %u\n", GetLastError());
929
930 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
931 ok(ret, "failed to send request %u\n", GetLastError());
932
933 ret = WinHttpReceiveResponse(req, NULL);
934 ok(ret, "failed to receive response %u\n", GetLastError());
935
936 size = sizeof(status);
937 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
938 ok(ret, "failed unexpectedly %u\n", GetLastError());
939 ok(status == 200, "request failed unexpectedly %u\n", status);
940
941 WinHttpCloseHandle(req);
942
943 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
944 ok(req != NULL, "failed to open a request %u\n", GetLastError());
945
946 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
947 ok(ret, "failed to send request %u\n", GetLastError());
948
949 ret = WinHttpReceiveResponse(req, NULL);
950 ok(ret, "failed to receive response %u\n", GetLastError());
951
952 size = 0;
953 SetLastError(0xdeadbeef);
954 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
955 error = GetLastError();
956 ok(!ret, "succeeded unexpectedly\n");
957 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
958
959 version = HeapAlloc(GetProcessHeap(), 0, size);
960 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
961 ok(ret, "failed unexpectedly %u\n", GetLastError());
962 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
963 HeapFree(GetProcessHeap(), 0, version);
964
965 size = sizeof(status);
966 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
967 ok(ret, "failed unexpectedly %u\n", GetLastError());
968 ok(status == 200, "request failed unexpectedly %u\n", status);
969
970 WinHttpCloseHandle(req);
971 WinHttpCloseHandle(con);
972 WinHttpCloseHandle(ses);
973 }
974
975 static const WCHAR Connections[] = {
976 'S','o','f','t','w','a','r','e','\\',
977 'M','i','c','r','o','s','o','f','t','\\',
978 'W','i','n','d','o','w','s','\\',
979 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
980 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
981 'C','o','n','n','e','c','t','i','o','n','s',0 };
982 static const WCHAR WinHttpSettings[] = {
983 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
984
985 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
986 {
987 LONG l;
988 HKEY key;
989 DWORD ret = 0;
990
991 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
992 if (!l)
993 {
994 DWORD size = 0;
995
996 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
997 if (!l)
998 {
999 if (size <= len)
1000 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1001 &size );
1002 if (!l)
1003 ret = size;
1004 }
1005 RegCloseKey( key );
1006 }
1007 return ret;
1008 }
1009
1010 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1011 {
1012 LONG l;
1013 HKEY key;
1014
1015 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
1016 KEY_WRITE, NULL, &key, NULL );
1017 if (!l)
1018 {
1019 if (len)
1020 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1021 else
1022 RegDeleteValueW( key, WinHttpSettings );
1023 RegCloseKey( key );
1024 }
1025 }
1026
1027 static void test_set_default_proxy_config(void)
1028 {
1029 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1030 static WCHAR normalString[] = { 'f','o','o',0 };
1031 DWORD type, len;
1032 BYTE *saved_proxy_settings = NULL;
1033 WINHTTP_PROXY_INFO info;
1034 BOOL ret;
1035
1036 /* FIXME: it would be simpler to read the current settings using
1037 * WinHttpGetDefaultProxyConfiguration and save them using
1038 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1039 *
1040 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1041 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1042 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1043 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1044 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1045 * the lpszProxy and lpszProxyBypass values are ignored.
1046 * Thus, if a proxy is set with proxycfg, then calling
1047 * WinHttpGetDefaultProxyConfiguration followed by
1048 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1049 * getting deleted from the registry.
1050 *
1051 * Instead I read the current registry value and restore it directly.
1052 */
1053 len = get_default_proxy_reg_value( NULL, 0, &type );
1054 if (len)
1055 {
1056 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1057 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1058 }
1059
1060 if (0)
1061 {
1062 /* Crashes on Vista and higher */
1063 SetLastError(0xdeadbeef);
1064 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1065 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1066 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1067 }
1068
1069 /* test with invalid access type */
1070 info.dwAccessType = 0xdeadbeef;
1071 info.lpszProxy = info.lpszProxyBypass = NULL;
1072 SetLastError(0xdeadbeef);
1073 ret = WinHttpSetDefaultProxyConfiguration(&info);
1074 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1075 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1076
1077 /* at a minimum, the proxy server must be set */
1078 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1079 info.lpszProxy = info.lpszProxyBypass = NULL;
1080 SetLastError(0xdeadbeef);
1081 ret = WinHttpSetDefaultProxyConfiguration(&info);
1082 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1083 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1084 info.lpszProxyBypass = normalString;
1085 SetLastError(0xdeadbeef);
1086 ret = WinHttpSetDefaultProxyConfiguration(&info);
1087 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1088 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1089
1090 /* the proxy server can't have wide characters */
1091 info.lpszProxy = wideString;
1092 SetLastError(0xdeadbeef);
1093 ret = WinHttpSetDefaultProxyConfiguration(&info);
1094 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1095 skip("couldn't set default proxy configuration: access denied\n");
1096 else
1097 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1098 broken(ret), /* Earlier winhttp versions on W2K/XP */
1099 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1100
1101 info.lpszProxy = normalString;
1102 SetLastError(0xdeadbeef);
1103 ret = WinHttpSetDefaultProxyConfiguration(&info);
1104 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1105 skip("couldn't set default proxy configuration: access denied\n");
1106 else
1107 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1108 GetLastError());
1109
1110 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1111 }
1112
1113 static void test_Timeouts (void)
1114 {
1115 BOOL ret;
1116 DWORD value, size;
1117 HINTERNET ses, req, con;
1118
1119 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1120 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1121
1122 SetLastError(0xdeadbeef);
1123 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1124 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1125 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1126
1127 SetLastError(0xdeadbeef);
1128 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1129 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1130 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1131
1132 SetLastError(0xdeadbeef);
1133 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1134 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1135 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1136
1137 SetLastError(0xdeadbeef);
1138 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1139 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1140 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1141
1142 SetLastError(0xdeadbeef);
1143 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1144 ok(ret, "%u\n", GetLastError());
1145
1146 SetLastError(0xdeadbeef);
1147 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1148 ok(ret, "%u\n", GetLastError());
1149
1150 SetLastError(0xdeadbeef);
1151 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1152 ok(ret, "%u\n", GetLastError());
1153
1154 SetLastError(0xdeadbeef);
1155 value = 0xdeadbeef;
1156 size = sizeof(DWORD);
1157 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1158 ok(ret, "%u\n", GetLastError());
1159 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1160
1161 SetLastError(0xdeadbeef);
1162 value = 0xdeadbeef;
1163 size = sizeof(DWORD);
1164 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1165 ok(ret, "%u\n", GetLastError());
1166 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1167
1168 SetLastError(0xdeadbeef);
1169 value = 0xdeadbeef;
1170 size = sizeof(DWORD);
1171 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1172 ok(ret, "%u\n", GetLastError());
1173 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1174
1175 SetLastError(0xdeadbeef);
1176 value = 0xdeadbeef;
1177 size = sizeof(DWORD);
1178 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1179 ok(ret, "%u\n", GetLastError());
1180 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1181
1182 SetLastError(0xdeadbeef);
1183 value = 0;
1184 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1185 ok(ret, "%u\n", GetLastError());
1186
1187 SetLastError(0xdeadbeef);
1188 value = 0xdeadbeef;
1189 size = sizeof(DWORD);
1190 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1191 ok(ret, "%u\n", GetLastError());
1192 ok(value == 0, "Expected 0, got %u\n", value);
1193
1194 SetLastError(0xdeadbeef);
1195 value = 0;
1196 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1197 ok(ret, "%u\n", GetLastError());
1198
1199 SetLastError(0xdeadbeef);
1200 value = 0xdeadbeef;
1201 size = sizeof(DWORD);
1202 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1203 ok(ret, "%u\n", GetLastError());
1204 ok(value == 0, "Expected 0, got %u\n", value);
1205
1206 SetLastError(0xdeadbeef);
1207 value = 0;
1208 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1209 ok(ret, "%u\n", GetLastError());
1210
1211 SetLastError(0xdeadbeef);
1212 value = 0xdeadbeef;
1213 size = sizeof(DWORD);
1214 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1215 ok(ret, "%u\n", GetLastError());
1216 ok(value == 0, "Expected 0, got %u\n", value);
1217
1218 SetLastError(0xdeadbeef);
1219 value = 0;
1220 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1221 ok(ret, "%u\n", GetLastError());
1222
1223 SetLastError(0xdeadbeef);
1224 value = 0xdeadbeef;
1225 size = sizeof(DWORD);
1226 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1227 ok(ret, "%u\n", GetLastError());
1228 ok(value == 0, "Expected 0, got %u\n", value);
1229
1230 SetLastError(0xdeadbeef);
1231 value = 0xbeefdead;
1232 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1233 ok(ret, "%u\n", GetLastError());
1234
1235 SetLastError(0xdeadbeef);
1236 value = 0xdeadbeef;
1237 size = sizeof(DWORD);
1238 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1239 ok(ret, "%u\n", GetLastError());
1240 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1241
1242 SetLastError(0xdeadbeef);
1243 value = 0xbeefdead;
1244 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1245 ok(ret, "%u\n", GetLastError());
1246
1247 SetLastError(0xdeadbeef);
1248 value = 0xdeadbeef;
1249 size = sizeof(DWORD);
1250 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1251 ok(ret, "%u\n", GetLastError());
1252 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1253
1254 SetLastError(0xdeadbeef);
1255 value = 0xbeefdead;
1256 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1257 ok(ret, "%u\n", GetLastError());
1258
1259 SetLastError(0xdeadbeef);
1260 value = 0xdeadbeef;
1261 size = sizeof(DWORD);
1262 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1263 ok(ret, "%u\n", GetLastError());
1264 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1265
1266 SetLastError(0xdeadbeef);
1267 value = 0xbeefdead;
1268 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1269 ok(ret, "%u\n", GetLastError());
1270
1271 SetLastError(0xdeadbeef);
1272 value = 0xdeadbeef;
1273 size = sizeof(DWORD);
1274 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1275 ok(ret, "%u\n", GetLastError());
1276 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1277
1278 con = WinHttpConnect(ses, test_winehq, 0, 0);
1279 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1280
1281 /* Timeout values should match the last one set for session */
1282 SetLastError(0xdeadbeef);
1283 value = 0xdeadbeef;
1284 size = sizeof(DWORD);
1285 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1286 ok(ret, "%u\n", GetLastError());
1287 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1288
1289 SetLastError(0xdeadbeef);
1290 value = 0xdeadbeef;
1291 size = sizeof(DWORD);
1292 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1293 ok(ret, "%u\n", GetLastError());
1294 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1295
1296 SetLastError(0xdeadbeef);
1297 value = 0xdeadbeef;
1298 size = sizeof(DWORD);
1299 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1300 ok(ret, "%u\n", GetLastError());
1301 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1302
1303 SetLastError(0xdeadbeef);
1304 value = 0xdeadbeef;
1305 size = sizeof(DWORD);
1306 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1307 ok(ret, "%u\n", GetLastError());
1308 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1309
1310 SetLastError(0xdeadbeef);
1311 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1312 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1313 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1314
1315 SetLastError(0xdeadbeef);
1316 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1317 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1318 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1319
1320 SetLastError(0xdeadbeef);
1321 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1322 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1323 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1324
1325 SetLastError(0xdeadbeef);
1326 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1327 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1328 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1329
1330 SetLastError(0xdeadbeef);
1331 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1332 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1333 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1334
1335 SetLastError(0xdeadbeef);
1336 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1337 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1338 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1339
1340 SetLastError(0xdeadbeef);
1341 value = 0;
1342 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1343 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1344 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1345
1346 SetLastError(0xdeadbeef);
1347 value = 0;
1348 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1349 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1350 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1351
1352 SetLastError(0xdeadbeef);
1353 value = 0;
1354 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1355 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1356 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1357
1358 SetLastError(0xdeadbeef);
1359 value = 0;
1360 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1361 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1362 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1363
1364 /* Changing timeout values for session should affect the values for connection */
1365 SetLastError(0xdeadbeef);
1366 value = 0xdead;
1367 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1368 ok(ret, "%u\n", GetLastError());
1369
1370 SetLastError(0xdeadbeef);
1371 value = 0xdeadbeef;
1372 size = sizeof(DWORD);
1373 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1374 ok(ret, "%u\n", GetLastError());
1375 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1376
1377 SetLastError(0xdeadbeef);
1378 value = 0xdead;
1379 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1380 ok(ret, "%u\n", GetLastError());
1381
1382 SetLastError(0xdeadbeef);
1383 value = 0xdeadbeef;
1384 size = sizeof(DWORD);
1385 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1386 ok(ret, "%u\n", GetLastError());
1387 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1388
1389 SetLastError(0xdeadbeef);
1390 value = 0xdead;
1391 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1392 ok(ret, "%u\n", GetLastError());
1393
1394 SetLastError(0xdeadbeef);
1395 value = 0xdeadbeef;
1396 size = sizeof(DWORD);
1397 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1398 ok(ret, "%u\n", GetLastError());
1399 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1400
1401 SetLastError(0xdeadbeef);
1402 value = 0xdead;
1403 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1404 ok(ret, "%u\n", GetLastError());
1405
1406 SetLastError(0xdeadbeef);
1407 value = 0xdeadbeef;
1408 size = sizeof(DWORD);
1409 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1410 ok(ret, "%u\n", GetLastError());
1411 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1412
1413 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1414 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1415
1416 /* Timeout values should match the last one set for session */
1417 SetLastError(0xdeadbeef);
1418 value = 0xdeadbeef;
1419 size = sizeof(DWORD);
1420 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1421 ok(ret, "%u\n", GetLastError());
1422 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1423
1424 SetLastError(0xdeadbeef);
1425 value = 0xdeadbeef;
1426 size = sizeof(DWORD);
1427 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1428 ok(ret, "%u\n", GetLastError());
1429 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1430
1431 SetLastError(0xdeadbeef);
1432 value = 0xdeadbeef;
1433 size = sizeof(DWORD);
1434 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1435 ok(ret, "%u\n", GetLastError());
1436 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1437
1438 SetLastError(0xdeadbeef);
1439 value = 0xdeadbeef;
1440 size = sizeof(DWORD);
1441 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1442 ok(ret, "%u\n", GetLastError());
1443 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1444
1445 SetLastError(0xdeadbeef);
1446 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1447 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1448 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1449
1450 SetLastError(0xdeadbeef);
1451 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1452 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1453 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1454
1455 SetLastError(0xdeadbeef);
1456 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1457 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1458 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1459
1460 SetLastError(0xdeadbeef);
1461 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1462 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1463 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1464
1465 SetLastError(0xdeadbeef);
1466 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1467 ok(ret, "%u\n", GetLastError());
1468
1469 SetLastError(0xdeadbeef);
1470 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1471 ok(ret, "%u\n", GetLastError());
1472
1473 SetLastError(0xdeadbeef);
1474 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1475 ok(ret, "%u\n", GetLastError());
1476
1477 SetLastError(0xdeadbeef);
1478 value = 0xdeadbeef;
1479 size = sizeof(DWORD);
1480 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1481 ok(ret, "%u\n", GetLastError());
1482 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1483
1484 SetLastError(0xdeadbeef);
1485 value = 0xdeadbeef;
1486 size = sizeof(DWORD);
1487 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1488 ok(ret, "%u\n", GetLastError());
1489 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1490
1491 SetLastError(0xdeadbeef);
1492 value = 0xdeadbeef;
1493 size = sizeof(DWORD);
1494 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1495 ok(ret, "%u\n", GetLastError());
1496 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1497
1498 SetLastError(0xdeadbeef);
1499 value = 0xdeadbeef;
1500 size = sizeof(DWORD);
1501 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1502 ok(ret, "%u\n", GetLastError());
1503 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1504
1505 SetLastError(0xdeadbeef);
1506 value = 0;
1507 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1508 ok(ret, "%u\n", GetLastError());
1509
1510 SetLastError(0xdeadbeef);
1511 value = 0xdeadbeef;
1512 size = sizeof(DWORD);
1513 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1514 ok(ret, "%u\n", GetLastError());
1515 ok(value == 0, "Expected 0, got %u\n", value);
1516
1517 SetLastError(0xdeadbeef);
1518 value = 0;
1519 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1520 ok(ret, "%u\n", GetLastError());
1521
1522 SetLastError(0xdeadbeef);
1523 value = 0xdeadbeef;
1524 size = sizeof(DWORD);
1525 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1526 ok(ret, "%u\n", GetLastError());
1527 ok(value == 0, "Expected 0, got %u\n", value);
1528
1529 SetLastError(0xdeadbeef);
1530 value = 0;
1531 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1532 ok(ret, "%u\n", GetLastError());
1533
1534 SetLastError(0xdeadbeef);
1535 value = 0xdeadbeef;
1536 size = sizeof(DWORD);
1537 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1538 ok(ret, "%u\n", GetLastError());
1539 ok(value == 0, "Expected 0, got %u\n", value);
1540
1541 SetLastError(0xdeadbeef);
1542 value = 0;
1543 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1544 ok(ret, "%u\n", GetLastError());
1545
1546 SetLastError(0xdeadbeef);
1547 value = 0xdeadbeef;
1548 size = sizeof(DWORD);
1549 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1550 ok(ret, "%u\n", GetLastError());
1551 ok(value == 0, "Expected 0, got %u\n", value);
1552
1553 SetLastError(0xdeadbeef);
1554 value = 0xbeefdead;
1555 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1556 ok(ret, "%u\n", GetLastError());
1557
1558 SetLastError(0xdeadbeef);
1559 value = 0xdeadbeef;
1560 size = sizeof(DWORD);
1561 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1562 ok(ret, "%u\n", GetLastError());
1563 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1564
1565 SetLastError(0xdeadbeef);
1566 value = 0xbeefdead;
1567 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1568 ok(ret, "%u\n", GetLastError());
1569
1570 SetLastError(0xdeadbeef);
1571 value = 0xdeadbeef;
1572 size = sizeof(DWORD);
1573 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1574 ok(ret, "%u\n", GetLastError());
1575 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1576
1577 SetLastError(0xdeadbeef);
1578 value = 0xbeefdead;
1579 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1580 ok(ret, "%u\n", GetLastError());
1581
1582 SetLastError(0xdeadbeef);
1583 value = 0xdeadbeef;
1584 size = sizeof(DWORD);
1585 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1586 ok(ret, "%u\n", GetLastError());
1587 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1588
1589 SetLastError(0xdeadbeef);
1590 value = 0xbeefdead;
1591 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1592 ok(ret, "%u\n", GetLastError());
1593
1594 SetLastError(0xdeadbeef);
1595 value = 0xdeadbeef;
1596 size = sizeof(DWORD);
1597 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1598 ok(ret, "%u\n", GetLastError());
1599 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1600
1601 /* Changing timeout values for session should not affect the values for a request,
1602 * neither should the other way around.
1603 */
1604 SetLastError(0xdeadbeef);
1605 value = 0xbeefdead;
1606 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1607 ok(ret, "%u\n", GetLastError());
1608
1609 SetLastError(0xdeadbeef);
1610 value = 0xdeadbeef;
1611 size = sizeof(DWORD);
1612 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1613 ok(ret, "%u\n", GetLastError());
1614 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1615
1616 SetLastError(0xdeadbeef);
1617 value = 0xbeefdead;
1618 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1619 ok(ret, "%u\n", GetLastError());
1620
1621 SetLastError(0xdeadbeef);
1622 value = 0xdeadbeef;
1623 size = sizeof(DWORD);
1624 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1625 ok(ret, "%u\n", GetLastError());
1626 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1627
1628 SetLastError(0xdeadbeef);
1629 value = 0xbeefdead;
1630 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1631 ok(ret, "%u\n", GetLastError());
1632
1633 SetLastError(0xdeadbeef);
1634 value = 0xdeadbeef;
1635 size = sizeof(DWORD);
1636 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1637 ok(ret, "%u\n", GetLastError());
1638 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1639
1640 SetLastError(0xdeadbeef);
1641 value = 0xbeefdead;
1642 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1643 ok(ret, "%u\n", GetLastError());
1644
1645 SetLastError(0xdeadbeef);
1646 value = 0xdeadbeef;
1647 size = sizeof(DWORD);
1648 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1649 ok(ret, "%u\n", GetLastError());
1650 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1651
1652 SetLastError(0xdeadbeef);
1653 value = 0xbeef;
1654 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1655 ok(ret, "%u\n", GetLastError());
1656
1657 SetLastError(0xdeadbeef);
1658 value = 0xdeadbeef;
1659 size = sizeof(DWORD);
1660 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1661 ok(ret, "%u\n", GetLastError());
1662 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1663
1664 SetLastError(0xdeadbeef);
1665 value = 0xbeef;
1666 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1667 ok(ret, "%u\n", GetLastError());
1668
1669 SetLastError(0xdeadbeef);
1670 value = 0xdeadbeef;
1671 size = sizeof(DWORD);
1672 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1673 ok(ret, "%u\n", GetLastError());
1674 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1675
1676 SetLastError(0xdeadbeef);
1677 value = 0xbeef;
1678 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1679 ok(ret, "%u\n", GetLastError());
1680
1681 SetLastError(0xdeadbeef);
1682 value = 0xdeadbeef;
1683 size = sizeof(DWORD);
1684 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1685 ok(ret, "%u\n", GetLastError());
1686 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1687
1688 SetLastError(0xdeadbeef);
1689 value = 0xbeef;
1690 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1691 ok(ret, "%u\n", GetLastError());
1692
1693 SetLastError(0xdeadbeef);
1694 value = 0xdeadbeef;
1695 size = sizeof(DWORD);
1696 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1697 ok(ret, "%u\n", GetLastError());
1698 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1699
1700 WinHttpCloseHandle(req);
1701 WinHttpCloseHandle(con);
1702 WinHttpCloseHandle(ses);
1703 }
1704
1705 static void test_resolve_timeout(void)
1706 {
1707 static const WCHAR nxdomain[] =
1708 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1709 HINTERNET ses, con, req;
1710 DWORD timeout;
1711 BOOL ret;
1712
1713 if (! proxy_active())
1714 {
1715 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1716 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1717
1718 timeout = 10000;
1719 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1720 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1721
1722 con = WinHttpConnect(ses, nxdomain, 0, 0);
1723 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1724
1725 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1726 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1727
1728 SetLastError(0xdeadbeef);
1729 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1730 if(ret == 1)
1731 {
1732 skip("nxdomain returned success. Broken ISP redirects?\n");
1733 return;
1734 }
1735 ok(!ret, "sent request\n");
1736 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1737 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1738
1739 WinHttpCloseHandle(req);
1740 WinHttpCloseHandle(con);
1741 WinHttpCloseHandle(ses);
1742 }
1743 else
1744 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1745
1746 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1747 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1748
1749 timeout = 10000;
1750 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1751 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1752
1753 con = WinHttpConnect(ses, test_winehq, 0, 0);
1754 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1755
1756 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1757 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1758
1759 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1760 ok(ret, "failed to send request\n");
1761
1762 WinHttpCloseHandle(req);
1763 WinHttpCloseHandle(con);
1764 WinHttpCloseHandle(ses);
1765 }
1766
1767 static const char page1[] =
1768 "<HTML>\r\n"
1769 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1770 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1771 "</HTML>\r\n\r\n";
1772
1773 static const char okmsg[] =
1774 "HTTP/1.1 200 OK\r\n"
1775 "Server: winetest\r\n"
1776 "\r\n";
1777
1778 static const char noauthmsg[] =
1779 "HTTP/1.1 401 Unauthorized\r\n"
1780 "Server: winetest\r\n"
1781 "Connection: close\r\n"
1782 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1783 "\r\n";
1784
1785 static const char proxymsg[] =
1786 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1787 "Server: winetest\r\n"
1788 "Proxy-Connection: close\r\n"
1789 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1790 "\r\n";
1791
1792 struct server_info
1793 {
1794 HANDLE event;
1795 int port;
1796 };
1797
1798 #define BIG_BUFFER_LEN 0x2250
1799
1800 static DWORD CALLBACK server_thread(LPVOID param)
1801 {
1802 struct server_info *si = param;
1803 int r, c, i, on;
1804 SOCKET s;
1805 struct sockaddr_in sa;
1806 char buffer[0x100];
1807 WSADATA wsaData;
1808 int last_request = 0;
1809
1810 WSAStartup(MAKEWORD(1,1), &wsaData);
1811
1812 s = socket(AF_INET, SOCK_STREAM, 0);
1813 if (s == INVALID_SOCKET)
1814 return 1;
1815
1816 on = 1;
1817 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1818
1819 memset(&sa, 0, sizeof sa);
1820 sa.sin_family = AF_INET;
1821 sa.sin_port = htons(si->port);
1822 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1823
1824 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1825 if (r < 0)
1826 return 1;
1827
1828 listen(s, 0);
1829 SetEvent(si->event);
1830 do
1831 {
1832 c = accept(s, NULL, NULL);
1833
1834 memset(buffer, 0, sizeof buffer);
1835 for(i = 0; i < sizeof buffer - 1; i++)
1836 {
1837 r = recv(c, &buffer[i], 1, 0);
1838 if (r != 1)
1839 break;
1840 if (i < 4) continue;
1841 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1842 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1843 break;
1844 }
1845 if (strstr(buffer, "GET /basic"))
1846 {
1847 send(c, okmsg, sizeof okmsg - 1, 0);
1848 send(c, page1, sizeof page1 - 1, 0);
1849 }
1850 if (strstr(buffer, "/auth"))
1851 {
1852 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1853 send(c, okmsg, sizeof okmsg - 1, 0);
1854 else
1855 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1856 }
1857 if (strstr(buffer, "/big"))
1858 {
1859 char msg[BIG_BUFFER_LEN];
1860 memset(msg, 'm', sizeof(msg));
1861 send(c, okmsg, sizeof(okmsg) - 1, 0);
1862 send(c, msg, sizeof(msg), 0);
1863 }
1864 if (strstr(buffer, "/no_headers"))
1865 {
1866 send(c, page1, sizeof page1 - 1, 0);
1867 }
1868 if (strstr(buffer, "GET /quit"))
1869 {
1870 send(c, okmsg, sizeof okmsg - 1, 0);
1871 send(c, page1, sizeof page1 - 1, 0);
1872 last_request = 1;
1873 }
1874 shutdown(c, 2);
1875 closesocket(c);
1876
1877 } while (!last_request);
1878
1879 closesocket(s);
1880 return 0;
1881 }
1882
1883 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1884 {
1885 HINTERNET ses, con, req;
1886 char buffer[0x100];
1887 DWORD count, status, size, error, supported, first, target;
1888 BOOL ret;
1889
1890 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1891 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1892
1893 con = WinHttpConnect(ses, localhostW, port, 0);
1894 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1895
1896 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1897 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1898
1899 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1900 ok(ret, "failed to send request %u\n", GetLastError());
1901
1902 ret = WinHttpReceiveResponse(req, NULL);
1903 ok(ret, "failed to receive response %u\n", GetLastError());
1904
1905 size = sizeof(status);
1906 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1907 ok(ret, "failed to query status code %u\n", GetLastError());
1908 ok(status == 200, "request failed unexpectedly %u\n", status);
1909
1910 supported = first = target = 0xdeadbeef;
1911 SetLastError(0xdeadbeef);
1912 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
1913 error = GetLastError();
1914 ok(!ret, "unexpected success\n");
1915 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
1916 ok(supported == 0xdeadbeef, "got %x\n", supported);
1917 ok(first == 0xdeadbeef, "got %x\n", first);
1918 ok(target == 0xdeadbeef, "got %x\n", target);
1919
1920 count = 0;
1921 memset(buffer, 0, sizeof(buffer));
1922 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1923 ok(ret, "failed to read data %u\n", GetLastError());
1924 ok(count == sizeof page1 - 1, "count was wrong\n");
1925 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1926
1927 WinHttpCloseHandle(req);
1928 WinHttpCloseHandle(con);
1929 WinHttpCloseHandle(ses);
1930 }
1931
1932 static void test_basic_authentication(int port)
1933 {
1934 static const WCHAR authW[] = {'/','a','u','t','h',0};
1935 static const WCHAR userW[] = {'u','s','e','r',0};
1936 static const WCHAR passW[] = {'p','w','d',0};
1937 HINTERNET ses, con, req;
1938 DWORD status, size, error, supported, first, target;
1939 BOOL ret;
1940
1941 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1942 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1943
1944 con = WinHttpConnect(ses, localhostW, port, 0);
1945 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1946
1947 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1948 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1949
1950 SetLastError(0xdeadbeef);
1951 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
1952 error = GetLastError();
1953 ok(!ret, "expected failure\n");
1954 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
1955
1956 SetLastError(0xdeadbeef);
1957 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
1958 error = GetLastError();
1959 ok(!ret, "expected failure\n");
1960 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
1961
1962 supported = 0xdeadbeef;
1963 SetLastError(0xdeadbeef);
1964 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
1965 error = GetLastError();
1966 ok(!ret, "expected failure\n");
1967 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
1968 ok(supported == 0xdeadbeef, "got %x\n", supported);
1969
1970 supported = first = 0xdeadbeef;
1971 SetLastError(0xdeadbeef);
1972 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
1973 error = GetLastError();
1974 ok(!ret, "expected failure\n");
1975 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
1976 ok(supported == 0xdeadbeef, "got %x\n", supported);
1977 ok(first == 0xdeadbeef, "got %x\n", first);
1978
1979 supported = first = target = 0xdeadbeef;
1980 SetLastError(0xdeadbeef);
1981 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
1982 error = GetLastError();
1983 ok(!ret, "expected failure\n");
1984 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
1985 ok(supported == 0xdeadbeef, "got %x\n", supported);
1986 ok(first == 0xdeadbeef, "got %x\n", first);
1987 ok(target == 0xdeadbeef, "got %x\n", target);
1988
1989 supported = first = target = 0xdeadbeef;
1990 SetLastError(0xdeadbeef);
1991 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
1992 error = GetLastError();
1993 ok(!ret, "expected failure\n");
1994 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
1995 ok(supported == 0xdeadbeef, "got %x\n", supported);
1996 ok(first == 0xdeadbeef, "got %x\n", first);
1997 ok(target == 0xdeadbeef, "got %x\n", target);
1998
1999 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2000 ok(ret, "failed to send request %u\n", GetLastError());
2001
2002 ret = WinHttpReceiveResponse(req, NULL);
2003 ok(ret, "failed to receive response %u\n", GetLastError());
2004
2005 size = sizeof(status);
2006 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2007 ok(ret, "failed to query status code %u\n", GetLastError());
2008 ok(status == 401, "request failed unexpectedly %u\n", status);
2009
2010 supported = first = target = 0xdeadbeef;
2011 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2012 ok(ret, "failed to query authentication schemes %u\n", GetLastError());
2013 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2014 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2015 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2016
2017 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2018 ok(ret, "failed to set credentials %u\n", GetLastError());
2019
2020 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2021 ok(ret, "failed to set credentials %u\n", GetLastError());
2022
2023 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2024 ok(ret, "failed to set credentials %u\n", GetLastError());
2025
2026 SetLastError(0xdeadbeef);
2027 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2028 error = GetLastError();
2029 ok(!ret, "expected failure\n");
2030 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2031
2032 SetLastError(0xdeadbeef);
2033 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2034 error = GetLastError();
2035 ok(!ret, "expected failure\n");
2036 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2037
2038 SetLastError(0xdeadbeef);
2039 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2040 error = GetLastError();
2041 ok(!ret, "expected failure\n");
2042 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2043
2044 SetLastError(0xdeadbeef);
2045 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2046 error = GetLastError();
2047 ok(!ret, "expected failure\n");
2048 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2049
2050 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2051 ok(ret, "failed to set credentials %u\n", GetLastError());
2052
2053 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2054 ok(ret, "failed to send request %u\n", GetLastError());
2055
2056 ret = WinHttpReceiveResponse(req, NULL);
2057 ok(ret, "failed to receive response %u\n", GetLastError());
2058
2059 size = sizeof(status);
2060 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2061 ok(ret, "failed to query status code %u\n", GetLastError());
2062 ok(status == 200, "request failed unexpectedly %u\n", status);
2063
2064 WinHttpCloseHandle(req);
2065 WinHttpCloseHandle(con);
2066 WinHttpCloseHandle(ses);
2067 }
2068
2069 static void test_no_headers(int port)
2070 {
2071 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2072 HINTERNET ses, con, req;
2073 DWORD error;
2074 BOOL ret;
2075
2076 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2077 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2078
2079 con = WinHttpConnect(ses, localhostW, port, 0);
2080 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2081
2082 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2083 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2084
2085 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2086 if (!ret)
2087 {
2088 error = GetLastError();
2089 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2090 }
2091 else
2092 {
2093 SetLastError(0xdeadbeef);
2094 ret = WinHttpReceiveResponse(req, NULL);
2095 error = GetLastError();
2096 ok(!ret, "expected failure\n");
2097 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2098 }
2099
2100 WinHttpCloseHandle(req);
2101 WinHttpCloseHandle(con);
2102 WinHttpCloseHandle(ses);
2103 }
2104
2105 static void test_bad_header( int port )
2106 {
2107 static const WCHAR bad_headerW[] =
2108 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2109 't','e','x','t','/','h','t','m','l','\n','\r',0};
2110 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
2111 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2112 WCHAR buffer[32];
2113 HINTERNET ses, con, req;
2114 DWORD index, len;
2115 BOOL ret;
2116
2117 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2118 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2119
2120 con = WinHttpConnect( ses, localhostW, port, 0 );
2121 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2122
2123 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2124 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2125
2126 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2127 ok( ret, "failed to add header %u\n", GetLastError() );
2128
2129 index = 0;
2130 buffer[0] = 0;
2131 len = sizeof(buffer);
2132 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2133 content_typeW, buffer, &len, &index );
2134 ok( ret, "failed to query headers %u\n", GetLastError() );
2135 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2136
2137 WinHttpCloseHandle( req );
2138 WinHttpCloseHandle( con );
2139 WinHttpCloseHandle( ses );
2140 }
2141
2142 static void test_multiple_reads(int port)
2143 {
2144 static const WCHAR bigW[] = {'b','i','g',0};
2145 HINTERNET ses, con, req;
2146 DWORD total_len = 0;
2147 BOOL ret;
2148
2149 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2150 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2151
2152 con = WinHttpConnect(ses, localhostW, port, 0);
2153 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2154
2155 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
2156 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2157
2158 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2159 ok(ret, "failed to send request %u\n", GetLastError());
2160
2161 ret = WinHttpReceiveResponse(req, NULL);
2162 ok(ret == TRUE, "expected success\n");
2163
2164 for (;;)
2165 {
2166 DWORD len = 0xdeadbeef;
2167 ret = WinHttpQueryDataAvailable( req, &len );
2168 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2169 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2170 if (len)
2171 {
2172 DWORD bytes_read;
2173 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
2174
2175 ret = WinHttpReadData( req, buf, len, &bytes_read );
2176 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
2177
2178 HeapFree( GetProcessHeap(), 0, buf );
2179 if (!bytes_read) break;
2180 total_len += bytes_read;
2181 }
2182 if (!len) break;
2183 }
2184 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
2185
2186 WinHttpCloseHandle(req);
2187 WinHttpCloseHandle(con);
2188 WinHttpCloseHandle(ses);
2189 }
2190
2191 static void test_connection_info( int port )
2192 {
2193 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2194 HINTERNET ses, con, req;
2195 WINHTTP_CONNECTION_INFO info;
2196 DWORD size, error;
2197 BOOL ret;
2198
2199 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2200 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2201
2202 con = WinHttpConnect( ses, localhostW, port, 0 );
2203 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2204
2205 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
2206 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2207
2208 size = sizeof(info);
2209 SetLastError( 0xdeadbeef );
2210 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2211 error = GetLastError();
2212 if (!ret && error == ERROR_INVALID_PARAMETER)
2213 {
2214 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2215 return;
2216 }
2217 ok( !ret, "unexpected success\n" );
2218 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
2219
2220 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
2221 ok( ret, "failed to send request %u\n", GetLastError() );
2222
2223 size = 0;
2224 SetLastError( 0xdeadbeef );
2225 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2226 error = GetLastError();
2227 ok( !ret, "unexpected success\n" );
2228 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
2229
2230 size = sizeof(info);
2231 memset( &info, 0, sizeof(info) );
2232 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2233 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2234 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2235
2236 ret = WinHttpReceiveResponse( req, NULL );
2237 ok( ret, "failed to receive response %u\n", GetLastError() );
2238
2239 size = sizeof(info);
2240 memset( &info, 0, sizeof(info) );
2241 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
2242 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
2243 ok( info.cbSize == sizeof(info), "wrong size %u\n", info.cbSize );
2244
2245 WinHttpCloseHandle( req );
2246 WinHttpCloseHandle( con );
2247 WinHttpCloseHandle( ses );
2248 }
2249
2250 static void test_credentials(void)
2251 {
2252 static WCHAR userW[] = {'u','s','e','r',0};
2253 static WCHAR passW[] = {'p','a','s','s',0};
2254 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2255 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2256 HINTERNET ses, con, req;
2257 DWORD size, error;
2258 WCHAR buffer[32];
2259 BOOL ret;
2260
2261 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2262 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2263
2264 con = WinHttpConnect(ses, localhostW, 0, 0);
2265 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2266
2267 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2268 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2269
2270 size = sizeof(buffer)/sizeof(WCHAR);
2271 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2272 ok(ret, "failed to query proxy username %u\n", GetLastError());
2273 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2274 ok(!size, "expected 0, got %u\n", size);
2275
2276 size = sizeof(buffer)/sizeof(WCHAR);
2277 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2278 ok(ret, "failed to query proxy password %u\n", GetLastError());
2279 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2280 ok(!size, "expected 0, got %u\n", size);
2281
2282 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2283 ok(ret, "failed to set username %u\n", GetLastError());
2284
2285 size = sizeof(buffer)/sizeof(WCHAR);
2286 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2287 ok(ret, "failed to query proxy username %u\n", GetLastError());
2288 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2289 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2290
2291 size = sizeof(buffer)/sizeof(WCHAR);
2292 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2293 ok(ret, "failed to query username %u\n", GetLastError());
2294 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2295 ok(!size, "expected 0, got %u\n", size);
2296
2297 size = sizeof(buffer)/sizeof(WCHAR);
2298 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2299 ok(ret, "failed to query password %u\n", GetLastError());
2300 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2301 ok(!size, "expected 0, got %u\n", size);
2302
2303 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2304 ok(ret, "failed to set proxy password %u\n", GetLastError());
2305
2306 size = sizeof(buffer)/sizeof(WCHAR);
2307 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2308 ok(ret, "failed to query proxy password %u\n", GetLastError());
2309 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2310 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2311
2312 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2313 ok(ret, "failed to set username %u\n", GetLastError());
2314
2315 size = sizeof(buffer)/sizeof(WCHAR);
2316 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2317 ok(ret, "failed to query username %u\n", GetLastError());
2318 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2319 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2320
2321 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2322 ok(ret, "failed to set password %u\n", GetLastError());
2323
2324 size = sizeof(buffer)/sizeof(WCHAR);
2325 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2326 ok(ret, "failed to query password %u\n", GetLastError());
2327 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2328 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2329
2330 WinHttpCloseHandle(req);
2331
2332 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2333 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2334
2335 SetLastError(0xdeadbeef);
2336 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2337 error = GetLastError();
2338 ok(!ret, "expected failure\n");
2339 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2340
2341 SetLastError(0xdeadbeef);
2342 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2343 error = GetLastError();
2344 ok(!ret, "expected failure\n");
2345 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2346
2347 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2348 ok(ret, "failed to set credentials %u\n", GetLastError());
2349
2350 size = sizeof(buffer)/sizeof(WCHAR);
2351 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2352 ok(ret, "failed to query username %u\n", GetLastError());
2353 todo_wine {
2354 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2355 ok(!size, "expected 0, got %u\n", size);
2356 }
2357
2358 size = sizeof(buffer)/sizeof(WCHAR);
2359 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2360 ok(ret, "failed to query password %u\n", GetLastError());
2361 todo_wine {
2362 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2363 ok(!size, "expected 0, got %u\n", size);
2364 }
2365
2366 WinHttpCloseHandle(req);
2367 WinHttpCloseHandle(con);
2368 WinHttpCloseHandle(ses);
2369 }
2370
2371 static void test_IWinHttpRequest(void)
2372 {
2373 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2374 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2375 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2376 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2377 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
2378 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
2379 static const WCHAR method1W[] = {'G','E','T',0};
2380 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2381 static const WCHAR method3W[] = {'P','O','S','T',0};
2382 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2383 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2384 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2385 static const WCHAR dateW[] = {'D','a','t','e',0};
2386 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
2387 HRESULT hr;
2388 IWinHttpRequest *req;
2389 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2390 BSTR date, today, connection, value = NULL;
2391 VARIANT async, empty, timeout, body, proxy_server, bypass_list, data;
2392 VARIANT_BOOL succeeded;
2393 LONG status;
2394 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2395 SYSTEMTIME st;
2396
2397 GetSystemTime( &st );
2398 WinHttpTimeFromSystemTime( &st, todayW );
2399
2400 CoInitialize( NULL );
2401 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2402 ok( hr == S_OK, "got %08x\n", hr );
2403
2404 V_VT( &empty ) = VT_ERROR;
2405 V_ERROR( &empty ) = 0xdeadbeef;
2406
2407 V_VT( &async ) = VT_BOOL;
2408 V_BOOL( &async ) = VARIANT_FALSE;
2409
2410 method = SysAllocString( method3W );
2411 url = SysAllocString( url3W );
2412 hr = IWinHttpRequest_Open( req, method, url, async );
2413 ok( hr == S_OK, "got %08x\n", hr );
2414 SysFreeString( method );
2415 SysFreeString( url );
2416
2417 V_VT( &data ) = VT_BSTR;
2418 V_BSTR( &data ) = SysAllocString( test_dataW );
2419 hr = IWinHttpRequest_Send( req, data );
2420 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
2421 "got %08x\n", hr );
2422 SysFreeString( V_BSTR( &data ) );
2423
2424 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2425 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2426
2427 method = SysAllocString( method1W );
2428 hr = IWinHttpRequest_Open( req, method, NULL, empty );
2429 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2430
2431 hr = IWinHttpRequest_Open( req, method, NULL, async );
2432 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2433
2434 url = SysAllocString( url1W );
2435 hr = IWinHttpRequest_Open( req, NULL, url, empty );
2436 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2437
2438 hr = IWinHttpRequest_Abort( req );
2439 ok( hr == S_OK, "got %08x\n", hr );
2440
2441 hr = IWinHttpRequest_Open( req, method, url, empty );
2442 ok( hr == S_OK, "got %08x\n", hr );
2443
2444 hr = IWinHttpRequest_Abort( req );
2445 ok( hr == S_OK, "got %08x\n", hr );
2446
2447 hr = IWinHttpRequest_Release( req );
2448 ok( hr == S_OK, "got %08x\n", hr );
2449
2450 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2451 ok( hr == S_OK, "got %08x\n", hr );
2452
2453 SysFreeString( url );
2454 url = SysAllocString( url2W );
2455 hr = IWinHttpRequest_Open( req, method, url, async );
2456 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2457
2458 SysFreeString( method );
2459 method = SysAllocString( method2W );
2460 hr = IWinHttpRequest_Open( req, method, url, async );
2461 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2462
2463 SysFreeString( method );
2464 method = SysAllocString( method1W );
2465 SysFreeString( url );
2466 url = SysAllocString( url1W );
2467 hr = IWinHttpRequest_Open( req, method, url, async );
2468 ok( hr == S_OK, "got %08x\n", hr );
2469
2470 hr = IWinHttpRequest_Abort( req );
2471 ok( hr == S_OK, "got %08x\n", hr );
2472
2473 hr = IWinHttpRequest_Send( req, empty );
2474 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2475
2476 hr = IWinHttpRequest_Abort( req );
2477 ok( hr == S_OK, "got %08x\n", hr );
2478
2479 hr = IWinHttpRequest_Release( req );
2480 ok( hr == S_OK, "got %08x\n", hr );
2481
2482 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2483 ok( hr == S_OK, "got %08x\n", hr );
2484
2485 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2486 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2487
2488 hr = IWinHttpRequest_get_ResponseText( req, &response );
2489 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2490
2491 hr = IWinHttpRequest_get_Status( req, NULL );
2492 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2493
2494 hr = IWinHttpRequest_get_Status( req, &status );
2495 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2496
2497 hr = IWinHttpRequest_get_StatusText( req, NULL );
2498 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2499
2500 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2501 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2502
2503 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2504 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2505
2506 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2507 ok( hr == S_OK, "got %08x\n", hr );
2508
2509 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2510 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2511
2512 VariantInit( &proxy_server );
2513 V_VT( &proxy_server ) = VT_ERROR;
2514 VariantInit( &bypass_list );
2515 V_VT( &bypass_list ) = VT_ERROR;
2516 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2517 ok( hr == S_OK, "got %08x\n", hr );
2518
2519 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2520 ok( hr == S_OK, "got %08x\n", hr );
2521
2522 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2523 ok( hr == S_OK, "got %08x\n", hr );
2524
2525 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2526 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2527
2528 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2529 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2530
2531 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2532 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2533
2534 connection = SysAllocString( connectionW );
2535 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2536 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2537
2538 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2539 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2540
2541 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2542 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2543
2544 date = SysAllocString( dateW );
2545 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2546 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2547
2548 today = SysAllocString( todayW );
2549 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2550 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2551
2552 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2553 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2554
2555 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2556 ok( hr == S_OK, "got %08x\n", hr );
2557
2558 SysFreeString( method );
2559 method = SysAllocString( method1W );
2560 SysFreeString( url );
2561 url = SysAllocString( url1W );
2562 hr = IWinHttpRequest_Open( req, method, url, async );
2563 ok( hr == S_OK, "got %08x\n", hr );
2564
2565 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2566 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2567
2568 hr = IWinHttpRequest_get_ResponseText( req, &response );
2569 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2570
2571 hr = IWinHttpRequest_get_Status( req, &status );
2572 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2573
2574 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2575 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2576
2577 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2578 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2579
2580 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2581 ok( hr == S_OK, "got %08x\n", hr );
2582
2583 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2584 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2585
2586 username = SysAllocString( usernameW );
2587 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2588 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2589
2590 password = SysAllocString( passwordW );
2591 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2592 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2593
2594 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2595 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2596
2597 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2598 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2599
2600 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2601 ok( hr == S_OK, "got %08x\n", hr );
2602
2603 V_VT( &proxy_server ) = VT_BSTR;
2604 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2605 V_VT( &bypass_list ) = VT_BSTR;
2606 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2607 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2608 ok( hr == S_OK, "got %08x\n", hr );
2609
2610 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2611 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2612
2613 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2614 ok( hr == S_OK, "got %08x\n", hr );
2615
2616 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2617 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2618
2619 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2620 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2621
2622 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2623 ok( hr == S_OK, "got %08x\n", hr );
2624
2625 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2626 ok( hr == S_OK, "got %08x\n", hr );
2627
2628 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2629 ok( hr == S_OK, "got %08x\n", hr );
2630
2631 hr = IWinHttpRequest_Send( req, empty );
2632 ok( hr == S_OK, "got %08x\n", hr );
2633
2634 hr = IWinHttpRequest_Send( req, empty );
2635 ok( hr == S_OK, "got %08x\n", hr );
2636
2637 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2638 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2639
2640 hr = IWinHttpRequest_get_ResponseText( req, &response );
2641 ok( hr == S_OK, "got %08x\n", hr );
2642 SysFreeString( response );
2643
2644 hr = IWinHttpRequest_get_Status( req, NULL );
2645 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2646
2647 status = 0;
2648 hr = IWinHttpRequest_get_Status( req, &status );
2649 ok( hr == S_OK, "got %08x\n", hr );
2650 trace("Status=%d\n", status);
2651
2652 hr = IWinHttpRequest_get_StatusText( req, NULL );
2653 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2654
2655 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2656 ok( hr == S_OK, "got %08x\n", hr );
2657 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
2658 SysFreeString( status_text );
2659
2660 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2661 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2662
2663 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2664 ok( hr == S_OK, "got %08x\n", hr );
2665
2666 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2667 ok( hr == S_OK, "got %08x\n", hr );
2668
2669 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2670 ok( hr == S_OK, "got %08x\n", hr );
2671
2672 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2673 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2674
2675 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2676 ok( hr == S_OK, "got %08x\n", hr );
2677 SysFreeString( headers );
2678
2679 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2680 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2681
2682 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2683 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2684
2685 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2686 ok( hr == S_OK, "got %08x\n", hr );
2687 SysFreeString( value );
2688
2689 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2690 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2691
2692 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2693 ok( hr == S_OK, "got %08x\n", hr );
2694
2695 VariantInit( &timeout );
2696 V_VT( &timeout ) = VT_I4;
2697 V_I4( &timeout ) = 10;
2698 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2699 ok( hr == S_OK, "got %08x\n", hr );
2700
2701 hr = IWinHttpRequest_get_Status( req, &status );
2702 ok( hr == S_OK, "got %08x\n", hr );
2703
2704 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2705 ok( hr == S_OK, "got %08x\n", hr );
2706 SysFreeString( status_text );
2707
2708 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2709 ok( hr == S_OK, "got %08x\n", hr );
2710
2711 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2712 ok( hr == S_OK, "got %08x\n", hr );
2713
2714 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2715 ok( hr == S_OK, "got %08x\n", hr );
2716
2717 hr = IWinHttpRequest_Send( req, empty );
2718 ok( hr == S_OK, "got %08x\n", hr );
2719
2720 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2721 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2722
2723 hr = IWinHttpRequest_get_ResponseText( req, &response );
2724 ok( hr == S_OK, "got %08x\n", hr );
2725 SysFreeString( response );
2726
2727 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2728 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2729
2730 VariantInit( &body );
2731 V_VT( &body ) = VT_ERROR;
2732 hr = IWinHttpRequest_get_ResponseBody( req, &body );
2733 ok( hr == S_OK, "got %08x\n", hr );
2734 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2735
2736 hr = VariantClear( &body );
2737 ok( hr == S_OK, "got %08x\n", hr );
2738
2739 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2740 ok( hr == S_OK, "got %08x\n", hr );
2741
2742 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2743 ok( hr == S_OK, "got %08x\n", hr );
2744
2745 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2746 ok( hr == S_OK, "got %08x\n", hr );
2747 SysFreeString( headers );
2748
2749 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2750 ok( hr == S_OK, "got %08x\n", hr );
2751 SysFreeString( value );
2752
2753 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2754 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2755
2756 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2757 ok( hr == S_OK, "got %08x\n", hr );
2758
2759 hr = IWinHttpRequest_Send( req, empty );
2760 ok( hr == S_OK, "got %08x\n", hr );
2761
2762 hr = IWinHttpRequest_Abort( req );
2763 ok( hr == S_OK, "got %08x\n", hr );
2764
2765 hr = IWinHttpRequest_Abort( req );
2766 ok( hr == S_OK, "got %08x\n", hr );
2767
2768 hr = IWinHttpRequest_Release( req );
2769 ok( hr == S_OK, "got %08x\n", hr );
2770
2771 SysFreeString( method );
2772 SysFreeString( url );
2773 SysFreeString( username );
2774 SysFreeString( password );
2775 SysFreeString( connection );
2776 SysFreeString( date );
2777 SysFreeString( today );
2778 VariantClear( &proxy_server );
2779 VariantClear( &bypass_list );
2780 CoUninitialize();
2781 }
2782
2783 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2784 {
2785 BOOL ret;
2786 WCHAR *url;
2787 DWORD error;
2788
2789 if (0) /* crashes on some win2k systems */
2790 {
2791 SetLastError(0xdeadbeef);
2792 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
2793 error = GetLastError();
2794 ok( !ret, "expected failure\n" );
2795 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2796 }
2797 url = NULL;
2798 SetLastError(0xdeadbeef);
2799 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
2800 error = GetLastError();
2801 ok( !ret, "expected failure\n" );
2802 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2803
2804 if (0) /* crashes on some win2k systems */
2805 {
2806 SetLastError(0xdeadbeef);
2807 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
2808 error = GetLastError();
2809 ok( !ret, "expected failure\n" );
2810 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2811 }
2812 url = (WCHAR *)0xdeadbeef;
2813 SetLastError(0xdeadbeef);
2814 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
2815 error = GetLastError();
2816 if (!ret)
2817 {
2818 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2819 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
2820 }
2821 else
2822 {
2823 trace("%s\n", wine_dbgstr_w(url));
2824 GlobalFree( url );
2825 }
2826
2827 url = (WCHAR *)0xdeadbeef;
2828 SetLastError(0xdeadbeef);
2829 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
2830 error = GetLastError();
2831 if (!ret)
2832 {
2833 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2834 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
2835 }
2836 else
2837 {
2838 trace("%s\n", wine_dbgstr_w(url));
2839 GlobalFree( url );
2840 }
2841 }
2842
2843 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2844 {
2845 BOOL ret;
2846 DWORD error;
2847 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
2848
2849 memset( &cfg, 0, sizeof(cfg) );
2850
2851 SetLastError(0xdeadbeef);
2852 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
2853 error = GetLastError();
2854 ok( !ret, "expected failure\n" );
2855 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2856
2857 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
2858 ok( ret, "expected success\n" );
2859 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
2860 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
2861 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
2862 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
2863 GlobalFree( cfg.lpszAutoConfigUrl );
2864 GlobalFree( cfg.lpszProxy );
2865 GlobalFree( cfg.lpszProxyBypass );
2866 }
2867
2868 static void test_WinHttpGetProxyForUrl(void)
2869 {
2870 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2871 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
2872 static const WCHAR emptyW[] = {0};
2873 BOOL ret;
2874 DWORD error;
2875 HINTERNET session;
2876 WINHTTP_AUTOPROXY_OPTIONS options;
2877 WINHTTP_PROXY_INFO info;
2878
2879 memset( &options, 0, sizeof(options) );
2880
2881 SetLastError(0xdeadbeef);
2882 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
2883 error = GetLastError();
2884 ok( !ret, "expected failure\n" );
2885 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
2886
2887 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2888 ok( session != NULL, "failed to open session %u\n", GetLastError() );
2889
2890 SetLastError(0xdeadbeef);
2891 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
2892 error = GetLastError();
2893 ok( !ret, "expected failure\n" );
2894 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2895
2896 SetLastError(0xdeadbeef);
2897 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
2898 error = GetLastError();
2899 ok( !ret, "expected failure\n" );
2900 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2901
2902 SetLastError(0xdeadbeef);
2903 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
2904 error = GetLastError();
2905 ok( !ret, "expected failure\n" );
2906 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2907
2908 SetLastError(0xdeadbeef);
2909 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2910 error = GetLastError();
2911 ok( !ret, "expected failure\n" );
2912 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2913
2914 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2915 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2916
2917 SetLastError(0xdeadbeef);
2918 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
2919 error = GetLastError();
2920 ok( !ret, "expected failure\n" );
2921 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2922
2923 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2924 options.dwAutoDetectFlags = 0;
2925
2926 SetLastError(0xdeadbeef);
2927 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2928 error = GetLastError();
2929 ok( !ret, "expected failure\n" );
2930 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2931
2932 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
2933 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2934
2935 SetLastError(0xdeadbeef);
2936 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2937 error = GetLastError();
2938 ok( !ret, "expected failure\n" );
2939 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2940
2941 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2942 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2943
2944 memset( &info, 0, sizeof(info) );
2945 SetLastError(0xdeadbeef);
2946 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2947 error = GetLastError();
2948 if (!ret) ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED ||
2949 error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
2950 else
2951 {
2952 trace("Proxy.AccessType=%u\n", info.dwAccessType);
2953 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
2954 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2955 GlobalFree( info.lpszProxy );
2956 GlobalFree( info.lpszProxyBypass );
2957 }
2958
2959 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
2960 options.dwAutoDetectFlags = 0;
2961 options.lpszAutoConfigUrl = wpadW;
2962
2963 memset( &info, 0, sizeof(info) );
2964 SetLastError(0xdeadbeef);
2965 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2966 error = GetLastError();
2967 if (!ret) ok( error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
2968 else
2969 {
2970 trace("Proxy.AccessType=%u\n", info.dwAccessType);
2971 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
2972 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2973 GlobalFree( info.lpszProxy );
2974 GlobalFree( info.lpszProxyBypass );
2975 }
2976 WinHttpCloseHandle( session );
2977 }
2978
2979 static void test_chunked_read(void)
2980 {
2981 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
2982 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
2983 WCHAR header[32];
2984 DWORD len;
2985 HINTERNET ses, con = NULL, req = NULL;
2986 BOOL ret;
2987
2988 trace( "starting chunked read test\n" );
2989
2990 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2991 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
2992 if (!ses) goto done;
2993
2994 con = WinHttpConnect( ses, test_winehq, 0, 0 );
2995 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
2996 if (!con) goto done;
2997
2998 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
2999 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
3000 if (!req) goto done;
3001
3002 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3003 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
3004
3005 ret = WinHttpReceiveResponse( req, NULL );
3006 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
3007
3008 header[0] = 0;
3009 len = sizeof(header);
3010 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
3011 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
3012 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
3013 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
3014
3015 header[0] = 0;
3016 len = sizeof(header);
3017 SetLastError( 0xdeadbeef );
3018 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
3019 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
3020 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
3021
3022 trace( "entering query loop\n" );
3023 for (;;)
3024 {
3025 len = 0xdeadbeef;
3026 ret = WinHttpQueryDataAvailable( req, &len );
3027 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3028 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3029 trace( "got %u available\n", len );
3030 if (len)
3031 {
3032 DWORD bytes_read;
3033 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
3034
3035 ret = WinHttpReadData( req, buf, len, &bytes_read );
3036
3037 buf[bytes_read] = 0;
3038 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
3039 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
3040 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
3041
3042 HeapFree( GetProcessHeap(), 0, buf );
3043 if (!bytes_read) break;
3044 }
3045 if (!len) break;
3046 }
3047 trace( "done\n" );
3048
3049 done:
3050 if (req) WinHttpCloseHandle( req );
3051 if (con) WinHttpCloseHandle( con );
3052 if (ses) WinHttpCloseHandle( ses );
3053 }
3054
3055 START_TEST (winhttp)
3056 {
3057 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
3058 static const WCHAR quitW[] = {'/','q','u','i','t',0};
3059 struct server_info si;
3060 HANDLE thread;
3061 DWORD ret;
3062
3063 test_OpenRequest();
3064 test_SendRequest();
3065 test_WinHttpTimeFromSystemTime();
3066 test_WinHttpTimeToSystemTime();
3067 test_WinHttpAddHeaders();
3068 test_secure_connection();
3069 test_request_parameter_defaults();
3070 test_QueryOption();
3071 test_set_default_proxy_config();
3072 test_empty_headers_param();
3073 test_Timeouts();
3074 test_resolve_timeout();
3075 test_credentials();
3076 test_IWinHttpRequest();
3077 test_WinHttpDetectAutoProxyConfigUrl();
3078 test_WinHttpGetIEProxyConfigForCurrentUser();
3079 test_WinHttpGetProxyForUrl();
3080 test_chunked_read();
3081
3082 si.event = CreateEventW(NULL, 0, 0, NULL);
3083 si.port = 7532;
3084
3085 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
3086 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
3087
3088 ret = WaitForSingleObject(si.event, 10000);
3089 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
3090 if (ret != WAIT_OBJECT_0)
3091 return;
3092
3093 test_connection_info(si.port);
3094 test_basic_request(si.port, NULL, basicW);
3095 test_no_headers(si.port);
3096 test_basic_authentication(si.port);
3097 test_bad_header(si.port);
3098 test_multiple_reads(si.port);
3099
3100 /* send the basic request again to shutdown the server thread */
3101 test_basic_request(si.port, NULL, quitW);
3102
3103 WaitForSingleObject(thread, 3000);
3104 }