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
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1005 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "setting client cert context returned %x (%u)\n", ret
, GetLastError());
1007 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1008 err
= GetLastError();
1009 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
1011 skip("Connection failed, skipping.\n");
1014 ok(ret
, "failed to send request %u\n", GetLastError());
1016 ret
= WinHttpReceiveResponse(req
, NULL
);
1017 ok(ret
, "failed to receive response %u\n", GetLastError());
1019 status
= 0xdeadbeef;
1020 size
= sizeof(status
);
1021 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1022 ok(ret
, "header query failed %u\n", GetLastError());
1023 ok(status
== HTTP_STATUS_BAD_REQUEST
, "got %u\n", status
);
1025 WinHttpCloseHandle(req
);
1027 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
1028 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1030 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1031 ok(ret
, "failed to set client cert context %u\n", GetLastError());
1033 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
1035 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1036 err
= GetLastError();
1037 if (!ret
&& (err
== ERROR_WINHTTP_SECURE_FAILURE
|| err
== ERROR_WINHTTP_CANNOT_CONNECT
||
1038 err
== ERROR_WINHTTP_TIMEOUT
))
1040 skip("secure connection failed, skipping remaining secure tests\n");
1043 ok(ret
, "failed to send request %u\n", GetLastError());
1045 size
= sizeof(cert
);
1046 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1047 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1048 if (ret
) CertFreeCertificateContext(cert
);
1050 size
= sizeof(bitness
);
1051 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
1052 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
1054 size
= sizeof(info
);
1055 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
1056 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
1060 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
1061 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
1062 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
1063 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
1064 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
1065 trace("dwKeySize %u\n", info
.dwKeySize
);
1068 ret
= WinHttpReceiveResponse(req
, NULL
);
1069 ok(ret
, "failed to receive response %u\n", GetLastError());
1072 ret
= WinHttpQueryDataAvailable(req
, &available_size
);
1073 ok(ret
, "failed to query available data %u\n", GetLastError());
1074 ok(available_size
> 2014, "available_size = %u\n", available_size
);
1076 status
= 0xdeadbeef;
1077 size
= sizeof(status
);
1078 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1079 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1080 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1083 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
1084 ok(!ret
, "succeeded unexpectedly\n");
1090 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
1091 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
1095 if (read_size
<= 32)
1096 ok(!memcmp(buffer
, data_start
, sizeof(data_start
)-1), "not expected: %.32s\n", buffer
);
1098 ok(read_size
>= available_size
, "read_size = %u, available_size = %u\n", read_size
, available_size
);
1101 WinHttpCloseHandle(req
);
1102 WinHttpCloseHandle(con
);
1103 WinHttpCloseHandle(ses
);
1106 static void test_request_parameter_defaults(void)
1108 static const WCHAR empty
[] = {0};
1109 HINTERNET ses
, con
, req
;
1110 DWORD size
, status
, error
;
1114 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1115 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1117 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1118 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1120 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1121 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1123 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1124 error
= GetLastError();
1125 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1127 skip("connection failed, skipping\n");
1130 ok(ret
, "failed to send request %u\n", GetLastError());
1132 ret
= WinHttpReceiveResponse(req
, NULL
);
1133 if (!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE
) /* win2k */
1135 win_skip("invalid response\n");
1138 ok(ret
, "failed to receive response %u\n", GetLastError());
1140 status
= 0xdeadbeef;
1141 size
= sizeof(status
);
1142 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1143 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1144 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1146 WinHttpCloseHandle(req
);
1148 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
1149 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1151 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1152 error
= GetLastError();
1153 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1155 skip("connection failed, skipping\n");
1158 ok(ret
, "failed to send request %u\n", GetLastError());
1160 ret
= WinHttpReceiveResponse(req
, NULL
);
1161 ok(ret
, "failed to receive response %u\n", GetLastError());
1164 SetLastError(0xdeadbeef);
1165 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
1166 error
= GetLastError();
1167 ok(!ret
, "succeeded unexpectedly\n");
1168 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
1170 version
= HeapAlloc(GetProcessHeap(), 0, size
);
1171 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
1172 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1173 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
1174 HeapFree(GetProcessHeap(), 0, version
);
1176 status
= 0xdeadbeef;
1177 size
= sizeof(status
);
1178 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1179 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1180 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1183 WinHttpCloseHandle(req
);
1184 WinHttpCloseHandle(con
);
1185 WinHttpCloseHandle(ses
);
1188 static const WCHAR Connections
[] = {
1189 'S','o','f','t','w','a','r','e','\\',
1190 'M','i','c','r','o','s','o','f','t','\\',
1191 'W','i','n','d','o','w','s','\\',
1192 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1193 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1194 'C','o','n','n','e','c','t','i','o','n','s',0 };
1195 static const WCHAR WinHttpSettings
[] = {
1196 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1198 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1204 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1209 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1213 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1223 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1228 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
1229 KEY_WRITE
, NULL
, &key
, NULL
);
1233 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
1235 RegDeleteValueW( key
, WinHttpSettings
);
1240 static void test_set_default_proxy_config(void)
1242 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1243 static WCHAR normalString
[] = { 'f','o','o',0 };
1245 BYTE
*saved_proxy_settings
= NULL
;
1246 WINHTTP_PROXY_INFO info
;
1249 /* FIXME: it would be simpler to read the current settings using
1250 * WinHttpGetDefaultProxyConfiguration and save them using
1251 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1253 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1254 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1255 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1256 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1257 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1258 * the lpszProxy and lpszProxyBypass values are ignored.
1259 * Thus, if a proxy is set with proxycfg, then calling
1260 * WinHttpGetDefaultProxyConfiguration followed by
1261 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1262 * getting deleted from the registry.
1264 * Instead I read the current registry value and restore it directly.
1266 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1269 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1270 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1275 /* Crashes on Vista and higher */
1276 SetLastError(0xdeadbeef);
1277 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1278 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1279 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1282 /* test with invalid access type */
1283 info
.dwAccessType
= 0xdeadbeef;
1284 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1285 SetLastError(0xdeadbeef);
1286 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1287 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1288 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1290 /* at a minimum, the proxy server must be set */
1291 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1292 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1293 SetLastError(0xdeadbeef);
1294 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1295 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1296 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1297 info
.lpszProxyBypass
= normalString
;
1298 SetLastError(0xdeadbeef);
1299 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1300 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1301 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1303 /* the proxy server can't have wide characters */
1304 info
.lpszProxy
= wideString
;
1305 SetLastError(0xdeadbeef);
1306 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1307 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1308 skip("couldn't set default proxy configuration: access denied\n");
1310 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1311 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1312 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1314 info
.lpszProxy
= normalString
;
1315 SetLastError(0xdeadbeef);
1316 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1317 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1318 skip("couldn't set default proxy configuration: access denied\n");
1321 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1322 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1323 "got %u\n", GetLastError());
1325 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1328 static void test_Timeouts (void)
1332 HINTERNET ses
, req
, con
;
1334 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1335 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1337 SetLastError(0xdeadbeef);
1338 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1339 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1340 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1342 SetLastError(0xdeadbeef);
1343 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1344 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1345 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1347 SetLastError(0xdeadbeef);
1348 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1349 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1350 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1352 SetLastError(0xdeadbeef);
1353 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1354 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1355 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1357 SetLastError(0xdeadbeef);
1358 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1359 ok(ret
, "%u\n", GetLastError());
1360 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1361 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1363 SetLastError(0xdeadbeef);
1364 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1365 ok(ret
, "%u\n", GetLastError());
1367 SetLastError(0xdeadbeef);
1368 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1369 ok(ret
, "%u\n", GetLastError());
1371 SetLastError(0xdeadbeef);
1373 size
= sizeof(DWORD
);
1374 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1375 ok(ret
, "%u\n", GetLastError());
1376 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1378 SetLastError(0xdeadbeef);
1380 size
= sizeof(DWORD
);
1381 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1382 ok(ret
, "%u\n", GetLastError());
1383 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1385 SetLastError(0xdeadbeef);
1387 size
= sizeof(DWORD
);
1388 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1389 ok(ret
, "%u\n", GetLastError());
1390 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1392 SetLastError(0xdeadbeef);
1394 size
= sizeof(DWORD
);
1395 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1396 ok(ret
, "%u\n", GetLastError());
1397 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1399 SetLastError(0xdeadbeef);
1401 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1402 ok(ret
, "%u\n", GetLastError());
1404 SetLastError(0xdeadbeef);
1406 size
= sizeof(DWORD
);
1407 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1408 ok(ret
, "%u\n", GetLastError());
1409 ok(value
== 0, "Expected 0, got %u\n", value
);
1411 SetLastError(0xdeadbeef);
1413 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1414 ok(ret
, "%u\n", GetLastError());
1416 SetLastError(0xdeadbeef);
1418 size
= sizeof(DWORD
);
1419 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1420 ok(ret
, "%u\n", GetLastError());
1421 ok(value
== 0, "Expected 0, got %u\n", value
);
1423 SetLastError(0xdeadbeef);
1425 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1426 ok(ret
, "%u\n", GetLastError());
1428 SetLastError(0xdeadbeef);
1430 size
= sizeof(DWORD
);
1431 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1432 ok(ret
, "%u\n", GetLastError());
1433 ok(value
== 0, "Expected 0, got %u\n", value
);
1435 SetLastError(0xdeadbeef);
1437 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1438 ok(ret
, "%u\n", GetLastError());
1440 SetLastError(0xdeadbeef);
1442 size
= sizeof(DWORD
);
1443 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1444 ok(ret
, "%u\n", GetLastError());
1445 ok(value
== 0, "Expected 0, got %u\n", value
);
1447 SetLastError(0xdeadbeef);
1449 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1450 ok(ret
, "%u\n", GetLastError());
1452 SetLastError(0xdeadbeef);
1454 size
= sizeof(DWORD
);
1455 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1456 ok(ret
, "%u\n", GetLastError());
1457 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1459 SetLastError(0xdeadbeef);
1461 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1462 ok(ret
, "%u\n", GetLastError());
1464 SetLastError(0xdeadbeef);
1466 size
= sizeof(DWORD
);
1467 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1468 ok(ret
, "%u\n", GetLastError());
1469 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1471 SetLastError(0xdeadbeef);
1473 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1474 ok(ret
, "%u\n", GetLastError());
1476 SetLastError(0xdeadbeef);
1478 size
= sizeof(DWORD
);
1479 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1480 ok(ret
, "%u\n", GetLastError());
1481 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1483 SetLastError(0xdeadbeef);
1485 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1486 ok(ret
, "%u\n", GetLastError());
1488 SetLastError(0xdeadbeef);
1490 size
= sizeof(DWORD
);
1491 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1492 ok(ret
, "%u\n", GetLastError());
1493 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1495 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1496 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1498 /* Timeout values should match the last one set for session */
1499 SetLastError(0xdeadbeef);
1501 size
= sizeof(DWORD
);
1502 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1503 ok(ret
, "%u\n", GetLastError());
1504 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1506 SetLastError(0xdeadbeef);
1508 size
= sizeof(DWORD
);
1509 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1510 ok(ret
, "%u\n", GetLastError());
1511 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1513 SetLastError(0xdeadbeef);
1515 size
= sizeof(DWORD
);
1516 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1517 ok(ret
, "%u\n", GetLastError());
1518 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1520 SetLastError(0xdeadbeef);
1522 size
= sizeof(DWORD
);
1523 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1524 ok(ret
, "%u\n", GetLastError());
1525 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1527 SetLastError(0xdeadbeef);
1528 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1529 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1530 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1532 SetLastError(0xdeadbeef);
1533 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1534 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1535 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1537 SetLastError(0xdeadbeef);
1538 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1539 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1540 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1542 SetLastError(0xdeadbeef);
1543 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1544 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1545 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1547 SetLastError(0xdeadbeef);
1548 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1549 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1550 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1552 SetLastError(0xdeadbeef);
1553 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
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_RESOLVE_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_CONNECT_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_SEND_TIMEOUT
, &value
, sizeof(value
));
1572 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1573 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1575 SetLastError(0xdeadbeef);
1577 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1578 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1579 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1581 /* Changing timeout values for session should affect the values for connection */
1582 SetLastError(0xdeadbeef);
1584 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1585 ok(ret
, "%u\n", GetLastError());
1587 SetLastError(0xdeadbeef);
1589 size
= sizeof(DWORD
);
1590 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1591 ok(ret
, "%u\n", GetLastError());
1592 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1594 SetLastError(0xdeadbeef);
1596 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1597 ok(ret
, "%u\n", GetLastError());
1599 SetLastError(0xdeadbeef);
1601 size
= sizeof(DWORD
);
1602 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1603 ok(ret
, "%u\n", GetLastError());
1604 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1606 SetLastError(0xdeadbeef);
1608 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1609 ok(ret
, "%u\n", GetLastError());
1611 SetLastError(0xdeadbeef);
1613 size
= sizeof(DWORD
);
1614 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1615 ok(ret
, "%u\n", GetLastError());
1616 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1618 SetLastError(0xdeadbeef);
1620 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1621 ok(ret
, "%u\n", GetLastError());
1623 SetLastError(0xdeadbeef);
1625 size
= sizeof(DWORD
);
1626 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1627 ok(ret
, "%u\n", GetLastError());
1628 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1630 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1631 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1633 /* Timeout values should match the last one set for session */
1634 SetLastError(0xdeadbeef);
1636 size
= sizeof(DWORD
);
1637 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1638 ok(ret
, "%u\n", GetLastError());
1639 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1641 SetLastError(0xdeadbeef);
1643 size
= sizeof(DWORD
);
1644 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1645 ok(ret
, "%u\n", GetLastError());
1646 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1648 SetLastError(0xdeadbeef);
1650 size
= sizeof(DWORD
);
1651 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1652 ok(ret
, "%u\n", GetLastError());
1653 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1655 SetLastError(0xdeadbeef);
1657 size
= sizeof(DWORD
);
1658 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1659 ok(ret
, "%u\n", GetLastError());
1660 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1662 SetLastError(0xdeadbeef);
1663 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1664 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1665 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1667 SetLastError(0xdeadbeef);
1668 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1669 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1670 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1672 SetLastError(0xdeadbeef);
1673 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1674 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1675 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1677 SetLastError(0xdeadbeef);
1678 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1679 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1680 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1682 SetLastError(0xdeadbeef);
1683 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1684 ok(ret
, "%u\n", GetLastError());
1686 SetLastError(0xdeadbeef);
1687 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1688 ok(ret
, "%u\n", GetLastError());
1690 SetLastError(0xdeadbeef);
1691 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1692 ok(ret
, "%u\n", GetLastError());
1694 SetLastError(0xdeadbeef);
1696 size
= sizeof(DWORD
);
1697 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1698 ok(ret
, "%u\n", GetLastError());
1699 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1701 SetLastError(0xdeadbeef);
1703 size
= sizeof(DWORD
);
1704 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1705 ok(ret
, "%u\n", GetLastError());
1706 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1708 SetLastError(0xdeadbeef);
1710 size
= sizeof(DWORD
);
1711 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1712 ok(ret
, "%u\n", GetLastError());
1713 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1715 SetLastError(0xdeadbeef);
1717 size
= sizeof(DWORD
);
1718 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1719 ok(ret
, "%u\n", GetLastError());
1720 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1722 SetLastError(0xdeadbeef);
1724 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1725 ok(ret
, "%u\n", GetLastError());
1727 SetLastError(0xdeadbeef);
1729 size
= sizeof(DWORD
);
1730 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1731 ok(ret
, "%u\n", GetLastError());
1732 ok(value
== 0, "Expected 0, got %u\n", value
);
1734 SetLastError(0xdeadbeef);
1736 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1737 ok(ret
, "%u\n", GetLastError());
1739 SetLastError(0xdeadbeef);
1741 size
= sizeof(DWORD
);
1742 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1743 ok(ret
, "%u\n", GetLastError());
1744 ok(value
== 0, "Expected 0, got %u\n", value
);
1746 SetLastError(0xdeadbeef);
1748 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1749 ok(ret
, "%u\n", GetLastError());
1751 SetLastError(0xdeadbeef);
1753 size
= sizeof(DWORD
);
1754 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1755 ok(ret
, "%u\n", GetLastError());
1756 ok(value
== 0, "Expected 0, got %u\n", value
);
1758 SetLastError(0xdeadbeef);
1760 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1761 ok(ret
, "%u\n", GetLastError());
1763 SetLastError(0xdeadbeef);
1765 size
= sizeof(DWORD
);
1766 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1767 ok(ret
, "%u\n", GetLastError());
1768 ok(value
== 0, "Expected 0, got %u\n", value
);
1770 SetLastError(0xdeadbeef);
1772 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1773 ok(ret
, "%u\n", GetLastError());
1775 SetLastError(0xdeadbeef);
1777 size
= sizeof(DWORD
);
1778 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1779 ok(ret
, "%u\n", GetLastError());
1780 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1782 SetLastError(0xdeadbeef);
1784 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1785 ok(ret
, "%u\n", GetLastError());
1787 SetLastError(0xdeadbeef);
1789 size
= sizeof(DWORD
);
1790 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1791 ok(ret
, "%u\n", GetLastError());
1792 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1794 SetLastError(0xdeadbeef);
1796 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1797 ok(ret
, "%u\n", GetLastError());
1799 SetLastError(0xdeadbeef);
1801 size
= sizeof(DWORD
);
1802 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1803 ok(ret
, "%u\n", GetLastError());
1804 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1806 SetLastError(0xdeadbeef);
1808 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1809 ok(ret
, "%u\n", GetLastError());
1811 SetLastError(0xdeadbeef);
1813 size
= sizeof(DWORD
);
1814 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1815 ok(ret
, "%u\n", GetLastError());
1816 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1818 /* Changing timeout values for session should not affect the values for a request,
1819 * neither should the other way around.
1821 SetLastError(0xdeadbeef);
1823 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1824 ok(ret
, "%u\n", GetLastError());
1826 SetLastError(0xdeadbeef);
1828 size
= sizeof(DWORD
);
1829 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1830 ok(ret
, "%u\n", GetLastError());
1831 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1833 SetLastError(0xdeadbeef);
1835 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1836 ok(ret
, "%u\n", GetLastError());
1838 SetLastError(0xdeadbeef);
1840 size
= sizeof(DWORD
);
1841 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1842 ok(ret
, "%u\n", GetLastError());
1843 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1845 SetLastError(0xdeadbeef);
1847 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1848 ok(ret
, "%u\n", GetLastError());
1850 SetLastError(0xdeadbeef);
1852 size
= sizeof(DWORD
);
1853 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1854 ok(ret
, "%u\n", GetLastError());
1855 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1857 SetLastError(0xdeadbeef);
1859 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1860 ok(ret
, "%u\n", GetLastError());
1862 SetLastError(0xdeadbeef);
1864 size
= sizeof(DWORD
);
1865 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1866 ok(ret
, "%u\n", GetLastError());
1867 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1869 SetLastError(0xdeadbeef);
1871 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1872 ok(ret
, "%u\n", GetLastError());
1874 SetLastError(0xdeadbeef);
1876 size
= sizeof(DWORD
);
1877 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1878 ok(ret
, "%u\n", GetLastError());
1879 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1881 SetLastError(0xdeadbeef);
1883 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1884 ok(ret
, "%u\n", GetLastError());
1886 SetLastError(0xdeadbeef);
1888 size
= sizeof(DWORD
);
1889 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1890 ok(ret
, "%u\n", GetLastError());
1891 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1893 SetLastError(0xdeadbeef);
1895 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1896 ok(ret
, "%u\n", GetLastError());
1898 SetLastError(0xdeadbeef);
1900 size
= sizeof(DWORD
);
1901 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1902 ok(ret
, "%u\n", GetLastError());
1903 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1905 SetLastError(0xdeadbeef);
1907 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1908 ok(ret
, "%u\n", GetLastError());
1910 SetLastError(0xdeadbeef);
1912 size
= sizeof(DWORD
);
1913 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1914 ok(ret
, "%u\n", GetLastError());
1915 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1917 WinHttpCloseHandle(req
);
1918 WinHttpCloseHandle(con
);
1919 WinHttpCloseHandle(ses
);
1922 static void test_resolve_timeout(void)
1924 static const WCHAR nxdomain
[] =
1925 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1926 HINTERNET ses
, con
, req
;
1930 if (! proxy_active())
1932 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1933 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1936 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1937 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1939 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1940 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1942 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1943 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1945 SetLastError(0xdeadbeef);
1946 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1949 skip("nxdomain returned success. Broken ISP redirects?\n");
1952 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1953 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1955 WinHttpCloseHandle(req
);
1956 WinHttpCloseHandle(con
);
1957 WinHttpCloseHandle(ses
);
1960 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1962 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1963 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1966 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1967 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1969 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1970 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1972 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1973 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1975 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1976 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
1978 skip("connection failed, skipping\n");
1981 ok(ret
, "failed to send request\n");
1984 WinHttpCloseHandle(req
);
1985 WinHttpCloseHandle(con
);
1986 WinHttpCloseHandle(ses
);
1989 static const char page1
[] =
1991 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1992 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1995 static const char okmsg
[] =
1996 "HTTP/1.1 200 OK\r\n"
1997 "Server: winetest\r\n"
2000 static const char notokmsg
[] =
2001 "HTTP/1.1 400 Bad Request\r\n"
2004 static const char cookiemsg
[] =
2005 "HTTP/1.1 200 OK\r\n"
2006 "Set-Cookie: name = value \r\n"
2007 "Set-Cookie: NAME = value \r\n"
2010 static const char nocontentmsg
[] =
2011 "HTTP/1.1 204 No Content\r\n"
2012 "Server: winetest\r\n"
2015 static const char notmodified
[] =
2016 "HTTP/1.1 304 Not Modified\r\n"
2019 static const char noauthmsg
[] =
2020 "HTTP/1.1 401 Unauthorized\r\n"
2021 "Server: winetest\r\n"
2022 "Connection: close\r\n"
2023 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2024 "Content-Length: 12\r\n"
2025 "Content-Type: text/plain\r\n"
2028 static const char okauthmsg
[] =
2029 "HTTP/1.1 200 OK\r\n"
2030 "Server: winetest\r\n"
2031 "Connection: close\r\n"
2032 "Content-Length: 11\r\n"
2033 "Content-Type: text/plain\r\n"
2036 static const char headmsg
[] =
2037 "HTTP/1.1 200 OK\r\n"
2038 "Content-Length: 100\r\n"
2041 static const char unauthorized
[] = "Unauthorized";
2042 static const char hello_world
[] = "Hello World";
2050 #define BIG_BUFFER_LEN 0x2250
2052 static DWORD CALLBACK
server_thread(LPVOID param
)
2054 struct server_info
*si
= param
;
2055 int r
, c
= -1, i
, on
;
2057 struct sockaddr_in sa
;
2060 int last_request
= 0;
2062 WSAStartup(MAKEWORD(1,1), &wsaData
);
2064 s
= socket(AF_INET
, SOCK_STREAM
, 0);
2065 if (s
== INVALID_SOCKET
)
2069 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
2071 memset(&sa
, 0, sizeof sa
);
2072 sa
.sin_family
= AF_INET
;
2073 sa
.sin_port
= htons(si
->port
);
2074 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
2076 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
2081 SetEvent(si
->event
);
2084 if (c
== -1) c
= accept(s
, NULL
, NULL
);
2086 memset(buffer
, 0, sizeof buffer
);
2087 for(i
= 0; i
< sizeof buffer
- 1; i
++)
2089 r
= recv(c
, &buffer
[i
], 1, 0);
2092 if (i
< 4) continue;
2093 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
2094 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
2097 if (strstr(buffer
, "GET /basic"))
2099 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2100 send(c
, page1
, sizeof page1
- 1, 0);
2102 if (strstr(buffer
, "/auth"))
2104 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2106 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2107 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2111 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
2112 send(c
, unauthorized
, sizeof unauthorized
- 1, 0);
2116 if (strstr(buffer
, "/big"))
2118 char msg
[BIG_BUFFER_LEN
];
2119 memset(msg
, 'm', sizeof(msg
));
2120 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2121 send(c
, msg
, sizeof(msg
), 0);
2123 if (strstr(buffer
, "/no_headers"))
2125 send(c
, page1
, sizeof page1
- 1, 0);
2127 if (strstr(buffer
, "GET /no_content"))
2129 send(c
, nocontentmsg
, sizeof nocontentmsg
- 1, 0);
2132 if (strstr(buffer
, "GET /not_modified"))
2134 if (strstr(buffer
, "If-Modified-Since:")) send(c
, notmodified
, sizeof notmodified
- 1, 0);
2135 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2138 if (strstr(buffer
, "HEAD /head"))
2140 send(c
, headmsg
, sizeof headmsg
- 1, 0);
2143 if (strstr(buffer
, "GET /cookie3"))
2145 if (strstr(buffer
, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2146 broken(strstr(buffer
, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL
))
2147 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2149 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2151 if (strstr(buffer
, "GET /cookie2"))
2153 if (strstr(buffer
, "Cookie: NAME=value; name=value\r\n") ||
2154 broken(strstr(buffer
, "Cookie: name=value; NAME=value\r\n") != NULL
))
2155 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2157 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2159 else if (strstr(buffer
, "GET /cookie"))
2161 if (!strstr(buffer
, "Cookie: name=value\r\n")) send(c
, cookiemsg
, sizeof(cookiemsg
) - 1, 0);
2162 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2164 if (strstr(buffer
, "GET /quit"))
2166 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2167 send(c
, page1
, sizeof page1
- 1, 0);
2174 } while (!last_request
);
2180 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
2182 static const WCHAR test_header_end_clrf
[] = {'\r','\n','\r','\n',0};
2183 static const WCHAR test_header_end_raw
[] = {0,0};
2184 HINTERNET ses
, con
, req
;
2186 WCHAR buffer2
[0x100];
2187 DWORD count
, status
, size
, error
, supported
, first
, target
;
2190 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2191 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2193 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2194 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2196 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
2197 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2199 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2200 ok(ret
, "failed to send request %u\n", GetLastError());
2202 ret
= WinHttpReceiveResponse(req
, NULL
);
2203 ok(ret
, "failed to receive response %u\n", GetLastError());
2205 status
= 0xdeadbeef;
2206 size
= sizeof(status
);
2207 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2208 ok(ret
, "failed to query status code %u\n", GetLastError());
2209 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2211 supported
= first
= target
= 0xdeadbeef;
2212 SetLastError(0xdeadbeef);
2213 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2214 error
= GetLastError();
2215 ok(!ret
, "unexpected success\n");
2216 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2217 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2218 ok(first
== 0xdeadbeef, "got %x\n", first
);
2219 ok(target
== 0xdeadbeef, "got %x\n", target
);
2221 size
= sizeof(buffer2
);
2222 memset(buffer2
, 0, sizeof(buffer2
));
2223 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, buffer2
, &size
, NULL
);
2224 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2225 ok(!memcmp(buffer2
+ lstrlenW(buffer2
) - 4, test_header_end_clrf
, sizeof(test_header_end_clrf
)),
2226 "WinHttpQueryHeaders returned invalid end of header string\n");
2228 size
= sizeof(buffer2
);
2229 memset(buffer2
, 0, sizeof(buffer2
));
2230 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS
, NULL
, buffer2
, &size
, NULL
);
2231 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2232 ok(!memcmp(buffer2
+ (size
/ sizeof(WCHAR
)) - 1, test_header_end_raw
, sizeof(test_header_end_raw
)),
2233 "WinHttpQueryHeaders returned invalid end of header string\n");
2234 ok(buffer2
[(size
/ sizeof(WCHAR
)) - 2] != 0, "returned string has too many NULL characters\n");
2237 memset(buffer
, 0, sizeof(buffer
));
2238 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
2239 ok(ret
, "failed to read data %u\n", GetLastError());
2240 ok(count
== sizeof page1
- 1, "count was wrong\n");
2241 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
2243 WinHttpCloseHandle(req
);
2244 WinHttpCloseHandle(con
);
2245 WinHttpCloseHandle(ses
);
2248 static void test_basic_authentication(int port
)
2250 static const WCHAR authW
[] = {'/','a','u','t','h',0};
2251 static WCHAR userW
[] = {'u','s','e','r',0};
2252 static WCHAR passW
[] = {'p','w','d',0};
2253 static WCHAR pass2W
[] = {'p','w','d','2',0};
2254 HINTERNET ses
, con
, req
;
2255 DWORD status
, size
, error
, supported
, first
, target
;
2259 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2260 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2262 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2263 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2265 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2266 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2268 SetLastError(0xdeadbeef);
2269 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
2270 error
= GetLastError();
2271 ok(!ret
, "expected failure\n");
2272 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2274 SetLastError(0xdeadbeef);
2275 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
2276 error
= GetLastError();
2277 ok(!ret
, "expected failure\n");
2278 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2280 supported
= 0xdeadbeef;
2281 SetLastError(0xdeadbeef);
2282 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
2283 error
= GetLastError();
2284 ok(!ret
, "expected failure\n");
2285 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2286 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2288 supported
= first
= 0xdeadbeef;
2289 SetLastError(0xdeadbeef);
2290 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
2291 error
= GetLastError();
2292 ok(!ret
, "expected failure\n");
2293 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2294 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2295 ok(first
== 0xdeadbeef, "got %x\n", first
);
2297 supported
= first
= target
= 0xdeadbeef;
2298 SetLastError(0xdeadbeef);
2299 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2300 error
= GetLastError();
2301 ok(!ret
, "expected failure\n");
2302 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2303 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2304 ok(first
== 0xdeadbeef, "got %x\n", first
);
2305 ok(target
== 0xdeadbeef, "got %x\n", target
);
2307 supported
= first
= target
= 0xdeadbeef;
2308 SetLastError(0xdeadbeef);
2309 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
2310 error
= GetLastError();
2311 ok(!ret
, "expected failure\n");
2312 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2313 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2314 ok(first
== 0xdeadbeef, "got %x\n", first
);
2315 ok(target
== 0xdeadbeef, "got %x\n", target
);
2317 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2318 ok(ret
, "failed to send request %u\n", GetLastError());
2320 ret
= WinHttpReceiveResponse(req
, NULL
);
2321 ok(ret
, "failed to receive response %u\n", GetLastError());
2323 status
= 0xdeadbeef;
2324 size
= sizeof(status
);
2325 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2326 ok(ret
, "failed to query status code %u\n", GetLastError());
2327 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2330 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2331 error
= GetLastError();
2332 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2335 ok(size
== 12, "expected 12, got %u\n", size
);
2336 ok(!memcmp(buffer
, unauthorized
, 12), "got %s\n", buffer
);
2339 supported
= first
= target
= 0xdeadbeef;
2340 SetLastError(0xdeadbeef);
2341 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2342 error
= GetLastError();
2343 ok(ret
, "failed to query authentication schemes %u\n", error
);
2344 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2345 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2346 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2347 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2349 SetLastError(0xdeadbeef);
2350 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2351 error
= GetLastError();
2352 ok(ret
, "failed to set credentials %u\n", error
);
2353 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2355 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2356 ok(ret
, "failed to set credentials %u\n", GetLastError());
2358 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2359 ok(ret
, "failed to set credentials %u\n", GetLastError());
2361 SetLastError(0xdeadbeef);
2362 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, 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
, NULL
, 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
, userW
, NULL
, 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 SetLastError(0xdeadbeef);
2380 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2381 error
= GetLastError();
2382 ok(!ret
, "expected failure\n");
2383 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2385 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2386 ok(ret
, "failed to set credentials %u\n", GetLastError());
2388 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2389 ok(ret
, "failed to send request %u\n", GetLastError());
2391 ret
= WinHttpReceiveResponse(req
, NULL
);
2392 ok(ret
, "failed to receive response %u\n", GetLastError());
2394 status
= 0xdeadbeef;
2395 size
= sizeof(status
);
2396 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2397 ok(ret
, "failed to query status code %u\n", GetLastError());
2398 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2401 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2402 error
= GetLastError();
2403 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2406 ok(size
== 11, "expected 11, got %u\n", size
);
2407 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2410 WinHttpCloseHandle(req
);
2411 WinHttpCloseHandle(con
);
2412 WinHttpCloseHandle(ses
);
2414 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2416 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2417 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2419 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2420 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2422 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2423 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2425 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2426 ok(ret
, "failed to set credentials %u\n", GetLastError());
2428 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2429 ok(ret
, "failed to set username %u\n", GetLastError());
2431 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, pass2W
, lstrlenW(pass2W
));
2432 ok(ret
, "failed to set password %u\n", GetLastError());
2434 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2435 ok(ret
, "failed to send request %u\n", GetLastError());
2437 ret
= WinHttpReceiveResponse(req
, NULL
);
2438 ok(ret
, "failed to receive response %u\n", GetLastError());
2440 status
= 0xdeadbeef;
2441 size
= sizeof(status
);
2442 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2443 ok(ret
, "failed to query status code %u\n", GetLastError());
2444 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2446 WinHttpCloseHandle(req
);
2447 WinHttpCloseHandle(con
);
2448 WinHttpCloseHandle(ses
);
2450 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2451 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2453 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2454 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2456 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2457 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2459 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2460 ok(ret
, "failed to set username %u\n", GetLastError());
2462 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2463 ok(ret
, "failed to set password %u\n", GetLastError());
2465 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, pass2W
, NULL
);
2466 ok(ret
, "failed to set credentials %u\n", GetLastError());
2468 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2469 ok(ret
, "failed to send request %u\n", GetLastError());
2471 ret
= WinHttpReceiveResponse(req
, NULL
);
2472 ok(ret
, "failed to receive response %u\n", GetLastError());
2474 status
= 0xdeadbeef;
2475 size
= sizeof(status
);
2476 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2477 ok(ret
, "failed to query status code %u\n", GetLastError());
2478 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2480 WinHttpCloseHandle(req
);
2481 WinHttpCloseHandle(con
);
2482 WinHttpCloseHandle(ses
);
2485 static void test_no_headers(int port
)
2487 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2488 HINTERNET ses
, con
, req
;
2492 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2493 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2495 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2496 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2498 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2499 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2501 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2504 error
= GetLastError();
2505 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2509 SetLastError(0xdeadbeef);
2510 ret
= WinHttpReceiveResponse(req
, NULL
);
2511 error
= GetLastError();
2512 ok(!ret
, "expected failure\n");
2513 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2516 WinHttpCloseHandle(req
);
2517 WinHttpCloseHandle(con
);
2518 WinHttpCloseHandle(ses
);
2521 static void test_no_content(int port
)
2523 static const WCHAR no_contentW
[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2524 HINTERNET ses
, con
, req
;
2526 DWORD size
, len
= sizeof(buf
), bytes_read
, status
;
2529 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2530 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2532 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2533 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2535 req
= WinHttpOpenRequest(con
, NULL
, no_contentW
, NULL
, NULL
, NULL
, 0);
2536 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2539 SetLastError(0xdeadbeef);
2540 ret
= WinHttpQueryDataAvailable(req
, &size
);
2542 ok(!ret
, "expected error\n");
2543 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
,
2544 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2545 ok(size
== 12345 || broken(size
== 0) /* Win <= 2003 */,
2546 "expected 12345, got %u\n", size
);
2549 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2550 ok(ret
, "expected success\n");
2552 ret
= WinHttpReceiveResponse(req
, NULL
);
2553 ok(ret
, "expected success\n");
2555 status
= 0xdeadbeef;
2556 size
= sizeof(status
);
2557 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2558 NULL
, &status
, &size
, NULL
);
2559 ok(ret
, "expected success\n");
2560 ok(status
== HTTP_STATUS_NO_CONTENT
, "expected status 204, got %d\n", status
);
2562 SetLastError(0xdeadbeef);
2563 size
= sizeof(status
);
2565 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2566 NULL
, &status
, &size
, 0);
2567 ok(!ret
, "expected no content-length header\n");
2568 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError());
2569 ok(status
== 12345, "expected 0, got %d\n", status
);
2571 SetLastError(0xdeadbeef);
2573 ret
= WinHttpQueryDataAvailable(req
, &size
);
2574 ok(ret
, "expected success\n");
2575 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2576 "wrong error %u\n", GetLastError());
2577 ok(!size
, "expected 0, got %u\n", size
);
2579 SetLastError(0xdeadbeef);
2580 ret
= WinHttpReadData(req
, buf
, len
, &bytes_read
);
2581 ok(ret
, "expected success\n");
2582 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2583 "wrong error %u\n", GetLastError());
2584 ok(!bytes_read
, "expected 0, got %u\n", bytes_read
);
2587 ret
= WinHttpQueryDataAvailable(req
, &size
);
2588 ok(ret
, "expected success\n");
2589 ok(size
== 0, "expected 0, got %d\n", size
);
2591 WinHttpCloseHandle(req
);
2594 SetLastError(0xdeadbeef);
2595 ret
= WinHttpQueryDataAvailable(req
, &size
);
2596 ok(!ret
, "expected error\n");
2597 ok(GetLastError() == ERROR_INVALID_HANDLE
,
2598 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2599 ok(size
== 12345, "expected 12345, got %u\n", size
);
2601 WinHttpCloseHandle(con
);
2602 WinHttpCloseHandle(ses
);
2605 static void test_head_request(int port
)
2607 static const WCHAR verbW
[] = {'H','E','A','D',0};
2608 static const WCHAR headW
[] = {'/','h','e','a','d',0};
2609 HINTERNET ses
, con
, req
;
2611 DWORD size
, len
, count
, status
;
2614 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2615 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2617 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2618 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2620 req
= WinHttpOpenRequest(con
, verbW
, headW
, NULL
, NULL
, NULL
, 0);
2621 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2623 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2624 ok(ret
, "failed to send request %u\n", GetLastError());
2626 ret
= WinHttpReceiveResponse(req
, NULL
);
2627 ok(ret
, "failed to receive response %u\n", GetLastError());
2629 status
= 0xdeadbeef;
2630 size
= sizeof(status
);
2631 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2632 NULL
, &status
, &size
, NULL
);
2633 ok(ret
, "failed to get status code %u\n", GetLastError());
2634 ok(status
== HTTP_STATUS_OK
, "got %u\n", status
);
2638 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2639 NULL
, &len
, &size
, 0);
2640 ok(ret
, "failed to get content-length header %u\n", GetLastError());
2641 ok(len
== HTTP_STATUS_CONTINUE
, "got %u\n", len
);
2644 ret
= WinHttpQueryDataAvailable(req
, &count
);
2645 ok(ret
, "failed to query data available %u\n", GetLastError());
2646 ok(!count
, "got %u\n", count
);
2650 ret
= WinHttpReadData(req
, buf
, len
, &count
);
2651 ok(ret
, "failed to read data %u\n", GetLastError());
2652 ok(!count
, "got %u\n", count
);
2655 ret
= WinHttpQueryDataAvailable(req
, &count
);
2656 ok(ret
, "failed to query data available %u\n", GetLastError());
2657 ok(!count
, "got %u\n", count
);
2659 WinHttpCloseHandle(req
);
2660 WinHttpCloseHandle(con
);
2661 WinHttpCloseHandle(ses
);
2664 static void test_not_modified(int port
)
2666 static const WCHAR pathW
[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2667 static const WCHAR ifmodifiedW
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2668 static const WCHAR ifmodified2W
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2670 HINTERNET session
, request
, connection
;
2671 DWORD index
, len
, status
, size
, start
= GetTickCount();
2673 WCHAR today
[(sizeof(ifmodifiedW
) + WINHTTP_TIME_FORMAT_BUFSIZE
)/sizeof(WCHAR
) + 3], buffer
[32];
2675 memcpy(today
, ifmodifiedW
, sizeof(ifmodifiedW
));
2677 WinHttpTimeFromSystemTime(&st
, &today
[sizeof(ifmodifiedW
)/sizeof(WCHAR
)]);
2679 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
,
2680 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
2681 ok(session
!= NULL
, "WinHttpOpen failed: %u\n", GetLastError());
2683 connection
= WinHttpConnect(session
, localhostW
, port
, 0);
2684 ok(connection
!= NULL
, "WinHttpConnect failed: %u\n", GetLastError());
2686 request
= WinHttpOpenRequest(connection
, NULL
, pathW
, NULL
, WINHTTP_NO_REFERER
,
2687 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
2688 ok(request
!= NULL
, "WinHttpOpenrequest failed: %u\n", GetLastError());
2690 ret
= WinHttpSendRequest(request
, today
, 0, NULL
, 0, 0, 0);
2691 ok(ret
, "WinHttpSendRequest failed: %u\n", GetLastError());
2693 ret
= WinHttpReceiveResponse(request
, NULL
);
2694 ok(ret
, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2697 len
= sizeof(buffer
);
2698 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2699 ifmodified2W
, buffer
, &len
, &index
);
2700 ok(ret
, "failed to get header %u\n", GetLastError());
2702 status
= 0xdeadbeef;
2703 size
= sizeof(status
);
2704 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
,
2705 NULL
, &status
, &size
, NULL
);
2706 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2707 ok(status
== HTTP_STATUS_NOT_MODIFIED
, "got %u\n", status
);
2710 ret
= WinHttpQueryDataAvailable(request
, &size
);
2711 ok(ret
, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2712 ok(!size
, "got %u\n", size
);
2714 WinHttpCloseHandle(request
);
2715 WinHttpCloseHandle(connection
);
2716 WinHttpCloseHandle(session
);
2717 start
= GetTickCount() - start
;
2718 ok(start
<= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start
);
2721 static void test_bad_header( int port
)
2723 static const WCHAR bad_headerW
[] =
2724 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2725 't','e','x','t','/','h','t','m','l','\n','\r',0};
2726 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2727 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2729 HINTERNET ses
, con
, req
;
2733 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2734 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2736 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2737 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2739 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2740 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2742 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2743 ok( ret
, "failed to add header %u\n", GetLastError() );
2747 len
= sizeof(buffer
);
2748 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2749 content_typeW
, buffer
, &len
, &index
);
2750 ok( ret
, "failed to query headers %u\n", GetLastError() );
2751 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2753 WinHttpCloseHandle( req
);
2754 WinHttpCloseHandle( con
);
2755 WinHttpCloseHandle( ses
);
2758 static void test_multiple_reads(int port
)
2760 static const WCHAR bigW
[] = {'b','i','g',0};
2761 HINTERNET ses
, con
, req
;
2762 DWORD total_len
= 0;
2765 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2766 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2768 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2769 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2771 req
= WinHttpOpenRequest(con
, NULL
, bigW
, NULL
, NULL
, NULL
, 0);
2772 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2774 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2775 ok(ret
, "failed to send request %u\n", GetLastError());
2777 ret
= WinHttpReceiveResponse(req
, NULL
);
2778 ok(ret
== TRUE
, "expected success\n");
2782 DWORD len
= 0xdeadbeef;
2783 ret
= WinHttpQueryDataAvailable( req
, &len
);
2784 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2785 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2789 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
2791 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
2792 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
2794 HeapFree( GetProcessHeap(), 0, buf
);
2795 if (!bytes_read
) break;
2796 total_len
+= bytes_read
;
2800 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
2802 WinHttpCloseHandle(req
);
2803 WinHttpCloseHandle(con
);
2804 WinHttpCloseHandle(ses
);
2807 static void test_cookies( int port
)
2809 static const WCHAR cookieW
[] = {'/','c','o','o','k','i','e',0};
2810 static const WCHAR cookie2W
[] = {'/','c','o','o','k','i','e','2',0};
2811 static const WCHAR cookie3W
[] = {'/','c','o','o','k','i','e','3',0};
2812 static const WCHAR cookieheaderW
[] =
2813 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2814 HINTERNET ses
, con
, req
;
2818 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2819 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2821 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2822 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2824 req
= WinHttpOpenRequest( con
, NULL
, cookieW
, NULL
, NULL
, NULL
, 0 );
2825 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2827 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2828 ok( ret
, "failed to send request %u\n", GetLastError() );
2830 ret
= WinHttpReceiveResponse( req
, NULL
);
2831 ok( ret
, "failed to receive response %u\n", GetLastError() );
2833 status
= 0xdeadbeef;
2834 size
= sizeof(status
);
2835 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2836 ok( ret
, "failed to query status code %u\n", GetLastError() );
2837 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2839 WinHttpCloseHandle( req
);
2841 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2842 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2844 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2845 ok( ret
, "failed to send request %u\n", GetLastError() );
2847 ret
= WinHttpReceiveResponse( req
, NULL
);
2848 ok( ret
, "failed to receive response %u\n", GetLastError() );
2850 status
= 0xdeadbeef;
2851 size
= sizeof(status
);
2852 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2853 ok( ret
, "failed to query status code %u\n", GetLastError() );
2854 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2856 WinHttpCloseHandle( req
);
2857 WinHttpCloseHandle( con
);
2859 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2860 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2862 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2863 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2865 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2866 ok( ret
, "failed to send request %u\n", GetLastError() );
2868 ret
= WinHttpReceiveResponse( req
, NULL
);
2869 ok( ret
, "failed to receive response %u\n", GetLastError() );
2871 status
= 0xdeadbeef;
2872 size
= sizeof(status
);
2873 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2874 ok( ret
, "failed to query status code %u\n", GetLastError() );
2875 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2877 WinHttpCloseHandle( req
);
2879 req
= WinHttpOpenRequest( con
, NULL
, cookie3W
, NULL
, NULL
, NULL
, 0 );
2880 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2882 ret
= WinHttpSendRequest( req
, cookieheaderW
, ~0u, NULL
, 0, 0, 0 );
2883 ok( ret
, "failed to send request %u\n", GetLastError() );
2885 ret
= WinHttpReceiveResponse( req
, NULL
);
2886 ok( ret
, "failed to receive response %u\n", GetLastError() );
2888 status
= 0xdeadbeef;
2889 size
= sizeof(status
);
2890 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2891 ok( ret
, "failed to query status code %u\n", GetLastError() );
2892 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
), "request failed unexpectedly %u\n", status
);
2894 WinHttpCloseHandle( req
);
2895 WinHttpCloseHandle( con
);
2896 WinHttpCloseHandle( ses
);
2898 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2899 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2901 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2902 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2904 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2905 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2907 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2908 ok( ret
, "failed to send request %u\n", GetLastError() );
2910 ret
= WinHttpReceiveResponse( req
, NULL
);
2911 ok( ret
, "failed to receive response %u\n", GetLastError() );
2913 status
= 0xdeadbeef;
2914 size
= sizeof(status
);
2915 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2916 ok( ret
, "failed to query status code %u\n", GetLastError() );
2917 ok( status
== HTTP_STATUS_BAD_REQUEST
, "request failed unexpectedly %u\n", status
);
2919 WinHttpCloseHandle( req
);
2920 WinHttpCloseHandle( con
);
2921 WinHttpCloseHandle( ses
);
2924 static void test_connection_info( int port
)
2926 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2927 HINTERNET ses
, con
, req
;
2928 WINHTTP_CONNECTION_INFO info
;
2932 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2933 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2935 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2936 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2938 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
2939 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2941 size
= sizeof(info
);
2942 SetLastError( 0xdeadbeef );
2943 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2944 error
= GetLastError();
2945 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
2947 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2950 ok( !ret
, "unexpected success\n" );
2951 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
2953 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2954 ok( ret
, "failed to send request %u\n", GetLastError() );
2957 SetLastError( 0xdeadbeef );
2958 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2959 error
= GetLastError();
2960 ok( !ret
, "unexpected success\n" );
2961 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
2963 size
= sizeof(info
);
2964 memset( &info
, 0, sizeof(info
) );
2965 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2966 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2967 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
2969 ret
= WinHttpReceiveResponse( req
, NULL
);
2970 ok( ret
, "failed to receive response %u\n", GetLastError() );
2972 size
= sizeof(info
);
2973 memset( &info
, 0, sizeof(info
) );
2974 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2975 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2976 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
2978 WinHttpCloseHandle( req
);
2979 WinHttpCloseHandle( con
);
2980 WinHttpCloseHandle( ses
);
2983 static void test_credentials(void)
2985 static WCHAR userW
[] = {'u','s','e','r',0};
2986 static WCHAR passW
[] = {'p','a','s','s',0};
2987 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
2988 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
2989 HINTERNET ses
, con
, req
;
2994 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
2995 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2997 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
2998 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3000 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3001 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3003 size
= sizeof(buffer
)/sizeof(WCHAR
);
3004 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3005 ok(ret
, "failed to query proxy username %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 size
= sizeof(buffer
)/sizeof(WCHAR
);
3010 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3011 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3012 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3013 ok(!size
, "expected 0, got %u\n", size
);
3015 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
3016 ok(ret
, "failed to set username %u\n", GetLastError());
3018 size
= sizeof(buffer
)/sizeof(WCHAR
);
3019 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3020 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3021 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3022 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3024 size
= sizeof(buffer
)/sizeof(WCHAR
);
3025 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3026 ok(ret
, "failed to query username %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 size
= sizeof(buffer
)/sizeof(WCHAR
);
3031 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3032 ok(ret
, "failed to query password %u\n", GetLastError());
3033 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3034 ok(!size
, "expected 0, got %u\n", size
);
3036 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
3037 ok(ret
, "failed to set proxy password %u\n", GetLastError());
3039 size
= sizeof(buffer
)/sizeof(WCHAR
);
3040 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3041 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3042 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3043 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3045 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
3046 ok(ret
, "failed to set username %u\n", GetLastError());
3048 size
= sizeof(buffer
)/sizeof(WCHAR
);
3049 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3050 ok(ret
, "failed to query username %u\n", GetLastError());
3051 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3052 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3054 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
3055 ok(ret
, "failed to set password %u\n", GetLastError());
3057 size
= sizeof(buffer
)/sizeof(WCHAR
);
3058 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3059 ok(ret
, "failed to query password %u\n", GetLastError());
3060 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3061 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3063 WinHttpCloseHandle(req
);
3065 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3066 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3068 SetLastError(0xdeadbeef);
3069 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, 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 SetLastError(0xdeadbeef);
3075 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
3076 error
= GetLastError();
3077 ok(!ret
, "expected failure\n");
3078 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3080 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
3081 ok(ret
, "failed to set credentials %u\n", GetLastError());
3083 size
= sizeof(buffer
)/sizeof(WCHAR
);
3084 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3085 ok(ret
, "failed to query username %u\n", GetLastError());
3087 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3088 ok(!size
, "expected 0, got %u\n", size
);
3091 size
= sizeof(buffer
)/sizeof(WCHAR
);
3092 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3093 ok(ret
, "failed to query password %u\n", GetLastError());
3095 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3096 ok(!size
, "expected 0, got %u\n", size
);
3099 WinHttpCloseHandle(req
);
3100 WinHttpCloseHandle(con
);
3101 WinHttpCloseHandle(ses
);
3104 static void test_IWinHttpRequest(int port
)
3106 static const WCHAR data_start
[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3107 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
3108 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
3109 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3110 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3111 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3112 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3113 static const WCHAR method1W
[] = {'G','E','T',0};
3114 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
3115 static const WCHAR method3W
[] = {'P','O','S','T',0};
3116 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3117 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
3118 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
3119 static const WCHAR dateW
[] = {'D','a','t','e',0};
3120 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
3121 static const WCHAR utf8W
[] = {'u','t','f','-','8',0};
3122 static const WCHAR unauthW
[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3124 IWinHttpRequest
*req
;
3125 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
3126 BSTR date
, today
, connection
, value
= NULL
;
3127 VARIANT async
, empty
, timeout
, body
, body2
, proxy_server
, bypass_list
, data
, cp
;
3128 VARIANT_BOOL succeeded
;
3130 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
3132 IStream
*stream
, *stream2
;
3138 GetSystemTime( &st
);
3139 WinHttpTimeFromSystemTime( &st
, todayW
);
3141 CoInitialize( NULL
);
3142 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3143 ok( hr
== S_OK
, "got %08x\n", hr
);
3145 V_VT( &empty
) = VT_ERROR
;
3146 V_ERROR( &empty
) = 0xdeadbeef;
3148 V_VT( &async
) = VT_BOOL
;
3149 V_BOOL( &async
) = VARIANT_FALSE
;
3151 method
= SysAllocString( method3W
);
3152 url
= SysAllocString( url3W
);
3153 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3154 ok( hr
== S_OK
, "got %08x\n", hr
);
3155 SysFreeString( method
);
3156 SysFreeString( url
);
3158 V_VT( &data
) = VT_BSTR
;
3159 V_BSTR( &data
) = SysAllocString( test_dataW
);
3160 hr
= IWinHttpRequest_Send( req
, data
);
3161 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
3163 SysFreeString( V_BSTR( &data
) );
3165 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
3166 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3168 method
= SysAllocString( method1W
);
3169 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
3170 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3172 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
3173 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3175 url
= SysAllocString( url1W
);
3176 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
3177 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3179 hr
= IWinHttpRequest_Abort( req
);
3180 ok( hr
== S_OK
, "got %08x\n", hr
);
3182 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
3183 ok( hr
== S_OK
, "got %08x\n", hr
);
3185 hr
= IWinHttpRequest_Abort( req
);
3186 ok( hr
== S_OK
, "got %08x\n", hr
);
3188 IWinHttpRequest_Release( req
);
3190 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3191 ok( hr
== S_OK
, "got %08x\n", hr
);
3193 SysFreeString( url
);
3194 url
= SysAllocString( url2W
);
3195 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3196 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3198 SysFreeString( method
);
3199 method
= SysAllocString( method2W
);
3200 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3201 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3203 SysFreeString( method
);
3204 method
= SysAllocString( method1W
);
3205 SysFreeString( url
);
3206 url
= SysAllocString( url1W
);
3207 V_VT( &async
) = VT_ERROR
;
3208 V_ERROR( &async
) = DISP_E_PARAMNOTFOUND
;
3209 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3210 ok( hr
== S_OK
, "got %08x\n", hr
);
3212 V_VT( &cp
) = VT_ERROR
;
3213 V_ERROR( &cp
) = 0xdeadbeef;
3214 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3215 ok( hr
== S_OK
, "got %08x\n", hr
);
3216 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3217 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3219 V_VT( &cp
) = VT_UI4
;
3220 V_UI4( &cp
) = CP_ACP
;
3221 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3222 ok( hr
== S_OK
, "got %08x\n", hr
);
3224 V_VT( &cp
) = VT_ERROR
;
3225 V_ERROR( &cp
) = 0xdeadbeef;
3226 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3227 ok( hr
== S_OK
, "got %08x\n", hr
);
3228 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3229 ok( V_I4( &cp
) == CP_ACP
, "got %u\n", V_I4( &cp
) );
3231 value
= SysAllocString( utf8W
);
3232 V_VT( &cp
) = VT_BSTR
;
3233 V_BSTR( &cp
) = value
;
3234 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3235 ok( hr
== S_OK
, "got %08x\n", hr
);
3236 SysFreeString( value
);
3238 V_VT( &cp
) = VT_ERROR
;
3239 V_ERROR( &cp
) = 0xdeadbeef;
3240 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3241 ok( hr
== S_OK
, "got %08x\n", hr
);
3242 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3243 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3245 hr
= IWinHttpRequest_Abort( req
);
3246 ok( hr
== S_OK
, "got %08x\n", hr
);
3248 hr
= IWinHttpRequest_Send( req
, empty
);
3249 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3251 hr
= IWinHttpRequest_Abort( req
);
3252 ok( hr
== S_OK
, "got %08x\n", hr
);
3254 IWinHttpRequest_Release( req
);
3256 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3257 ok( hr
== S_OK
, "got %08x\n", hr
);
3259 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3260 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3262 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3263 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3265 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3266 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3268 hr
= IWinHttpRequest_get_Status( req
, &status
);
3269 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3271 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3272 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3274 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3275 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3277 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3278 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3280 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3281 ok( hr
== S_OK
, "got %08x\n", hr
);
3283 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3284 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3286 VariantInit( &proxy_server
);
3287 V_VT( &proxy_server
) = VT_ERROR
;
3288 VariantInit( &bypass_list
);
3289 V_VT( &bypass_list
) = VT_ERROR
;
3290 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3291 ok( hr
== S_OK
, "got %08x\n", hr
);
3293 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3294 ok( hr
== S_OK
, "got %08x\n", hr
);
3296 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3297 ok( hr
== S_OK
, "got %08x\n", hr
);
3299 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3300 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3302 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3303 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3305 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3306 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3308 connection
= SysAllocString( connectionW
);
3309 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3310 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3312 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3313 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3315 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
3316 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3318 date
= SysAllocString( dateW
);
3319 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3320 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3322 today
= SysAllocString( todayW
);
3323 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3324 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3326 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
3327 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3329 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3330 ok( hr
== S_OK
, "got %08x\n", hr
);
3332 SysFreeString( method
);
3333 method
= SysAllocString( method1W
);
3334 SysFreeString( url
);
3335 url
= SysAllocString( url1W
);
3336 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3337 ok( hr
== S_OK
, "got %08x\n", hr
);
3339 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3340 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3342 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3343 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3345 hr
= IWinHttpRequest_get_Status( req
, &status
);
3346 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3348 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3349 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3351 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3352 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3354 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3355 ok( hr
== S_OK
, "got %08x\n", hr
);
3357 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3358 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3360 username
= SysAllocString( usernameW
);
3361 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
3362 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3364 password
= SysAllocString( passwordW
);
3365 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
3366 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3368 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
3369 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3371 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3372 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3374 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3375 ok( hr
== S_OK
, "got %08x\n", hr
);
3377 V_VT( &proxy_server
) = VT_BSTR
;
3378 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
3379 V_VT( &bypass_list
) = VT_BSTR
;
3380 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
3381 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3382 ok( hr
== S_OK
, "got %08x\n", hr
);
3384 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
3385 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3387 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3388 ok( hr
== S_OK
, "got %08x\n", hr
);
3390 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3391 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3393 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3394 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3396 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3397 ok( hr
== S_OK
, "got %08x\n", hr
);
3399 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3400 ok( hr
== S_OK
, "got %08x\n", hr
);
3402 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3403 ok( hr
== S_OK
, "got %08x\n", hr
);
3405 hr
= IWinHttpRequest_Send( req
, empty
);
3406 ok( hr
== S_OK
, "got %08x\n", hr
);
3408 hr
= IWinHttpRequest_Send( req
, empty
);
3409 ok( hr
== S_OK
, "got %08x\n", hr
);
3411 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3412 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3414 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3415 ok( hr
== S_OK
, "got %08x\n", hr
);
3416 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3417 SysFreeString( response
);
3419 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3420 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3423 hr
= IWinHttpRequest_get_Status( req
, &status
);
3424 ok( hr
== S_OK
, "got %08x\n", hr
);
3425 trace("Status=%d\n", status
);
3427 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3428 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3430 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3431 ok( hr
== S_OK
, "got %08x\n", hr
);
3432 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
3433 SysFreeString( status_text
);
3435 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3436 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3438 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3439 ok( hr
== S_OK
, "got %08x\n", hr
);
3441 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3442 ok( hr
== S_OK
, "got %08x\n", hr
);
3444 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3445 ok( hr
== S_OK
, "got %08x\n", hr
);
3447 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3448 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3450 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3451 ok( hr
== S_OK
, "got %08x\n", hr
);
3452 SysFreeString( headers
);
3454 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3455 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3457 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3458 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3460 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3461 ok( hr
== S_OK
, "got %08x\n", hr
);
3462 SysFreeString( value
);
3464 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3465 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3467 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3468 ok( hr
== S_OK
, "got %08x\n", hr
);
3470 VariantInit( &timeout
);
3471 V_VT( &timeout
) = VT_I4
;
3472 V_I4( &timeout
) = 10;
3473 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3474 ok( hr
== S_OK
, "got %08x\n", hr
);
3476 hr
= IWinHttpRequest_get_Status( req
, &status
);
3477 ok( hr
== S_OK
, "got %08x\n", hr
);
3479 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3480 ok( hr
== S_OK
, "got %08x\n", hr
);
3481 SysFreeString( status_text
);
3483 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3484 ok( hr
== S_OK
, "got %08x\n", hr
);
3486 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3487 ok( hr
== S_OK
, "got %08x\n", hr
);
3489 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3490 ok( hr
== S_OK
, "got %08x\n", hr
);
3492 hr
= IWinHttpRequest_Send( req
, empty
);
3493 ok( hr
== S_OK
, "got %08x\n", hr
);
3495 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3496 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3498 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3499 ok( hr
== S_OK
, "got %08x\n", hr
);
3500 SysFreeString( response
);
3502 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3503 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3505 VariantInit( &body
);
3506 V_VT( &body
) = VT_ERROR
;
3507 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
3508 ok( hr
== S_OK
, "got %08x\n", hr
);
3509 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
3511 hr
= VariantClear( &body
);
3512 ok( hr
== S_OK
, "got %08x\n", hr
);
3514 VariantInit( &body
);
3515 V_VT( &body
) = VT_ERROR
;
3516 hr
= IWinHttpRequest_get_ResponseStream( req
, &body
);
3517 ok( hr
== S_OK
, "got %08x\n", hr
);
3518 ok( V_VT( &body
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body
) );
3520 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body
), &IID_IStream
, (void **)&stream
);
3521 ok( hr
== S_OK
, "got %08x\n", hr
);
3522 ok( V_UNKNOWN( &body
) == (IUnknown
*)stream
, "got different interface pointer\n" );
3526 hr
= IStream_Read( stream
, buf
, 128, &count
);
3527 ok( hr
== S_OK
, "got %08x\n", hr
);
3528 ok( count
!= 0xdeadbeef, "count not set\n" );
3529 ok( buf
[0], "no data\n" );
3531 VariantInit( &body2
);
3532 V_VT( &body2
) = VT_ERROR
;
3533 hr
= IWinHttpRequest_get_ResponseStream( req
, &body2
);
3534 ok( hr
== S_OK
, "got %08x\n", hr
);
3535 ok( V_VT( &body2
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body2
) );
3536 ok( V_UNKNOWN( &body
) != V_UNKNOWN( &body2
), "got same interface pointer\n" );
3538 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body2
), &IID_IStream
, (void **)&stream2
);
3539 ok( hr
== S_OK
, "got %08x\n", hr
);
3540 ok( V_UNKNOWN( &body2
) == (IUnknown
*)stream2
, "got different interface pointer\n" );
3541 IStream_Release( stream2
);
3543 hr
= VariantClear( &body
);
3544 ok( hr
== S_OK
, "got %08x\n", hr
);
3546 hr
= VariantClear( &body2
);
3547 ok( hr
== S_OK
, "got %08x\n", hr
);
3549 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3550 ok( hr
== S_OK
, "got %08x\n", hr
);
3552 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3553 ok( hr
== S_OK
, "got %08x\n", hr
);
3555 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3556 ok( hr
== S_OK
, "got %08x\n", hr
);
3557 SysFreeString( headers
);
3559 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3560 ok( hr
== S_OK
, "got %08x\n", hr
);
3561 SysFreeString( value
);
3563 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3564 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3566 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3567 ok( hr
== S_OK
, "got %08x\n", hr
);
3569 hr
= IWinHttpRequest_Send( req
, empty
);
3570 ok( hr
== S_OK
, "got %08x\n", hr
);
3572 hr
= IWinHttpRequest_Abort( req
);
3573 ok( hr
== S_OK
, "got %08x\n", hr
);
3575 hr
= IWinHttpRequest_Abort( req
);
3576 ok( hr
== S_OK
, "got %08x\n", hr
);
3578 IWinHttpRequest_Release( req
);
3581 hr
= IStream_Seek( stream
, pos
, STREAM_SEEK_SET
, NULL
);
3582 ok( hr
== S_OK
, "got %08x\n", hr
);
3586 hr
= IStream_Read( stream
, buf
, 128, &count
);
3587 ok( hr
== S_OK
, "got %08x\n", hr
);
3588 ok( count
!= 0xdeadbeef, "count not set\n" );
3589 ok( buf
[0], "no data\n" );
3590 IStream_Release( stream
);
3592 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3593 ok( hr
== S_OK
, "got %08x\n", hr
);
3595 V_VT( &async
) = VT_I4
;
3597 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3598 ok( hr
== S_OK
, "got %08x\n", hr
);
3600 hr
= IWinHttpRequest_Send( req
, empty
);
3601 ok( hr
== S_OK
, "got %08x\n", hr
);
3603 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3604 ok( hr
== S_OK
, "got %08x\n", hr
);
3606 IWinHttpRequest_Release( req
);
3608 SysFreeString( method
);
3609 SysFreeString( url
);
3610 SysFreeString( username
);
3611 SysFreeString( password
);
3612 SysFreeString( connection
);
3613 SysFreeString( date
);
3614 SysFreeString( today
);
3615 VariantClear( &proxy_server
);
3616 VariantClear( &bypass_list
);
3618 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3619 ok( hr
== S_OK
, "got %08x\n", hr
);
3621 url
= SysAllocString( test_winehq_https
);
3622 method
= SysAllocString( method3W
);
3623 V_VT( &async
) = VT_BOOL
;
3624 V_BOOL( &async
) = VARIANT_FALSE
;
3625 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3626 ok( hr
== S_OK
, "got %08x\n", hr
);
3627 SysFreeString( method
);
3628 SysFreeString( url
);
3630 hr
= IWinHttpRequest_Send( req
, empty
);
3631 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)), "got %08x\n", hr
);
3634 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3635 ok( hr
== S_OK
, "got %08x\n", hr
);
3636 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3637 SysFreeString( response
);
3640 IWinHttpRequest_Release( req
);
3642 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3643 ok( hr
== S_OK
, "got %08x\n", hr
);
3645 sprintf( buf
, "http://localhost:%d/auth", port
);
3646 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, bufW
, sizeof(bufW
)/sizeof(bufW
[0]) );
3647 url
= SysAllocString( bufW
);
3648 method
= SysAllocString( method3W
);
3649 V_VT( &async
) = VT_BOOL
;
3650 V_BOOL( &async
) = VARIANT_FALSE
;
3651 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3652 ok( hr
== S_OK
, "got %08x\n", hr
);
3653 SysFreeString( method
);
3654 SysFreeString( url
);
3656 hr
= IWinHttpRequest_get_Status( req
, &status
);
3657 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3659 V_VT( &data
) = VT_BSTR
;
3660 V_BSTR( &data
) = SysAllocString( test_dataW
);
3661 hr
= IWinHttpRequest_Send( req
, data
);
3662 ok( hr
== S_OK
, "got %08x\n", hr
);
3663 SysFreeString( V_BSTR( &data
) );
3665 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3666 ok( hr
== S_OK
, "got %08x\n", hr
);
3667 ok( !memcmp( response
, unauthW
, sizeof(unauthW
) ), "got %s\n", wine_dbgstr_w(response
) );
3668 SysFreeString( response
);
3670 status
= 0xdeadbeef;
3671 hr
= IWinHttpRequest_get_Status( req
, &status
);
3672 ok( hr
== S_OK
, "got %08x\n", hr
);
3673 ok( status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
3675 IWinHttpRequest_Release( req
);
3680 static void request_get_property(IWinHttpRequest
*request
, int property
, VARIANT
*ret
)
3686 memset(¶ms
, 0, sizeof(params
));
3687 params
.cNamedArgs
= 0;
3688 params
.rgdispidNamedArgs
= NULL
;
3690 params
.rgvarg
= &arg
;
3693 V_I4(&arg
) = property
;
3695 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3696 DISPATCH_PROPERTYGET
, ¶ms
, ret
, NULL
, NULL
);
3697 ok(hr
== S_OK
, "error %#x\n", hr
);
3700 static void test_IWinHttpRequest_Invoke(void)
3702 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
3703 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};
3704 WCHAR openW
[] = {'O','p','e','n',0};
3705 WCHAR optionW
[] = {'O','p','t','i','o','n',0};
3706 OLECHAR
*open
= openW
, *option
= optionW
;
3709 IWinHttpRequest
*request
;
3710 IDispatch
*dispatch
;
3713 VARIANT arg
[3], ret
;
3720 hr
= CLSIDFromProgID(regid
, &clsid
);
3721 ok(hr
== S_OK
, "CLSIDFromProgID error %#x\n", hr
);
3722 bret
= IsEqualIID(&clsid
, &CLSID_WinHttpRequest
);
3723 ok(bret
|| broken(!bret
) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid
));
3725 hr
= CoCreateInstance(&CLSID_WinHttpRequest
, 0, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&request
);
3726 ok(hr
== S_OK
, "error %#x\n", hr
);
3728 hr
= IWinHttpRequest_QueryInterface(request
, &IID_IDispatch
, (void **)&dispatch
);
3729 ok(hr
== S_OK
, "error %#x\n", hr
);
3730 IDispatch_Release(dispatch
);
3732 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &open
, 1, 0x0409, &id
);
3733 ok(hr
== S_OK
, "error %#x\n", hr
);
3734 ok(id
== DISPID_HTTPREQUEST_OPEN
, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id
);
3736 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &option
, 1, 0x0409, &id
);
3737 ok(hr
== S_OK
, "error %#x\n", hr
);
3738 ok(id
== DISPID_HTTPREQUEST_OPTION
, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id
);
3740 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3741 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3742 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3744 memset(¶ms
, 0, sizeof(params
));
3746 params
.cNamedArgs
= 0;
3747 params
.rgvarg
= arg
;
3748 V_VT(&arg
[0]) = VT_I4
;
3749 V_I4(&arg
[0]) = 1252;
3750 V_VT(&arg
[1]) = VT_R8
;
3751 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3753 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3754 DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3755 ok(hr
== S_OK
, "error %#x\n", hr
);
3757 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3758 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3759 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3761 memset(¶ms
, 0, sizeof(params
));
3763 params
.cNamedArgs
= 0;
3764 params
.rgvarg
= arg
;
3765 V_VT(&arg
[0]) = VT_I4
;
3766 V_I4(&arg
[0]) = 1252;
3767 V_VT(&arg
[1]) = VT_R8
;
3768 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3770 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3771 DISPATCH_METHOD
| DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3772 ok(hr
== S_OK
, "error %#x\n", hr
);
3774 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3775 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3776 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3778 memset(¶ms
, 0, sizeof(params
));
3780 params
.cNamedArgs
= 0;
3781 params
.rgvarg
= arg
;
3782 V_VT(&arg
[0]) = VT_I4
;
3783 V_I4(&arg
[0]) = 1252;
3784 V_VT(&arg
[1]) = VT_R8
;
3785 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3787 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3788 DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3789 ok(hr
== S_OK
, "error %#x\n", hr
);
3791 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3792 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3793 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3795 memset(¶ms
, 0, sizeof(params
));
3797 params
.cNamedArgs
= 0;
3798 params
.rgvarg
= arg
;
3799 V_VT(&arg
[0]) = VT_BSTR
;
3800 utf8
= SysAllocString(utf8W
);
3801 V_BSTR(&arg
[0]) = utf8
;
3802 V_VT(&arg
[1]) = VT_R8
;
3803 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3804 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3805 ok(hr
== S_OK
, "error %#x\n", hr
);
3807 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3808 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3809 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3812 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, &err
);
3813 ok(hr
== S_OK
, "error %#x\n", hr
);
3815 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3816 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3817 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3820 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3821 ok(hr
== S_OK
, "error %#x\n", hr
);
3823 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3824 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3825 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3827 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
3828 ok(hr
== S_OK
, "error %#x\n", hr
);
3830 hr
= IWinHttpRequest_Invoke(request
, 255, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
3831 ok(hr
== DISP_E_MEMBERNOTFOUND
, "error %#x\n", hr
);
3834 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3835 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
3838 if (0) /* crashes */
3839 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, &ret
, NULL
, &err
);
3842 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3843 ok(hr
== DISP_E_TYPEMISMATCH
, "error %#x\n", hr
);
3845 VariantInit(&arg
[2]);
3847 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3849 ok(hr
== S_OK
, "error %#x\n", hr
);
3851 VariantInit(&arg
[0]);
3852 VariantInit(&arg
[1]);
3853 VariantInit(&arg
[2]);
3856 V_VT(&arg
[0]) = VT_I4
;
3857 V_I4(&arg
[0]) = WinHttpRequestOption_URLCodePage
;
3858 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3859 ok(hr
== S_OK
, "error %#x\n", hr
);
3861 V_VT(&ret
) = 0xdead;
3862 V_I4(&ret
) = 0xbeef;
3863 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, &ret
, NULL
, NULL
);
3864 ok(hr
== S_OK
, "error %#x\n", hr
);
3865 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3866 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3868 V_VT(&ret
) = 0xdead;
3869 V_I4(&ret
) = 0xbeef;
3870 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
3871 ok(hr
== S_OK
, "error %#x\n", hr
);
3872 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3873 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3875 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3876 ok(hr
== S_OK
, "error %#x\n", hr
);
3878 V_VT(&ret
) = 0xdead;
3879 V_I4(&ret
) = 0xbeef;
3880 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, &ret
, NULL
, NULL
);
3881 ok(hr
== S_OK
, "error %#x\n", hr
);
3882 ok(V_VT(&ret
) == VT_EMPTY
, "expected VT_EMPTY, got %d\n", V_VT(&ret
));
3883 ok(V_I4(&ret
) == 0xbeef || V_I4(&ret
) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret
));
3885 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, NULL
, NULL
, NULL
);
3886 ok(hr
== S_OK
, "error %#x\n", hr
);
3888 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3889 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
3892 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3894 ok(hr
== S_OK
, "error %#x\n", hr
);
3897 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3898 ok(hr
== DISP_E_PARAMNOTFOUND
, "error %#x\n", hr
);
3900 SysFreeString(utf8
);
3903 V_VT(&arg
[0]) = VT_I4
;
3904 V_I4(&arg
[0]) = AutoLogonPolicy_Never
;
3906 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY
, &IID_NULL
, 0,
3907 DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
3908 ok(hr
== S_OK
, "error %#x\n", hr
);
3910 IWinHttpRequest_Release(request
);
3915 static void test_WinHttpDetectAutoProxyConfigUrl(void)
3921 if (0) /* crashes on some win2k systems */
3923 SetLastError(0xdeadbeef);
3924 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
3925 error
= GetLastError();
3926 ok( !ret
, "expected failure\n" );
3927 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3930 SetLastError(0xdeadbeef);
3931 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
3932 error
= GetLastError();
3933 ok( !ret
, "expected failure\n" );
3934 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3936 if (0) /* crashes on some win2k systems */
3938 SetLastError(0xdeadbeef);
3939 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
3940 error
= GetLastError();
3941 ok( !ret
, "expected failure\n" );
3942 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3944 url
= (WCHAR
*)0xdeadbeef;
3945 SetLastError(0xdeadbeef);
3946 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
3947 error
= GetLastError();
3950 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
3951 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
3955 trace("%s\n", wine_dbgstr_w(url
));
3959 url
= (WCHAR
*)0xdeadbeef;
3960 SetLastError(0xdeadbeef);
3961 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
3962 error
= GetLastError();
3965 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
3966 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
3970 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
3971 trace("%s\n", wine_dbgstr_w(url
));
3976 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
3980 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
3982 memset( &cfg
, 0, sizeof(cfg
) );
3984 SetLastError(0xdeadbeef);
3985 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
3986 error
= GetLastError();
3987 ok( !ret
, "expected failure\n" );
3988 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3990 SetLastError(0xdeadbeef);
3991 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
3992 error
= GetLastError();
3993 ok( ret
, "expected success\n" );
3994 ok( error
== ERROR_SUCCESS
|| broken(error
== ERROR_NO_TOKEN
) /* < win7 */, "got %u\n", error
);
3996 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
3997 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
3998 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
3999 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
4000 GlobalFree( cfg
.lpszAutoConfigUrl
);
4001 GlobalFree( cfg
.lpszProxy
);
4002 GlobalFree( cfg
.lpszProxyBypass
);
4005 static void test_WinHttpGetProxyForUrl(void)
4007 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4008 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4009 static const WCHAR emptyW
[] = {0};
4013 WINHTTP_AUTOPROXY_OPTIONS options
;
4014 WINHTTP_PROXY_INFO info
;
4016 memset( &options
, 0, sizeof(options
) );
4018 SetLastError(0xdeadbeef);
4019 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
4020 error
= GetLastError();
4021 ok( !ret
, "expected failure\n" );
4022 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
4024 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4025 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
4027 SetLastError(0xdeadbeef);
4028 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
4029 error
= GetLastError();
4030 ok( !ret
, "expected failure\n" );
4031 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4033 SetLastError(0xdeadbeef);
4034 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
4035 error
= GetLastError();
4036 ok( !ret
, "expected failure\n" );
4037 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4039 SetLastError(0xdeadbeef);
4040 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
4041 error
= GetLastError();
4042 ok( !ret
, "expected failure\n" );
4043 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4045 SetLastError(0xdeadbeef);
4046 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4047 error
= GetLastError();
4048 ok( !ret
, "expected failure\n" );
4049 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4051 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4052 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4054 SetLastError(0xdeadbeef);
4055 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
4056 error
= GetLastError();
4057 ok( !ret
, "expected failure\n" );
4058 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4060 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4061 options
.dwAutoDetectFlags
= 0;
4063 SetLastError(0xdeadbeef);
4064 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4065 error
= GetLastError();
4066 ok( !ret
, "expected failure\n" );
4067 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4069 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
4070 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4072 SetLastError(0xdeadbeef);
4073 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4074 error
= GetLastError();
4075 ok( !ret
, "expected failure\n" );
4076 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4078 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4079 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4081 memset( &info
, 0, sizeof(info
) );
4082 SetLastError(0xdeadbeef);
4083 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4084 error
= GetLastError();
4087 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4088 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4089 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4090 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4091 GlobalFree( info
.lpszProxy
);
4092 GlobalFree( info
.lpszProxyBypass
);
4095 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
4096 options
.dwAutoDetectFlags
= 0;
4097 options
.lpszAutoConfigUrl
= wpadW
;
4099 memset( &info
, 0, sizeof(info
) );
4100 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4103 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4104 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4105 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4106 GlobalFree( info
.lpszProxy
);
4107 GlobalFree( info
.lpszProxyBypass
);
4109 WinHttpCloseHandle( session
);
4112 static void test_chunked_read(void)
4114 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4115 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
4118 HINTERNET ses
, con
= NULL
, req
= NULL
;
4121 trace( "starting chunked read test\n" );
4123 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4124 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
4125 if (!ses
) goto done
;
4127 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
4128 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
4129 if (!con
) goto done
;
4131 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
4132 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4133 if (!req
) goto done
;
4135 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
4136 err
= GetLastError();
4137 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
4139 skip("connection failed, skipping\n");
4142 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4144 ret
= WinHttpReceiveResponse( req
, NULL
);
4145 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4148 len
= sizeof(header
);
4149 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
4150 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4151 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
4152 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
4155 len
= sizeof(header
);
4156 SetLastError( 0xdeadbeef );
4157 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
4158 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
4159 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
4161 trace( "entering query loop\n" );
4165 ret
= WinHttpQueryDataAvailable( req
, &len
);
4166 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4167 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4168 trace( "got %u available\n", len
);
4172 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
4174 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
4176 buf
[bytes_read
] = 0;
4177 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
4178 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
4179 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
4181 HeapFree( GetProcessHeap(), 0, buf
);
4182 if (!bytes_read
) break;
4189 if (req
) WinHttpCloseHandle( req
);
4190 if (con
) WinHttpCloseHandle( con
);
4191 if (ses
) WinHttpCloseHandle( ses
);
4194 START_TEST (winhttp
)
4196 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
4197 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
4198 struct server_info si
;
4204 test_WinHttpTimeFromSystemTime();
4205 test_WinHttpTimeToSystemTime();
4206 test_WinHttpAddHeaders();
4207 test_secure_connection();
4208 test_request_parameter_defaults();
4210 test_set_default_proxy_config();
4211 test_empty_headers_param();
4213 test_resolve_timeout();
4215 test_IWinHttpRequest_Invoke();
4216 test_WinHttpDetectAutoProxyConfigUrl();
4217 test_WinHttpGetIEProxyConfigForCurrentUser();
4218 test_WinHttpGetProxyForUrl();
4219 test_chunked_read();
4221 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
4224 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
4225 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
4227 ret
= WaitForSingleObject(si
.event
, 10000);
4228 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
4229 if (ret
!= WAIT_OBJECT_0
)
4232 test_IWinHttpRequest(si
.port
);
4233 test_connection_info(si
.port
);
4234 test_basic_request(si
.port
, NULL
, basicW
);
4235 test_no_headers(si
.port
);
4236 test_no_content(si
.port
);
4237 test_head_request(si
.port
);
4238 test_not_modified(si
.port
);
4239 test_basic_authentication(si
.port
);
4240 test_bad_header(si
.port
);
4241 test_multiple_reads(si
.port
);
4242 test_cookies(si
.port
);
4244 /* send the basic request again to shutdown the server thread */
4245 test_basic_request(si
.port
, NULL
, quitW
);
4247 WaitForSingleObject(thread
, 3000);