4 * Copyright 2008 Google (Zac Brown)
5 * Copyright 2015 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define WIN32_NO_STATUS
24 #define COM_NO_WINDOWS_H
33 //#include <ws2tcpip.h>
38 //#include "initguid.h"
39 #include <httprequest.h>
40 #include <httprequestid.h>
42 #include <wine/test.h>
44 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
46 static const WCHAR test_useragent
[] =
47 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
48 static const WCHAR test_winehq
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
49 static const WCHAR test_winehq_https
[] = {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','4','4','3',0};
50 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
52 static BOOL
proxy_active(void)
54 WINHTTP_PROXY_INFO proxy_info
;
57 SetLastError(0xdeadbeef);
58 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
60 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
61 "got %u\n", GetLastError());
62 active
= (proxy_info
.lpszProxy
!= NULL
);
64 GlobalFree(proxy_info
.lpszProxy
);
65 if (proxy_info
.lpszProxyBypass
!= NULL
)
66 GlobalFree(proxy_info
.lpszProxyBypass
);
74 static void test_QueryOption(void)
77 HINTERNET session
, request
, connection
;
80 SetLastError(0xdeadbeef);
81 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
82 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
84 SetLastError(0xdeadbeef);
85 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
86 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
87 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
88 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
91 SetLastError(0xdeadbeef);
92 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
93 ok(!ret
, "should fail to query option\n");
94 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
95 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
96 ok(size
== 4, "expected 4, got %u\n", size
);
99 size
= sizeof(feature
) - 1;
100 SetLastError(0xdeadbeef);
101 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
102 ok(!ret
, "should fail to query option\n");
103 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
104 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
105 ok(size
== 4, "expected 4, got %u\n", size
);
107 feature
= 0xdeadbeef;
108 size
= sizeof(feature
) + 1;
109 SetLastError(0xdeadbeef);
110 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
111 ok(ret
, "failed to query option %u\n", GetLastError());
112 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
113 "got %u\n", GetLastError());
114 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
115 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
116 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
118 SetLastError(0xdeadbeef);
119 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
120 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
121 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
122 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
124 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
125 SetLastError(0xdeadbeef);
126 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
127 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
128 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
129 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
131 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
132 SetLastError(0xdeadbeef);
133 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
134 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
135 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
136 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
138 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
139 SetLastError(0xdeadbeef);
140 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
141 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
143 feature
= 0xdeadbeef;
144 size
= sizeof(feature
);
145 SetLastError(0xdeadbeef);
146 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
147 ok(ret
, "failed to query option %u\n", GetLastError());
148 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
149 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
151 feature
= WINHTTP_DISABLE_COOKIES
;
152 SetLastError(0xdeadbeef);
153 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
154 ok(!ret
, "should fail to set disable feature for a session\n");
155 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
156 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
158 SetLastError(0xdeadbeef);
159 connection
= WinHttpConnect(session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
160 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
162 feature
= WINHTTP_DISABLE_COOKIES
;
163 SetLastError(0xdeadbeef);
164 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
165 ok(!ret
, "should fail to set disable feature for a connection\n");
166 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
167 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
169 SetLastError(0xdeadbeef);
170 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
171 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
172 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
174 skip("Network unreachable, skipping the test\n");
178 feature
= 0xdeadbeef;
179 size
= sizeof(feature
);
180 SetLastError(0xdeadbeef);
181 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
182 ok(!ret
, "should fail to query disable feature for a request\n");
183 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
184 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
187 size
= sizeof(feature
);
188 SetLastError(0xdeadbeef);
189 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
190 ok(ret
, "failed to set feature %u\n", GetLastError());
192 feature
= 0xffffffff;
193 size
= sizeof(feature
);
194 SetLastError(0xdeadbeef);
195 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
196 ok(ret
, "failed to set feature %u\n", GetLastError());
198 feature
= WINHTTP_DISABLE_COOKIES
;
199 size
= sizeof(feature
);
200 SetLastError(0xdeadbeef);
201 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
202 ok(ret
, "failed to set feature %u\n", GetLastError());
205 SetLastError(0xdeadbeef);
206 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
207 ok(!ret
, "should fail to query disable feature for a request\n");
208 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
209 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
211 SetLastError(0xdeadbeef);
212 ret
= WinHttpCloseHandle(request
);
213 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
216 SetLastError(0xdeadbeef);
217 ret
= WinHttpCloseHandle(connection
);
218 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
219 SetLastError(0xdeadbeef);
220 ret
= WinHttpCloseHandle(session
);
221 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
224 static void test_OpenRequest (void)
227 HINTERNET session
, request
, connection
;
230 SetLastError(0xdeadbeef);
231 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
232 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
233 err
= GetLastError();
234 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
235 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
237 /* Test with a bad server name */
238 SetLastError(0xdeadbeef);
239 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
240 err
= GetLastError();
241 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
242 ok(err
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err
);
244 /* Test with a valid server name */
245 SetLastError(0xdeadbeef);
246 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
247 err
= GetLastError();
248 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", err
);
249 ok(err
== ERROR_SUCCESS
|| broken(err
== WSAEINVAL
) /* < win7 */, "got %u\n", err
);
251 SetLastError(0xdeadbeef);
252 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
253 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
254 err
= GetLastError();
255 if (request
== NULL
&& err
== ERROR_WINHTTP_NAME_NOT_RESOLVED
)
257 skip("Network unreachable, skipping.\n");
260 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", err
);
261 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
263 SetLastError(0xdeadbeef);
264 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
265 err
= GetLastError();
266 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
268 skip("Connection failed, skipping.\n");
271 ok(ret
, "WinHttpSendRequest failed: %u\n", err
);
272 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
274 SetLastError(0xdeadbeef);
275 ret
= WinHttpCloseHandle(request
);
276 err
= GetLastError();
277 ok(ret
, "WinHttpCloseHandle failed on closing request, got %u.\n", err
);
278 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
281 ret
= WinHttpCloseHandle(connection
);
282 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
283 ret
= WinHttpCloseHandle(session
);
284 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
288 static void test_empty_headers_param(void)
290 static const WCHAR empty
[] = {0};
291 HINTERNET ses
, con
, req
;
295 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
296 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
298 con
= WinHttpConnect(ses
, test_winehq
, 80, 0);
299 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
301 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
302 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
304 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
305 err
= GetLastError();
306 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
308 skip("connection failed, skipping\n");
311 ok(ret
, "failed to send request %u\n", GetLastError());
314 WinHttpCloseHandle(req
);
315 WinHttpCloseHandle(con
);
316 WinHttpCloseHandle(ses
);
319 static void test_SendRequest (void)
321 static const WCHAR content_type
[] =
322 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
323 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
324 static const WCHAR test_file
[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
325 static const WCHAR test_verb
[] = {'P','O','S','T',0};
326 static CHAR post_data
[] = "mode=Test";
327 static const char test_post
[] = "mode => Test\0\n";
328 HINTERNET session
, request
, connection
;
329 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
, err
;
336 total_len
= optional_len
= sizeof(post_data
);
337 memset(buffer
, 0xff, sizeof(buffer
));
339 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
340 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
341 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
343 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
344 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
346 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
347 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
348 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
350 skip("Network unreachable, skipping.\n");
353 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
354 if (!request
) goto done
;
356 context
= 0xdeadbeef;
357 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
358 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
361 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
362 err
= GetLastError();
363 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
365 skip("connection failed, skipping\n");
368 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
371 size
= sizeof(context
);
372 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
373 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
374 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
376 for (i
= 3; post_data
[i
]; i
++)
379 SetLastError(0xdeadbeef);
380 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
383 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
384 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
386 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
388 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
389 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
393 SetLastError(0xdeadbeef);
394 ret
= WinHttpReceiveResponse(request
, NULL
);
395 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == ERROR_NO_TOKEN
) /* < win7 */,
396 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
397 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
400 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
401 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
403 ok(bytes_rw
== sizeof(test_post
) - 1, "Read %u bytes\n", bytes_rw
);
404 ok(!memcmp(buffer
, test_post
, sizeof(test_post
) - 1), "Data read did not match.\n");
407 ret
= WinHttpCloseHandle(request
);
408 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
409 ret
= WinHttpCloseHandle(connection
);
410 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
411 ret
= WinHttpCloseHandle(session
);
412 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
415 static void test_WinHttpTimeFromSystemTime(void)
418 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
419 static const WCHAR expected_string
[] =
420 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
421 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
422 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
425 SetLastError(0xdeadbeef);
426 ret
= WinHttpTimeFromSystemTime(&time
, NULL
);
427 err
= GetLastError();
428 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
429 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
431 SetLastError(0xdeadbeef);
432 ret
= WinHttpTimeFromSystemTime(NULL
, time_string
);
433 err
= GetLastError();
434 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
435 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
437 SetLastError(0xdeadbeef);
438 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
439 err
= GetLastError();
440 ok(ret
, "WinHttpTimeFromSystemTime failed: %u\n", err
);
441 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
442 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
443 "Time string returned did not match expected time string.\n");
446 static void test_WinHttpTimeToSystemTime(void)
450 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
451 static const WCHAR time_string1
[] =
452 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
453 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
454 static const WCHAR time_string2
[] =
455 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
456 '1','0',' ','0','5',' ','5','2','\n',0};
459 SetLastError(0xdeadbeef);
460 ret
= WinHttpTimeToSystemTime(time_string1
, NULL
);
461 err
= GetLastError();
462 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
463 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
465 SetLastError(0xdeadbeef);
466 ret
= WinHttpTimeToSystemTime(NULL
, &time
);
467 err
= GetLastError();
468 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
469 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
471 SetLastError(0xdeadbeef);
472 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
473 err
= GetLastError();
474 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
475 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
476 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
477 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
479 SetLastError(0xdeadbeef);
480 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
481 err
= GetLastError();
482 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
483 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
484 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
485 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
488 static void test_WinHttpAddHeaders(void)
490 HINTERNET session
, request
, connection
;
492 WCHAR buffer
[MAX_PATH
];
493 WCHAR check_buffer
[MAX_PATH
];
494 DWORD err
, index
, len
, oldlen
;
496 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
497 static const WCHAR test_verb
[] = {'P','O','S','T',0};
498 static const WCHAR test_header_begin
[] =
499 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
500 static const WCHAR full_path_test_header_begin
[] =
501 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
502 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
503 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
504 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
505 static const WCHAR test_header_name2
[] = {'n','a','m','e',0};
506 static const WCHAR test_header_name3
[] = {'a',0};
507 static const WCHAR test_header_range
[] = {'R','a','n','g','e',0};
508 static const WCHAR test_header_range_bytes
[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
509 static const WCHAR test_header_bytes
[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
511 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
512 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
513 static const WCHAR test_flag_coalesce_comma
[] =
514 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
515 static const WCHAR test_flag_coalesce_comma_reverse
[] =
516 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
517 static const WCHAR test_flag_coalesce_semicolon
[] =
518 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
519 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
520 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
522 static const WCHAR field
[] = {'f','i','e','l','d',0};
523 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
524 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
525 static const WCHAR empty
[] = {0};
527 static const WCHAR test_headers
[][14] =
529 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
530 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
531 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
532 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
533 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
534 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
535 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
541 {' ','e',' ',':','f',0},
542 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
543 {'n','a','m','e',':',' ','v','a','l','u','e',0},
544 {'n','a','m','e',':',0}
546 static const WCHAR test_indices
[][6] =
548 {'t','e','s','t','1',0},
549 {'t','e','s','t','2',0},
550 {'t','e','s','t','3',0},
551 {'t','e','s','t','4',0}
554 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
555 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
556 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
558 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
559 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
561 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
562 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
563 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
565 skip("Network unreachable, skipping.\n");
568 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
571 len
= sizeof(buffer
);
572 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
573 test_header_name
, buffer
, &len
, &index
);
574 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
575 SetLastError(0xdeadbeef);
576 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
577 err
= GetLastError();
578 ok(ret
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, err
);
579 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
582 len
= sizeof(buffer
);
583 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
584 test_header_name
, buffer
, &len
, &index
);
585 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
586 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
587 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
588 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
590 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
591 test_header_name
, buffer
, &len
, &index
);
592 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
594 /* Try to fetch the header info with a buffer that's big enough to fit the
595 * string but not the NULL terminator.
598 len
= 5*sizeof(WCHAR
);
599 memset(check_buffer
, 0xab, sizeof(check_buffer
));
600 memcpy(buffer
, check_buffer
, sizeof(buffer
));
601 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
602 test_header_name
, buffer
, &len
, &index
);
603 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
604 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
605 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
606 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
608 /* Try with a NULL buffer */
610 len
= sizeof(buffer
);
611 SetLastError(0xdeadbeef);
612 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
613 test_header_name
, NULL
, &len
, &index
);
614 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
615 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
616 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
617 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
619 /* Try with a NULL buffer and a length that's too small */
622 SetLastError(0xdeadbeef);
623 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
624 test_header_name
, NULL
, &len
, &index
);
625 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
626 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
627 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
628 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
629 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
633 SetLastError(0xdeadbeef);
634 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
635 test_header_name
, NULL
, &len
, &index
);
636 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
637 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
638 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
639 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
640 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
645 len
= sizeof(buffer
);
646 memset(buffer
, 0xff, sizeof(buffer
));
647 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
648 test_header_name
, buffer
, &len
, &index
);
649 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
650 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
651 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
652 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
653 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
654 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
655 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
656 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
657 "WinHttpQueryHeaders returned invalid end of header string.\n");
658 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
662 SetLastError(0xdeadbeef);
663 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
664 test_header_name
, NULL
, &len
, &index
);
665 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
666 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
667 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
668 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
669 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
673 len
= sizeof(buffer
);
674 memset(buffer
, 0xff, sizeof(buffer
));
675 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
676 test_header_name
, buffer
, &len
, &index
);
677 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
678 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
679 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
680 "no double NULL terminator\n");
681 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
682 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
683 "invalid beginning of header string.\n");
684 ok(index
== 0, "header index was incremented\n");
686 /* tests for more indices */
687 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
688 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
691 len
= sizeof(buffer
);
692 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
693 test_header_name
, buffer
, &len
, &index
);
694 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "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
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
705 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
706 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
709 len
= sizeof(buffer
);
710 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
711 test_header_name
, buffer
, &len
, &index
);
712 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
713 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
714 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
715 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
717 len
= sizeof(buffer
);
718 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
719 test_header_name
, buffer
, &len
, &index
);
720 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
721 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
722 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
724 /* add if new flag */
725 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
726 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
729 len
= sizeof(buffer
);
730 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
731 test_header_name
, buffer
, &len
, &index
);
732 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
733 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
734 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
736 len
= sizeof(buffer
);
737 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
738 test_header_name
, buffer
, &len
, &index
);
739 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
740 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
741 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
743 len
= sizeof(buffer
);
744 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
745 test_header_name
, buffer
, &len
, &index
);
746 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
749 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
750 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
753 len
= sizeof(buffer
);
754 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
755 test_header_name
, buffer
, &len
, &index
);
756 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
757 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
758 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
759 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
761 len
= sizeof(buffer
);
762 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
763 test_header_name
, buffer
, &len
, &index
);
764 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
765 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
766 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
768 len
= sizeof(buffer
);
769 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
770 test_header_name
, buffer
, &len
, &index
);
771 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
773 /* coalesce with comma flag */
774 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
775 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
778 len
= sizeof(buffer
);
779 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
780 test_header_name
, buffer
, &len
, &index
);
781 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
782 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
783 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
784 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
785 "WinHttpQueryHeaders returned incorrect string.\n");
787 len
= sizeof(buffer
);
788 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
789 test_header_name
, buffer
, &len
, &index
);
790 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
791 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
792 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
794 len
= sizeof(buffer
);
795 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
796 test_header_name
, buffer
, &len
, &index
);
797 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
800 /* coalesce with semicolon flag */
801 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
802 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
805 len
= sizeof(buffer
);
806 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
807 test_header_name
, buffer
, &len
, &index
);
808 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
809 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
810 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
811 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
812 "WinHttpQueryHeaders returned incorrect string.\n");
814 len
= sizeof(buffer
);
815 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
816 test_header_name
, buffer
, &len
, &index
);
817 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
818 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
819 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
821 len
= sizeof(buffer
);
822 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
823 test_header_name
, buffer
, &len
, &index
);
824 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
826 /* add and replace flags */
827 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
828 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
831 len
= sizeof(buffer
);
832 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
833 test_header_name
, buffer
, &len
, &index
);
834 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
835 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
836 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
838 len
= sizeof(buffer
);
839 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
840 test_header_name
, buffer
, &len
, &index
);
841 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
842 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
843 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
845 len
= sizeof(buffer
);
846 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
847 test_header_name
, buffer
, &len
, &index
);
848 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
850 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
851 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
853 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
854 ok(ret
, "WinHttpAddRequestHeaders failed\n");
857 memset(buffer
, 0xff, sizeof(buffer
));
858 len
= sizeof(buffer
);
859 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
860 test_header_name3
, buffer
, &len
, &index
);
861 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
862 ok(!memcmp(buffer
, empty
, sizeof(empty
)), "unexpected result\n");
864 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
865 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
867 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
868 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
870 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
871 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
873 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
874 ok(ret
, "WinHttpAddRequestHeaders failed\n");
878 len
= sizeof(buffer
);
879 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
880 field
, buffer
, &len
, &index
);
881 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
882 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
884 SetLastError(0xdeadbeef);
885 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, 0,
886 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
887 err
= GetLastError();
888 ok(!ret
, "unexpected success\n");
889 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
891 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, ~0u,
892 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
893 ok(ret
, "failed to add header: %u\n", GetLastError());
896 len
= sizeof(buffer
);
897 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
898 test_header_range
, buffer
, &len
, &index
);
899 ok(ret
, "failed to get range header %u\n", GetLastError());
900 ok(!memcmp(buffer
, test_header_bytes
, sizeof(test_header_bytes
)), "incorrect string returned\n");
901 ok(len
== lstrlenW(test_header_bytes
) * sizeof(WCHAR
), "wrong length %u\n", len
);
902 ok(index
== 1, "wrong index %u\n", index
);
905 len
= sizeof(buffer
);
906 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
907 test_header_name2
, buffer
, &len
, &index
);
908 ok(!ret
, "unexpected success\n");
910 SetLastError(0xdeadbeef);
911 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
912 err
= GetLastError();
913 ok(!ret
, "unexpected success\n");
914 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
916 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
917 ok(ret
, "got %u\n", GetLastError());
920 len
= sizeof(buffer
);
921 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
922 test_header_name2
, buffer
, &len
, &index
);
923 ok(ret
, "got %u\n", GetLastError());
924 ok(index
== 1, "wrong index %u\n", index
);
925 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
927 ret
= WinHttpAddRequestHeaders(request
, test_headers
[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
928 ok(ret
, "got %u\n", GetLastError());
931 len
= sizeof(buffer
);
932 SetLastError(0xdeadbeef);
933 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
934 test_header_name2
, buffer
, &len
, &index
);
935 err
= GetLastError();
936 ok(!ret
, "unexpected success\n");
937 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
939 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], -1L, 0);
940 ok(ret
, "got %u\n", GetLastError());
943 len
= sizeof(buffer
);
944 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
945 test_header_name2
, buffer
, &len
, &index
);
946 ok(ret
, "got %u\n", GetLastError());
947 ok(index
== 1, "wrong index %u\n", index
);
948 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
950 ret
= WinHttpCloseHandle(request
);
951 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
953 ret
= WinHttpCloseHandle(connection
);
954 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
955 ret
= WinHttpCloseHandle(session
);
956 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
960 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
962 DWORD flags
= *(DWORD
*)buf
;
966 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
969 #define X(x) if (flags & x) trace("%s\n", #x);
970 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
971 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
972 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
973 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
974 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
975 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
976 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
980 static void test_secure_connection(void)
982 static const char data_start
[] = "<!DOCTYPE html PUBLIC";
983 HINTERNET ses
, con
, req
;
984 DWORD size
, status
, policy
, bitness
, read_size
, err
, available_size
;
987 WINHTTP_CERTIFICATE_INFO info
;
990 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
991 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
993 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
994 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
995 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
997 con
= WinHttpConnect(ses
, test_winehq
, 443, 0);
998 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1000 /* try without setting WINHTTP_FLAG_SECURE */
1001 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1002 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1004 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1005 err
= GetLastError();
1006 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
1008 skip("Connection failed, skipping.\n");
1011 ok(ret
, "failed to send request %u\n", GetLastError());
1013 ret
= WinHttpReceiveResponse(req
, NULL
);
1014 ok(ret
, "failed to receive response %u\n", GetLastError());
1016 status
= 0xdeadbeef;
1017 size
= sizeof(status
);
1018 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1019 ok(ret
, "header query failed %u\n", GetLastError());
1020 ok(status
== HTTP_STATUS_BAD_REQUEST
, "got %u\n", status
);
1022 WinHttpCloseHandle(req
);
1024 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
1025 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1027 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
1029 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1030 err
= GetLastError();
1031 if (!ret
&& (err
== ERROR_WINHTTP_SECURE_FAILURE
|| err
== ERROR_WINHTTP_CANNOT_CONNECT
||
1032 err
== ERROR_WINHTTP_TIMEOUT
))
1034 skip("secure connection failed, skipping remaining secure tests\n");
1037 ok(ret
, "failed to send request %u\n", GetLastError());
1039 size
= sizeof(cert
);
1040 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1041 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1042 if (ret
) CertFreeCertificateContext(cert
);
1044 size
= sizeof(bitness
);
1045 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
1046 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
1048 size
= sizeof(info
);
1049 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
1050 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
1054 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
1055 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
1056 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
1057 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
1058 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
1059 trace("dwKeySize %u\n", info
.dwKeySize
);
1062 ret
= WinHttpReceiveResponse(req
, NULL
);
1063 ok(ret
, "failed to receive response %u\n", GetLastError());
1066 ret
= WinHttpQueryDataAvailable(req
, &available_size
);
1067 ok(ret
, "failed to query available data %u\n", GetLastError());
1068 ok(available_size
> 2014, "available_size = %u\n", available_size
);
1070 status
= 0xdeadbeef;
1071 size
= sizeof(status
);
1072 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1073 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1074 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1077 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
1078 ok(!ret
, "succeeded unexpectedly\n");
1084 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
1085 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
1089 if (read_size
<= 32)
1090 ok(!memcmp(buffer
, data_start
, sizeof(data_start
)-1), "not expected: %.32s\n", buffer
);
1092 ok(read_size
>= available_size
, "read_size = %u, available_size = %u\n", read_size
, available_size
);
1095 WinHttpCloseHandle(req
);
1096 WinHttpCloseHandle(con
);
1097 WinHttpCloseHandle(ses
);
1100 static void test_request_parameter_defaults(void)
1102 static const WCHAR empty
[] = {0};
1103 HINTERNET ses
, con
, req
;
1104 DWORD size
, status
, error
;
1108 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1109 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1111 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1112 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1114 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1115 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1117 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1118 error
= GetLastError();
1119 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1121 skip("connection failed, skipping\n");
1124 ok(ret
, "failed to send request %u\n", GetLastError());
1126 ret
= WinHttpReceiveResponse(req
, NULL
);
1127 if (!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE
) /* win2k */
1129 win_skip("invalid response\n");
1132 ok(ret
, "failed to receive response %u\n", GetLastError());
1134 status
= 0xdeadbeef;
1135 size
= sizeof(status
);
1136 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1137 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1138 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1140 WinHttpCloseHandle(req
);
1142 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
1143 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1145 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1146 error
= GetLastError();
1147 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1149 skip("connection failed, skipping\n");
1152 ok(ret
, "failed to send request %u\n", GetLastError());
1154 ret
= WinHttpReceiveResponse(req
, NULL
);
1155 ok(ret
, "failed to receive response %u\n", GetLastError());
1158 SetLastError(0xdeadbeef);
1159 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
1160 error
= GetLastError();
1161 ok(!ret
, "succeeded unexpectedly\n");
1162 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
1164 version
= HeapAlloc(GetProcessHeap(), 0, size
);
1165 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
1166 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1167 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
1168 HeapFree(GetProcessHeap(), 0, version
);
1170 status
= 0xdeadbeef;
1171 size
= sizeof(status
);
1172 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1173 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1174 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1177 WinHttpCloseHandle(req
);
1178 WinHttpCloseHandle(con
);
1179 WinHttpCloseHandle(ses
);
1182 static const WCHAR Connections
[] = {
1183 'S','o','f','t','w','a','r','e','\\',
1184 'M','i','c','r','o','s','o','f','t','\\',
1185 'W','i','n','d','o','w','s','\\',
1186 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1187 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1188 'C','o','n','n','e','c','t','i','o','n','s',0 };
1189 static const WCHAR WinHttpSettings
[] = {
1190 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1192 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1198 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1203 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1207 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1217 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1222 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
1223 KEY_WRITE
, NULL
, &key
, NULL
);
1227 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
1229 RegDeleteValueW( key
, WinHttpSettings
);
1234 static void test_set_default_proxy_config(void)
1236 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1237 static WCHAR normalString
[] = { 'f','o','o',0 };
1239 BYTE
*saved_proxy_settings
= NULL
;
1240 WINHTTP_PROXY_INFO info
;
1243 /* FIXME: it would be simpler to read the current settings using
1244 * WinHttpGetDefaultProxyConfiguration and save them using
1245 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1247 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1248 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1249 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1250 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1251 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1252 * the lpszProxy and lpszProxyBypass values are ignored.
1253 * Thus, if a proxy is set with proxycfg, then calling
1254 * WinHttpGetDefaultProxyConfiguration followed by
1255 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1256 * getting deleted from the registry.
1258 * Instead I read the current registry value and restore it directly.
1260 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1263 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1264 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1269 /* Crashes on Vista and higher */
1270 SetLastError(0xdeadbeef);
1271 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1272 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1273 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1276 /* test with invalid access type */
1277 info
.dwAccessType
= 0xdeadbeef;
1278 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1279 SetLastError(0xdeadbeef);
1280 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1281 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1282 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1284 /* at a minimum, the proxy server must be set */
1285 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1286 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1287 SetLastError(0xdeadbeef);
1288 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1289 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1290 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1291 info
.lpszProxyBypass
= normalString
;
1292 SetLastError(0xdeadbeef);
1293 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1294 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1295 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1297 /* the proxy server can't have wide characters */
1298 info
.lpszProxy
= wideString
;
1299 SetLastError(0xdeadbeef);
1300 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1301 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1302 skip("couldn't set default proxy configuration: access denied\n");
1304 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1305 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1306 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1308 info
.lpszProxy
= normalString
;
1309 SetLastError(0xdeadbeef);
1310 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1311 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1312 skip("couldn't set default proxy configuration: access denied\n");
1315 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1316 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1317 "got %u\n", GetLastError());
1319 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1322 static void test_Timeouts (void)
1326 HINTERNET ses
, req
, con
;
1328 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1329 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1331 SetLastError(0xdeadbeef);
1332 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1333 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1334 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1336 SetLastError(0xdeadbeef);
1337 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1338 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1339 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1341 SetLastError(0xdeadbeef);
1342 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1343 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1344 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1346 SetLastError(0xdeadbeef);
1347 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1348 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1349 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1351 SetLastError(0xdeadbeef);
1352 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1353 ok(ret
, "%u\n", GetLastError());
1354 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1355 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1357 SetLastError(0xdeadbeef);
1358 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1359 ok(ret
, "%u\n", GetLastError());
1361 SetLastError(0xdeadbeef);
1362 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1363 ok(ret
, "%u\n", GetLastError());
1365 SetLastError(0xdeadbeef);
1367 size
= sizeof(DWORD
);
1368 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1369 ok(ret
, "%u\n", GetLastError());
1370 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1372 SetLastError(0xdeadbeef);
1374 size
= sizeof(DWORD
);
1375 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1376 ok(ret
, "%u\n", GetLastError());
1377 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1379 SetLastError(0xdeadbeef);
1381 size
= sizeof(DWORD
);
1382 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1383 ok(ret
, "%u\n", GetLastError());
1384 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1386 SetLastError(0xdeadbeef);
1388 size
= sizeof(DWORD
);
1389 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1390 ok(ret
, "%u\n", GetLastError());
1391 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1393 SetLastError(0xdeadbeef);
1395 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1396 ok(ret
, "%u\n", GetLastError());
1398 SetLastError(0xdeadbeef);
1400 size
= sizeof(DWORD
);
1401 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1402 ok(ret
, "%u\n", GetLastError());
1403 ok(value
== 0, "Expected 0, got %u\n", value
);
1405 SetLastError(0xdeadbeef);
1407 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1408 ok(ret
, "%u\n", GetLastError());
1410 SetLastError(0xdeadbeef);
1412 size
= sizeof(DWORD
);
1413 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1414 ok(ret
, "%u\n", GetLastError());
1415 ok(value
== 0, "Expected 0, got %u\n", value
);
1417 SetLastError(0xdeadbeef);
1419 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1420 ok(ret
, "%u\n", GetLastError());
1422 SetLastError(0xdeadbeef);
1424 size
= sizeof(DWORD
);
1425 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1426 ok(ret
, "%u\n", GetLastError());
1427 ok(value
== 0, "Expected 0, got %u\n", value
);
1429 SetLastError(0xdeadbeef);
1431 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1432 ok(ret
, "%u\n", GetLastError());
1434 SetLastError(0xdeadbeef);
1436 size
= sizeof(DWORD
);
1437 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1438 ok(ret
, "%u\n", GetLastError());
1439 ok(value
== 0, "Expected 0, got %u\n", value
);
1441 SetLastError(0xdeadbeef);
1443 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1444 ok(ret
, "%u\n", GetLastError());
1446 SetLastError(0xdeadbeef);
1448 size
= sizeof(DWORD
);
1449 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1450 ok(ret
, "%u\n", GetLastError());
1451 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1453 SetLastError(0xdeadbeef);
1455 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1456 ok(ret
, "%u\n", GetLastError());
1458 SetLastError(0xdeadbeef);
1460 size
= sizeof(DWORD
);
1461 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1462 ok(ret
, "%u\n", GetLastError());
1463 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1465 SetLastError(0xdeadbeef);
1467 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1468 ok(ret
, "%u\n", GetLastError());
1470 SetLastError(0xdeadbeef);
1472 size
= sizeof(DWORD
);
1473 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1474 ok(ret
, "%u\n", GetLastError());
1475 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1477 SetLastError(0xdeadbeef);
1479 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1480 ok(ret
, "%u\n", GetLastError());
1482 SetLastError(0xdeadbeef);
1484 size
= sizeof(DWORD
);
1485 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1486 ok(ret
, "%u\n", GetLastError());
1487 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1489 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1490 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1492 /* Timeout values should match the last one set for session */
1493 SetLastError(0xdeadbeef);
1495 size
= sizeof(DWORD
);
1496 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1497 ok(ret
, "%u\n", GetLastError());
1498 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1500 SetLastError(0xdeadbeef);
1502 size
= sizeof(DWORD
);
1503 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1504 ok(ret
, "%u\n", GetLastError());
1505 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1507 SetLastError(0xdeadbeef);
1509 size
= sizeof(DWORD
);
1510 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1511 ok(ret
, "%u\n", GetLastError());
1512 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1514 SetLastError(0xdeadbeef);
1516 size
= sizeof(DWORD
);
1517 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1518 ok(ret
, "%u\n", GetLastError());
1519 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1521 SetLastError(0xdeadbeef);
1522 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1523 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1524 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1526 SetLastError(0xdeadbeef);
1527 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1528 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1529 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1531 SetLastError(0xdeadbeef);
1532 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1533 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1534 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1536 SetLastError(0xdeadbeef);
1537 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1538 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1539 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1541 SetLastError(0xdeadbeef);
1542 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1543 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1544 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1546 SetLastError(0xdeadbeef);
1547 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1548 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1549 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1551 SetLastError(0xdeadbeef);
1553 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1554 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1555 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1557 SetLastError(0xdeadbeef);
1559 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1560 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1561 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1563 SetLastError(0xdeadbeef);
1565 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1566 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1567 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1569 SetLastError(0xdeadbeef);
1571 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1572 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1573 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1575 /* Changing timeout values for session should affect the values for connection */
1576 SetLastError(0xdeadbeef);
1578 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1579 ok(ret
, "%u\n", GetLastError());
1581 SetLastError(0xdeadbeef);
1583 size
= sizeof(DWORD
);
1584 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1585 ok(ret
, "%u\n", GetLastError());
1586 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1588 SetLastError(0xdeadbeef);
1590 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1591 ok(ret
, "%u\n", GetLastError());
1593 SetLastError(0xdeadbeef);
1595 size
= sizeof(DWORD
);
1596 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1597 ok(ret
, "%u\n", GetLastError());
1598 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1600 SetLastError(0xdeadbeef);
1602 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1603 ok(ret
, "%u\n", GetLastError());
1605 SetLastError(0xdeadbeef);
1607 size
= sizeof(DWORD
);
1608 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1609 ok(ret
, "%u\n", GetLastError());
1610 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1612 SetLastError(0xdeadbeef);
1614 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1615 ok(ret
, "%u\n", GetLastError());
1617 SetLastError(0xdeadbeef);
1619 size
= sizeof(DWORD
);
1620 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1621 ok(ret
, "%u\n", GetLastError());
1622 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1624 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1625 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1627 /* Timeout values should match the last one set for session */
1628 SetLastError(0xdeadbeef);
1630 size
= sizeof(DWORD
);
1631 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1632 ok(ret
, "%u\n", GetLastError());
1633 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1635 SetLastError(0xdeadbeef);
1637 size
= sizeof(DWORD
);
1638 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1639 ok(ret
, "%u\n", GetLastError());
1640 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1642 SetLastError(0xdeadbeef);
1644 size
= sizeof(DWORD
);
1645 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1646 ok(ret
, "%u\n", GetLastError());
1647 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1649 SetLastError(0xdeadbeef);
1651 size
= sizeof(DWORD
);
1652 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1653 ok(ret
, "%u\n", GetLastError());
1654 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1656 SetLastError(0xdeadbeef);
1657 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1658 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1659 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1661 SetLastError(0xdeadbeef);
1662 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1663 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1664 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1666 SetLastError(0xdeadbeef);
1667 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1668 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1669 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1671 SetLastError(0xdeadbeef);
1672 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1673 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1674 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1676 SetLastError(0xdeadbeef);
1677 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1678 ok(ret
, "%u\n", GetLastError());
1680 SetLastError(0xdeadbeef);
1681 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1682 ok(ret
, "%u\n", GetLastError());
1684 SetLastError(0xdeadbeef);
1685 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1686 ok(ret
, "%u\n", GetLastError());
1688 SetLastError(0xdeadbeef);
1690 size
= sizeof(DWORD
);
1691 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1692 ok(ret
, "%u\n", GetLastError());
1693 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1695 SetLastError(0xdeadbeef);
1697 size
= sizeof(DWORD
);
1698 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1699 ok(ret
, "%u\n", GetLastError());
1700 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1702 SetLastError(0xdeadbeef);
1704 size
= sizeof(DWORD
);
1705 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1706 ok(ret
, "%u\n", GetLastError());
1707 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1709 SetLastError(0xdeadbeef);
1711 size
= sizeof(DWORD
);
1712 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1713 ok(ret
, "%u\n", GetLastError());
1714 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1716 SetLastError(0xdeadbeef);
1718 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1719 ok(ret
, "%u\n", GetLastError());
1721 SetLastError(0xdeadbeef);
1723 size
= sizeof(DWORD
);
1724 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1725 ok(ret
, "%u\n", GetLastError());
1726 ok(value
== 0, "Expected 0, got %u\n", value
);
1728 SetLastError(0xdeadbeef);
1730 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1731 ok(ret
, "%u\n", GetLastError());
1733 SetLastError(0xdeadbeef);
1735 size
= sizeof(DWORD
);
1736 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1737 ok(ret
, "%u\n", GetLastError());
1738 ok(value
== 0, "Expected 0, got %u\n", value
);
1740 SetLastError(0xdeadbeef);
1742 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1743 ok(ret
, "%u\n", GetLastError());
1745 SetLastError(0xdeadbeef);
1747 size
= sizeof(DWORD
);
1748 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1749 ok(ret
, "%u\n", GetLastError());
1750 ok(value
== 0, "Expected 0, got %u\n", value
);
1752 SetLastError(0xdeadbeef);
1754 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1755 ok(ret
, "%u\n", GetLastError());
1757 SetLastError(0xdeadbeef);
1759 size
= sizeof(DWORD
);
1760 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1761 ok(ret
, "%u\n", GetLastError());
1762 ok(value
== 0, "Expected 0, got %u\n", value
);
1764 SetLastError(0xdeadbeef);
1766 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1767 ok(ret
, "%u\n", GetLastError());
1769 SetLastError(0xdeadbeef);
1771 size
= sizeof(DWORD
);
1772 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1773 ok(ret
, "%u\n", GetLastError());
1774 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1776 SetLastError(0xdeadbeef);
1778 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1779 ok(ret
, "%u\n", GetLastError());
1781 SetLastError(0xdeadbeef);
1783 size
= sizeof(DWORD
);
1784 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1785 ok(ret
, "%u\n", GetLastError());
1786 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1788 SetLastError(0xdeadbeef);
1790 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1791 ok(ret
, "%u\n", GetLastError());
1793 SetLastError(0xdeadbeef);
1795 size
= sizeof(DWORD
);
1796 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1797 ok(ret
, "%u\n", GetLastError());
1798 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1800 SetLastError(0xdeadbeef);
1802 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1803 ok(ret
, "%u\n", GetLastError());
1805 SetLastError(0xdeadbeef);
1807 size
= sizeof(DWORD
);
1808 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1809 ok(ret
, "%u\n", GetLastError());
1810 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1812 /* Changing timeout values for session should not affect the values for a request,
1813 * neither should the other way around.
1815 SetLastError(0xdeadbeef);
1817 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1818 ok(ret
, "%u\n", GetLastError());
1820 SetLastError(0xdeadbeef);
1822 size
= sizeof(DWORD
);
1823 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1824 ok(ret
, "%u\n", GetLastError());
1825 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1827 SetLastError(0xdeadbeef);
1829 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1830 ok(ret
, "%u\n", GetLastError());
1832 SetLastError(0xdeadbeef);
1834 size
= sizeof(DWORD
);
1835 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1836 ok(ret
, "%u\n", GetLastError());
1837 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1839 SetLastError(0xdeadbeef);
1841 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1842 ok(ret
, "%u\n", GetLastError());
1844 SetLastError(0xdeadbeef);
1846 size
= sizeof(DWORD
);
1847 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1848 ok(ret
, "%u\n", GetLastError());
1849 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1851 SetLastError(0xdeadbeef);
1853 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1854 ok(ret
, "%u\n", GetLastError());
1856 SetLastError(0xdeadbeef);
1858 size
= sizeof(DWORD
);
1859 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1860 ok(ret
, "%u\n", GetLastError());
1861 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1863 SetLastError(0xdeadbeef);
1865 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1866 ok(ret
, "%u\n", GetLastError());
1868 SetLastError(0xdeadbeef);
1870 size
= sizeof(DWORD
);
1871 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1872 ok(ret
, "%u\n", GetLastError());
1873 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1875 SetLastError(0xdeadbeef);
1877 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1878 ok(ret
, "%u\n", GetLastError());
1880 SetLastError(0xdeadbeef);
1882 size
= sizeof(DWORD
);
1883 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1884 ok(ret
, "%u\n", GetLastError());
1885 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1887 SetLastError(0xdeadbeef);
1889 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1890 ok(ret
, "%u\n", GetLastError());
1892 SetLastError(0xdeadbeef);
1894 size
= sizeof(DWORD
);
1895 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1896 ok(ret
, "%u\n", GetLastError());
1897 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1899 SetLastError(0xdeadbeef);
1901 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1902 ok(ret
, "%u\n", GetLastError());
1904 SetLastError(0xdeadbeef);
1906 size
= sizeof(DWORD
);
1907 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1908 ok(ret
, "%u\n", GetLastError());
1909 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1911 WinHttpCloseHandle(req
);
1912 WinHttpCloseHandle(con
);
1913 WinHttpCloseHandle(ses
);
1916 static void test_resolve_timeout(void)
1918 static const WCHAR nxdomain
[] =
1919 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1920 HINTERNET ses
, con
, req
;
1924 if (! proxy_active())
1926 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1927 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1930 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1931 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1933 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1934 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1936 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1937 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1939 SetLastError(0xdeadbeef);
1940 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1943 skip("nxdomain returned success. Broken ISP redirects?\n");
1946 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1947 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1949 WinHttpCloseHandle(req
);
1950 WinHttpCloseHandle(con
);
1951 WinHttpCloseHandle(ses
);
1954 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1956 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1957 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1960 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1961 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1963 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1964 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1966 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1967 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1969 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1970 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
1972 skip("connection failed, skipping\n");
1975 ok(ret
, "failed to send request\n");
1978 WinHttpCloseHandle(req
);
1979 WinHttpCloseHandle(con
);
1980 WinHttpCloseHandle(ses
);
1983 static const char page1
[] =
1985 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1986 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1989 static const char okmsg
[] =
1990 "HTTP/1.1 200 OK\r\n"
1991 "Server: winetest\r\n"
1994 static const char notokmsg
[] =
1995 "HTTP/1.1 400 Bad Request\r\n"
1998 static const char cookiemsg
[] =
1999 "HTTP/1.1 200 OK\r\n"
2000 "Set-Cookie: name = value \r\n"
2001 "Set-Cookie: NAME = value \r\n"
2004 static const char nocontentmsg
[] =
2005 "HTTP/1.1 204 No Content\r\n"
2006 "Server: winetest\r\n"
2009 static const char notmodified
[] =
2010 "HTTP/1.1 304 Not Modified\r\n"
2013 static const char noauthmsg
[] =
2014 "HTTP/1.1 401 Unauthorized\r\n"
2015 "Server: winetest\r\n"
2016 "Connection: close\r\n"
2017 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2018 "Content-Length: 12\r\n"
2019 "Content-Type: text/plain\r\n"
2022 static const char okauthmsg
[] =
2023 "HTTP/1.1 200 OK\r\n"
2024 "Server: winetest\r\n"
2025 "Connection: close\r\n"
2026 "Content-Length: 11\r\n"
2027 "Content-Type: text/plain\r\n"
2030 static const char headmsg
[] =
2031 "HTTP/1.1 200 OK\r\n"
2032 "Content-Length: 100\r\n"
2035 static const char unauthorized
[] = "Unauthorized";
2036 static const char hello_world
[] = "Hello World";
2044 #define BIG_BUFFER_LEN 0x2250
2046 static DWORD CALLBACK
server_thread(LPVOID param
)
2048 struct server_info
*si
= param
;
2049 int r
, c
= -1, i
, on
;
2051 struct sockaddr_in sa
;
2054 int last_request
= 0;
2056 WSAStartup(MAKEWORD(1,1), &wsaData
);
2058 s
= socket(AF_INET
, SOCK_STREAM
, 0);
2059 if (s
== INVALID_SOCKET
)
2063 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
2065 memset(&sa
, 0, sizeof sa
);
2066 sa
.sin_family
= AF_INET
;
2067 sa
.sin_port
= htons(si
->port
);
2068 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
2070 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
2075 SetEvent(si
->event
);
2078 if (c
== -1) c
= accept(s
, NULL
, NULL
);
2080 memset(buffer
, 0, sizeof buffer
);
2081 for(i
= 0; i
< sizeof buffer
- 1; i
++)
2083 r
= recv(c
, &buffer
[i
], 1, 0);
2086 if (i
< 4) continue;
2087 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
2088 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
2091 if (strstr(buffer
, "GET /basic"))
2093 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2094 send(c
, page1
, sizeof page1
- 1, 0);
2096 if (strstr(buffer
, "/auth"))
2098 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2100 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2101 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2105 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
2106 send(c
, unauthorized
, sizeof unauthorized
- 1, 0);
2110 if (strstr(buffer
, "/big"))
2112 char msg
[BIG_BUFFER_LEN
];
2113 memset(msg
, 'm', sizeof(msg
));
2114 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2115 send(c
, msg
, sizeof(msg
), 0);
2117 if (strstr(buffer
, "/no_headers"))
2119 send(c
, page1
, sizeof page1
- 1, 0);
2121 if (strstr(buffer
, "GET /no_content"))
2123 send(c
, nocontentmsg
, sizeof nocontentmsg
- 1, 0);
2126 if (strstr(buffer
, "GET /not_modified"))
2128 if (strstr(buffer
, "If-Modified-Since:")) send(c
, notmodified
, sizeof notmodified
- 1, 0);
2129 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2132 if (strstr(buffer
, "HEAD /head"))
2134 send(c
, headmsg
, sizeof headmsg
- 1, 0);
2137 if (strstr(buffer
, "GET /cookie3"))
2139 if (strstr(buffer
, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2140 broken(strstr(buffer
, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL
))
2141 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2143 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2145 if (strstr(buffer
, "GET /cookie2"))
2147 if (strstr(buffer
, "Cookie: NAME=value; name=value\r\n") ||
2148 broken(strstr(buffer
, "Cookie: name=value; NAME=value\r\n") != NULL
))
2149 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2151 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2153 else if (strstr(buffer
, "GET /cookie"))
2155 if (!strstr(buffer
, "Cookie: name=value\r\n")) send(c
, cookiemsg
, sizeof(cookiemsg
) - 1, 0);
2156 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2158 if (strstr(buffer
, "GET /quit"))
2160 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2161 send(c
, page1
, sizeof page1
- 1, 0);
2168 } while (!last_request
);
2174 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
2176 static const WCHAR test_header_end_clrf
[] = {'\r','\n','\r','\n',0};
2177 static const WCHAR test_header_end_raw
[] = {0,0};
2178 HINTERNET ses
, con
, req
;
2180 WCHAR buffer2
[0x100];
2181 DWORD count
, status
, size
, error
, supported
, first
, target
;
2184 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2185 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2187 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2188 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2190 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
2191 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2193 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2194 ok(ret
, "failed to send request %u\n", GetLastError());
2196 ret
= WinHttpReceiveResponse(req
, NULL
);
2197 ok(ret
, "failed to receive response %u\n", GetLastError());
2199 status
= 0xdeadbeef;
2200 size
= sizeof(status
);
2201 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2202 ok(ret
, "failed to query status code %u\n", GetLastError());
2203 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2205 supported
= first
= target
= 0xdeadbeef;
2206 SetLastError(0xdeadbeef);
2207 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2208 error
= GetLastError();
2209 ok(!ret
, "unexpected success\n");
2210 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2211 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2212 ok(first
== 0xdeadbeef, "got %x\n", first
);
2213 ok(target
== 0xdeadbeef, "got %x\n", target
);
2215 size
= sizeof(buffer2
);
2216 memset(buffer2
, 0, sizeof(buffer2
));
2217 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, buffer2
, &size
, NULL
);
2218 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2219 ok(!memcmp(buffer2
+ lstrlenW(buffer2
) - 4, test_header_end_clrf
, sizeof(test_header_end_clrf
)),
2220 "WinHttpQueryHeaders returned invalid end of header string\n");
2222 size
= sizeof(buffer2
);
2223 memset(buffer2
, 0, sizeof(buffer2
));
2224 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS
, NULL
, buffer2
, &size
, NULL
);
2225 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2226 ok(!memcmp(buffer2
+ (size
/ sizeof(WCHAR
)) - 1, test_header_end_raw
, sizeof(test_header_end_raw
)),
2227 "WinHttpQueryHeaders returned invalid end of header string\n");
2228 ok(buffer2
[(size
/ sizeof(WCHAR
)) - 2] != 0, "returned string has too many NULL characters\n");
2231 memset(buffer
, 0, sizeof(buffer
));
2232 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
2233 ok(ret
, "failed to read data %u\n", GetLastError());
2234 ok(count
== sizeof page1
- 1, "count was wrong\n");
2235 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
2237 WinHttpCloseHandle(req
);
2238 WinHttpCloseHandle(con
);
2239 WinHttpCloseHandle(ses
);
2242 static void test_basic_authentication(int port
)
2244 static const WCHAR authW
[] = {'/','a','u','t','h',0};
2245 static WCHAR userW
[] = {'u','s','e','r',0};
2246 static WCHAR passW
[] = {'p','w','d',0};
2247 static WCHAR pass2W
[] = {'p','w','d','2',0};
2248 HINTERNET ses
, con
, req
;
2249 DWORD status
, size
, error
, supported
, first
, target
;
2253 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2254 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2256 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2257 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2259 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2260 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2262 SetLastError(0xdeadbeef);
2263 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
2264 error
= GetLastError();
2265 ok(!ret
, "expected failure\n");
2266 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2268 SetLastError(0xdeadbeef);
2269 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
2270 error
= GetLastError();
2271 ok(!ret
, "expected failure\n");
2272 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2274 supported
= 0xdeadbeef;
2275 SetLastError(0xdeadbeef);
2276 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
2277 error
= GetLastError();
2278 ok(!ret
, "expected failure\n");
2279 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2280 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2282 supported
= first
= 0xdeadbeef;
2283 SetLastError(0xdeadbeef);
2284 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
2285 error
= GetLastError();
2286 ok(!ret
, "expected failure\n");
2287 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2288 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2289 ok(first
== 0xdeadbeef, "got %x\n", first
);
2291 supported
= first
= target
= 0xdeadbeef;
2292 SetLastError(0xdeadbeef);
2293 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2294 error
= GetLastError();
2295 ok(!ret
, "expected failure\n");
2296 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2297 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2298 ok(first
== 0xdeadbeef, "got %x\n", first
);
2299 ok(target
== 0xdeadbeef, "got %x\n", target
);
2301 supported
= first
= target
= 0xdeadbeef;
2302 SetLastError(0xdeadbeef);
2303 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
2304 error
= GetLastError();
2305 ok(!ret
, "expected failure\n");
2306 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2307 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2308 ok(first
== 0xdeadbeef, "got %x\n", first
);
2309 ok(target
== 0xdeadbeef, "got %x\n", target
);
2311 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2312 ok(ret
, "failed to send request %u\n", GetLastError());
2314 ret
= WinHttpReceiveResponse(req
, NULL
);
2315 ok(ret
, "failed to receive response %u\n", GetLastError());
2317 status
= 0xdeadbeef;
2318 size
= sizeof(status
);
2319 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2320 ok(ret
, "failed to query status code %u\n", GetLastError());
2321 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2324 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2325 error
= GetLastError();
2326 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2329 ok(size
== 12, "expected 12, got %u\n", size
);
2330 ok(!memcmp(buffer
, unauthorized
, 12), "got %s\n", buffer
);
2333 supported
= first
= target
= 0xdeadbeef;
2334 SetLastError(0xdeadbeef);
2335 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2336 error
= GetLastError();
2337 ok(ret
, "failed to query authentication schemes %u\n", error
);
2338 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2339 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2340 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2341 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2343 SetLastError(0xdeadbeef);
2344 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2345 error
= GetLastError();
2346 ok(ret
, "failed to set credentials %u\n", error
);
2347 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2349 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2350 ok(ret
, "failed to set credentials %u\n", GetLastError());
2352 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2353 ok(ret
, "failed to set credentials %u\n", GetLastError());
2355 SetLastError(0xdeadbeef);
2356 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2357 error
= GetLastError();
2358 ok(!ret
, "expected failure\n");
2359 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2361 SetLastError(0xdeadbeef);
2362 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2363 error
= GetLastError();
2364 ok(!ret
, "expected failure\n");
2365 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2367 SetLastError(0xdeadbeef);
2368 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2369 error
= GetLastError();
2370 ok(!ret
, "expected failure\n");
2371 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2373 SetLastError(0xdeadbeef);
2374 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2375 error
= GetLastError();
2376 ok(!ret
, "expected failure\n");
2377 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2379 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2380 ok(ret
, "failed to set credentials %u\n", GetLastError());
2382 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2383 ok(ret
, "failed to send request %u\n", GetLastError());
2385 ret
= WinHttpReceiveResponse(req
, NULL
);
2386 ok(ret
, "failed to receive response %u\n", GetLastError());
2388 status
= 0xdeadbeef;
2389 size
= sizeof(status
);
2390 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2391 ok(ret
, "failed to query status code %u\n", GetLastError());
2392 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2395 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2396 error
= GetLastError();
2397 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2400 ok(size
== 11, "expected 11, got %u\n", size
);
2401 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2404 WinHttpCloseHandle(req
);
2405 WinHttpCloseHandle(con
);
2406 WinHttpCloseHandle(ses
);
2408 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2410 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2411 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2413 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2414 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2416 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2417 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2419 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2420 ok(ret
, "failed to set credentials %u\n", GetLastError());
2422 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2423 ok(ret
, "failed to set username %u\n", GetLastError());
2425 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, pass2W
, lstrlenW(pass2W
));
2426 ok(ret
, "failed to set password %u\n", GetLastError());
2428 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2429 ok(ret
, "failed to send request %u\n", GetLastError());
2431 ret
= WinHttpReceiveResponse(req
, NULL
);
2432 ok(ret
, "failed to receive response %u\n", GetLastError());
2434 status
= 0xdeadbeef;
2435 size
= sizeof(status
);
2436 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2437 ok(ret
, "failed to query status code %u\n", GetLastError());
2438 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2440 WinHttpCloseHandle(req
);
2441 WinHttpCloseHandle(con
);
2442 WinHttpCloseHandle(ses
);
2444 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2445 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2447 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2448 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2450 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2451 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2453 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2454 ok(ret
, "failed to set username %u\n", GetLastError());
2456 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2457 ok(ret
, "failed to set password %u\n", GetLastError());
2459 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, pass2W
, NULL
);
2460 ok(ret
, "failed to set credentials %u\n", GetLastError());
2462 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2463 ok(ret
, "failed to send request %u\n", GetLastError());
2465 ret
= WinHttpReceiveResponse(req
, NULL
);
2466 ok(ret
, "failed to receive response %u\n", GetLastError());
2468 status
= 0xdeadbeef;
2469 size
= sizeof(status
);
2470 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2471 ok(ret
, "failed to query status code %u\n", GetLastError());
2472 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2474 WinHttpCloseHandle(req
);
2475 WinHttpCloseHandle(con
);
2476 WinHttpCloseHandle(ses
);
2479 static void test_no_headers(int port
)
2481 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2482 HINTERNET ses
, con
, req
;
2486 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2487 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2489 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2490 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2492 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2493 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2495 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2498 error
= GetLastError();
2499 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2503 SetLastError(0xdeadbeef);
2504 ret
= WinHttpReceiveResponse(req
, NULL
);
2505 error
= GetLastError();
2506 ok(!ret
, "expected failure\n");
2507 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2510 WinHttpCloseHandle(req
);
2511 WinHttpCloseHandle(con
);
2512 WinHttpCloseHandle(ses
);
2515 static void test_no_content(int port
)
2517 static const WCHAR no_contentW
[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2518 HINTERNET ses
, con
, req
;
2520 DWORD size
, len
= sizeof(buf
), bytes_read
, status
;
2523 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2524 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2526 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2527 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2529 req
= WinHttpOpenRequest(con
, NULL
, no_contentW
, NULL
, NULL
, NULL
, 0);
2530 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2533 SetLastError(0xdeadbeef);
2534 ret
= WinHttpQueryDataAvailable(req
, &size
);
2536 ok(!ret
, "expected error\n");
2537 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
,
2538 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2539 ok(size
== 12345 || broken(size
== 0) /* Win <= 2003 */,
2540 "expected 12345, got %u\n", size
);
2543 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2544 ok(ret
, "expected success\n");
2546 ret
= WinHttpReceiveResponse(req
, NULL
);
2547 ok(ret
, "expected success\n");
2549 status
= 0xdeadbeef;
2550 size
= sizeof(status
);
2551 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2552 NULL
, &status
, &size
, NULL
);
2553 ok(ret
, "expected success\n");
2554 ok(status
== HTTP_STATUS_NO_CONTENT
, "expected status 204, got %d\n", status
);
2556 SetLastError(0xdeadbeef);
2557 size
= sizeof(status
);
2559 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2560 NULL
, &status
, &size
, 0);
2561 ok(!ret
, "expected no content-length header\n");
2562 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError());
2563 ok(status
== 12345, "expected 0, got %d\n", status
);
2565 SetLastError(0xdeadbeef);
2567 ret
= WinHttpQueryDataAvailable(req
, &size
);
2568 ok(ret
, "expected success\n");
2569 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2570 "wrong error %u\n", GetLastError());
2571 ok(!size
, "expected 0, got %u\n", size
);
2573 SetLastError(0xdeadbeef);
2574 ret
= WinHttpReadData(req
, buf
, len
, &bytes_read
);
2575 ok(ret
, "expected success\n");
2576 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2577 "wrong error %u\n", GetLastError());
2578 ok(!bytes_read
, "expected 0, got %u\n", bytes_read
);
2581 ret
= WinHttpQueryDataAvailable(req
, &size
);
2582 ok(ret
, "expected success\n");
2583 ok(size
== 0, "expected 0, got %d\n", size
);
2585 WinHttpCloseHandle(req
);
2588 SetLastError(0xdeadbeef);
2589 ret
= WinHttpQueryDataAvailable(req
, &size
);
2590 ok(!ret
, "expected error\n");
2591 ok(GetLastError() == ERROR_INVALID_HANDLE
,
2592 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2593 ok(size
== 12345, "expected 12345, got %u\n", size
);
2595 WinHttpCloseHandle(con
);
2596 WinHttpCloseHandle(ses
);
2599 static void test_head_request(int port
)
2601 static const WCHAR verbW
[] = {'H','E','A','D',0};
2602 static const WCHAR headW
[] = {'/','h','e','a','d',0};
2603 HINTERNET ses
, con
, req
;
2605 DWORD size
, len
, count
, status
;
2608 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2609 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2611 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2612 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2614 req
= WinHttpOpenRequest(con
, verbW
, headW
, NULL
, NULL
, NULL
, 0);
2615 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2617 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2618 ok(ret
, "failed to send request %u\n", GetLastError());
2620 ret
= WinHttpReceiveResponse(req
, NULL
);
2621 ok(ret
, "failed to receive response %u\n", GetLastError());
2623 status
= 0xdeadbeef;
2624 size
= sizeof(status
);
2625 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2626 NULL
, &status
, &size
, NULL
);
2627 ok(ret
, "failed to get status code %u\n", GetLastError());
2628 ok(status
== HTTP_STATUS_OK
, "got %u\n", status
);
2632 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2633 NULL
, &len
, &size
, 0);
2634 ok(ret
, "failed to get content-length header %u\n", GetLastError());
2635 ok(len
== HTTP_STATUS_CONTINUE
, "got %u\n", len
);
2638 ret
= WinHttpQueryDataAvailable(req
, &count
);
2639 ok(ret
, "failed to query data available %u\n", GetLastError());
2640 ok(!count
, "got %u\n", count
);
2644 ret
= WinHttpReadData(req
, buf
, len
, &count
);
2645 ok(ret
, "failed to read data %u\n", GetLastError());
2646 ok(!count
, "got %u\n", count
);
2649 ret
= WinHttpQueryDataAvailable(req
, &count
);
2650 ok(ret
, "failed to query data available %u\n", GetLastError());
2651 ok(!count
, "got %u\n", count
);
2653 WinHttpCloseHandle(req
);
2654 WinHttpCloseHandle(con
);
2655 WinHttpCloseHandle(ses
);
2658 static void test_not_modified(int port
)
2660 static const WCHAR pathW
[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2661 static const WCHAR ifmodifiedW
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2662 static const WCHAR ifmodified2W
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2664 HINTERNET session
, request
, connection
;
2665 DWORD index
, len
, status
, size
, start
= GetTickCount();
2667 WCHAR today
[(sizeof(ifmodifiedW
) + WINHTTP_TIME_FORMAT_BUFSIZE
)/sizeof(WCHAR
) + 3], buffer
[32];
2669 memcpy(today
, ifmodifiedW
, sizeof(ifmodifiedW
));
2671 WinHttpTimeFromSystemTime(&st
, &today
[sizeof(ifmodifiedW
)/sizeof(WCHAR
)]);
2673 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
,
2674 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
2675 ok(session
!= NULL
, "WinHttpOpen failed: %u\n", GetLastError());
2677 connection
= WinHttpConnect(session
, localhostW
, port
, 0);
2678 ok(connection
!= NULL
, "WinHttpConnect failed: %u\n", GetLastError());
2680 request
= WinHttpOpenRequest(connection
, NULL
, pathW
, NULL
, WINHTTP_NO_REFERER
,
2681 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
2682 ok(request
!= NULL
, "WinHttpOpenrequest failed: %u\n", GetLastError());
2684 ret
= WinHttpSendRequest(request
, today
, 0, NULL
, 0, 0, 0);
2685 ok(ret
, "WinHttpSendRequest failed: %u\n", GetLastError());
2687 ret
= WinHttpReceiveResponse(request
, NULL
);
2688 ok(ret
, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2691 len
= sizeof(buffer
);
2692 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2693 ifmodified2W
, buffer
, &len
, &index
);
2694 ok(ret
, "failed to get header %u\n", GetLastError());
2696 status
= 0xdeadbeef;
2697 size
= sizeof(status
);
2698 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
,
2699 NULL
, &status
, &size
, NULL
);
2700 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2701 ok(status
== HTTP_STATUS_NOT_MODIFIED
, "got %u\n", status
);
2704 ret
= WinHttpQueryDataAvailable(request
, &size
);
2705 ok(ret
, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2706 ok(!size
, "got %u\n", size
);
2708 WinHttpCloseHandle(request
);
2709 WinHttpCloseHandle(connection
);
2710 WinHttpCloseHandle(session
);
2711 start
= GetTickCount() - start
;
2712 ok(start
<= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start
);
2715 static void test_bad_header( int port
)
2717 static const WCHAR bad_headerW
[] =
2718 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2719 't','e','x','t','/','h','t','m','l','\n','\r',0};
2720 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2721 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2723 HINTERNET ses
, con
, req
;
2727 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2728 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2730 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2731 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2733 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2734 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2736 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2737 ok( ret
, "failed to add header %u\n", GetLastError() );
2741 len
= sizeof(buffer
);
2742 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2743 content_typeW
, buffer
, &len
, &index
);
2744 ok( ret
, "failed to query headers %u\n", GetLastError() );
2745 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2747 WinHttpCloseHandle( req
);
2748 WinHttpCloseHandle( con
);
2749 WinHttpCloseHandle( ses
);
2752 static void test_multiple_reads(int port
)
2754 static const WCHAR bigW
[] = {'b','i','g',0};
2755 HINTERNET ses
, con
, req
;
2756 DWORD total_len
= 0;
2759 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2760 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2762 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2763 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2765 req
= WinHttpOpenRequest(con
, NULL
, bigW
, NULL
, NULL
, NULL
, 0);
2766 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2768 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2769 ok(ret
, "failed to send request %u\n", GetLastError());
2771 ret
= WinHttpReceiveResponse(req
, NULL
);
2772 ok(ret
== TRUE
, "expected success\n");
2776 DWORD len
= 0xdeadbeef;
2777 ret
= WinHttpQueryDataAvailable( req
, &len
);
2778 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2779 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2783 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
2785 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
2786 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
2788 HeapFree( GetProcessHeap(), 0, buf
);
2789 if (!bytes_read
) break;
2790 total_len
+= bytes_read
;
2794 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
2796 WinHttpCloseHandle(req
);
2797 WinHttpCloseHandle(con
);
2798 WinHttpCloseHandle(ses
);
2801 static void test_cookies( int port
)
2803 static const WCHAR cookieW
[] = {'/','c','o','o','k','i','e',0};
2804 static const WCHAR cookie2W
[] = {'/','c','o','o','k','i','e','2',0};
2805 static const WCHAR cookie3W
[] = {'/','c','o','o','k','i','e','3',0};
2806 static const WCHAR cookieheaderW
[] =
2807 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2808 HINTERNET ses
, con
, req
;
2812 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2813 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2815 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2816 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2818 req
= WinHttpOpenRequest( con
, NULL
, cookieW
, NULL
, NULL
, NULL
, 0 );
2819 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2821 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2822 ok( ret
, "failed to send request %u\n", GetLastError() );
2824 ret
= WinHttpReceiveResponse( req
, NULL
);
2825 ok( ret
, "failed to receive response %u\n", GetLastError() );
2827 status
= 0xdeadbeef;
2828 size
= sizeof(status
);
2829 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2830 ok( ret
, "failed to query status code %u\n", GetLastError() );
2831 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2833 WinHttpCloseHandle( req
);
2835 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2836 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2838 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2839 ok( ret
, "failed to send request %u\n", GetLastError() );
2841 ret
= WinHttpReceiveResponse( req
, NULL
);
2842 ok( ret
, "failed to receive response %u\n", GetLastError() );
2844 status
= 0xdeadbeef;
2845 size
= sizeof(status
);
2846 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2847 ok( ret
, "failed to query status code %u\n", GetLastError() );
2848 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2850 WinHttpCloseHandle( req
);
2851 WinHttpCloseHandle( con
);
2853 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2854 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2856 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2857 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2859 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2860 ok( ret
, "failed to send request %u\n", GetLastError() );
2862 ret
= WinHttpReceiveResponse( req
, NULL
);
2863 ok( ret
, "failed to receive response %u\n", GetLastError() );
2865 status
= 0xdeadbeef;
2866 size
= sizeof(status
);
2867 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2868 ok( ret
, "failed to query status code %u\n", GetLastError() );
2869 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2871 WinHttpCloseHandle( req
);
2873 req
= WinHttpOpenRequest( con
, NULL
, cookie3W
, NULL
, NULL
, NULL
, 0 );
2874 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2876 ret
= WinHttpSendRequest( req
, cookieheaderW
, ~0u, NULL
, 0, 0, 0 );
2877 ok( ret
, "failed to send request %u\n", GetLastError() );
2879 ret
= WinHttpReceiveResponse( req
, NULL
);
2880 ok( ret
, "failed to receive response %u\n", GetLastError() );
2882 status
= 0xdeadbeef;
2883 size
= sizeof(status
);
2884 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2885 ok( ret
, "failed to query status code %u\n", GetLastError() );
2886 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
), "request failed unexpectedly %u\n", status
);
2888 WinHttpCloseHandle( req
);
2889 WinHttpCloseHandle( con
);
2890 WinHttpCloseHandle( ses
);
2892 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2893 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2895 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2896 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2898 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2899 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2901 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2902 ok( ret
, "failed to send request %u\n", GetLastError() );
2904 ret
= WinHttpReceiveResponse( req
, NULL
);
2905 ok( ret
, "failed to receive response %u\n", GetLastError() );
2907 status
= 0xdeadbeef;
2908 size
= sizeof(status
);
2909 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2910 ok( ret
, "failed to query status code %u\n", GetLastError() );
2911 ok( status
== HTTP_STATUS_BAD_REQUEST
, "request failed unexpectedly %u\n", status
);
2913 WinHttpCloseHandle( req
);
2914 WinHttpCloseHandle( con
);
2915 WinHttpCloseHandle( ses
);
2918 static void test_connection_info( int port
)
2920 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2921 HINTERNET ses
, con
, req
;
2922 WINHTTP_CONNECTION_INFO info
;
2926 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2927 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2929 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2930 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2932 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
2933 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2935 size
= sizeof(info
);
2936 SetLastError( 0xdeadbeef );
2937 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2938 error
= GetLastError();
2939 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
2941 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2944 ok( !ret
, "unexpected success\n" );
2945 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
2947 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2948 ok( ret
, "failed to send request %u\n", GetLastError() );
2951 SetLastError( 0xdeadbeef );
2952 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2953 error
= GetLastError();
2954 ok( !ret
, "unexpected success\n" );
2955 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
2957 size
= sizeof(info
);
2958 memset( &info
, 0, sizeof(info
) );
2959 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2960 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2961 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
2963 ret
= WinHttpReceiveResponse( req
, NULL
);
2964 ok( ret
, "failed to receive response %u\n", GetLastError() );
2966 size
= sizeof(info
);
2967 memset( &info
, 0, sizeof(info
) );
2968 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2969 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2970 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
2972 WinHttpCloseHandle( req
);
2973 WinHttpCloseHandle( con
);
2974 WinHttpCloseHandle( ses
);
2977 static void test_credentials(void)
2979 static WCHAR userW
[] = {'u','s','e','r',0};
2980 static WCHAR passW
[] = {'p','a','s','s',0};
2981 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
2982 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
2983 HINTERNET ses
, con
, req
;
2988 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
2989 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2991 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
2992 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2994 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2995 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2997 size
= sizeof(buffer
)/sizeof(WCHAR
);
2998 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
2999 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3000 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3001 ok(!size
, "expected 0, got %u\n", size
);
3003 size
= sizeof(buffer
)/sizeof(WCHAR
);
3004 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3005 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3006 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3007 ok(!size
, "expected 0, got %u\n", size
);
3009 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
3010 ok(ret
, "failed to set username %u\n", GetLastError());
3012 size
= sizeof(buffer
)/sizeof(WCHAR
);
3013 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3014 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3015 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3016 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3018 size
= sizeof(buffer
)/sizeof(WCHAR
);
3019 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3020 ok(ret
, "failed to query username %u\n", GetLastError());
3021 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3022 ok(!size
, "expected 0, got %u\n", size
);
3024 size
= sizeof(buffer
)/sizeof(WCHAR
);
3025 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3026 ok(ret
, "failed to query password %u\n", GetLastError());
3027 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3028 ok(!size
, "expected 0, got %u\n", size
);
3030 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
3031 ok(ret
, "failed to set proxy password %u\n", GetLastError());
3033 size
= sizeof(buffer
)/sizeof(WCHAR
);
3034 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3035 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3036 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3037 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3039 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
3040 ok(ret
, "failed to set username %u\n", GetLastError());
3042 size
= sizeof(buffer
)/sizeof(WCHAR
);
3043 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3044 ok(ret
, "failed to query username %u\n", GetLastError());
3045 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3046 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3048 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
3049 ok(ret
, "failed to set password %u\n", GetLastError());
3051 size
= sizeof(buffer
)/sizeof(WCHAR
);
3052 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3053 ok(ret
, "failed to query password %u\n", GetLastError());
3054 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3055 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3057 WinHttpCloseHandle(req
);
3059 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3060 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3062 SetLastError(0xdeadbeef);
3063 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
3064 error
= GetLastError();
3065 ok(!ret
, "expected failure\n");
3066 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3068 SetLastError(0xdeadbeef);
3069 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
3070 error
= GetLastError();
3071 ok(!ret
, "expected failure\n");
3072 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3074 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
3075 ok(ret
, "failed to set credentials %u\n", GetLastError());
3077 size
= sizeof(buffer
)/sizeof(WCHAR
);
3078 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3079 ok(ret
, "failed to query username %u\n", GetLastError());
3081 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3082 ok(!size
, "expected 0, got %u\n", size
);
3085 size
= sizeof(buffer
)/sizeof(WCHAR
);
3086 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3087 ok(ret
, "failed to query password %u\n", GetLastError());
3089 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3090 ok(!size
, "expected 0, got %u\n", size
);
3093 WinHttpCloseHandle(req
);
3094 WinHttpCloseHandle(con
);
3095 WinHttpCloseHandle(ses
);
3098 static void test_IWinHttpRequest(int port
)
3100 static const WCHAR data_start
[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3101 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
3102 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
3103 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3104 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3105 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3106 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3107 static const WCHAR method1W
[] = {'G','E','T',0};
3108 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
3109 static const WCHAR method3W
[] = {'P','O','S','T',0};
3110 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3111 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
3112 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
3113 static const WCHAR dateW
[] = {'D','a','t','e',0};
3114 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
3115 static const WCHAR utf8W
[] = {'u','t','f','-','8',0};
3116 static const WCHAR unauthW
[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3118 IWinHttpRequest
*req
;
3119 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
3120 BSTR date
, today
, connection
, value
= NULL
;
3121 VARIANT async
, empty
, timeout
, body
, body2
, proxy_server
, bypass_list
, data
, cp
;
3122 VARIANT_BOOL succeeded
;
3124 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
3126 IStream
*stream
, *stream2
;
3132 GetSystemTime( &st
);
3133 WinHttpTimeFromSystemTime( &st
, todayW
);
3135 CoInitialize( NULL
);
3136 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3137 ok( hr
== S_OK
, "got %08x\n", hr
);
3139 V_VT( &empty
) = VT_ERROR
;
3140 V_ERROR( &empty
) = 0xdeadbeef;
3142 V_VT( &async
) = VT_BOOL
;
3143 V_BOOL( &async
) = VARIANT_FALSE
;
3145 method
= SysAllocString( method3W
);
3146 url
= SysAllocString( url3W
);
3147 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3148 ok( hr
== S_OK
, "got %08x\n", hr
);
3149 SysFreeString( method
);
3150 SysFreeString( url
);
3152 V_VT( &data
) = VT_BSTR
;
3153 V_BSTR( &data
) = SysAllocString( test_dataW
);
3154 hr
= IWinHttpRequest_Send( req
, data
);
3155 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
3157 SysFreeString( V_BSTR( &data
) );
3159 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
3160 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3162 method
= SysAllocString( method1W
);
3163 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
3164 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3166 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
3167 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3169 url
= SysAllocString( url1W
);
3170 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
3171 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3173 hr
= IWinHttpRequest_Abort( req
);
3174 ok( hr
== S_OK
, "got %08x\n", hr
);
3176 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
3177 ok( hr
== S_OK
, "got %08x\n", hr
);
3179 hr
= IWinHttpRequest_Abort( req
);
3180 ok( hr
== S_OK
, "got %08x\n", hr
);
3182 IWinHttpRequest_Release( req
);
3184 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3185 ok( hr
== S_OK
, "got %08x\n", hr
);
3187 SysFreeString( url
);
3188 url
= SysAllocString( url2W
);
3189 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3190 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3192 SysFreeString( method
);
3193 method
= SysAllocString( method2W
);
3194 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3195 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3197 SysFreeString( method
);
3198 method
= SysAllocString( method1W
);
3199 SysFreeString( url
);
3200 url
= SysAllocString( url1W
);
3201 V_VT( &async
) = VT_ERROR
;
3202 V_ERROR( &async
) = DISP_E_PARAMNOTFOUND
;
3203 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3204 ok( hr
== S_OK
, "got %08x\n", hr
);
3206 V_VT( &cp
) = VT_ERROR
;
3207 V_ERROR( &cp
) = 0xdeadbeef;
3208 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3209 ok( hr
== S_OK
, "got %08x\n", hr
);
3210 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3211 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3213 V_VT( &cp
) = VT_UI4
;
3214 V_UI4( &cp
) = CP_ACP
;
3215 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3216 ok( hr
== S_OK
, "got %08x\n", hr
);
3218 V_VT( &cp
) = VT_ERROR
;
3219 V_ERROR( &cp
) = 0xdeadbeef;
3220 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3221 ok( hr
== S_OK
, "got %08x\n", hr
);
3222 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3223 ok( V_I4( &cp
) == CP_ACP
, "got %u\n", V_I4( &cp
) );
3225 value
= SysAllocString( utf8W
);
3226 V_VT( &cp
) = VT_BSTR
;
3227 V_BSTR( &cp
) = value
;
3228 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3229 ok( hr
== S_OK
, "got %08x\n", hr
);
3230 SysFreeString( value
);
3232 V_VT( &cp
) = VT_ERROR
;
3233 V_ERROR( &cp
) = 0xdeadbeef;
3234 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3235 ok( hr
== S_OK
, "got %08x\n", hr
);
3236 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3237 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3239 hr
= IWinHttpRequest_Abort( req
);
3240 ok( hr
== S_OK
, "got %08x\n", hr
);
3242 hr
= IWinHttpRequest_Send( req
, empty
);
3243 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3245 hr
= IWinHttpRequest_Abort( req
);
3246 ok( hr
== S_OK
, "got %08x\n", hr
);
3248 IWinHttpRequest_Release( req
);
3250 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3251 ok( hr
== S_OK
, "got %08x\n", hr
);
3253 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3254 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3256 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3257 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3259 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3260 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3262 hr
= IWinHttpRequest_get_Status( req
, &status
);
3263 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3265 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3266 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3268 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3269 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3271 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3272 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3274 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3275 ok( hr
== S_OK
, "got %08x\n", hr
);
3277 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3278 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3280 VariantInit( &proxy_server
);
3281 V_VT( &proxy_server
) = VT_ERROR
;
3282 VariantInit( &bypass_list
);
3283 V_VT( &bypass_list
) = VT_ERROR
;
3284 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3285 ok( hr
== S_OK
, "got %08x\n", hr
);
3287 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3288 ok( hr
== S_OK
, "got %08x\n", hr
);
3290 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3291 ok( hr
== S_OK
, "got %08x\n", hr
);
3293 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3294 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3296 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3297 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3299 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3300 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3302 connection
= SysAllocString( connectionW
);
3303 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3304 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3306 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3307 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3309 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
3310 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3312 date
= SysAllocString( dateW
);
3313 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3314 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3316 today
= SysAllocString( todayW
);
3317 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3318 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3320 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
3321 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3323 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3324 ok( hr
== S_OK
, "got %08x\n", hr
);
3326 SysFreeString( method
);
3327 method
= SysAllocString( method1W
);
3328 SysFreeString( url
);
3329 url
= SysAllocString( url1W
);
3330 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3331 ok( hr
== S_OK
, "got %08x\n", hr
);
3333 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3334 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3336 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3337 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3339 hr
= IWinHttpRequest_get_Status( req
, &status
);
3340 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3342 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3343 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3345 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3346 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3348 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3349 ok( hr
== S_OK
, "got %08x\n", hr
);
3351 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3352 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3354 username
= SysAllocString( usernameW
);
3355 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
3356 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3358 password
= SysAllocString( passwordW
);
3359 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
3360 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3362 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
3363 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3365 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3366 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3368 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3369 ok( hr
== S_OK
, "got %08x\n", hr
);
3371 V_VT( &proxy_server
) = VT_BSTR
;
3372 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
3373 V_VT( &bypass_list
) = VT_BSTR
;
3374 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
3375 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3376 ok( hr
== S_OK
, "got %08x\n", hr
);
3378 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
3379 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3381 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3382 ok( hr
== S_OK
, "got %08x\n", hr
);
3384 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3385 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3387 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3388 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3390 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3391 ok( hr
== S_OK
, "got %08x\n", hr
);
3393 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3394 ok( hr
== S_OK
, "got %08x\n", hr
);
3396 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3397 ok( hr
== S_OK
, "got %08x\n", hr
);
3399 hr
= IWinHttpRequest_Send( req
, empty
);
3400 ok( hr
== S_OK
, "got %08x\n", hr
);
3402 hr
= IWinHttpRequest_Send( req
, empty
);
3403 ok( hr
== S_OK
, "got %08x\n", hr
);
3405 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3406 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3408 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3409 ok( hr
== S_OK
, "got %08x\n", hr
);
3410 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3411 SysFreeString( response
);
3413 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3414 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3417 hr
= IWinHttpRequest_get_Status( req
, &status
);
3418 ok( hr
== S_OK
, "got %08x\n", hr
);
3419 trace("Status=%d\n", status
);
3421 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3422 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3424 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3425 ok( hr
== S_OK
, "got %08x\n", hr
);
3426 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
3427 SysFreeString( status_text
);
3429 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3430 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3432 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3433 ok( hr
== S_OK
, "got %08x\n", hr
);
3435 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3436 ok( hr
== S_OK
, "got %08x\n", hr
);
3438 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3439 ok( hr
== S_OK
, "got %08x\n", hr
);
3441 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3442 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3444 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3445 ok( hr
== S_OK
, "got %08x\n", hr
);
3446 SysFreeString( headers
);
3448 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3449 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3451 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3452 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3454 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3455 ok( hr
== S_OK
, "got %08x\n", hr
);
3456 SysFreeString( value
);
3458 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3459 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3461 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3462 ok( hr
== S_OK
, "got %08x\n", hr
);
3464 VariantInit( &timeout
);
3465 V_VT( &timeout
) = VT_I4
;
3466 V_I4( &timeout
) = 10;
3467 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3468 ok( hr
== S_OK
, "got %08x\n", hr
);
3470 hr
= IWinHttpRequest_get_Status( req
, &status
);
3471 ok( hr
== S_OK
, "got %08x\n", hr
);
3473 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3474 ok( hr
== S_OK
, "got %08x\n", hr
);
3475 SysFreeString( status_text
);
3477 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3478 ok( hr
== S_OK
, "got %08x\n", hr
);
3480 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3481 ok( hr
== S_OK
, "got %08x\n", hr
);
3483 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3484 ok( hr
== S_OK
, "got %08x\n", hr
);
3486 hr
= IWinHttpRequest_Send( req
, empty
);
3487 ok( hr
== S_OK
, "got %08x\n", hr
);
3489 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3490 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3492 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3493 ok( hr
== S_OK
, "got %08x\n", hr
);
3494 SysFreeString( response
);
3496 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3497 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3499 VariantInit( &body
);
3500 V_VT( &body
) = VT_ERROR
;
3501 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
3502 ok( hr
== S_OK
, "got %08x\n", hr
);
3503 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
3505 hr
= VariantClear( &body
);
3506 ok( hr
== S_OK
, "got %08x\n", hr
);
3508 VariantInit( &body
);
3509 V_VT( &body
) = VT_ERROR
;
3510 hr
= IWinHttpRequest_get_ResponseStream( req
, &body
);
3511 ok( hr
== S_OK
, "got %08x\n", hr
);
3512 ok( V_VT( &body
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body
) );
3514 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body
), &IID_IStream
, (void **)&stream
);
3515 ok( hr
== S_OK
, "got %08x\n", hr
);
3516 ok( V_UNKNOWN( &body
) == (IUnknown
*)stream
, "got different interface pointer\n" );
3520 hr
= IStream_Read( stream
, buf
, 128, &count
);
3521 ok( hr
== S_OK
, "got %08x\n", hr
);
3522 ok( count
!= 0xdeadbeef, "count not set\n" );
3523 ok( buf
[0], "no data\n" );
3525 VariantInit( &body2
);
3526 V_VT( &body2
) = VT_ERROR
;
3527 hr
= IWinHttpRequest_get_ResponseStream( req
, &body2
);
3528 ok( hr
== S_OK
, "got %08x\n", hr
);
3529 ok( V_VT( &body2
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body2
) );
3530 ok( V_UNKNOWN( &body
) != V_UNKNOWN( &body2
), "got same interface pointer\n" );
3532 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body2
), &IID_IStream
, (void **)&stream2
);
3533 ok( hr
== S_OK
, "got %08x\n", hr
);
3534 ok( V_UNKNOWN( &body2
) == (IUnknown
*)stream2
, "got different interface pointer\n" );
3535 IStream_Release( stream2
);
3537 hr
= VariantClear( &body
);
3538 ok( hr
== S_OK
, "got %08x\n", hr
);
3540 hr
= VariantClear( &body2
);
3541 ok( hr
== S_OK
, "got %08x\n", hr
);
3543 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3544 ok( hr
== S_OK
, "got %08x\n", hr
);
3546 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3547 ok( hr
== S_OK
, "got %08x\n", hr
);
3549 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3550 ok( hr
== S_OK
, "got %08x\n", hr
);
3551 SysFreeString( headers
);
3553 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3554 ok( hr
== S_OK
, "got %08x\n", hr
);
3555 SysFreeString( value
);
3557 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3558 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3560 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3561 ok( hr
== S_OK
, "got %08x\n", hr
);
3563 hr
= IWinHttpRequest_Send( req
, empty
);
3564 ok( hr
== S_OK
, "got %08x\n", hr
);
3566 hr
= IWinHttpRequest_Abort( req
);
3567 ok( hr
== S_OK
, "got %08x\n", hr
);
3569 hr
= IWinHttpRequest_Abort( req
);
3570 ok( hr
== S_OK
, "got %08x\n", hr
);
3572 IWinHttpRequest_Release( req
);
3575 hr
= IStream_Seek( stream
, pos
, STREAM_SEEK_SET
, NULL
);
3576 ok( hr
== S_OK
, "got %08x\n", hr
);
3580 hr
= IStream_Read( stream
, buf
, 128, &count
);
3581 ok( hr
== S_OK
, "got %08x\n", hr
);
3582 ok( count
!= 0xdeadbeef, "count not set\n" );
3583 ok( buf
[0], "no data\n" );
3584 IStream_Release( stream
);
3586 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3587 ok( hr
== S_OK
, "got %08x\n", hr
);
3589 V_VT( &async
) = VT_I4
;
3591 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3592 ok( hr
== S_OK
, "got %08x\n", hr
);
3594 hr
= IWinHttpRequest_Send( req
, empty
);
3595 ok( hr
== S_OK
, "got %08x\n", hr
);
3597 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3598 ok( hr
== S_OK
, "got %08x\n", hr
);
3600 IWinHttpRequest_Release( req
);
3602 SysFreeString( method
);
3603 SysFreeString( url
);
3604 SysFreeString( username
);
3605 SysFreeString( password
);
3606 SysFreeString( connection
);
3607 SysFreeString( date
);
3608 SysFreeString( today
);
3609 VariantClear( &proxy_server
);
3610 VariantClear( &bypass_list
);
3612 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3613 ok( hr
== S_OK
, "got %08x\n", hr
);
3615 url
= SysAllocString( test_winehq_https
);
3616 method
= SysAllocString( method3W
);
3617 V_VT( &async
) = VT_BOOL
;
3618 V_BOOL( &async
) = VARIANT_FALSE
;
3619 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3620 ok( hr
== S_OK
, "got %08x\n", hr
);
3621 SysFreeString( method
);
3622 SysFreeString( url
);
3624 hr
= IWinHttpRequest_Send( req
, empty
);
3625 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)), "got %08x\n", hr
);
3628 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3629 ok( hr
== S_OK
, "got %08x\n", hr
);
3630 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3631 SysFreeString( response
);
3634 IWinHttpRequest_Release( req
);
3636 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3637 ok( hr
== S_OK
, "got %08x\n", hr
);
3639 sprintf( buf
, "http://localhost:%d/auth", port
);
3640 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, bufW
, sizeof(bufW
)/sizeof(bufW
[0]) );
3641 url
= SysAllocString( bufW
);
3642 method
= SysAllocString( method3W
);
3643 V_VT( &async
) = VT_BOOL
;
3644 V_BOOL( &async
) = VARIANT_FALSE
;
3645 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3646 ok( hr
== S_OK
, "got %08x\n", hr
);
3647 SysFreeString( method
);
3648 SysFreeString( url
);
3650 hr
= IWinHttpRequest_get_Status( req
, &status
);
3651 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3653 V_VT( &data
) = VT_BSTR
;
3654 V_BSTR( &data
) = SysAllocString( test_dataW
);
3655 hr
= IWinHttpRequest_Send( req
, data
);
3656 ok( hr
== S_OK
, "got %08x\n", hr
);
3657 SysFreeString( V_BSTR( &data
) );
3659 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3660 ok( hr
== S_OK
, "got %08x\n", hr
);
3661 ok( !memcmp( response
, unauthW
, sizeof(unauthW
) ), "got %s\n", wine_dbgstr_w(response
) );
3662 SysFreeString( response
);
3664 status
= 0xdeadbeef;
3665 hr
= IWinHttpRequest_get_Status( req
, &status
);
3666 ok( hr
== S_OK
, "got %08x\n", hr
);
3667 ok( status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
3669 IWinHttpRequest_Release( req
);
3674 static void request_get_property(IWinHttpRequest
*request
, int property
, VARIANT
*ret
)
3680 memset(¶ms
, 0, sizeof(params
));
3681 params
.cNamedArgs
= 0;
3682 params
.rgdispidNamedArgs
= NULL
;
3684 params
.rgvarg
= &arg
;
3687 V_I4(&arg
) = property
;
3689 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3690 DISPATCH_PROPERTYGET
, ¶ms
, ret
, NULL
, NULL
);
3691 ok(hr
== S_OK
, "error %#x\n", hr
);
3694 static void test_IWinHttpRequest_Invoke(void)
3696 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
3697 static const WCHAR regid
[] = {'W','i','n','H','t','t','p','.','W','i','n','H','t','t','p','R','e','q','u','e','s','t','.','5','.','1',0};
3698 WCHAR openW
[] = {'O','p','e','n',0};
3699 WCHAR optionW
[] = {'O','p','t','i','o','n',0};
3700 OLECHAR
*open
= openW
, *option
= optionW
;
3703 IWinHttpRequest
*request
;
3704 IDispatch
*dispatch
;
3707 VARIANT arg
[3], ret
;
3714 hr
= CLSIDFromProgID(regid
, &clsid
);
3715 ok(hr
== S_OK
, "CLSIDFromProgID error %#x\n", hr
);
3716 bret
= IsEqualIID(&clsid
, &CLSID_WinHttpRequest
);
3717 ok(bret
|| broken(!bret
) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid
));
3719 hr
= CoCreateInstance(&CLSID_WinHttpRequest
, 0, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&request
);
3720 ok(hr
== S_OK
, "error %#x\n", hr
);
3722 hr
= IWinHttpRequest_QueryInterface(request
, &IID_IDispatch
, (void **)&dispatch
);
3723 ok(hr
== S_OK
, "error %#x\n", hr
);
3724 IDispatch_Release(dispatch
);
3726 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &open
, 1, 0x0409, &id
);
3727 ok(hr
== S_OK
, "error %#x\n", hr
);
3728 ok(id
== DISPID_HTTPREQUEST_OPEN
, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id
);
3730 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &option
, 1, 0x0409, &id
);
3731 ok(hr
== S_OK
, "error %#x\n", hr
);
3732 ok(id
== DISPID_HTTPREQUEST_OPTION
, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id
);
3734 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3735 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3736 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3738 memset(¶ms
, 0, sizeof(params
));
3740 params
.cNamedArgs
= 0;
3741 params
.rgvarg
= arg
;
3742 V_VT(&arg
[0]) = VT_I4
;
3743 V_I4(&arg
[0]) = 1252;
3744 V_VT(&arg
[1]) = VT_R8
;
3745 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3747 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3748 DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3749 ok(hr
== S_OK
, "error %#x\n", hr
);
3751 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3752 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3753 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3755 memset(¶ms
, 0, sizeof(params
));
3757 params
.cNamedArgs
= 0;
3758 params
.rgvarg
= arg
;
3759 V_VT(&arg
[0]) = VT_I4
;
3760 V_I4(&arg
[0]) = 1252;
3761 V_VT(&arg
[1]) = VT_R8
;
3762 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3764 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3765 DISPATCH_METHOD
| DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3766 ok(hr
== S_OK
, "error %#x\n", hr
);
3768 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3769 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3770 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3772 memset(¶ms
, 0, sizeof(params
));
3774 params
.cNamedArgs
= 0;
3775 params
.rgvarg
= arg
;
3776 V_VT(&arg
[0]) = VT_I4
;
3777 V_I4(&arg
[0]) = 1252;
3778 V_VT(&arg
[1]) = VT_R8
;
3779 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3781 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3782 DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3783 ok(hr
== S_OK
, "error %#x\n", hr
);
3785 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3786 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3787 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3789 memset(¶ms
, 0, sizeof(params
));
3791 params
.cNamedArgs
= 0;
3792 params
.rgvarg
= arg
;
3793 V_VT(&arg
[0]) = VT_BSTR
;
3794 utf8
= SysAllocString(utf8W
);
3795 V_BSTR(&arg
[0]) = utf8
;
3796 V_VT(&arg
[1]) = VT_R8
;
3797 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3798 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3799 ok(hr
== S_OK
, "error %#x\n", hr
);
3801 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3802 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3803 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3806 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, &err
);
3807 ok(hr
== S_OK
, "error %#x\n", hr
);
3809 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3810 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3811 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3814 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3815 ok(hr
== S_OK
, "error %#x\n", hr
);
3817 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3818 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3819 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3821 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
3822 ok(hr
== S_OK
, "error %#x\n", hr
);
3824 hr
= IWinHttpRequest_Invoke(request
, 255, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
3825 ok(hr
== DISP_E_MEMBERNOTFOUND
, "error %#x\n", hr
);
3828 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3829 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
3832 if (0) /* crashes */
3834 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, &ret
, NULL
, &err
);
3838 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3839 ok(hr
== DISP_E_TYPEMISMATCH
, "error %#x\n", hr
);
3841 VariantInit(&arg
[2]);
3843 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3845 ok(hr
== S_OK
, "error %#x\n", hr
);
3847 VariantInit(&arg
[0]);
3848 VariantInit(&arg
[1]);
3849 VariantInit(&arg
[2]);
3852 V_VT(&arg
[0]) = VT_I4
;
3853 V_I4(&arg
[0]) = WinHttpRequestOption_URLCodePage
;
3854 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3855 ok(hr
== S_OK
, "error %#x\n", hr
);
3857 V_VT(&ret
) = 0xdead;
3858 V_I4(&ret
) = 0xbeef;
3859 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, &ret
, NULL
, NULL
);
3860 ok(hr
== S_OK
, "error %#x\n", hr
);
3861 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3862 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3864 V_VT(&ret
) = 0xdead;
3865 V_I4(&ret
) = 0xbeef;
3866 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
3867 ok(hr
== S_OK
, "error %#x\n", hr
);
3868 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3869 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3871 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3872 ok(hr
== S_OK
, "error %#x\n", hr
);
3874 V_VT(&ret
) = 0xdead;
3875 V_I4(&ret
) = 0xbeef;
3876 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, &ret
, NULL
, NULL
);
3877 ok(hr
== S_OK
, "error %#x\n", hr
);
3878 ok(V_VT(&ret
) == VT_EMPTY
, "expected VT_EMPTY, got %d\n", V_VT(&ret
));
3879 ok(V_I4(&ret
) == 0xbeef || V_I4(&ret
) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret
));
3881 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, NULL
, NULL
, NULL
);
3882 ok(hr
== S_OK
, "error %#x\n", hr
);
3884 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3885 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
3888 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3890 ok(hr
== S_OK
, "error %#x\n", hr
);
3893 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3894 ok(hr
== DISP_E_PARAMNOTFOUND
, "error %#x\n", hr
);
3896 SysFreeString(utf8
);
3899 V_VT(&arg
[0]) = VT_I4
;
3900 V_I4(&arg
[0]) = AutoLogonPolicy_Never
;
3902 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY
, &IID_NULL
, 0,
3903 DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
3904 ok(hr
== S_OK
, "error %#x\n", hr
);
3906 IWinHttpRequest_Release(request
);
3911 static void test_WinHttpDetectAutoProxyConfigUrl(void)
3917 if (0) /* crashes on some win2k systems */
3919 SetLastError(0xdeadbeef);
3920 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
3921 error
= GetLastError();
3922 ok( !ret
, "expected failure\n" );
3923 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3926 SetLastError(0xdeadbeef);
3927 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
3928 error
= GetLastError();
3929 ok( !ret
, "expected failure\n" );
3930 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3932 if (0) /* crashes on some win2k systems */
3934 SetLastError(0xdeadbeef);
3935 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
3936 error
= GetLastError();
3937 ok( !ret
, "expected failure\n" );
3938 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3940 url
= (WCHAR
*)0xdeadbeef;
3941 SetLastError(0xdeadbeef);
3942 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
3943 error
= GetLastError();
3946 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
3947 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
3951 trace("%s\n", wine_dbgstr_w(url
));
3955 url
= (WCHAR
*)0xdeadbeef;
3956 SetLastError(0xdeadbeef);
3957 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
3958 error
= GetLastError();
3961 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
3962 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
3966 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
3967 trace("%s\n", wine_dbgstr_w(url
));
3972 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
3976 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
3978 memset( &cfg
, 0, sizeof(cfg
) );
3980 SetLastError(0xdeadbeef);
3981 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
3982 error
= GetLastError();
3983 ok( !ret
, "expected failure\n" );
3984 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3986 SetLastError(0xdeadbeef);
3987 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
3988 error
= GetLastError();
3989 ok( ret
, "expected success\n" );
3990 ok( error
== ERROR_SUCCESS
|| broken(error
== ERROR_NO_TOKEN
) /* < win7 */, "got %u\n", error
);
3992 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
3993 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
3994 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
3995 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
3996 GlobalFree( cfg
.lpszAutoConfigUrl
);
3997 GlobalFree( cfg
.lpszProxy
);
3998 GlobalFree( cfg
.lpszProxyBypass
);
4001 static void test_WinHttpGetProxyForUrl(void)
4003 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4004 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4005 static const WCHAR emptyW
[] = {0};
4009 WINHTTP_AUTOPROXY_OPTIONS options
;
4010 WINHTTP_PROXY_INFO info
;
4012 memset( &options
, 0, sizeof(options
) );
4014 SetLastError(0xdeadbeef);
4015 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
4016 error
= GetLastError();
4017 ok( !ret
, "expected failure\n" );
4018 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
4020 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4021 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
4023 SetLastError(0xdeadbeef);
4024 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
4025 error
= GetLastError();
4026 ok( !ret
, "expected failure\n" );
4027 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4029 SetLastError(0xdeadbeef);
4030 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
4031 error
= GetLastError();
4032 ok( !ret
, "expected failure\n" );
4033 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4035 SetLastError(0xdeadbeef);
4036 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
4037 error
= GetLastError();
4038 ok( !ret
, "expected failure\n" );
4039 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4041 SetLastError(0xdeadbeef);
4042 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4043 error
= GetLastError();
4044 ok( !ret
, "expected failure\n" );
4045 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4047 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4048 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4050 SetLastError(0xdeadbeef);
4051 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
4052 error
= GetLastError();
4053 ok( !ret
, "expected failure\n" );
4054 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4056 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4057 options
.dwAutoDetectFlags
= 0;
4059 SetLastError(0xdeadbeef);
4060 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4061 error
= GetLastError();
4062 ok( !ret
, "expected failure\n" );
4063 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4065 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
4066 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4068 SetLastError(0xdeadbeef);
4069 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4070 error
= GetLastError();
4071 ok( !ret
, "expected failure\n" );
4072 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4074 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4075 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4077 memset( &info
, 0, sizeof(info
) );
4078 SetLastError(0xdeadbeef);
4079 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4080 error
= GetLastError();
4083 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4084 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4085 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4086 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4087 GlobalFree( info
.lpszProxy
);
4088 GlobalFree( info
.lpszProxyBypass
);
4091 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
4092 options
.dwAutoDetectFlags
= 0;
4093 options
.lpszAutoConfigUrl
= wpadW
;
4095 memset( &info
, 0, sizeof(info
) );
4096 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4099 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4100 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4101 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4102 GlobalFree( info
.lpszProxy
);
4103 GlobalFree( info
.lpszProxyBypass
);
4105 WinHttpCloseHandle( session
);
4108 static void test_chunked_read(void)
4110 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4111 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
4114 HINTERNET ses
, con
= NULL
, req
= NULL
;
4117 trace( "starting chunked read test\n" );
4119 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4120 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
4121 if (!ses
) goto done
;
4123 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
4124 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
4125 if (!con
) goto done
;
4127 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
4128 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4129 if (!req
) goto done
;
4131 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
4132 err
= GetLastError();
4133 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
4135 skip("connection failed, skipping\n");
4138 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4140 ret
= WinHttpReceiveResponse( req
, NULL
);
4141 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4144 len
= sizeof(header
);
4145 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
4146 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4147 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
4148 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
4151 len
= sizeof(header
);
4152 SetLastError( 0xdeadbeef );
4153 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
4154 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
4155 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
4157 trace( "entering query loop\n" );
4161 ret
= WinHttpQueryDataAvailable( req
, &len
);
4162 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4163 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4164 trace( "got %u available\n", len
);
4168 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
4170 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
4172 buf
[bytes_read
] = 0;
4173 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
4174 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
4175 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
4177 HeapFree( GetProcessHeap(), 0, buf
);
4178 if (!bytes_read
) break;
4185 if (req
) WinHttpCloseHandle( req
);
4186 if (con
) WinHttpCloseHandle( con
);
4187 if (ses
) WinHttpCloseHandle( ses
);
4190 START_TEST (winhttp
)
4192 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
4193 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
4194 struct server_info si
;
4200 test_WinHttpTimeFromSystemTime();
4201 test_WinHttpTimeToSystemTime();
4202 test_WinHttpAddHeaders();
4203 test_secure_connection();
4204 test_request_parameter_defaults();
4206 test_set_default_proxy_config();
4207 test_empty_headers_param();
4209 test_resolve_timeout();
4211 test_IWinHttpRequest_Invoke();
4212 test_WinHttpDetectAutoProxyConfigUrl();
4213 test_WinHttpGetIEProxyConfigForCurrentUser();
4214 test_WinHttpGetProxyForUrl();
4215 test_chunked_read();
4217 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
4220 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
4221 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
4223 ret
= WaitForSingleObject(si
.event
, 10000);
4224 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
4225 if (ret
!= WAIT_OBJECT_0
)
4228 test_IWinHttpRequest(si
.port
);
4229 test_connection_info(si
.port
);
4230 test_basic_request(si
.port
, NULL
, basicW
);
4231 test_no_headers(si
.port
);
4232 test_no_content(si
.port
);
4233 test_head_request(si
.port
);
4234 test_not_modified(si
.port
);
4235 test_basic_authentication(si
.port
);
4236 test_bad_header(si
.port
);
4237 test_multiple_reads(si
.port
);
4238 test_cookies(si
.port
);
4240 /* send the basic request again to shutdown the server thread */
4241 test_basic_request(si
.port
, NULL
, quitW
);
4243 WaitForSingleObject(thread
, 3000);