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