[WINHTTP_WINETEST]
[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 COBJMACROS
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winhttp.h>
27 #include <wincrypt.h>
28 #include <winreg.h>
29 #include <winsock.h>
30 #include "initguid.h"
31 #include <httprequest.h>
32
33 #include "wine/test.h"
34
35 static const WCHAR test_useragent[] =
36 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
37 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
38 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
39
40 static BOOL proxy_active(void)
41 {
42 WINHTTP_PROXY_INFO proxy_info;
43 BOOL active = FALSE;
44
45 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
46 {
47 active = (proxy_info.lpszProxy != NULL);
48 if (active)
49 GlobalFree((HGLOBAL) proxy_info.lpszProxy);
50 if (proxy_info.lpszProxyBypass != NULL)
51 GlobalFree((HGLOBAL) proxy_info.lpszProxyBypass);
52 }
53 else
54 active = FALSE;
55
56 return active;
57 }
58
59 static void test_QueryOption(void)
60 {
61 BOOL ret;
62 HINTERNET session, request, connection;
63 DWORD feature, size;
64
65 SetLastError(0xdeadbeef);
66 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
67 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
68
69 SetLastError(0xdeadbeef);
70 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
71 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
72 ok(GetLastError() == ERROR_INVALID_PARAMETER,
73 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
74
75 size = 0xdeadbeef;
76 SetLastError(0xdeadbeef);
77 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
78 ok(!ret, "should fail to query option\n");
79 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
80 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
81 ok(size == 4, "expected 4, got %u\n", size);
82
83 feature = 0xdeadbeef;
84 size = sizeof(feature) - 1;
85 SetLastError(0xdeadbeef);
86 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
87 ok(!ret, "should fail to query option\n");
88 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
89 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
90 ok(size == 4, "expected 4, got %u\n", size);
91
92 feature = 0xdeadbeef;
93 size = sizeof(feature) + 1;
94 SetLastError(0xdeadbeef);
95 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
96 ok(ret, "failed to query option %u\n", GetLastError());
97 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
98 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
99 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
100
101 SetLastError(0xdeadbeef);
102 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
103 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
104 ok(GetLastError() == ERROR_INVALID_PARAMETER,
105 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
106
107 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
108 SetLastError(0xdeadbeef);
109 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
110 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
111 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
112 "expected ERROR_INSUFFICIENT_BUFFER, 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));
124 ok(ret, "failed to set redirect policy %u\n", GetLastError());
125
126 feature = 0xdeadbeef;
127 size = sizeof(feature);
128 SetLastError(0xdeadbeef);
129 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
130 ok(ret, "failed to query option %u\n", GetLastError());
131 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
132 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
133
134 feature = WINHTTP_DISABLE_COOKIES;
135 SetLastError(0xdeadbeef);
136 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
137 ok(!ret, "should fail to set disable feature for a session\n");
138 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
139 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
140
141 SetLastError(0xdeadbeef);
142 connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
143 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
144
145 feature = WINHTTP_DISABLE_COOKIES;
146 SetLastError(0xdeadbeef);
147 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
148 ok(!ret, "should fail to set disable feature for a connection\n");
149 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
150 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151
152 SetLastError(0xdeadbeef);
153 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
154 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
155 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
156 {
157 skip("Network unreachable, skipping the test\n");
158 goto done;
159 }
160
161 feature = 0xdeadbeef;
162 size = sizeof(feature);
163 SetLastError(0xdeadbeef);
164 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
165 ok(!ret, "should fail to query disable feature for a request\n");
166 ok(GetLastError() == ERROR_INVALID_PARAMETER,
167 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
168
169 feature = 0;
170 size = sizeof(feature);
171 SetLastError(0xdeadbeef);
172 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
173 ok(ret, "failed to set feature %u\n", GetLastError());
174
175 feature = 0xffffffff;
176 size = sizeof(feature);
177 SetLastError(0xdeadbeef);
178 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
179 ok(ret, "failed to set feature %u\n", GetLastError());
180
181 feature = WINHTTP_DISABLE_COOKIES;
182 size = sizeof(feature);
183 SetLastError(0xdeadbeef);
184 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
185 ok(ret, "failed to set feature %u\n", GetLastError());
186
187 size = 0;
188 SetLastError(0xdeadbeef);
189 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
190 ok(!ret, "should fail to query disable feature for a request\n");
191 ok(GetLastError() == ERROR_INVALID_PARAMETER,
192 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
193
194 SetLastError(0xdeadbeef);
195 ret = WinHttpCloseHandle(request);
196 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
197
198 done:
199 SetLastError(0xdeadbeef);
200 ret = WinHttpCloseHandle(connection);
201 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
202 SetLastError(0xdeadbeef);
203 ret = WinHttpCloseHandle(session);
204 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
205 }
206
207 static void test_OpenRequest (void)
208 {
209 BOOL ret;
210 HINTERNET session, request, connection;
211
212 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
213 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
214 ok(session != NULL, "WinHttpOpen failed to open session.\n");
215
216 /* Test with a bad server name */
217 SetLastError(0xdeadbeef);
218 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
219 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
220 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
221
222 /* Test with a valid server name */
223 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
224 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
225
226 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
227 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
228 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
229 {
230 skip("Network unreachable, skipping.\n");
231 goto done;
232 }
233 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
234
235 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
236 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
237 {
238 skip("Connection failed, skipping.\n");
239 goto done;
240 }
241 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
242 ret = WinHttpCloseHandle(request);
243 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
244
245 done:
246 ret = WinHttpCloseHandle(connection);
247 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
248 ret = WinHttpCloseHandle(session);
249 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
250
251 }
252
253 static void test_empty_headers_param(void)
254 {
255 static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
256 static const WCHAR empty[] = {0};
257 HINTERNET ses, con, req;
258 BOOL ret;
259
260 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
261 ok(ses != NULL, "failed to open session %u\n", GetLastError());
262
263 con = WinHttpConnect(ses, winehq, 80, 0);
264 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
265
266 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
267 ok(req != NULL, "failed to open a request %u\n", GetLastError());
268
269 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
270 ok(ret, "failed to send request %u\n", GetLastError());
271
272 WinHttpCloseHandle(req);
273 WinHttpCloseHandle(con);
274 WinHttpCloseHandle(ses);
275 }
276
277 static void test_SendRequest (void)
278 {
279 HINTERNET session, request, connection;
280 DWORD header_len, optional_len, total_len, bytes_rw, size;
281 DWORD_PTR context;
282 BOOL ret;
283 CHAR buffer[256];
284 int i;
285
286 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
287 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
288 static const WCHAR content_type[] =
289 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
290 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
291 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
292 static const WCHAR test_verb[] = {'P','O','S','T',0};
293 static CHAR post_data[] = "mode=Test";
294 static CHAR test_post[] = "mode => Test\\0\n";
295
296 header_len = -1L;
297 total_len = optional_len = sizeof(post_data);
298 memset(buffer, 0xff, sizeof(buffer));
299
300 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
301 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
302 ok(session != NULL, "WinHttpOpen failed to open session.\n");
303
304 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
305 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
306
307 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
308 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
309 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
310 {
311 skip("Network unreachable, skipping.\n");
312 goto done;
313 }
314 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
315 if (!request) goto done;
316
317 context = 0xdeadbeef;
318 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
319 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
320
321 context++;
322 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
323 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
324
325 context = 0;
326 size = sizeof(context);
327 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
328 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
329 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
330
331 for (i = 3; post_data[i]; i++)
332 {
333 bytes_rw = -1;
334 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
335 if (ret)
336 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
337 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
338 {
339 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
340 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
341 }
342 }
343
344 ret = WinHttpReceiveResponse(request, NULL);
345 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
346
347 bytes_rw = -1;
348 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
349 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
350
351 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
352 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
353
354 ret = WinHttpCloseHandle(request);
355 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
356 done:
357 ret = WinHttpCloseHandle(connection);
358 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
359 ret = WinHttpCloseHandle(session);
360 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
361 }
362
363 static void test_WinHttpTimeFromSystemTime(void)
364 {
365 BOOL ret;
366 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
367 static const WCHAR expected_string[] =
368 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
369 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
370 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
371
372 ret = WinHttpTimeFromSystemTime(&time, time_string);
373 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
374 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
375 "Time string returned did not match expected time string.\n");
376 }
377
378 static void test_WinHttpTimeToSystemTime(void)
379 {
380 BOOL ret;
381 SYSTEMTIME time;
382 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
383 static const WCHAR time_string1[] =
384 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
385 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
386 static const WCHAR time_string2[] =
387 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
388 '1','0',' ','0','5',' ','5','2','\n',0};
389
390 ret = WinHttpTimeToSystemTime(time_string1, &time);
391 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
392 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
393 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
394
395 ret = WinHttpTimeToSystemTime(time_string2, &time);
396 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
397 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
398 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
399 }
400
401 static void test_WinHttpAddHeaders(void)
402 {
403 HINTERNET session, request, connection;
404 BOOL ret, reverse;
405 WCHAR buffer[MAX_PATH];
406 WCHAR check_buffer[MAX_PATH];
407 DWORD index, len, oldlen;
408
409 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
410 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
411 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
412 static const WCHAR test_verb[] = {'P','O','S','T',0};
413
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',':','/','/','c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',':','8','0','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
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_site, 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 test_secure_connection(void)
791 {
792 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
793
794 HINTERNET ses, con, req;
795 DWORD size, status, policy, bitness;
796 BOOL ret;
797 CERT_CONTEXT *cert;
798 WINHTTP_CERTIFICATE_INFO info;
799 char buffer[32];
800
801 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
802 ok(ses != NULL, "failed to open session %u\n", GetLastError());
803
804 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
805 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
806 ok(ret, "failed to set redirect policy %u\n", GetLastError());
807
808 con = WinHttpConnect(ses, google, 443, 0);
809 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
810
811 /* try without setting WINHTTP_FLAG_SECURE */
812 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
813 ok(req != NULL, "failed to open a request %u\n", GetLastError());
814
815 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
816 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
817 {
818 skip("Connection failed, skipping.\n");
819 goto cleanup;
820 }
821 ok(ret, "failed to send request %u\n", GetLastError());
822
823 ret = WinHttpReceiveResponse(req, NULL);
824 ok(!ret || proxy_active(), "succeeded unexpectedly\n");
825
826 size = 0;
827 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
828 ok(!ret, "succeeded unexpectedly\n");
829
830 WinHttpCloseHandle(req);
831
832 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
833 ok(req != NULL, "failed to open a request %u\n", GetLastError());
834
835 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
836 ok(ret, "failed to send request %u\n", GetLastError());
837 if (!ret)
838 {
839 skip("secure connection failed, skipping remaining secure tests\n");
840 goto cleanup;
841 }
842
843 size = sizeof(cert);
844 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
845 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
846 if (ret)
847 CertFreeCertificateContext(cert);
848
849 size = sizeof(bitness);
850 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
851 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
852
853 size = sizeof(info);
854 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
855 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
856
857 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
858 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
859 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
860 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
861 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
862 trace("dwKeySize %u\n", info.dwKeySize);
863
864 ret = WinHttpReceiveResponse(req, NULL);
865 ok(ret, "failed to receive response %u\n", GetLastError());
866
867 size = sizeof(status);
868 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
869 ok(ret, "failed unexpectedly %u\n", GetLastError());
870 ok(status == 200, "request failed unexpectedly %u\n", status);
871
872 size = 0;
873 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
874 ok(!ret, "succeeded unexpectedly\n");
875
876 for (;;)
877 {
878 size = 0;
879 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
880 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
881 if (!size) break;
882 }
883
884 cleanup:
885 WinHttpCloseHandle(req);
886 WinHttpCloseHandle(con);
887 WinHttpCloseHandle(ses);
888 }
889
890 static void test_request_parameter_defaults(void)
891 {
892 static const WCHAR empty[] = {0};
893 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
894
895 HINTERNET ses, con, req;
896 DWORD size, status, error;
897 WCHAR *version;
898 BOOL ret;
899
900 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
901 ok(ses != NULL, "failed to open session %u\n", GetLastError());
902
903 con = WinHttpConnect(ses, codeweavers, 0, 0);
904 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
905
906 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
907 ok(req != NULL, "failed to open a request %u\n", GetLastError());
908
909 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
910 ok(ret, "failed to send request %u\n", GetLastError());
911
912 ret = WinHttpReceiveResponse(req, NULL);
913 ok(ret, "failed to receive response %u\n", GetLastError());
914
915 size = sizeof(status);
916 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
917 ok(ret, "failed unexpectedly %u\n", GetLastError());
918 ok(status == 200, "request failed unexpectedly %u\n", status);
919
920 WinHttpCloseHandle(req);
921
922 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
923 ok(req != NULL, "failed to open a request %u\n", GetLastError());
924
925 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
926 ok(ret, "failed to send request %u\n", GetLastError());
927
928 ret = WinHttpReceiveResponse(req, NULL);
929 ok(ret, "failed to receive response %u\n", GetLastError());
930
931 size = 0;
932 SetLastError(0xdeadbeef);
933 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
934 error = GetLastError();
935 ok(!ret, "succeeded unexpectedly\n");
936 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
937
938 version = HeapAlloc(GetProcessHeap(), 0, size);
939 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
940 ok(ret, "failed unexpectedly %u\n", GetLastError());
941 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
942 HeapFree(GetProcessHeap(), 0, version);
943
944 size = sizeof(status);
945 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
946 ok(ret, "failed unexpectedly %u\n", GetLastError());
947 ok(status == 200, "request failed unexpectedly %u\n", status);
948
949 WinHttpCloseHandle(req);
950 WinHttpCloseHandle(con);
951 WinHttpCloseHandle(ses);
952 }
953
954 static const WCHAR Connections[] = {
955 'S','o','f','t','w','a','r','e','\\',
956 'M','i','c','r','o','s','o','f','t','\\',
957 'W','i','n','d','o','w','s','\\',
958 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
959 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
960 'C','o','n','n','e','c','t','i','o','n','s',0 };
961 static const WCHAR WinHttpSettings[] = {
962 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
963
964 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
965 {
966 LONG l;
967 HKEY key;
968 DWORD ret = 0;
969
970 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
971 if (!l)
972 {
973 DWORD size = 0;
974
975 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
976 if (!l)
977 {
978 if (size <= len)
979 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
980 &size );
981 if (!l)
982 ret = size;
983 }
984 RegCloseKey( key );
985 }
986 return ret;
987 }
988
989 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
990 {
991 LONG l;
992 HKEY key;
993
994 l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
995 KEY_WRITE, NULL, &key, NULL );
996 if (!l)
997 {
998 if (len)
999 RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1000 else
1001 RegDeleteValueW( key, WinHttpSettings );
1002 RegCloseKey( key );
1003 }
1004 }
1005
1006 static void test_set_default_proxy_config(void)
1007 {
1008 static const WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1009 static const WCHAR normalString[] = { 'f','o','o',0 };
1010 DWORD type, len;
1011 BYTE *saved_proxy_settings = NULL;
1012 WINHTTP_PROXY_INFO info;
1013 BOOL ret;
1014
1015 /* FIXME: it would be simpler to read the current settings using
1016 * WinHttpGetDefaultProxyConfiguration and save them using
1017 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1018 *
1019 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1020 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1021 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1022 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1023 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1024 * the lpszProxy and lpszProxyBypass values are ignored.
1025 * Thus, if a proxy is set with proxycfg, then calling
1026 * WinHttpGetDefaultProxyConfiguration followed by
1027 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1028 * getting deleted from the registry.
1029 *
1030 * Instead I read the current registry value and restore it directly.
1031 */
1032 len = get_default_proxy_reg_value( NULL, 0, &type );
1033 if (len)
1034 {
1035 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1036 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1037 }
1038
1039 if (0)
1040 {
1041 /* Crashes on Vista and higher */
1042 SetLastError(0xdeadbeef);
1043 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1044 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1045 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1046 }
1047
1048 /* test with invalid access type */
1049 info.dwAccessType = 0xdeadbeef;
1050 info.lpszProxy = info.lpszProxyBypass = NULL;
1051 SetLastError(0xdeadbeef);
1052 ret = WinHttpSetDefaultProxyConfiguration(&info);
1053 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1054 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1055
1056 /* at a minimum, the proxy server must be set */
1057 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1058 info.lpszProxy = info.lpszProxyBypass = NULL;
1059 SetLastError(0xdeadbeef);
1060 ret = WinHttpSetDefaultProxyConfiguration(&info);
1061 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1062 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1063 info.lpszProxyBypass = normalString;
1064 SetLastError(0xdeadbeef);
1065 ret = WinHttpSetDefaultProxyConfiguration(&info);
1066 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1067 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1068
1069 /* the proxy server can't have wide characters */
1070 info.lpszProxy = wideString;
1071 SetLastError(0xdeadbeef);
1072 ret = WinHttpSetDefaultProxyConfiguration(&info);
1073 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1074 broken(ret), /* Earlier winhttp versions on W2K/XP */
1075 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1076
1077 info.lpszProxy = normalString;
1078 SetLastError(0xdeadbeef);
1079 ret = WinHttpSetDefaultProxyConfiguration(&info);
1080 if (ret)
1081 {
1082 ok(ret, "always true\n");
1083 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1084 }
1085 else if (GetLastError() == ERROR_ACCESS_DENIED)
1086 skip("couldn't set default proxy configuration: access denied\n");
1087 else
1088 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1089 GetLastError());
1090 }
1091
1092 static void test_Timeouts (void)
1093 {
1094 BOOL ret;
1095 DWORD value, size;
1096 HINTERNET ses, req, con;
1097 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1098
1099
1100 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1101 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1102
1103 SetLastError(0xdeadbeef);
1104 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1105 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1106 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1107
1108 SetLastError(0xdeadbeef);
1109 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1110 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1111 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1112
1113 SetLastError(0xdeadbeef);
1114 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1115 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1116 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1117
1118 SetLastError(0xdeadbeef);
1119 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1120 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1121 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1122
1123 SetLastError(0xdeadbeef);
1124 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1125 ok(ret, "%u\n", GetLastError());
1126
1127 SetLastError(0xdeadbeef);
1128 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1129 ok(ret, "%u\n", GetLastError());
1130
1131 SetLastError(0xdeadbeef);
1132 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1133 ok(ret, "%u\n", GetLastError());
1134
1135 SetLastError(0xdeadbeef);
1136 value = 0xdeadbeef;
1137 size = sizeof(DWORD);
1138 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1139 ok(ret, "%u\n", GetLastError());
1140 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1141
1142 SetLastError(0xdeadbeef);
1143 value = 0xdeadbeef;
1144 size = sizeof(DWORD);
1145 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1146 ok(ret, "%u\n", GetLastError());
1147 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1148
1149 SetLastError(0xdeadbeef);
1150 value = 0xdeadbeef;
1151 size = sizeof(DWORD);
1152 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1153 ok(ret, "%u\n", GetLastError());
1154 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1155
1156 SetLastError(0xdeadbeef);
1157 value = 0xdeadbeef;
1158 size = sizeof(DWORD);
1159 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1160 ok(ret, "%u\n", GetLastError());
1161 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1162
1163 SetLastError(0xdeadbeef);
1164 value = 0;
1165 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1166 ok(ret, "%u\n", GetLastError());
1167
1168 SetLastError(0xdeadbeef);
1169 value = 0xdeadbeef;
1170 size = sizeof(DWORD);
1171 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1172 ok(ret, "%u\n", GetLastError());
1173 ok(value == 0, "Expected 0, got %u\n", value);
1174
1175 SetLastError(0xdeadbeef);
1176 value = 0;
1177 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1178 ok(ret, "%u\n", GetLastError());
1179
1180 SetLastError(0xdeadbeef);
1181 value = 0xdeadbeef;
1182 size = sizeof(DWORD);
1183 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1184 ok(ret, "%u\n", GetLastError());
1185 ok(value == 0, "Expected 0, got %u\n", value);
1186
1187 SetLastError(0xdeadbeef);
1188 value = 0;
1189 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1190 ok(ret, "%u\n", GetLastError());
1191
1192 SetLastError(0xdeadbeef);
1193 value = 0xdeadbeef;
1194 size = sizeof(DWORD);
1195 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1196 ok(ret, "%u\n", GetLastError());
1197 ok(value == 0, "Expected 0, got %u\n", value);
1198
1199 SetLastError(0xdeadbeef);
1200 value = 0;
1201 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1202 ok(ret, "%u\n", GetLastError());
1203
1204 SetLastError(0xdeadbeef);
1205 value = 0xdeadbeef;
1206 size = sizeof(DWORD);
1207 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1208 ok(ret, "%u\n", GetLastError());
1209 ok(value == 0, "Expected 0, got %u\n", value);
1210
1211 SetLastError(0xdeadbeef);
1212 value = 0xbeefdead;
1213 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1214 ok(ret, "%u\n", GetLastError());
1215
1216 SetLastError(0xdeadbeef);
1217 value = 0xdeadbeef;
1218 size = sizeof(DWORD);
1219 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1220 ok(ret, "%u\n", GetLastError());
1221 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1222
1223 SetLastError(0xdeadbeef);
1224 value = 0xbeefdead;
1225 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1226 ok(ret, "%u\n", GetLastError());
1227
1228 SetLastError(0xdeadbeef);
1229 value = 0xdeadbeef;
1230 size = sizeof(DWORD);
1231 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1232 ok(ret, "%u\n", GetLastError());
1233 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1234
1235 SetLastError(0xdeadbeef);
1236 value = 0xbeefdead;
1237 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1238 ok(ret, "%u\n", GetLastError());
1239
1240 SetLastError(0xdeadbeef);
1241 value = 0xdeadbeef;
1242 size = sizeof(DWORD);
1243 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1244 ok(ret, "%u\n", GetLastError());
1245 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1246
1247 SetLastError(0xdeadbeef);
1248 value = 0xbeefdead;
1249 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1250 ok(ret, "%u\n", GetLastError());
1251
1252 SetLastError(0xdeadbeef);
1253 value = 0xdeadbeef;
1254 size = sizeof(DWORD);
1255 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1256 ok(ret, "%u\n", GetLastError());
1257 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1258
1259 con = WinHttpConnect(ses, codeweavers, 0, 0);
1260 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1261
1262 /* Timeout values should match the last one set for session */
1263 SetLastError(0xdeadbeef);
1264 value = 0xdeadbeef;
1265 size = sizeof(DWORD);
1266 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1267 ok(ret, "%u\n", GetLastError());
1268 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1269
1270 SetLastError(0xdeadbeef);
1271 value = 0xdeadbeef;
1272 size = sizeof(DWORD);
1273 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1274 ok(ret, "%u\n", GetLastError());
1275 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1276
1277 SetLastError(0xdeadbeef);
1278 value = 0xdeadbeef;
1279 size = sizeof(DWORD);
1280 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1281 ok(ret, "%u\n", GetLastError());
1282 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1283
1284 SetLastError(0xdeadbeef);
1285 value = 0xdeadbeef;
1286 size = sizeof(DWORD);
1287 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1288 ok(ret, "%u\n", GetLastError());
1289 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1290
1291 SetLastError(0xdeadbeef);
1292 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1293 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1294 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1295
1296 SetLastError(0xdeadbeef);
1297 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1298 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1299 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1300
1301 SetLastError(0xdeadbeef);
1302 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1303 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1304 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1305
1306 SetLastError(0xdeadbeef);
1307 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1308 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1309 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1310
1311 SetLastError(0xdeadbeef);
1312 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1313 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1314 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1315
1316 SetLastError(0xdeadbeef);
1317 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1318 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1319 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1320
1321 SetLastError(0xdeadbeef);
1322 value = 0;
1323 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1324 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1325 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1326
1327 SetLastError(0xdeadbeef);
1328 value = 0;
1329 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1330 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1331 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1332
1333 SetLastError(0xdeadbeef);
1334 value = 0;
1335 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1336 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1337 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1338
1339 SetLastError(0xdeadbeef);
1340 value = 0;
1341 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1342 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1343 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1344
1345 /* Changing timeout values for session should affect the values for connection */
1346 SetLastError(0xdeadbeef);
1347 value = 0xdead;
1348 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1349 ok(ret, "%u\n", GetLastError());
1350
1351 SetLastError(0xdeadbeef);
1352 value = 0xdeadbeef;
1353 size = sizeof(DWORD);
1354 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1355 ok(ret, "%u\n", GetLastError());
1356 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1357
1358 SetLastError(0xdeadbeef);
1359 value = 0xdead;
1360 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1361 ok(ret, "%u\n", GetLastError());
1362
1363 SetLastError(0xdeadbeef);
1364 value = 0xdeadbeef;
1365 size = sizeof(DWORD);
1366 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1367 ok(ret, "%u\n", GetLastError());
1368 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1369
1370 SetLastError(0xdeadbeef);
1371 value = 0xdead;
1372 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1373 ok(ret, "%u\n", GetLastError());
1374
1375 SetLastError(0xdeadbeef);
1376 value = 0xdeadbeef;
1377 size = sizeof(DWORD);
1378 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1379 ok(ret, "%u\n", GetLastError());
1380 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1381
1382 SetLastError(0xdeadbeef);
1383 value = 0xdead;
1384 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1385 ok(ret, "%u\n", GetLastError());
1386
1387 SetLastError(0xdeadbeef);
1388 value = 0xdeadbeef;
1389 size = sizeof(DWORD);
1390 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1391 ok(ret, "%u\n", GetLastError());
1392 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1393
1394 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1395 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1396
1397 /* Timeout values should match the last one set for session */
1398 SetLastError(0xdeadbeef);
1399 value = 0xdeadbeef;
1400 size = sizeof(DWORD);
1401 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1402 ok(ret, "%u\n", GetLastError());
1403 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1404
1405 SetLastError(0xdeadbeef);
1406 value = 0xdeadbeef;
1407 size = sizeof(DWORD);
1408 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1409 ok(ret, "%u\n", GetLastError());
1410 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1411
1412 SetLastError(0xdeadbeef);
1413 value = 0xdeadbeef;
1414 size = sizeof(DWORD);
1415 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1416 ok(ret, "%u\n", GetLastError());
1417 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1418
1419 SetLastError(0xdeadbeef);
1420 value = 0xdeadbeef;
1421 size = sizeof(DWORD);
1422 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1423 ok(ret, "%u\n", GetLastError());
1424 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1425
1426 SetLastError(0xdeadbeef);
1427 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1428 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1429 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1430
1431 SetLastError(0xdeadbeef);
1432 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1433 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1434 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1435
1436 SetLastError(0xdeadbeef);
1437 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1438 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1439 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1440
1441 SetLastError(0xdeadbeef);
1442 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1443 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1444 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1445
1446 SetLastError(0xdeadbeef);
1447 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1448 ok(ret, "%u\n", GetLastError());
1449
1450 SetLastError(0xdeadbeef);
1451 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1452 ok(ret, "%u\n", GetLastError());
1453
1454 SetLastError(0xdeadbeef);
1455 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1456 ok(ret, "%u\n", GetLastError());
1457
1458 SetLastError(0xdeadbeef);
1459 value = 0xdeadbeef;
1460 size = sizeof(DWORD);
1461 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1462 ok(ret, "%u\n", GetLastError());
1463 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1464
1465 SetLastError(0xdeadbeef);
1466 value = 0xdeadbeef;
1467 size = sizeof(DWORD);
1468 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1469 ok(ret, "%u\n", GetLastError());
1470 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1471
1472 SetLastError(0xdeadbeef);
1473 value = 0xdeadbeef;
1474 size = sizeof(DWORD);
1475 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1476 ok(ret, "%u\n", GetLastError());
1477 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1478
1479 SetLastError(0xdeadbeef);
1480 value = 0xdeadbeef;
1481 size = sizeof(DWORD);
1482 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1483 ok(ret, "%u\n", GetLastError());
1484 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1485
1486 SetLastError(0xdeadbeef);
1487 value = 0;
1488 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1489 ok(ret, "%u\n", GetLastError());
1490
1491 SetLastError(0xdeadbeef);
1492 value = 0xdeadbeef;
1493 size = sizeof(DWORD);
1494 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1495 ok(ret, "%u\n", GetLastError());
1496 ok(value == 0, "Expected 0, got %u\n", value);
1497
1498 SetLastError(0xdeadbeef);
1499 value = 0;
1500 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1501 ok(ret, "%u\n", GetLastError());
1502
1503 SetLastError(0xdeadbeef);
1504 value = 0xdeadbeef;
1505 size = sizeof(DWORD);
1506 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1507 ok(ret, "%u\n", GetLastError());
1508 ok(value == 0, "Expected 0, got %u\n", value);
1509
1510 SetLastError(0xdeadbeef);
1511 value = 0;
1512 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1513 ok(ret, "%u\n", GetLastError());
1514
1515 SetLastError(0xdeadbeef);
1516 value = 0xdeadbeef;
1517 size = sizeof(DWORD);
1518 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1519 ok(ret, "%u\n", GetLastError());
1520 ok(value == 0, "Expected 0, got %u\n", value);
1521
1522 SetLastError(0xdeadbeef);
1523 value = 0;
1524 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1525 ok(ret, "%u\n", GetLastError());
1526
1527 SetLastError(0xdeadbeef);
1528 value = 0xdeadbeef;
1529 size = sizeof(DWORD);
1530 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1531 ok(ret, "%u\n", GetLastError());
1532 ok(value == 0, "Expected 0, got %u\n", value);
1533
1534 SetLastError(0xdeadbeef);
1535 value = 0xbeefdead;
1536 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1537 ok(ret, "%u\n", GetLastError());
1538
1539 SetLastError(0xdeadbeef);
1540 value = 0xdeadbeef;
1541 size = sizeof(DWORD);
1542 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1543 ok(ret, "%u\n", GetLastError());
1544 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1545
1546 SetLastError(0xdeadbeef);
1547 value = 0xbeefdead;
1548 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1549 ok(ret, "%u\n", GetLastError());
1550
1551 SetLastError(0xdeadbeef);
1552 value = 0xdeadbeef;
1553 size = sizeof(DWORD);
1554 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1555 ok(ret, "%u\n", GetLastError());
1556 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1557
1558 SetLastError(0xdeadbeef);
1559 value = 0xbeefdead;
1560 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1561 ok(ret, "%u\n", GetLastError());
1562
1563 SetLastError(0xdeadbeef);
1564 value = 0xdeadbeef;
1565 size = sizeof(DWORD);
1566 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1567 ok(ret, "%u\n", GetLastError());
1568 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1569
1570 SetLastError(0xdeadbeef);
1571 value = 0xbeefdead;
1572 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1573 ok(ret, "%u\n", GetLastError());
1574
1575 SetLastError(0xdeadbeef);
1576 value = 0xdeadbeef;
1577 size = sizeof(DWORD);
1578 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1579 ok(ret, "%u\n", GetLastError());
1580 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1581
1582 /* Changing timeout values for session should not affect the values for a request,
1583 * neither should the other way around.
1584 */
1585 SetLastError(0xdeadbeef);
1586 value = 0xbeefdead;
1587 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1588 ok(ret, "%u\n", GetLastError());
1589
1590 SetLastError(0xdeadbeef);
1591 value = 0xdeadbeef;
1592 size = sizeof(DWORD);
1593 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1594 ok(ret, "%u\n", GetLastError());
1595 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1596
1597 SetLastError(0xdeadbeef);
1598 value = 0xbeefdead;
1599 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1600 ok(ret, "%u\n", GetLastError());
1601
1602 SetLastError(0xdeadbeef);
1603 value = 0xdeadbeef;
1604 size = sizeof(DWORD);
1605 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1606 ok(ret, "%u\n", GetLastError());
1607 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1608
1609 SetLastError(0xdeadbeef);
1610 value = 0xbeefdead;
1611 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1612 ok(ret, "%u\n", GetLastError());
1613
1614 SetLastError(0xdeadbeef);
1615 value = 0xdeadbeef;
1616 size = sizeof(DWORD);
1617 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1618 ok(ret, "%u\n", GetLastError());
1619 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1620
1621 SetLastError(0xdeadbeef);
1622 value = 0xbeefdead;
1623 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1624 ok(ret, "%u\n", GetLastError());
1625
1626 SetLastError(0xdeadbeef);
1627 value = 0xdeadbeef;
1628 size = sizeof(DWORD);
1629 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1630 ok(ret, "%u\n", GetLastError());
1631 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1632
1633 SetLastError(0xdeadbeef);
1634 value = 0xbeef;
1635 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1636 ok(ret, "%u\n", GetLastError());
1637
1638 SetLastError(0xdeadbeef);
1639 value = 0xdeadbeef;
1640 size = sizeof(DWORD);
1641 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1642 ok(ret, "%u\n", GetLastError());
1643 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1644
1645 SetLastError(0xdeadbeef);
1646 value = 0xbeef;
1647 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1648 ok(ret, "%u\n", GetLastError());
1649
1650 SetLastError(0xdeadbeef);
1651 value = 0xdeadbeef;
1652 size = sizeof(DWORD);
1653 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1654 ok(ret, "%u\n", GetLastError());
1655 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1656
1657 SetLastError(0xdeadbeef);
1658 value = 0xbeef;
1659 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1660 ok(ret, "%u\n", GetLastError());
1661
1662 SetLastError(0xdeadbeef);
1663 value = 0xdeadbeef;
1664 size = sizeof(DWORD);
1665 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1666 ok(ret, "%u\n", GetLastError());
1667 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1668
1669 SetLastError(0xdeadbeef);
1670 value = 0xbeef;
1671 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1672 ok(ret, "%u\n", GetLastError());
1673
1674 SetLastError(0xdeadbeef);
1675 value = 0xdeadbeef;
1676 size = sizeof(DWORD);
1677 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1678 ok(ret, "%u\n", GetLastError());
1679 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1680
1681 WinHttpCloseHandle(req);
1682 WinHttpCloseHandle(con);
1683 WinHttpCloseHandle(ses);
1684 }
1685
1686 static void test_resolve_timeout(void)
1687 {
1688 static const WCHAR codeweavers[] =
1689 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1690 static const WCHAR nxdomain[] =
1691 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1692
1693 HINTERNET ses, con, req;
1694 DWORD timeout;
1695 BOOL ret;
1696
1697 if (! proxy_active())
1698 {
1699 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1700 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1701
1702 timeout = 10000;
1703 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1704 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1705
1706 con = WinHttpConnect(ses, nxdomain, 0, 0);
1707 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1708
1709 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1710 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1711
1712 SetLastError(0xdeadbeef);
1713 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1714 ok(!ret, "sent request\n");
1715 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1716 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1717
1718 WinHttpCloseHandle(req);
1719 WinHttpCloseHandle(con);
1720 WinHttpCloseHandle(ses);
1721 }
1722 else
1723 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1724
1725 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1726 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1727
1728 timeout = 10000;
1729 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1730 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1731
1732 con = WinHttpConnect(ses, codeweavers, 0, 0);
1733 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1734
1735 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1736 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1737
1738 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1739 ok(ret, "failed to send request\n");
1740
1741 WinHttpCloseHandle(req);
1742 WinHttpCloseHandle(con);
1743 WinHttpCloseHandle(ses);
1744 }
1745
1746 static const char page1[] =
1747 "<HTML>\r\n"
1748 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1749 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1750 "</HTML>\r\n\r\n";
1751
1752 static const char okmsg[] =
1753 "HTTP/1.1 200 OK\r\n"
1754 "Server: winetest\r\n"
1755 "\r\n";
1756
1757 static const char noauthmsg[] =
1758 "HTTP/1.1 401 Unauthorized\r\n"
1759 "Server: winetest\r\n"
1760 "Connection: close\r\n"
1761 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1762 "\r\n";
1763
1764 static const char proxymsg[] =
1765 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1766 "Server: winetest\r\n"
1767 "Proxy-Connection: close\r\n"
1768 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1769 "\r\n";
1770
1771 struct server_info
1772 {
1773 HANDLE event;
1774 int port;
1775 };
1776
1777 static DWORD CALLBACK server_thread(LPVOID param)
1778 {
1779 struct server_info *si = param;
1780 int r, c, i, on;
1781 SOCKET s;
1782 struct sockaddr_in sa;
1783 char buffer[0x100];
1784 WSADATA wsaData;
1785 int last_request = 0;
1786
1787 WSAStartup(MAKEWORD(1,1), &wsaData);
1788
1789 s = socket(AF_INET, SOCK_STREAM, 0);
1790 if (s == INVALID_SOCKET)
1791 return 1;
1792
1793 on = 1;
1794 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1795
1796 memset(&sa, 0, sizeof sa);
1797 sa.sin_family = AF_INET;
1798 sa.sin_port = htons(si->port);
1799 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1800
1801 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1802 if (r < 0)
1803 return 1;
1804
1805 listen(s, 0);
1806 SetEvent(si->event);
1807 do
1808 {
1809 c = accept(s, NULL, NULL);
1810
1811 memset(buffer, 0, sizeof buffer);
1812 for(i = 0; i < sizeof buffer - 1; i++)
1813 {
1814 r = recv(c, &buffer[i], 1, 0);
1815 if (r != 1)
1816 break;
1817 if (i < 4) continue;
1818 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1819 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1820 break;
1821 }
1822 if (strstr(buffer, "GET /basic"))
1823 {
1824 send(c, okmsg, sizeof okmsg - 1, 0);
1825 send(c, page1, sizeof page1 - 1, 0);
1826 }
1827 if (strstr(buffer, "/auth"))
1828 {
1829 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1830 send(c, okmsg, sizeof okmsg - 1, 0);
1831 else
1832 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1833 }
1834 if (strstr(buffer, "/no_headers"))
1835 {
1836 send(c, page1, sizeof page1 - 1, 0);
1837 }
1838 if (strstr(buffer, "GET /quit"))
1839 {
1840 send(c, okmsg, sizeof okmsg - 1, 0);
1841 send(c, page1, sizeof page1 - 1, 0);
1842 last_request = 1;
1843 }
1844 shutdown(c, 2);
1845 closesocket(c);
1846
1847 } while (!last_request);
1848
1849 closesocket(s);
1850 return 0;
1851 }
1852
1853 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1854 {
1855 HINTERNET ses, con, req;
1856 char buffer[0x100];
1857 DWORD count, status, size;
1858 BOOL ret;
1859
1860 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1861 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1862
1863 con = WinHttpConnect(ses, localhostW, port, 0);
1864 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1865
1866 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1867 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1868
1869 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1870 ok(ret, "failed to send request %u\n", GetLastError());
1871
1872 ret = WinHttpReceiveResponse(req, NULL);
1873 ok(ret, "failed to receive response %u\n", GetLastError());
1874
1875 size = sizeof(status);
1876 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1877 ok(ret, "failed to query status code %u\n", GetLastError());
1878 ok(status == 200, "request failed unexpectedly %u\n", status);
1879
1880 count = 0;
1881 memset(buffer, 0, sizeof(buffer));
1882 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1883 ok(ret, "failed to read data %u\n", GetLastError());
1884 ok(count == sizeof page1 - 1, "count was wrong\n");
1885 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1886
1887 WinHttpCloseHandle(req);
1888 WinHttpCloseHandle(con);
1889 WinHttpCloseHandle(ses);
1890 }
1891
1892 static void test_basic_authentication(int port)
1893 {
1894 static const WCHAR authW[] = {'/','a','u','t','h',0};
1895 static const WCHAR userW[] = {'u','s','e','r',0};
1896 static const WCHAR passW[] = {'p','w','d',0};
1897 HINTERNET ses, con, req;
1898 DWORD status, size, error;
1899 BOOL ret;
1900
1901 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1902 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1903
1904 con = WinHttpConnect(ses, localhostW, port, 0);
1905 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1906
1907 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1908 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1909
1910 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1911 ok(ret, "failed to send request %u\n", GetLastError());
1912
1913 ret = WinHttpReceiveResponse(req, NULL);
1914 ok(ret, "failed to receive response %u\n", GetLastError());
1915
1916 size = sizeof(status);
1917 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1918 ok(ret, "failed to query status code %u\n", GetLastError());
1919 ok(status == 401, "request failed unexpectedly %u\n", status);
1920
1921 SetLastError(0xdeadbeef);
1922 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1923 error = GetLastError();
1924 ok(!ret, "expected failure\n");
1925 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1926
1927 SetLastError(0xdeadbeef);
1928 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1929 error = GetLastError();
1930 ok(!ret, "expected failure\n");
1931 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1932
1933 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1934 ok(ret, "failed to set credentials %u\n", GetLastError());
1935
1936 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1937 ok(ret, "failed to send request %u\n", GetLastError());
1938
1939 ret = WinHttpReceiveResponse(req, NULL);
1940 ok(ret, "failed to receive response %u\n", GetLastError());
1941
1942 size = sizeof(status);
1943 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1944 ok(ret, "failed to query status code %u\n", GetLastError());
1945 ok(status == 200, "request failed unexpectedly %u\n", status);
1946
1947 WinHttpCloseHandle(req);
1948 WinHttpCloseHandle(con);
1949 WinHttpCloseHandle(ses);
1950 }
1951
1952 static void test_no_headers(int port)
1953 {
1954 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1955 HINTERNET ses, con, req;
1956 DWORD error;
1957 BOOL ret;
1958
1959 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1960 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1961
1962 con = WinHttpConnect(ses, localhostW, port, 0);
1963 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1964
1965 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1966 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1967
1968 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1969 ok(ret, "failed to send request %u\n", GetLastError());
1970
1971 SetLastError(0xdeadbeef);
1972 ret = WinHttpReceiveResponse(req, NULL);
1973 error = GetLastError();
1974 ok(!ret, "expected failure\n");
1975 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
1976
1977 WinHttpCloseHandle(req);
1978 WinHttpCloseHandle(con);
1979 WinHttpCloseHandle(ses);
1980 }
1981
1982 static void test_bad_header( int port )
1983 {
1984 static const WCHAR bad_headerW[] =
1985 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
1986 't','e','x','t','/','h','t','m','l','\n','\r',0};
1987 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
1988 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
1989 WCHAR buffer[32];
1990 HINTERNET ses, con, req;
1991 DWORD index, len;
1992 BOOL ret;
1993
1994 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
1995 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
1996
1997 con = WinHttpConnect( ses, localhostW, port, 0 );
1998 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
1999
2000 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2001 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2002
2003 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2004 ok( ret, "failed to add header %u\n", GetLastError() );
2005
2006 index = 0;
2007 buffer[0] = 0;
2008 len = sizeof(buffer);
2009 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2010 content_typeW, buffer, &len, &index );
2011 ok( ret, "failed to query headers %u\n", GetLastError() );
2012 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2013
2014 WinHttpCloseHandle( req );
2015 WinHttpCloseHandle( con );
2016 WinHttpCloseHandle( ses );
2017 }
2018
2019 static void test_credentials(void)
2020 {
2021 static WCHAR userW[] = {'u','s','e','r',0};
2022 static WCHAR passW[] = {'p','a','s','s',0};
2023 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2024 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2025 HINTERNET ses, con, req;
2026 DWORD size, error;
2027 WCHAR buffer[32];
2028 BOOL ret;
2029
2030 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2031 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2032
2033 con = WinHttpConnect(ses, localhostW, 0, 0);
2034 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2035
2036 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2037 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2038
2039 size = sizeof(buffer)/sizeof(WCHAR);
2040 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2041 ok(ret, "failed to query proxy username %u\n", GetLastError());
2042 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2043 ok(!size, "expected 0, got %u\n", size);
2044
2045 size = sizeof(buffer)/sizeof(WCHAR);
2046 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2047 ok(ret, "failed to query proxy password %u\n", GetLastError());
2048 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2049 ok(!size, "expected 0, got %u\n", size);
2050
2051 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2052 ok(ret, "failed to set username %u\n", GetLastError());
2053
2054 size = sizeof(buffer)/sizeof(WCHAR);
2055 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2056 ok(ret, "failed to query proxy username %u\n", GetLastError());
2057 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2058 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2059
2060 size = sizeof(buffer)/sizeof(WCHAR);
2061 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2062 ok(ret, "failed to query username %u\n", GetLastError());
2063 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2064 ok(!size, "expected 0, got %u\n", size);
2065
2066 size = sizeof(buffer)/sizeof(WCHAR);
2067 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2068 ok(ret, "failed to query password %u\n", GetLastError());
2069 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2070 ok(!size, "expected 0, got %u\n", size);
2071
2072 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2073 ok(ret, "failed to set proxy password %u\n", GetLastError());
2074
2075 size = sizeof(buffer)/sizeof(WCHAR);
2076 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2077 ok(ret, "failed to query proxy password %u\n", GetLastError());
2078 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2079 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2080
2081 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2082 ok(ret, "failed to set username %u\n", GetLastError());
2083
2084 size = sizeof(buffer)/sizeof(WCHAR);
2085 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2086 ok(ret, "failed to query username %u\n", GetLastError());
2087 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2088 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2089
2090 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2091 ok(ret, "failed to set password %u\n", GetLastError());
2092
2093 size = sizeof(buffer)/sizeof(WCHAR);
2094 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2095 ok(ret, "failed to query password %u\n", GetLastError());
2096 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2097 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2098
2099 WinHttpCloseHandle(req);
2100
2101 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2102 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2103
2104 SetLastError(0xdeadbeef);
2105 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2106 error = GetLastError();
2107 ok(!ret, "expected failure\n");
2108 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2109
2110 SetLastError(0xdeadbeef);
2111 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2112 error = GetLastError();
2113 ok(!ret, "expected failure\n");
2114 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2115
2116 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2117 ok(ret, "failed to set credentials %u\n", GetLastError());
2118
2119 size = sizeof(buffer)/sizeof(WCHAR);
2120 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2121 ok(ret, "failed to query username %u\n", GetLastError());
2122 todo_wine {
2123 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2124 ok(!size, "expected 0, got %u\n", size);
2125 }
2126
2127 size = sizeof(buffer)/sizeof(WCHAR);
2128 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2129 ok(ret, "failed to query password %u\n", GetLastError());
2130 todo_wine {
2131 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2132 ok(!size, "expected 0, got %u\n", size);
2133 }
2134
2135 WinHttpCloseHandle(req);
2136 WinHttpCloseHandle(con);
2137 WinHttpCloseHandle(ses);
2138 }
2139
2140 static void test_IWinHttpRequest(void)
2141 {
2142 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2143 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2144 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2145 static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
2146 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
2147 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
2148 'p','o','s','t','t','e','s','t','.','p','h','p',0};
2149 static const WCHAR method1W[] = {'G','E','T',0};
2150 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2151 static const WCHAR method3W[] = {'P','O','S','T',0};
2152 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2153 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2154 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2155 static const WCHAR dateW[] = {'D','a','t','e',0};
2156 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
2157 HRESULT hr;
2158 IWinHttpRequest *req;
2159 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2160 BSTR date, today, connection, value = NULL;
2161 VARIANT async, empty, timeout, body, proxy_server, bypass_list, data;
2162 VARIANT_BOOL succeeded;
2163 LONG status;
2164 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2165 SYSTEMTIME st;
2166
2167 GetSystemTime( &st );
2168 WinHttpTimeFromSystemTime( &st, todayW );
2169
2170 CoInitialize( NULL );
2171 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2172 ok( hr == S_OK, "got %08x\n", hr );
2173
2174 V_VT( &empty ) = VT_ERROR;
2175 V_ERROR( &empty ) = 0xdeadbeef;
2176
2177 V_VT( &async ) = VT_BOOL;
2178 V_BOOL( &async ) = VARIANT_FALSE;
2179
2180 method = SysAllocString( method3W );
2181 url = SysAllocString( url3W );
2182 hr = IWinHttpRequest_Open( req, method, url, async );
2183 ok( hr == S_OK, "got %08x\n", hr );
2184 SysFreeString( method );
2185 SysFreeString( url );
2186
2187 V_VT( &data ) = VT_BSTR;
2188 V_BSTR( &data ) = SysAllocString( test_dataW );
2189 hr = IWinHttpRequest_Send( req, data );
2190 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
2191 "got %08x\n", hr );
2192 SysFreeString( V_BSTR( &data ) );
2193
2194 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2195 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2196
2197 method = SysAllocString( method1W );
2198 hr = IWinHttpRequest_Open( req, method, NULL, empty );
2199 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2200
2201 hr = IWinHttpRequest_Open( req, method, NULL, async );
2202 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2203
2204 url = SysAllocString( url1W );
2205 hr = IWinHttpRequest_Open( req, NULL, url, empty );
2206 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2207
2208 hr = IWinHttpRequest_Abort( req );
2209 ok( hr == S_OK, "got %08x\n", hr );
2210
2211 hr = IWinHttpRequest_Open( req, method, url, empty );
2212 ok( hr == S_OK, "got %08x\n", hr );
2213
2214 hr = IWinHttpRequest_Abort( req );
2215 ok( hr == S_OK, "got %08x\n", hr );
2216
2217 hr = IWinHttpRequest_Release( req );
2218 ok( hr == S_OK, "got %08x\n", hr );
2219
2220 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2221 ok( hr == S_OK, "got %08x\n", hr );
2222
2223 SysFreeString( url );
2224 url = SysAllocString( url2W );
2225 hr = IWinHttpRequest_Open( req, method, url, async );
2226 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2227
2228 SysFreeString( method );
2229 method = SysAllocString( method2W );
2230 hr = IWinHttpRequest_Open( req, method, url, async );
2231 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2232
2233 SysFreeString( method );
2234 method = SysAllocString( method1W );
2235 SysFreeString( url );
2236 url = SysAllocString( url1W );
2237 hr = IWinHttpRequest_Open( req, method, url, async );
2238 ok( hr == S_OK, "got %08x\n", hr );
2239
2240 hr = IWinHttpRequest_Abort( req );
2241 ok( hr == S_OK, "got %08x\n", hr );
2242
2243 hr = IWinHttpRequest_Send( req, empty );
2244 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2245
2246 hr = IWinHttpRequest_Abort( req );
2247 ok( hr == S_OK, "got %08x\n", hr );
2248
2249 hr = IWinHttpRequest_Release( req );
2250 ok( hr == S_OK, "got %08x\n", hr );
2251
2252 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2253 ok( hr == S_OK, "got %08x\n", hr );
2254
2255 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2256 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2257
2258 hr = IWinHttpRequest_get_ResponseText( req, &response );
2259 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2260
2261 hr = IWinHttpRequest_get_Status( req, NULL );
2262 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2263
2264 hr = IWinHttpRequest_get_Status( req, &status );
2265 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2266
2267 hr = IWinHttpRequest_get_StatusText( req, NULL );
2268 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2269
2270 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2271 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2272
2273 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2274 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2275
2276 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2277 ok( hr == S_OK, "got %08x\n", hr );
2278
2279 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2280 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2281
2282 VariantInit( &proxy_server );
2283 V_VT( &proxy_server ) = VT_ERROR;
2284 VariantInit( &bypass_list );
2285 V_VT( &bypass_list ) = VT_ERROR;
2286 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2287 ok( hr == S_OK, "got %08x\n", hr );
2288
2289 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2290 ok( hr == S_OK, "got %08x\n", hr );
2291
2292 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2293 ok( hr == S_OK, "got %08x\n", hr );
2294
2295 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2296 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2297
2298 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2299 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2300
2301 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2302 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2303
2304 connection = SysAllocString( connectionW );
2305 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2306 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2307
2308 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2309 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2310
2311 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2312 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2313
2314 date = SysAllocString( dateW );
2315 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2316 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2317
2318 today = SysAllocString( todayW );
2319 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2320 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2321
2322 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2323 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2324
2325 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2326 ok( hr == S_OK, "got %08x\n", hr );
2327
2328 SysFreeString( method );
2329 method = SysAllocString( method1W );
2330 SysFreeString( url );
2331 url = SysAllocString( url1W );
2332 hr = IWinHttpRequest_Open( req, method, url, async );
2333 ok( hr == S_OK, "got %08x\n", hr );
2334
2335 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2336 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2337
2338 hr = IWinHttpRequest_get_ResponseText( req, &response );
2339 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2340
2341 hr = IWinHttpRequest_get_Status( req, &status );
2342 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2343
2344 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2345 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2346
2347 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2348 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2349
2350 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2351 ok( hr == S_OK, "got %08x\n", hr );
2352
2353 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2354 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2355
2356 username = SysAllocString( usernameW );
2357 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2358 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2359
2360 password = SysAllocString( passwordW );
2361 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2362 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2363
2364 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2365 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2366
2367 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2368 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2369
2370 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2371 ok( hr == S_OK, "got %08x\n", hr );
2372
2373 V_VT( &proxy_server ) = VT_BSTR;
2374 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2375 V_VT( &bypass_list ) = VT_BSTR;
2376 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2377 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2378 ok( hr == S_OK, "got %08x\n", hr );
2379
2380 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2381 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2382
2383 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2384 ok( hr == S_OK, "got %08x\n", hr );
2385
2386 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2387 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2388
2389 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2390 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2391
2392 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2393 ok( hr == S_OK, "got %08x\n", hr );
2394
2395 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2396 ok( hr == S_OK, "got %08x\n", hr );
2397
2398 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2399 ok( hr == S_OK, "got %08x\n", hr );
2400
2401 hr = IWinHttpRequest_Send( req, empty );
2402 ok( hr == S_OK, "got %08x\n", hr );
2403
2404 hr = IWinHttpRequest_Send( req, empty );
2405 ok( hr == S_OK, "got %08x\n", hr );
2406
2407 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2408 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2409
2410 hr = IWinHttpRequest_get_ResponseText( req, &response );
2411 ok( hr == S_OK, "got %08x\n", hr );
2412 SysFreeString( response );
2413
2414 hr = IWinHttpRequest_get_Status( req, NULL );
2415 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2416
2417 status = 0;
2418 hr = IWinHttpRequest_get_Status( req, &status );
2419 ok( hr == S_OK, "got %08x\n", hr );
2420 trace("%d\n", status);
2421
2422 hr = IWinHttpRequest_get_StatusText( req, NULL );
2423 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2424
2425 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2426 ok( hr == S_OK, "got %08x\n", hr );
2427 trace("%s\n", wine_dbgstr_w(status_text));
2428 SysFreeString( status_text );
2429
2430 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2431 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2432
2433 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2434 ok( hr == S_OK, "got %08x\n", hr );
2435
2436 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2437 ok( hr == S_OK, "got %08x\n", hr );
2438
2439 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2440 ok( hr == S_OK, "got %08x\n", hr );
2441
2442 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2443 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2444
2445 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2446 ok( hr == S_OK, "got %08x\n", hr );
2447 SysFreeString( headers );
2448
2449 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2450 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2451
2452 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2453 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2454
2455 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2456 ok( hr == S_OK, "got %08x\n", hr );
2457 SysFreeString( value );
2458
2459 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2460 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2461
2462 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2463 ok( hr == S_OK, "got %08x\n", hr );
2464
2465 VariantInit( &timeout );
2466 V_VT( &timeout ) = VT_I4;
2467 V_I4( &timeout ) = 10;
2468 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2469 ok( hr == S_OK, "got %08x\n", hr );
2470
2471 hr = IWinHttpRequest_get_Status( req, &status );
2472 ok( hr == S_OK, "got %08x\n", hr );
2473
2474 hr = IWinHttpRequest_get_StatusText( req, &status_text );
2475 ok( hr == S_OK, "got %08x\n", hr );
2476 SysFreeString( status_text );
2477
2478 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2479 ok( hr == S_OK, "got %08x\n", hr );
2480
2481 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2482 ok( hr == S_OK, "got %08x\n", hr );
2483
2484 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2485 ok( hr == S_OK, "got %08x\n", hr );
2486
2487 hr = IWinHttpRequest_Send( req, empty );
2488 ok( hr == S_OK, "got %08x\n", hr );
2489
2490 hr = IWinHttpRequest_get_ResponseText( req, NULL );
2491 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2492
2493 hr = IWinHttpRequest_get_ResponseText( req, &response );
2494 ok( hr == S_OK, "got %08x\n", hr );
2495 SysFreeString( response );
2496
2497 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2498 ok( hr == E_INVALIDARG, "got %08x\n", hr );
2499
2500 VariantInit( &body );
2501 V_VT( &body ) = VT_ERROR;
2502 hr = IWinHttpRequest_get_ResponseBody( req, &body );
2503 ok( hr == S_OK, "got %08x\n", hr );
2504 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2505
2506 hr = VariantClear( &body );
2507 ok( hr == S_OK, "got %08x\n", hr );
2508
2509 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2510 ok( hr == S_OK, "got %08x\n", hr );
2511
2512 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2513 ok( hr == S_OK, "got %08x\n", hr );
2514
2515 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2516 ok( hr == S_OK, "got %08x\n", hr );
2517 SysFreeString( headers );
2518
2519 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2520 ok( hr == S_OK, "got %08x\n", hr );
2521 SysFreeString( value );
2522
2523 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2524 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2525
2526 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2527 ok( hr == S_OK, "got %08x\n", hr );
2528
2529 hr = IWinHttpRequest_Send( req, empty );
2530 ok( hr == S_OK, "got %08x\n", hr );
2531
2532 hr = IWinHttpRequest_Abort( req );
2533 ok( hr == S_OK, "got %08x\n", hr );
2534
2535 hr = IWinHttpRequest_Abort( req );
2536 ok( hr == S_OK, "got %08x\n", hr );
2537
2538 hr = IWinHttpRequest_Release( req );
2539 ok( hr == S_OK, "got %08x\n", hr );
2540
2541 SysFreeString( method );
2542 SysFreeString( url );
2543 SysFreeString( username );
2544 SysFreeString( password );
2545 SysFreeString( connection );
2546 SysFreeString( date );
2547 SysFreeString( today );
2548 VariantClear( &proxy_server );
2549 VariantClear( &bypass_list );
2550 CoUninitialize();
2551 }
2552
2553 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2554 {
2555 BOOL ret;
2556 WCHAR *url;
2557 DWORD error;
2558
2559 if (0) /* crashes on some win2k systems */
2560 {
2561 SetLastError(0xdeadbeef);
2562 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
2563 error = GetLastError();
2564 ok( !ret, "expected failure\n" );
2565 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2566 }
2567 url = NULL;
2568 SetLastError(0xdeadbeef);
2569 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
2570 error = GetLastError();
2571 ok( !ret, "expected failure\n" );
2572 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2573
2574 if (0) /* crashes on some win2k systems */
2575 {
2576 SetLastError(0xdeadbeef);
2577 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
2578 error = GetLastError();
2579 ok( !ret, "expected failure\n" );
2580 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2581 }
2582 url = NULL;
2583 SetLastError(0xdeadbeef);
2584 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
2585 error = GetLastError();
2586 if (!ret)
2587 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2588 else
2589 {
2590 trace("%s\n", wine_dbgstr_w(url));
2591 GlobalFree( url );
2592 }
2593 }
2594
2595 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2596 {
2597 BOOL ret;
2598 DWORD error;
2599 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
2600
2601 memset( &cfg, 0, sizeof(cfg) );
2602
2603 SetLastError(0xdeadbeef);
2604 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
2605 error = GetLastError();
2606 ok( !ret, "expected failure\n" );
2607 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2608
2609 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
2610 ok( ret, "expected success\n" );
2611 trace("%d\n", cfg.fAutoDetect);
2612 trace("%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
2613 trace("%s\n", wine_dbgstr_w(cfg.lpszProxy));
2614 trace("%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
2615 GlobalFree( cfg.lpszAutoConfigUrl );
2616 GlobalFree( cfg.lpszProxy );
2617 GlobalFree( cfg.lpszProxyBypass );
2618 }
2619
2620 static void test_WinHttpGetProxyForUrl(void)
2621 {
2622 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2623 static const WCHAR emptyW[] = {0};
2624 BOOL ret;
2625 DWORD error;
2626 HINTERNET session;
2627 WINHTTP_AUTOPROXY_OPTIONS options;
2628 WINHTTP_PROXY_INFO info;
2629
2630 memset( &options, 0, sizeof(options) );
2631
2632 SetLastError(0xdeadbeef);
2633 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
2634 error = GetLastError();
2635 ok( !ret, "expected failure\n" );
2636 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
2637
2638 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2639 ok( session != NULL, "failed to open session %u\n", GetLastError() );
2640
2641 SetLastError(0xdeadbeef);
2642 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
2643 error = GetLastError();
2644 ok( !ret, "expected failure\n" );
2645 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2646
2647 SetLastError(0xdeadbeef);
2648 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
2649 error = GetLastError();
2650 ok( !ret, "expected failure\n" );
2651 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2652
2653 SetLastError(0xdeadbeef);
2654 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
2655 error = GetLastError();
2656 ok( !ret, "expected failure\n" );
2657 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2658
2659 SetLastError(0xdeadbeef);
2660 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2661 error = GetLastError();
2662 ok( !ret, "expected failure\n" );
2663 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2664
2665 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2666 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2667
2668 SetLastError(0xdeadbeef);
2669 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
2670 error = GetLastError();
2671 ok( !ret, "expected failure\n" );
2672 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2673
2674 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2675 options.dwAutoDetectFlags = 0;
2676
2677 SetLastError(0xdeadbeef);
2678 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2679 error = GetLastError();
2680 ok( !ret, "expected failure\n" );
2681 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2682
2683 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
2684 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2685
2686 SetLastError(0xdeadbeef);
2687 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2688 error = GetLastError();
2689 ok( !ret, "expected failure\n" );
2690 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2691
2692 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2693 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2694
2695 memset( &info, 0, sizeof(info) );
2696 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2697 if (ret)
2698 {
2699 trace("%u\n", info.dwAccessType);
2700 trace("%s\n", wine_dbgstr_w(info.lpszProxy));
2701 trace("%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2702 GlobalFree( (WCHAR *)info.lpszProxy );
2703 GlobalFree( (WCHAR *)info.lpszProxyBypass );
2704 }
2705 WinHttpCloseHandle( session );
2706 }
2707
2708 START_TEST (winhttp)
2709 {
2710 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2711 static const WCHAR quitW[] = {'/','q','u','i','t',0};
2712 struct server_info si;
2713 HANDLE thread;
2714 DWORD ret;
2715
2716 test_OpenRequest();
2717 test_SendRequest();
2718 test_WinHttpTimeFromSystemTime();
2719 test_WinHttpTimeToSystemTime();
2720 test_WinHttpAddHeaders();
2721 test_secure_connection();
2722 test_request_parameter_defaults();
2723 test_QueryOption();
2724 test_set_default_proxy_config();
2725 test_empty_headers_param();
2726 test_Timeouts();
2727 test_resolve_timeout();
2728 test_credentials();
2729 test_IWinHttpRequest();
2730 test_WinHttpDetectAutoProxyConfigUrl();
2731 test_WinHttpGetIEProxyConfigForCurrentUser();
2732 test_WinHttpGetProxyForUrl();
2733
2734 si.event = CreateEvent(NULL, 0, 0, NULL);
2735 si.port = 7532;
2736
2737 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2738 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2739
2740 ret = WaitForSingleObject(si.event, 10000);
2741 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2742 if (ret != WAIT_OBJECT_0)
2743 return;
2744
2745 test_basic_request(si.port, NULL, basicW);
2746 test_no_headers(si.port);
2747 test_basic_authentication(si.port);
2748 test_bad_header(si.port);
2749
2750 /* send the basic request again to shutdown the server thread */
2751 test_basic_request(si.port, NULL, quitW);
2752
2753 WaitForSingleObject(thread, 3000);
2754 }