4 * Copyright 2008 Google (Zac Brown)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
32 //#include <ws2tcpip.h>
36 //#include <winsock.h>
37 //#include "initguid.h"
38 #include <httprequest.h>
40 #include <wine/test.h>
42 static const WCHAR test_useragent
[] =
43 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
44 static const WCHAR test_server
[] = {'w','i','n','e','h','q','.','o','r','g',0};
45 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
47 static BOOL
proxy_active(void)
49 WINHTTP_PROXY_INFO proxy_info
;
52 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
54 active
= (proxy_info
.lpszProxy
!= NULL
);
56 GlobalFree(proxy_info
.lpszProxy
);
57 if (proxy_info
.lpszProxyBypass
!= NULL
)
58 GlobalFree(proxy_info
.lpszProxyBypass
);
66 static void test_QueryOption(void)
69 HINTERNET session
, request
, connection
;
72 SetLastError(0xdeadbeef);
73 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
74 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
76 SetLastError(0xdeadbeef);
77 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
78 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
79 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
80 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
83 SetLastError(0xdeadbeef);
84 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
85 ok(!ret
, "should fail to query option\n");
86 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
87 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
88 ok(size
== 4, "expected 4, got %u\n", size
);
91 size
= sizeof(feature
) - 1;
92 SetLastError(0xdeadbeef);
93 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
94 ok(!ret
, "should fail to query option\n");
95 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
96 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
97 ok(size
== 4, "expected 4, got %u\n", size
);
100 size
= sizeof(feature
) + 1;
101 SetLastError(0xdeadbeef);
102 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
103 ok(ret
, "failed to query option %u\n", GetLastError());
104 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
105 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
106 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
108 SetLastError(0xdeadbeef);
109 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
110 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
111 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
112 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
114 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
115 SetLastError(0xdeadbeef);
116 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
117 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
118 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
119 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
121 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
122 SetLastError(0xdeadbeef);
123 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
124 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
125 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
126 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
128 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
129 SetLastError(0xdeadbeef);
130 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
131 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
133 feature
= 0xdeadbeef;
134 size
= sizeof(feature
);
135 SetLastError(0xdeadbeef);
136 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
137 ok(ret
, "failed to query option %u\n", GetLastError());
138 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
139 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
141 feature
= WINHTTP_DISABLE_COOKIES
;
142 SetLastError(0xdeadbeef);
143 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
144 ok(!ret
, "should fail to set disable feature for a session\n");
145 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
146 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
148 SetLastError(0xdeadbeef);
149 connection
= WinHttpConnect(session
, test_server
, INTERNET_DEFAULT_HTTP_PORT
, 0);
150 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
152 feature
= WINHTTP_DISABLE_COOKIES
;
153 SetLastError(0xdeadbeef);
154 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
155 ok(!ret
, "should fail to set disable feature for a connection\n");
156 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
157 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
159 SetLastError(0xdeadbeef);
160 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
161 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
162 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
164 skip("Network unreachable, skipping the test\n");
168 feature
= 0xdeadbeef;
169 size
= sizeof(feature
);
170 SetLastError(0xdeadbeef);
171 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
172 ok(!ret
, "should fail to query disable feature for a request\n");
173 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
174 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
177 size
= sizeof(feature
);
178 SetLastError(0xdeadbeef);
179 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
180 ok(ret
, "failed to set feature %u\n", GetLastError());
182 feature
= 0xffffffff;
183 size
= sizeof(feature
);
184 SetLastError(0xdeadbeef);
185 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
186 ok(ret
, "failed to set feature %u\n", GetLastError());
188 feature
= WINHTTP_DISABLE_COOKIES
;
189 size
= sizeof(feature
);
190 SetLastError(0xdeadbeef);
191 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
192 ok(ret
, "failed to set feature %u\n", GetLastError());
195 SetLastError(0xdeadbeef);
196 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
197 ok(!ret
, "should fail to query disable feature for a request\n");
198 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
199 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
201 SetLastError(0xdeadbeef);
202 ret
= WinHttpCloseHandle(request
);
203 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
206 SetLastError(0xdeadbeef);
207 ret
= WinHttpCloseHandle(connection
);
208 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
209 SetLastError(0xdeadbeef);
210 ret
= WinHttpCloseHandle(session
);
211 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
214 static void test_OpenRequest (void)
217 HINTERNET session
, request
, connection
;
219 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
220 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
221 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
223 /* Test with a bad server name */
224 SetLastError(0xdeadbeef);
225 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
226 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
227 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
229 /* Test with a valid server name */
230 connection
= WinHttpConnect (session
, test_server
, INTERNET_DEFAULT_HTTP_PORT
, 0);
231 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
233 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
234 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
235 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
237 skip("Network unreachable, skipping.\n");
240 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
242 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
243 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
245 skip("Connection failed, skipping.\n");
248 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
249 ret
= WinHttpCloseHandle(request
);
250 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
253 ret
= WinHttpCloseHandle(connection
);
254 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
255 ret
= WinHttpCloseHandle(session
);
256 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
260 static void test_empty_headers_param(void)
262 static const WCHAR winehq
[] = {'w','i','n','e','h','q','.','o','r','g',0};
263 static const WCHAR empty
[] = {0};
264 HINTERNET ses
, con
, req
;
267 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
268 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
270 con
= WinHttpConnect(ses
, winehq
, 80, 0);
271 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
273 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
274 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
276 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
277 ok(ret
, "failed to send request %u\n", GetLastError());
279 WinHttpCloseHandle(req
);
280 WinHttpCloseHandle(con
);
281 WinHttpCloseHandle(ses
);
284 static void test_SendRequest (void)
286 HINTERNET session
, request
, connection
;
287 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
;
293 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
294 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
295 static const WCHAR content_type
[] =
296 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
297 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
298 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
299 static const WCHAR test_verb
[] = {'P','O','S','T',0};
300 static CHAR post_data
[] = "mode=Test";
301 static CHAR test_post
[] = "mode => Test\\0\n";
304 total_len
= optional_len
= sizeof(post_data
);
305 memset(buffer
, 0xff, sizeof(buffer
));
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");
311 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
312 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
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
)
318 skip("Network unreachable, skipping.\n");
321 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
322 if (!request
) goto done
;
324 context
= 0xdeadbeef;
325 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
326 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
329 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
330 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
333 size
= sizeof(context
);
334 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
335 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
336 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
338 for (i
= 3; post_data
[i
]; i
++)
341 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
343 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
344 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
346 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
347 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
351 ret
= WinHttpReceiveResponse(request
, NULL
);
352 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
355 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
356 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
358 ok(bytes_rw
== strlen(test_post
), "Read %u bytes instead of %d.\n", bytes_rw
, lstrlen(test_post
));
359 ok(strncmp(buffer
, test_post
, bytes_rw
) == 0, "Data read did not match, got '%s'.\n", buffer
);
361 ret
= WinHttpCloseHandle(request
);
362 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
364 ret
= WinHttpCloseHandle(connection
);
365 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
366 ret
= WinHttpCloseHandle(session
);
367 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
370 static void test_WinHttpTimeFromSystemTime(void)
373 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
374 static const WCHAR expected_string
[] =
375 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
376 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
377 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
379 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
380 ok(ret
== TRUE
, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
381 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
382 "Time string returned did not match expected time string.\n");
385 static void test_WinHttpTimeToSystemTime(void)
389 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
390 static const WCHAR time_string1
[] =
391 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
392 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
393 static const WCHAR time_string2
[] =
394 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
395 '1','0',' ','0','5',' ','5','2','\n',0};
397 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
398 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
399 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
400 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
402 ret
= WinHttpTimeToSystemTime(time_string2
, &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");
408 static void test_WinHttpAddHeaders(void)
410 HINTERNET session
, request
, connection
;
412 WCHAR buffer
[MAX_PATH
];
413 WCHAR check_buffer
[MAX_PATH
];
414 DWORD index
, len
, oldlen
;
416 static const WCHAR test_site
[] = {'c','r','o','s','s','o','v','e','r','.',
417 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
418 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
419 static const WCHAR test_verb
[] = {'P','O','S','T',0};
421 static const WCHAR test_header_begin
[] =
422 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
423 static const WCHAR full_path_test_header_begin
[] =
424 {'P','O','S','T',' ','h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',':','8','0','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
425 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
426 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
428 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
429 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
430 static const WCHAR test_flag_coalesce_comma
[] =
431 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
432 static const WCHAR test_flag_coalesce_comma_reverse
[] =
433 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
434 static const WCHAR test_flag_coalesce_semicolon
[] =
435 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
436 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
437 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
439 static const WCHAR field
[] = {'f','i','e','l','d',0};
440 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
441 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
443 static const WCHAR test_headers
[][14] =
445 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
446 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
447 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
448 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
449 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
450 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
451 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
457 {' ','e',' ',':','f',0},
458 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
460 static const WCHAR test_indices
[][6] =
462 {'t','e','s','t','1',0},
463 {'t','e','s','t','2',0},
464 {'t','e','s','t','3',0},
465 {'t','e','s','t','4',0}
468 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
469 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
470 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
472 connection
= WinHttpConnect (session
, test_site
, INTERNET_DEFAULT_HTTP_PORT
, 0);
473 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
475 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
476 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
477 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
479 skip("Network unreachable, skipping.\n");
482 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
485 len
= sizeof(buffer
);
486 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
487 test_header_name
, buffer
, &len
, &index
);
488 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
489 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
490 ok(ret
== TRUE
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, GetLastError());
493 len
= sizeof(buffer
);
494 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
495 test_header_name
, buffer
, &len
, &index
);
496 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
497 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
498 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
499 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
501 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
502 test_header_name
, buffer
, &len
, &index
);
503 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
505 /* Try to fetch the header info with a buffer that's big enough to fit the
506 * string but not the NULL terminator.
509 len
= 5*sizeof(WCHAR
);
510 memset(check_buffer
, 0xab, sizeof(check_buffer
));
511 memcpy(buffer
, check_buffer
, sizeof(buffer
));
512 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
513 test_header_name
, buffer
, &len
, &index
);
514 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
515 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
516 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
517 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
519 /* Try with a NULL buffer */
521 len
= sizeof(buffer
);
522 SetLastError(0xdeadbeef);
523 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
524 test_header_name
, NULL
, &len
, &index
);
525 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
526 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
527 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
528 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
530 /* Try with a NULL buffer and a length that's too small */
533 SetLastError(0xdeadbeef);
534 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
535 test_header_name
, NULL
, &len
, &index
);
536 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
537 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
538 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
539 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
540 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
544 SetLastError(0xdeadbeef);
545 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
546 test_header_name
, NULL
, &len
, &index
);
547 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
548 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
549 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
550 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
551 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
556 len
= sizeof(buffer
);
557 memset(buffer
, 0xff, sizeof(buffer
));
558 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
559 test_header_name
, buffer
, &len
, &index
);
560 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
561 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
562 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
563 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
564 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
565 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
566 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
567 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
568 "WinHttpQueryHeaders returned invalid end of header string.\n");
569 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
573 SetLastError(0xdeadbeef);
574 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
575 test_header_name
, NULL
, &len
, &index
);
576 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
577 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
578 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
579 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
580 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
584 len
= sizeof(buffer
);
585 memset(buffer
, 0xff, sizeof(buffer
));
586 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
587 test_header_name
, buffer
, &len
, &index
);
588 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
589 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
590 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
591 "no double NULL terminator\n");
592 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
593 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
594 "invalid beginning of header string.\n");
595 ok(index
== 0, "header index was incremented\n");
597 /* tests for more indices */
598 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
599 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
602 len
= sizeof(buffer
);
603 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
604 test_header_name
, buffer
, &len
, &index
);
605 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
606 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
607 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
609 len
= sizeof(buffer
);
610 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
611 test_header_name
, buffer
, &len
, &index
);
612 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
613 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
614 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
616 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
617 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
620 len
= sizeof(buffer
);
621 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
622 test_header_name
, buffer
, &len
, &index
);
623 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
624 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
625 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
626 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
628 len
= sizeof(buffer
);
629 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
630 test_header_name
, buffer
, &len
, &index
);
631 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
632 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
633 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
635 /* add if new flag */
636 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
637 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
640 len
= sizeof(buffer
);
641 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
642 test_header_name
, buffer
, &len
, &index
);
643 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
644 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
645 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
647 len
= sizeof(buffer
);
648 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
649 test_header_name
, buffer
, &len
, &index
);
650 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
651 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
652 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
654 len
= sizeof(buffer
);
655 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
656 test_header_name
, buffer
, &len
, &index
);
657 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
660 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
661 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
668 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
669 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
670 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
672 len
= sizeof(buffer
);
673 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
674 test_header_name
, buffer
, &len
, &index
);
675 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
676 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
677 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
679 len
= sizeof(buffer
);
680 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
681 test_header_name
, buffer
, &len
, &index
);
682 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
684 /* coalesce with comma flag */
685 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
686 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
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
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
693 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
694 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
695 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
696 "WinHttpQueryHeaders returned incorrect string.\n");
698 len
= sizeof(buffer
);
699 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
700 test_header_name
, buffer
, &len
, &index
);
701 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
702 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
703 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
705 len
= sizeof(buffer
);
706 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
707 test_header_name
, buffer
, &len
, &index
);
708 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
711 /* coalesce with semicolon flag */
712 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
713 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
716 len
= sizeof(buffer
);
717 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
718 test_header_name
, buffer
, &len
, &index
);
719 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
720 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
721 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
722 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
723 "WinHttpQueryHeaders returned incorrect string.\n");
725 len
= sizeof(buffer
);
726 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
727 test_header_name
, buffer
, &len
, &index
);
728 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
729 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
730 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
732 len
= sizeof(buffer
);
733 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
734 test_header_name
, buffer
, &len
, &index
);
735 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
737 /* add and replace flags */
738 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
739 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
742 len
= sizeof(buffer
);
743 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
744 test_header_name
, buffer
, &len
, &index
);
745 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
746 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
747 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
749 len
= sizeof(buffer
);
750 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
751 test_header_name
, buffer
, &len
, &index
);
752 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
753 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
754 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
756 len
= sizeof(buffer
);
757 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
758 test_header_name
, buffer
, &len
, &index
);
759 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
761 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
762 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
764 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
765 ok(ret
, "WinHttpAddRequestHeaders failed\n");
767 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
768 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
770 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
771 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
773 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
774 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
776 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
777 ok(ret
, "WinHttpAddRequestHeaders failed\n");
781 len
= sizeof(buffer
);
782 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
783 field
, buffer
, &len
, &index
);
784 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
785 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
787 ret
= WinHttpCloseHandle(request
);
788 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
790 ret
= WinHttpCloseHandle(connection
);
791 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
792 ret
= WinHttpCloseHandle(session
);
793 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
797 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
799 DWORD flags
= *(DWORD
*)buf
;
803 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
806 #define X(x) if (flags & x) trace("%s\n", #x);
807 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
808 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
809 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
810 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
811 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
812 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
813 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
817 static void test_secure_connection(void)
819 static const WCHAR google
[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
821 HINTERNET ses
, con
, req
;
822 DWORD size
, status
, policy
, bitness
, read_size
;
825 WINHTTP_CERTIFICATE_INFO info
;
828 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
829 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
831 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
832 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
833 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
835 con
= WinHttpConnect(ses
, google
, 443, 0);
836 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
838 /* try without setting WINHTTP_FLAG_SECURE */
839 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
840 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
842 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
843 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
845 skip("Connection failed, skipping.\n");
848 ok(ret
, "failed to send request %u\n", GetLastError());
850 ret
= WinHttpReceiveResponse(req
, NULL
);
851 ok(!ret
|| proxy_active(), "succeeded unexpectedly\n");
854 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
855 ok(!ret
, "succeeded unexpectedly\n");
857 WinHttpCloseHandle(req
);
859 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
860 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
862 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
864 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
865 ok(ret
, "failed to send request %u\n", GetLastError());
868 skip("secure connection failed, skipping remaining secure tests\n");
873 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
874 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
876 CertFreeCertificateContext(cert
);
878 size
= sizeof(bitness
);
879 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
880 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
883 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
884 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
886 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
887 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
888 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
889 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
890 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
891 trace("dwKeySize %u\n", info
.dwKeySize
);
893 ret
= WinHttpReceiveResponse(req
, NULL
);
894 ok(ret
, "failed to receive response %u\n", GetLastError());
896 size
= sizeof(status
);
897 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
898 ok(ret
, "failed unexpectedly %u\n", GetLastError());
899 ok(status
== 200, "request failed unexpectedly %u\n", status
);
902 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
903 ok(!ret
, "succeeded unexpectedly\n");
909 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
910 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
914 ok(read_size
> 2014, "read_size = %u\n", read_size
);
917 WinHttpCloseHandle(req
);
918 WinHttpCloseHandle(con
);
919 WinHttpCloseHandle(ses
);
922 static void test_request_parameter_defaults(void)
924 static const WCHAR empty
[] = {0};
925 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
927 HINTERNET ses
, con
, req
;
928 DWORD size
, status
, error
;
932 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
933 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
935 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
936 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
938 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
939 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
941 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
942 ok(ret
, "failed to send request %u\n", GetLastError());
944 ret
= WinHttpReceiveResponse(req
, NULL
);
945 ok(ret
, "failed to receive response %u\n", GetLastError());
947 size
= sizeof(status
);
948 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
949 ok(ret
, "failed unexpectedly %u\n", GetLastError());
950 ok(status
== 200, "request failed unexpectedly %u\n", status
);
952 WinHttpCloseHandle(req
);
954 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
955 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
957 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
958 ok(ret
, "failed to send request %u\n", GetLastError());
960 ret
= WinHttpReceiveResponse(req
, NULL
);
961 ok(ret
, "failed to receive response %u\n", GetLastError());
964 SetLastError(0xdeadbeef);
965 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
966 error
= GetLastError();
967 ok(!ret
, "succeeded unexpectedly\n");
968 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
970 version
= HeapAlloc(GetProcessHeap(), 0, size
);
971 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
972 ok(ret
, "failed unexpectedly %u\n", GetLastError());
973 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
974 HeapFree(GetProcessHeap(), 0, version
);
976 size
= sizeof(status
);
977 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
978 ok(ret
, "failed unexpectedly %u\n", GetLastError());
979 ok(status
== 200, "request failed unexpectedly %u\n", status
);
981 WinHttpCloseHandle(req
);
982 WinHttpCloseHandle(con
);
983 WinHttpCloseHandle(ses
);
986 static const WCHAR Connections
[] = {
987 'S','o','f','t','w','a','r','e','\\',
988 'M','i','c','r','o','s','o','f','t','\\',
989 'W','i','n','d','o','w','s','\\',
990 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
991 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
992 'C','o','n','n','e','c','t','i','o','n','s',0 };
993 static const WCHAR WinHttpSettings
[] = {
994 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
996 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1002 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1007 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1011 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1021 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1026 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
1027 KEY_WRITE
, NULL
, &key
, NULL
);
1031 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
1033 RegDeleteValueW( key
, WinHttpSettings
);
1038 static void test_set_default_proxy_config(void)
1040 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1041 static WCHAR normalString
[] = { 'f','o','o',0 };
1043 BYTE
*saved_proxy_settings
= NULL
;
1044 WINHTTP_PROXY_INFO info
;
1047 /* FIXME: it would be simpler to read the current settings using
1048 * WinHttpGetDefaultProxyConfiguration and save them using
1049 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1051 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1052 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1053 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1054 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1055 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1056 * the lpszProxy and lpszProxyBypass values are ignored.
1057 * Thus, if a proxy is set with proxycfg, then calling
1058 * WinHttpGetDefaultProxyConfiguration followed by
1059 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1060 * getting deleted from the registry.
1062 * Instead I read the current registry value and restore it directly.
1064 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1067 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1068 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1073 /* Crashes on Vista and higher */
1074 SetLastError(0xdeadbeef);
1075 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1076 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1077 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1080 /* test with invalid access type */
1081 info
.dwAccessType
= 0xdeadbeef;
1082 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1083 SetLastError(0xdeadbeef);
1084 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1085 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1086 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1088 /* at a minimum, the proxy server must be set */
1089 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1090 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1091 SetLastError(0xdeadbeef);
1092 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1093 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1094 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1095 info
.lpszProxyBypass
= normalString
;
1096 SetLastError(0xdeadbeef);
1097 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1098 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1099 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1101 /* the proxy server can't have wide characters */
1102 info
.lpszProxy
= wideString
;
1103 SetLastError(0xdeadbeef);
1104 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1105 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1106 skip("couldn't set default proxy configuration: access denied\n");
1108 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1109 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1110 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1112 info
.lpszProxy
= normalString
;
1113 SetLastError(0xdeadbeef);
1114 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1115 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1116 skip("couldn't set default proxy configuration: access denied\n");
1118 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1121 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1124 static void test_Timeouts (void)
1128 HINTERNET ses
, req
, con
;
1129 static const WCHAR codeweavers
[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1132 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1133 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1135 SetLastError(0xdeadbeef);
1136 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1137 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1138 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1140 SetLastError(0xdeadbeef);
1141 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1142 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1143 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1145 SetLastError(0xdeadbeef);
1146 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1147 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1148 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1150 SetLastError(0xdeadbeef);
1151 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1152 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1153 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1155 SetLastError(0xdeadbeef);
1156 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1157 ok(ret
, "%u\n", GetLastError());
1159 SetLastError(0xdeadbeef);
1160 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1161 ok(ret
, "%u\n", GetLastError());
1163 SetLastError(0xdeadbeef);
1164 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1165 ok(ret
, "%u\n", GetLastError());
1167 SetLastError(0xdeadbeef);
1169 size
= sizeof(DWORD
);
1170 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1171 ok(ret
, "%u\n", GetLastError());
1172 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1174 SetLastError(0xdeadbeef);
1176 size
= sizeof(DWORD
);
1177 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1178 ok(ret
, "%u\n", GetLastError());
1179 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1181 SetLastError(0xdeadbeef);
1183 size
= sizeof(DWORD
);
1184 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1185 ok(ret
, "%u\n", GetLastError());
1186 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1188 SetLastError(0xdeadbeef);
1190 size
= sizeof(DWORD
);
1191 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1192 ok(ret
, "%u\n", GetLastError());
1193 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1195 SetLastError(0xdeadbeef);
1197 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1198 ok(ret
, "%u\n", GetLastError());
1200 SetLastError(0xdeadbeef);
1202 size
= sizeof(DWORD
);
1203 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1204 ok(ret
, "%u\n", GetLastError());
1205 ok(value
== 0, "Expected 0, got %u\n", value
);
1207 SetLastError(0xdeadbeef);
1209 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1210 ok(ret
, "%u\n", GetLastError());
1212 SetLastError(0xdeadbeef);
1214 size
= sizeof(DWORD
);
1215 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1216 ok(ret
, "%u\n", GetLastError());
1217 ok(value
== 0, "Expected 0, got %u\n", value
);
1219 SetLastError(0xdeadbeef);
1221 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1222 ok(ret
, "%u\n", GetLastError());
1224 SetLastError(0xdeadbeef);
1226 size
= sizeof(DWORD
);
1227 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1228 ok(ret
, "%u\n", GetLastError());
1229 ok(value
== 0, "Expected 0, got %u\n", value
);
1231 SetLastError(0xdeadbeef);
1233 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1234 ok(ret
, "%u\n", GetLastError());
1236 SetLastError(0xdeadbeef);
1238 size
= sizeof(DWORD
);
1239 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1240 ok(ret
, "%u\n", GetLastError());
1241 ok(value
== 0, "Expected 0, got %u\n", value
);
1243 SetLastError(0xdeadbeef);
1245 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1246 ok(ret
, "%u\n", GetLastError());
1248 SetLastError(0xdeadbeef);
1250 size
= sizeof(DWORD
);
1251 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1252 ok(ret
, "%u\n", GetLastError());
1253 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1255 SetLastError(0xdeadbeef);
1257 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1258 ok(ret
, "%u\n", GetLastError());
1260 SetLastError(0xdeadbeef);
1262 size
= sizeof(DWORD
);
1263 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1264 ok(ret
, "%u\n", GetLastError());
1265 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1267 SetLastError(0xdeadbeef);
1269 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1270 ok(ret
, "%u\n", GetLastError());
1272 SetLastError(0xdeadbeef);
1274 size
= sizeof(DWORD
);
1275 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1276 ok(ret
, "%u\n", GetLastError());
1277 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1279 SetLastError(0xdeadbeef);
1281 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1282 ok(ret
, "%u\n", GetLastError());
1284 SetLastError(0xdeadbeef);
1286 size
= sizeof(DWORD
);
1287 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1288 ok(ret
, "%u\n", GetLastError());
1289 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1291 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1292 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1294 /* Timeout values should match the last one set for session */
1295 SetLastError(0xdeadbeef);
1297 size
= sizeof(DWORD
);
1298 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1299 ok(ret
, "%u\n", GetLastError());
1300 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1302 SetLastError(0xdeadbeef);
1304 size
= sizeof(DWORD
);
1305 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1306 ok(ret
, "%u\n", GetLastError());
1307 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1309 SetLastError(0xdeadbeef);
1311 size
= sizeof(DWORD
);
1312 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1313 ok(ret
, "%u\n", GetLastError());
1314 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1316 SetLastError(0xdeadbeef);
1318 size
= sizeof(DWORD
);
1319 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1320 ok(ret
, "%u\n", GetLastError());
1321 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1323 SetLastError(0xdeadbeef);
1324 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1325 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1326 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1328 SetLastError(0xdeadbeef);
1329 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1330 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1331 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1333 SetLastError(0xdeadbeef);
1334 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1335 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1336 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1338 SetLastError(0xdeadbeef);
1339 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1340 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1341 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1343 SetLastError(0xdeadbeef);
1344 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1345 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1346 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1348 SetLastError(0xdeadbeef);
1349 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1350 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1351 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1353 SetLastError(0xdeadbeef);
1355 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1356 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1357 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1359 SetLastError(0xdeadbeef);
1361 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1362 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1363 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1365 SetLastError(0xdeadbeef);
1367 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1368 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1369 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1371 SetLastError(0xdeadbeef);
1373 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1374 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1375 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1377 /* Changing timeout values for session should affect the values for connection */
1378 SetLastError(0xdeadbeef);
1380 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1381 ok(ret
, "%u\n", GetLastError());
1383 SetLastError(0xdeadbeef);
1385 size
= sizeof(DWORD
);
1386 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1387 ok(ret
, "%u\n", GetLastError());
1388 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1390 SetLastError(0xdeadbeef);
1392 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1393 ok(ret
, "%u\n", GetLastError());
1395 SetLastError(0xdeadbeef);
1397 size
= sizeof(DWORD
);
1398 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1399 ok(ret
, "%u\n", GetLastError());
1400 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1402 SetLastError(0xdeadbeef);
1404 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1405 ok(ret
, "%u\n", GetLastError());
1407 SetLastError(0xdeadbeef);
1409 size
= sizeof(DWORD
);
1410 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1411 ok(ret
, "%u\n", GetLastError());
1412 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1414 SetLastError(0xdeadbeef);
1416 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1417 ok(ret
, "%u\n", GetLastError());
1419 SetLastError(0xdeadbeef);
1421 size
= sizeof(DWORD
);
1422 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1423 ok(ret
, "%u\n", GetLastError());
1424 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1426 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1427 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1429 /* Timeout values should match the last one set for session */
1430 SetLastError(0xdeadbeef);
1432 size
= sizeof(DWORD
);
1433 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1434 ok(ret
, "%u\n", GetLastError());
1435 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1437 SetLastError(0xdeadbeef);
1439 size
= sizeof(DWORD
);
1440 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1441 ok(ret
, "%u\n", GetLastError());
1442 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1444 SetLastError(0xdeadbeef);
1446 size
= sizeof(DWORD
);
1447 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1448 ok(ret
, "%u\n", GetLastError());
1449 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1451 SetLastError(0xdeadbeef);
1453 size
= sizeof(DWORD
);
1454 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1455 ok(ret
, "%u\n", GetLastError());
1456 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1458 SetLastError(0xdeadbeef);
1459 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1460 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1461 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1463 SetLastError(0xdeadbeef);
1464 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1465 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1466 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1468 SetLastError(0xdeadbeef);
1469 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1470 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1471 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1473 SetLastError(0xdeadbeef);
1474 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1475 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1476 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1478 SetLastError(0xdeadbeef);
1479 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1480 ok(ret
, "%u\n", GetLastError());
1482 SetLastError(0xdeadbeef);
1483 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1484 ok(ret
, "%u\n", GetLastError());
1486 SetLastError(0xdeadbeef);
1487 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1488 ok(ret
, "%u\n", GetLastError());
1490 SetLastError(0xdeadbeef);
1492 size
= sizeof(DWORD
);
1493 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1494 ok(ret
, "%u\n", GetLastError());
1495 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1497 SetLastError(0xdeadbeef);
1499 size
= sizeof(DWORD
);
1500 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1501 ok(ret
, "%u\n", GetLastError());
1502 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1504 SetLastError(0xdeadbeef);
1506 size
= sizeof(DWORD
);
1507 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1508 ok(ret
, "%u\n", GetLastError());
1509 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1511 SetLastError(0xdeadbeef);
1513 size
= sizeof(DWORD
);
1514 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1515 ok(ret
, "%u\n", GetLastError());
1516 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1518 SetLastError(0xdeadbeef);
1520 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1521 ok(ret
, "%u\n", GetLastError());
1523 SetLastError(0xdeadbeef);
1525 size
= sizeof(DWORD
);
1526 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1527 ok(ret
, "%u\n", GetLastError());
1528 ok(value
== 0, "Expected 0, got %u\n", value
);
1530 SetLastError(0xdeadbeef);
1532 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1533 ok(ret
, "%u\n", GetLastError());
1535 SetLastError(0xdeadbeef);
1537 size
= sizeof(DWORD
);
1538 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1539 ok(ret
, "%u\n", GetLastError());
1540 ok(value
== 0, "Expected 0, got %u\n", value
);
1542 SetLastError(0xdeadbeef);
1544 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1545 ok(ret
, "%u\n", GetLastError());
1547 SetLastError(0xdeadbeef);
1549 size
= sizeof(DWORD
);
1550 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1551 ok(ret
, "%u\n", GetLastError());
1552 ok(value
== 0, "Expected 0, got %u\n", value
);
1554 SetLastError(0xdeadbeef);
1556 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1557 ok(ret
, "%u\n", GetLastError());
1559 SetLastError(0xdeadbeef);
1561 size
= sizeof(DWORD
);
1562 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1563 ok(ret
, "%u\n", GetLastError());
1564 ok(value
== 0, "Expected 0, got %u\n", value
);
1566 SetLastError(0xdeadbeef);
1568 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1569 ok(ret
, "%u\n", GetLastError());
1571 SetLastError(0xdeadbeef);
1573 size
= sizeof(DWORD
);
1574 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1575 ok(ret
, "%u\n", GetLastError());
1576 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1578 SetLastError(0xdeadbeef);
1580 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1581 ok(ret
, "%u\n", GetLastError());
1583 SetLastError(0xdeadbeef);
1585 size
= sizeof(DWORD
);
1586 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1587 ok(ret
, "%u\n", GetLastError());
1588 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1590 SetLastError(0xdeadbeef);
1592 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1593 ok(ret
, "%u\n", GetLastError());
1595 SetLastError(0xdeadbeef);
1597 size
= sizeof(DWORD
);
1598 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1599 ok(ret
, "%u\n", GetLastError());
1600 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1602 SetLastError(0xdeadbeef);
1604 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1605 ok(ret
, "%u\n", GetLastError());
1607 SetLastError(0xdeadbeef);
1609 size
= sizeof(DWORD
);
1610 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1611 ok(ret
, "%u\n", GetLastError());
1612 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1614 /* Changing timeout values for session should not affect the values for a request,
1615 * neither should the other way around.
1617 SetLastError(0xdeadbeef);
1619 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1620 ok(ret
, "%u\n", GetLastError());
1622 SetLastError(0xdeadbeef);
1624 size
= sizeof(DWORD
);
1625 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1626 ok(ret
, "%u\n", GetLastError());
1627 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1629 SetLastError(0xdeadbeef);
1631 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1632 ok(ret
, "%u\n", GetLastError());
1634 SetLastError(0xdeadbeef);
1636 size
= sizeof(DWORD
);
1637 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1638 ok(ret
, "%u\n", GetLastError());
1639 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1641 SetLastError(0xdeadbeef);
1643 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1644 ok(ret
, "%u\n", GetLastError());
1646 SetLastError(0xdeadbeef);
1648 size
= sizeof(DWORD
);
1649 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1650 ok(ret
, "%u\n", GetLastError());
1651 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1653 SetLastError(0xdeadbeef);
1655 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1656 ok(ret
, "%u\n", GetLastError());
1658 SetLastError(0xdeadbeef);
1660 size
= sizeof(DWORD
);
1661 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1662 ok(ret
, "%u\n", GetLastError());
1663 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1665 SetLastError(0xdeadbeef);
1667 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1668 ok(ret
, "%u\n", GetLastError());
1670 SetLastError(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
);
1677 SetLastError(0xdeadbeef);
1679 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1680 ok(ret
, "%u\n", GetLastError());
1682 SetLastError(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
);
1689 SetLastError(0xdeadbeef);
1691 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1692 ok(ret
, "%u\n", GetLastError());
1694 SetLastError(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
);
1701 SetLastError(0xdeadbeef);
1703 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1704 ok(ret
, "%u\n", GetLastError());
1706 SetLastError(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
);
1713 WinHttpCloseHandle(req
);
1714 WinHttpCloseHandle(con
);
1715 WinHttpCloseHandle(ses
);
1718 static void test_resolve_timeout(void)
1720 static const WCHAR codeweavers
[] =
1721 {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1722 static const WCHAR nxdomain
[] =
1723 {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1725 HINTERNET ses
, con
, req
;
1729 if (! proxy_active())
1731 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1732 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1735 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1736 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1738 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1739 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1741 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1742 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1744 SetLastError(0xdeadbeef);
1745 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1746 ok(!ret
, "sent request\n");
1747 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1748 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1750 WinHttpCloseHandle(req
);
1751 WinHttpCloseHandle(con
);
1752 WinHttpCloseHandle(ses
);
1755 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1757 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1758 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1761 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1762 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1764 con
= WinHttpConnect(ses
, codeweavers
, 0, 0);
1765 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1767 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1768 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1770 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1771 ok(ret
, "failed to send request\n");
1773 WinHttpCloseHandle(req
);
1774 WinHttpCloseHandle(con
);
1775 WinHttpCloseHandle(ses
);
1778 static const char page1
[] =
1780 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1781 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1784 static const char okmsg
[] =
1785 "HTTP/1.1 200 OK\r\n"
1786 "Server: winetest\r\n"
1789 static const char noauthmsg
[] =
1790 "HTTP/1.1 401 Unauthorized\r\n"
1791 "Server: winetest\r\n"
1792 "Connection: close\r\n"
1793 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1796 static const char proxymsg
[] =
1797 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1798 "Server: winetest\r\n"
1799 "Proxy-Connection: close\r\n"
1800 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1809 static DWORD CALLBACK
server_thread(LPVOID param
)
1811 struct server_info
*si
= param
;
1814 struct sockaddr_in sa
;
1817 int last_request
= 0;
1819 WSAStartup(MAKEWORD(1,1), &wsaData
);
1821 s
= socket(AF_INET
, SOCK_STREAM
, 0);
1822 if (s
== INVALID_SOCKET
)
1826 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
1828 memset(&sa
, 0, sizeof sa
);
1829 sa
.sin_family
= AF_INET
;
1830 sa
.sin_port
= htons(si
->port
);
1831 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
1833 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
1838 SetEvent(si
->event
);
1841 c
= accept(s
, NULL
, NULL
);
1843 memset(buffer
, 0, sizeof buffer
);
1844 for(i
= 0; i
< sizeof buffer
- 1; i
++)
1846 r
= recv(c
, &buffer
[i
], 1, 0);
1849 if (i
< 4) continue;
1850 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
1851 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
1854 if (strstr(buffer
, "GET /basic"))
1856 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1857 send(c
, page1
, sizeof page1
- 1, 0);
1859 if (strstr(buffer
, "/auth"))
1861 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
1862 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1864 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
1866 if (strstr(buffer
, "/no_headers"))
1868 send(c
, page1
, sizeof page1
- 1, 0);
1870 if (strstr(buffer
, "GET /quit"))
1872 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1873 send(c
, page1
, sizeof page1
- 1, 0);
1879 } while (!last_request
);
1885 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
1887 HINTERNET ses
, con
, req
;
1889 DWORD count
, status
, size
, error
, supported
, first
, target
;
1892 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1893 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1895 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1896 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1898 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
1899 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1901 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1902 ok(ret
, "failed to send request %u\n", GetLastError());
1904 ret
= WinHttpReceiveResponse(req
, NULL
);
1905 ok(ret
, "failed to receive response %u\n", GetLastError());
1907 size
= sizeof(status
);
1908 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1909 ok(ret
, "failed to query status code %u\n", GetLastError());
1910 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1912 supported
= first
= target
= 0xdeadbeef;
1913 SetLastError(0xdeadbeef);
1914 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
1915 error
= GetLastError();
1916 ok(!ret
, "unexpected success\n");
1917 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
1918 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1919 ok(first
== 0xdeadbeef, "got %x\n", first
);
1920 ok(target
== 0xdeadbeef, "got %x\n", target
);
1923 memset(buffer
, 0, sizeof(buffer
));
1924 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
1925 ok(ret
, "failed to read data %u\n", GetLastError());
1926 ok(count
== sizeof page1
- 1, "count was wrong\n");
1927 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
1929 WinHttpCloseHandle(req
);
1930 WinHttpCloseHandle(con
);
1931 WinHttpCloseHandle(ses
);
1934 static void test_basic_authentication(int port
)
1936 static const WCHAR authW
[] = {'/','a','u','t','h',0};
1937 static const WCHAR userW
[] = {'u','s','e','r',0};
1938 static const WCHAR passW
[] = {'p','w','d',0};
1939 HINTERNET ses
, con
, req
;
1940 DWORD status
, size
, error
, supported
, first
, target
;
1943 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1944 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1946 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1947 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1949 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
1950 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1952 SetLastError(0xdeadbeef);
1953 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
1954 error
= GetLastError();
1955 ok(!ret
, "expected failure\n");
1956 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
1958 SetLastError(0xdeadbeef);
1959 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
1960 error
= GetLastError();
1961 ok(!ret
, "expected failure\n");
1962 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
1964 supported
= 0xdeadbeef;
1965 SetLastError(0xdeadbeef);
1966 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
1967 error
= GetLastError();
1968 ok(!ret
, "expected failure\n");
1969 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
1970 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1972 supported
= first
= 0xdeadbeef;
1973 SetLastError(0xdeadbeef);
1974 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
1975 error
= GetLastError();
1976 ok(!ret
, "expected failure\n");
1977 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
1978 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1979 ok(first
== 0xdeadbeef, "got %x\n", first
);
1981 supported
= first
= target
= 0xdeadbeef;
1982 SetLastError(0xdeadbeef);
1983 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
1984 error
= GetLastError();
1985 ok(!ret
, "expected failure\n");
1986 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
1987 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1988 ok(first
== 0xdeadbeef, "got %x\n", first
);
1989 ok(target
== 0xdeadbeef, "got %x\n", target
);
1991 supported
= first
= target
= 0xdeadbeef;
1992 SetLastError(0xdeadbeef);
1993 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
1994 error
= GetLastError();
1995 ok(!ret
, "expected failure\n");
1996 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
1997 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1998 ok(first
== 0xdeadbeef, "got %x\n", first
);
1999 ok(target
== 0xdeadbeef, "got %x\n", target
);
2001 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2002 ok(ret
, "failed to send request %u\n", GetLastError());
2004 ret
= WinHttpReceiveResponse(req
, NULL
);
2005 ok(ret
, "failed to receive response %u\n", GetLastError());
2007 size
= sizeof(status
);
2008 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2009 ok(ret
, "failed to query status code %u\n", GetLastError());
2010 ok(status
== 401, "request failed unexpectedly %u\n", status
);
2012 supported
= first
= target
= 0xdeadbeef;
2013 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2014 ok(ret
, "failed to query authentication schemes %u\n", GetLastError());
2015 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2016 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2017 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2019 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2020 ok(ret
, "failed to set credentials %u\n", GetLastError());
2022 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2023 ok(ret
, "failed to set credentials %u\n", GetLastError());
2025 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2026 ok(ret
, "failed to set credentials %u\n", GetLastError());
2028 SetLastError(0xdeadbeef);
2029 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2030 error
= GetLastError();
2031 ok(!ret
, "expected failure\n");
2032 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2034 SetLastError(0xdeadbeef);
2035 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2036 error
= GetLastError();
2037 ok(!ret
, "expected failure\n");
2038 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2040 SetLastError(0xdeadbeef);
2041 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2042 error
= GetLastError();
2043 ok(!ret
, "expected failure\n");
2044 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2046 SetLastError(0xdeadbeef);
2047 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2048 error
= GetLastError();
2049 ok(!ret
, "expected failure\n");
2050 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2052 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2053 ok(ret
, "failed to set credentials %u\n", GetLastError());
2055 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2056 ok(ret
, "failed to send request %u\n", GetLastError());
2058 ret
= WinHttpReceiveResponse(req
, NULL
);
2059 ok(ret
, "failed to receive response %u\n", GetLastError());
2061 size
= sizeof(status
);
2062 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2063 ok(ret
, "failed to query status code %u\n", GetLastError());
2064 ok(status
== 200, "request failed unexpectedly %u\n", status
);
2066 WinHttpCloseHandle(req
);
2067 WinHttpCloseHandle(con
);
2068 WinHttpCloseHandle(ses
);
2071 static void test_no_headers(int port
)
2073 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2074 HINTERNET ses
, con
, req
;
2078 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
2079 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2081 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2082 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2084 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2085 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2087 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2088 ok(ret
, "failed to send request %u\n", GetLastError());
2090 SetLastError(0xdeadbeef);
2091 ret
= WinHttpReceiveResponse(req
, NULL
);
2092 error
= GetLastError();
2093 ok(!ret
, "expected failure\n");
2094 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2096 WinHttpCloseHandle(req
);
2097 WinHttpCloseHandle(con
);
2098 WinHttpCloseHandle(ses
);
2101 static void test_bad_header( int port
)
2103 static const WCHAR bad_headerW
[] =
2104 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2105 't','e','x','t','/','h','t','m','l','\n','\r',0};
2106 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2107 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2109 HINTERNET ses
, con
, req
;
2113 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2114 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2116 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2117 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2119 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2120 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2122 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2123 ok( ret
, "failed to add header %u\n", GetLastError() );
2127 len
= sizeof(buffer
);
2128 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2129 content_typeW
, buffer
, &len
, &index
);
2130 ok( ret
, "failed to query headers %u\n", GetLastError() );
2131 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2133 WinHttpCloseHandle( req
);
2134 WinHttpCloseHandle( con
);
2135 WinHttpCloseHandle( ses
);
2138 static void test_connection_info( int port
)
2140 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2141 HINTERNET ses
, con
, req
;
2142 WINHTTP_CONNECTION_INFO info
;
2146 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2147 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2149 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2150 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2152 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
2153 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2155 size
= sizeof(info
);
2156 SetLastError( 0xdeadbeef );
2157 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2158 error
= GetLastError();
2159 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
2161 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2164 ok( !ret
, "unexpected success\n" );
2165 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
2167 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2168 ok( ret
, "failed to send request %u\n", GetLastError() );
2171 SetLastError( 0xdeadbeef );
2172 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2173 error
= GetLastError();
2174 ok( !ret
, "unexpected success\n" );
2175 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
2177 size
= sizeof(info
);
2178 memset( &info
, 0, sizeof(info
) );
2179 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2180 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2181 ok( info
.cbSize
== sizeof(info
), "wrong size %u\n", info
.cbSize
);
2183 ret
= WinHttpReceiveResponse( req
, NULL
);
2184 ok( ret
, "failed to receive response %u\n", GetLastError() );
2186 size
= sizeof(info
);
2187 memset( &info
, 0, sizeof(info
) );
2188 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2189 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2190 ok( info
.cbSize
== sizeof(info
), "wrong size %u\n", info
.cbSize
);
2192 WinHttpCloseHandle( req
);
2193 WinHttpCloseHandle( con
);
2194 WinHttpCloseHandle( ses
);
2197 static void test_credentials(void)
2199 static WCHAR userW
[] = {'u','s','e','r',0};
2200 static WCHAR passW
[] = {'p','a','s','s',0};
2201 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
2202 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
2203 HINTERNET ses
, con
, req
;
2208 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
2209 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2211 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
2212 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2214 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2215 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2217 size
= sizeof(buffer
)/sizeof(WCHAR
);
2218 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
2219 ok(ret
, "failed to query proxy username %u\n", GetLastError());
2220 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2221 ok(!size
, "expected 0, got %u\n", size
);
2223 size
= sizeof(buffer
)/sizeof(WCHAR
);
2224 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
2225 ok(ret
, "failed to query proxy password %u\n", GetLastError());
2226 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2227 ok(!size
, "expected 0, got %u\n", size
);
2229 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
2230 ok(ret
, "failed to set username %u\n", GetLastError());
2232 size
= sizeof(buffer
)/sizeof(WCHAR
);
2233 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
2234 ok(ret
, "failed to query proxy username %u\n", GetLastError());
2235 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2236 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2238 size
= sizeof(buffer
)/sizeof(WCHAR
);
2239 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2240 ok(ret
, "failed to query username %u\n", GetLastError());
2241 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2242 ok(!size
, "expected 0, got %u\n", size
);
2244 size
= sizeof(buffer
)/sizeof(WCHAR
);
2245 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2246 ok(ret
, "failed to query password %u\n", GetLastError());
2247 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2248 ok(!size
, "expected 0, got %u\n", size
);
2250 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
2251 ok(ret
, "failed to set proxy password %u\n", GetLastError());
2253 size
= sizeof(buffer
)/sizeof(WCHAR
);
2254 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
2255 ok(ret
, "failed to query proxy password %u\n", GetLastError());
2256 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2257 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2259 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2260 ok(ret
, "failed to set username %u\n", GetLastError());
2262 size
= sizeof(buffer
)/sizeof(WCHAR
);
2263 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2264 ok(ret
, "failed to query username %u\n", GetLastError());
2265 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2266 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2268 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2269 ok(ret
, "failed to set password %u\n", GetLastError());
2271 size
= sizeof(buffer
)/sizeof(WCHAR
);
2272 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2273 ok(ret
, "failed to query password %u\n", GetLastError());
2274 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2275 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2277 WinHttpCloseHandle(req
);
2279 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2280 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2282 SetLastError(0xdeadbeef);
2283 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2284 error
= GetLastError();
2285 ok(!ret
, "expected failure\n");
2286 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2288 SetLastError(0xdeadbeef);
2289 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2290 error
= GetLastError();
2291 ok(!ret
, "expected failure\n");
2292 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2294 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2295 ok(ret
, "failed to set credentials %u\n", GetLastError());
2297 size
= sizeof(buffer
)/sizeof(WCHAR
);
2298 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2299 ok(ret
, "failed to query username %u\n", GetLastError());
2301 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2302 ok(!size
, "expected 0, got %u\n", size
);
2305 size
= sizeof(buffer
)/sizeof(WCHAR
);
2306 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2307 ok(ret
, "failed to query password %u\n", GetLastError());
2309 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2310 ok(!size
, "expected 0, got %u\n", size
);
2313 WinHttpCloseHandle(req
);
2314 WinHttpCloseHandle(con
);
2315 WinHttpCloseHandle(ses
);
2318 static void test_IWinHttpRequest(void)
2320 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
2321 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
2322 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2323 static const WCHAR url2W
[] = {'w','i','n','e','h','q','.','o','r','g',0};
2324 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
2325 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
2326 'p','o','s','t','t','e','s','t','.','p','h','p',0};
2327 static const WCHAR method1W
[] = {'G','E','T',0};
2328 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
2329 static const WCHAR method3W
[] = {'P','O','S','T',0};
2330 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2331 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
2332 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
2333 static const WCHAR dateW
[] = {'D','a','t','e',0};
2334 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
2336 IWinHttpRequest
*req
;
2337 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
2338 BSTR date
, today
, connection
, value
= NULL
;
2339 VARIANT async
, empty
, timeout
, body
, proxy_server
, bypass_list
, data
;
2340 VARIANT_BOOL succeeded
;
2342 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
2345 GetSystemTime( &st
);
2346 WinHttpTimeFromSystemTime( &st
, todayW
);
2348 CoInitialize( NULL
);
2349 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
2350 ok( hr
== S_OK
, "got %08x\n", hr
);
2352 V_VT( &empty
) = VT_ERROR
;
2353 V_ERROR( &empty
) = 0xdeadbeef;
2355 V_VT( &async
) = VT_BOOL
;
2356 V_BOOL( &async
) = VARIANT_FALSE
;
2358 method
= SysAllocString( method3W
);
2359 url
= SysAllocString( url3W
);
2360 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2361 ok( hr
== S_OK
, "got %08x\n", hr
);
2362 SysFreeString( method
);
2363 SysFreeString( url
);
2365 V_VT( &data
) = VT_BSTR
;
2366 V_BSTR( &data
) = SysAllocString( test_dataW
);
2367 hr
= IWinHttpRequest_Send( req
, data
);
2368 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
2370 SysFreeString( V_BSTR( &data
) );
2372 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
2373 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2375 method
= SysAllocString( method1W
);
2376 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
2377 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2379 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
2380 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2382 url
= SysAllocString( url1W
);
2383 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
2384 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2386 hr
= IWinHttpRequest_Abort( req
);
2387 ok( hr
== S_OK
, "got %08x\n", hr
);
2389 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
2390 ok( hr
== S_OK
, "got %08x\n", hr
);
2392 hr
= IWinHttpRequest_Abort( req
);
2393 ok( hr
== S_OK
, "got %08x\n", hr
);
2395 hr
= IWinHttpRequest_Release( req
);
2396 ok( hr
== S_OK
, "got %08x\n", hr
);
2398 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
2399 ok( hr
== S_OK
, "got %08x\n", hr
);
2401 SysFreeString( url
);
2402 url
= SysAllocString( url2W
);
2403 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2404 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
2406 SysFreeString( method
);
2407 method
= SysAllocString( method2W
);
2408 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2409 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
2411 SysFreeString( method
);
2412 method
= SysAllocString( method1W
);
2413 SysFreeString( url
);
2414 url
= SysAllocString( url1W
);
2415 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2416 ok( hr
== S_OK
, "got %08x\n", hr
);
2418 hr
= IWinHttpRequest_Abort( req
);
2419 ok( hr
== S_OK
, "got %08x\n", hr
);
2421 hr
= IWinHttpRequest_Send( req
, empty
);
2422 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2424 hr
= IWinHttpRequest_Abort( req
);
2425 ok( hr
== S_OK
, "got %08x\n", hr
);
2427 hr
= IWinHttpRequest_Release( req
);
2428 ok( hr
== S_OK
, "got %08x\n", hr
);
2430 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
2431 ok( hr
== S_OK
, "got %08x\n", hr
);
2433 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2434 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2436 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2437 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2439 hr
= IWinHttpRequest_get_Status( req
, NULL
);
2440 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2442 hr
= IWinHttpRequest_get_Status( req
, &status
);
2443 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2445 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
2446 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2448 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2449 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2451 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2452 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2454 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
2455 ok( hr
== S_OK
, "got %08x\n", hr
);
2457 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
2458 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2460 VariantInit( &proxy_server
);
2461 V_VT( &proxy_server
) = VT_ERROR
;
2462 VariantInit( &bypass_list
);
2463 V_VT( &bypass_list
) = VT_ERROR
;
2464 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2465 ok( hr
== S_OK
, "got %08x\n", hr
);
2467 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2468 ok( hr
== S_OK
, "got %08x\n", hr
);
2470 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2471 ok( hr
== S_OK
, "got %08x\n", hr
);
2473 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
2474 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2476 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2477 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2479 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
2480 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2482 connection
= SysAllocString( connectionW
);
2483 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
2484 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2486 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2487 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2489 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
2490 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2492 date
= SysAllocString( dateW
);
2493 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
2494 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2496 today
= SysAllocString( todayW
);
2497 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2498 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2500 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
2501 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2503 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2504 ok( hr
== S_OK
, "got %08x\n", hr
);
2506 SysFreeString( method
);
2507 method
= SysAllocString( method1W
);
2508 SysFreeString( url
);
2509 url
= SysAllocString( url1W
);
2510 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2511 ok( hr
== S_OK
, "got %08x\n", hr
);
2513 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2514 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2516 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2517 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2519 hr
= IWinHttpRequest_get_Status( req
, &status
);
2520 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2522 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2523 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2525 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2526 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2528 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
2529 ok( hr
== S_OK
, "got %08x\n", hr
);
2531 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
2532 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2534 username
= SysAllocString( usernameW
);
2535 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
2536 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2538 password
= SysAllocString( passwordW
);
2539 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
2540 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2542 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
2543 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2545 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2546 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2548 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2549 ok( hr
== S_OK
, "got %08x\n", hr
);
2551 V_VT( &proxy_server
) = VT_BSTR
;
2552 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
2553 V_VT( &bypass_list
) = VT_BSTR
;
2554 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
2555 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2556 ok( hr
== S_OK
, "got %08x\n", hr
);
2558 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
2559 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2561 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2562 ok( hr
== S_OK
, "got %08x\n", hr
);
2564 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2565 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2567 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2568 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2570 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2571 ok( hr
== S_OK
, "got %08x\n", hr
);
2573 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
2574 ok( hr
== S_OK
, "got %08x\n", hr
);
2576 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2577 ok( hr
== S_OK
, "got %08x\n", hr
);
2579 hr
= IWinHttpRequest_Send( req
, empty
);
2580 ok( hr
== S_OK
, "got %08x\n", hr
);
2582 hr
= IWinHttpRequest_Send( req
, empty
);
2583 ok( hr
== S_OK
, "got %08x\n", hr
);
2585 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2586 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2588 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2589 ok( hr
== S_OK
, "got %08x\n", hr
);
2590 SysFreeString( response
);
2592 hr
= IWinHttpRequest_get_Status( req
, NULL
);
2593 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2596 hr
= IWinHttpRequest_get_Status( req
, &status
);
2597 ok( hr
== S_OK
, "got %08x\n", hr
);
2598 trace("Status=%d\n", status
);
2600 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
2601 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2603 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2604 ok( hr
== S_OK
, "got %08x\n", hr
);
2605 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
2606 SysFreeString( status_text
);
2608 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2609 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2611 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2612 ok( hr
== S_OK
, "got %08x\n", hr
);
2614 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2615 ok( hr
== S_OK
, "got %08x\n", hr
);
2617 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2618 ok( hr
== S_OK
, "got %08x\n", hr
);
2620 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
2621 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2623 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2624 ok( hr
== S_OK
, "got %08x\n", hr
);
2625 SysFreeString( headers
);
2627 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
2628 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2630 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
2631 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2633 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2634 ok( hr
== S_OK
, "got %08x\n", hr
);
2635 SysFreeString( value
);
2637 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2638 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
2640 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2641 ok( hr
== S_OK
, "got %08x\n", hr
);
2643 VariantInit( &timeout
);
2644 V_VT( &timeout
) = VT_I4
;
2645 V_I4( &timeout
) = 10;
2646 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
2647 ok( hr
== S_OK
, "got %08x\n", hr
);
2649 hr
= IWinHttpRequest_get_Status( req
, &status
);
2650 ok( hr
== S_OK
, "got %08x\n", hr
);
2652 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2653 ok( hr
== S_OK
, "got %08x\n", hr
);
2654 SysFreeString( status_text
);
2656 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2657 ok( hr
== S_OK
, "got %08x\n", hr
);
2659 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2660 ok( hr
== S_OK
, "got %08x\n", hr
);
2662 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2663 ok( hr
== S_OK
, "got %08x\n", hr
);
2665 hr
= IWinHttpRequest_Send( req
, empty
);
2666 ok( hr
== S_OK
, "got %08x\n", hr
);
2668 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2669 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2671 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2672 ok( hr
== S_OK
, "got %08x\n", hr
);
2673 SysFreeString( response
);
2675 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2676 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2678 VariantInit( &body
);
2679 V_VT( &body
) = VT_ERROR
;
2680 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
2681 ok( hr
== S_OK
, "got %08x\n", hr
);
2682 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
2684 hr
= VariantClear( &body
);
2685 ok( hr
== S_OK
, "got %08x\n", hr
);
2687 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2688 ok( hr
== S_OK
, "got %08x\n", hr
);
2690 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2691 ok( hr
== S_OK
, "got %08x\n", hr
);
2693 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2694 ok( hr
== S_OK
, "got %08x\n", hr
);
2695 SysFreeString( headers
);
2697 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2698 ok( hr
== S_OK
, "got %08x\n", hr
);
2699 SysFreeString( value
);
2701 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2702 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
2704 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2705 ok( hr
== S_OK
, "got %08x\n", hr
);
2707 hr
= IWinHttpRequest_Send( req
, empty
);
2708 ok( hr
== S_OK
, "got %08x\n", hr
);
2710 hr
= IWinHttpRequest_Abort( req
);
2711 ok( hr
== S_OK
, "got %08x\n", hr
);
2713 hr
= IWinHttpRequest_Abort( req
);
2714 ok( hr
== S_OK
, "got %08x\n", hr
);
2716 hr
= IWinHttpRequest_Release( req
);
2717 ok( hr
== S_OK
, "got %08x\n", hr
);
2719 SysFreeString( method
);
2720 SysFreeString( url
);
2721 SysFreeString( username
);
2722 SysFreeString( password
);
2723 SysFreeString( connection
);
2724 SysFreeString( date
);
2725 SysFreeString( today
);
2726 VariantClear( &proxy_server
);
2727 VariantClear( &bypass_list
);
2731 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2737 if (0) /* crashes on some win2k systems */
2739 SetLastError(0xdeadbeef);
2740 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
2741 error
= GetLastError();
2742 ok( !ret
, "expected failure\n" );
2743 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2746 SetLastError(0xdeadbeef);
2747 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
2748 error
= GetLastError();
2749 ok( !ret
, "expected failure\n" );
2750 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2752 if (0) /* crashes on some win2k systems */
2754 SetLastError(0xdeadbeef);
2755 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
2756 error
= GetLastError();
2757 ok( !ret
, "expected failure\n" );
2758 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2760 url
= (WCHAR
*)0xdeadbeef;
2761 SetLastError(0xdeadbeef);
2762 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
2763 error
= GetLastError();
2766 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
2767 ok( url
== (WCHAR
*)0xdeadbeef, "got %p\n", url
);
2771 trace("%s\n", wine_dbgstr_w(url
));
2775 url
= (WCHAR
*)0xdeadbeef;
2776 SetLastError(0xdeadbeef);
2777 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
2778 error
= GetLastError();
2781 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
2782 ok( url
== (WCHAR
*)0xdeadbeef, "got %p\n", url
);
2786 trace("%s\n", wine_dbgstr_w(url
));
2791 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2795 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
2797 memset( &cfg
, 0, sizeof(cfg
) );
2799 SetLastError(0xdeadbeef);
2800 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
2801 error
= GetLastError();
2802 ok( !ret
, "expected failure\n" );
2803 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2805 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
2806 ok( ret
, "expected success\n" );
2807 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
2808 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
2809 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
2810 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
2811 GlobalFree( cfg
.lpszAutoConfigUrl
);
2812 GlobalFree( cfg
.lpszProxy
);
2813 GlobalFree( cfg
.lpszProxyBypass
);
2816 static void test_WinHttpGetProxyForUrl(void)
2818 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2819 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
2820 static const WCHAR emptyW
[] = {0};
2824 WINHTTP_AUTOPROXY_OPTIONS options
;
2825 WINHTTP_PROXY_INFO info
;
2827 memset( &options
, 0, sizeof(options
) );
2829 SetLastError(0xdeadbeef);
2830 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
2831 error
= GetLastError();
2832 ok( !ret
, "expected failure\n" );
2833 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
2835 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2836 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
2838 SetLastError(0xdeadbeef);
2839 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
2840 error
= GetLastError();
2841 ok( !ret
, "expected failure\n" );
2842 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2844 SetLastError(0xdeadbeef);
2845 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
2846 error
= GetLastError();
2847 ok( !ret
, "expected failure\n" );
2848 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2850 SetLastError(0xdeadbeef);
2851 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
2852 error
= GetLastError();
2853 ok( !ret
, "expected failure\n" );
2854 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2856 SetLastError(0xdeadbeef);
2857 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2858 error
= GetLastError();
2859 ok( !ret
, "expected failure\n" );
2860 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2862 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
2863 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
2865 SetLastError(0xdeadbeef);
2866 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
2867 error
= GetLastError();
2868 ok( !ret
, "expected failure\n" );
2869 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2871 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
2872 options
.dwAutoDetectFlags
= 0;
2874 SetLastError(0xdeadbeef);
2875 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2876 error
= GetLastError();
2877 ok( !ret
, "expected failure\n" );
2878 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2880 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
2881 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
2883 SetLastError(0xdeadbeef);
2884 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2885 error
= GetLastError();
2886 ok( !ret
, "expected failure\n" );
2887 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2889 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
2890 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
2892 memset( &info
, 0, sizeof(info
) );
2893 SetLastError(0xdeadbeef);
2894 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2895 error
= GetLastError();
2896 if (!ret
) ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
||
2897 error
== ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT
, "got %u\n", error
);
2900 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
2901 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
2902 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
2903 GlobalFree( info
.lpszProxy
);
2904 GlobalFree( info
.lpszProxyBypass
);
2907 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
2908 options
.dwAutoDetectFlags
= 0;
2909 options
.lpszAutoConfigUrl
= wpadW
;
2911 memset( &info
, 0, sizeof(info
) );
2912 SetLastError(0xdeadbeef);
2913 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2914 error
= GetLastError();
2915 if (!ret
) ok( error
== ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT
, "got %u\n", error
);
2918 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
2919 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
2920 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
2921 GlobalFree( info
.lpszProxy
);
2922 GlobalFree( info
.lpszProxyBypass
);
2924 WinHttpCloseHandle( session
);
2927 static void test_chunked_read(void)
2929 static const WCHAR host
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2930 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
2931 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
2934 HINTERNET ses
, con
= NULL
, req
= NULL
;
2937 trace( "starting chunked read test\n" );
2939 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2940 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
2941 if (!ses
) goto done
;
2943 con
= WinHttpConnect( ses
, host
, 0, 0 );
2944 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
2945 if (!con
) goto done
;
2947 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
2948 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
2949 if (!req
) goto done
;
2951 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2952 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
2954 ret
= WinHttpReceiveResponse( req
, NULL
);
2955 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
2958 len
= sizeof(header
);
2959 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
2960 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
2961 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
2962 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
2965 len
= sizeof(header
);
2966 SetLastError( 0xdeadbeef );
2967 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
2968 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
2969 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
2971 trace( "entering query loop\n" );
2975 ret
= WinHttpQueryDataAvailable( req
, &len
);
2976 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2977 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2978 trace( "got %u available\n", len
);
2982 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
2984 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
2986 buf
[bytes_read
] = 0;
2987 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
2988 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
2989 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
2991 HeapFree( GetProcessHeap(), 0, buf
);
2992 if (!bytes_read
) break;
2999 if (req
) WinHttpCloseHandle( req
);
3000 if (con
) WinHttpCloseHandle( con
);
3001 if (ses
) WinHttpCloseHandle( ses
);
3004 START_TEST (winhttp
)
3006 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
3007 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
3008 struct server_info si
;
3014 test_WinHttpTimeFromSystemTime();
3015 test_WinHttpTimeToSystemTime();
3016 test_WinHttpAddHeaders();
3017 test_secure_connection();
3018 test_request_parameter_defaults();
3020 test_set_default_proxy_config();
3021 test_empty_headers_param();
3023 test_resolve_timeout();
3025 test_IWinHttpRequest();
3026 test_WinHttpDetectAutoProxyConfigUrl();
3027 test_WinHttpGetIEProxyConfigForCurrentUser();
3028 test_WinHttpGetProxyForUrl();
3029 test_chunked_read();
3031 si
.event
= CreateEvent(NULL
, 0, 0, NULL
);
3034 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
3035 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
3037 ret
= WaitForSingleObject(si
.event
, 10000);
3038 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
3039 if (ret
!= WAIT_OBJECT_0
)
3042 test_connection_info(si
.port
);
3043 test_basic_request(si
.port
, NULL
, basicW
);
3044 test_no_headers(si
.port
);
3045 test_basic_authentication(si
.port
);
3046 test_bad_header(si
.port
);
3048 /* send the basic request again to shutdown the server thread */
3049 test_basic_request(si
.port
, NULL
, quitW
);
3051 WaitForSingleObject(thread
, 3000);