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
32 #include <httprequest.h>
33 #include <httprequestid.h>
35 #include "wine/test.h"
37 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
39 static const WCHAR test_useragent
[] =
40 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
41 static const WCHAR test_winehq
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
42 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};
43 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
45 static BOOL
proxy_active(void)
47 WINHTTP_PROXY_INFO proxy_info
;
50 SetLastError(0xdeadbeef);
51 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
53 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
54 "got %u\n", GetLastError());
55 active
= (proxy_info
.lpszProxy
!= NULL
);
57 GlobalFree(proxy_info
.lpszProxy
);
58 if (proxy_info
.lpszProxyBypass
!= NULL
)
59 GlobalFree(proxy_info
.lpszProxyBypass
);
67 static void test_QueryOption(void)
70 HINTERNET session
, request
, connection
;
73 SetLastError(0xdeadbeef);
74 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
75 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
77 SetLastError(0xdeadbeef);
78 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
79 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
80 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
81 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
84 SetLastError(0xdeadbeef);
85 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
86 ok(!ret
, "should fail to query option\n");
87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
89 ok(size
== 4, "expected 4, got %u\n", size
);
92 size
= sizeof(feature
) - 1;
93 SetLastError(0xdeadbeef);
94 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
95 ok(!ret
, "should fail to query option\n");
96 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
97 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
98 ok(size
== 4, "expected 4, got %u\n", size
);
100 feature
= 0xdeadbeef;
101 size
= sizeof(feature
) + 1;
102 SetLastError(0xdeadbeef);
103 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
104 ok(ret
, "failed to query option %u\n", GetLastError());
105 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
106 "got %u\n", GetLastError());
107 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
108 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
109 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
111 SetLastError(0xdeadbeef);
112 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
113 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
114 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
115 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
117 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
118 SetLastError(0xdeadbeef);
119 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
120 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
121 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
122 "expected ERROR_INSUFFICIENT_BUFFER, 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
));
134 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
136 feature
= 0xdeadbeef;
137 size
= sizeof(feature
);
138 SetLastError(0xdeadbeef);
139 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
140 ok(ret
, "failed to query option %u\n", GetLastError());
141 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
142 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
144 feature
= WINHTTP_DISABLE_COOKIES
;
145 SetLastError(0xdeadbeef);
146 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
147 ok(!ret
, "should fail to set disable feature for a session\n");
148 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
149 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151 SetLastError(0xdeadbeef);
152 connection
= WinHttpConnect(session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
153 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
155 feature
= WINHTTP_DISABLE_COOKIES
;
156 SetLastError(0xdeadbeef);
157 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
158 ok(!ret
, "should fail to set disable feature for a connection\n");
159 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
160 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
162 SetLastError(0xdeadbeef);
163 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
164 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
165 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
167 skip("Network unreachable, skipping the test\n");
171 feature
= 0xdeadbeef;
172 size
= sizeof(feature
);
173 SetLastError(0xdeadbeef);
174 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
175 ok(!ret
, "should fail to query disable feature for a request\n");
176 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
177 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
180 size
= sizeof(feature
);
181 SetLastError(0xdeadbeef);
182 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
183 ok(ret
, "failed to set feature %u\n", GetLastError());
185 feature
= 0xffffffff;
186 size
= sizeof(feature
);
187 SetLastError(0xdeadbeef);
188 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
189 ok(ret
, "failed to set feature %u\n", GetLastError());
191 feature
= WINHTTP_DISABLE_COOKIES
;
192 size
= sizeof(feature
);
193 SetLastError(0xdeadbeef);
194 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
195 ok(ret
, "failed to set feature %u\n", GetLastError());
198 SetLastError(0xdeadbeef);
199 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
200 ok(!ret
, "should fail to query disable feature for a request\n");
201 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
202 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
204 SetLastError(0xdeadbeef);
205 ret
= WinHttpCloseHandle(request
);
206 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
209 SetLastError(0xdeadbeef);
210 ret
= WinHttpCloseHandle(connection
);
211 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
212 SetLastError(0xdeadbeef);
213 ret
= WinHttpCloseHandle(session
);
214 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
217 static void test_OpenRequest (void)
220 HINTERNET session
, request
, connection
;
223 SetLastError(0xdeadbeef);
224 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
225 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
226 err
= GetLastError();
227 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
228 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
230 /* Test with a bad server name */
231 SetLastError(0xdeadbeef);
232 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
233 err
= GetLastError();
234 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
235 ok(err
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err
);
237 /* Test with a valid server name */
238 SetLastError(0xdeadbeef);
239 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
240 err
= GetLastError();
241 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", err
);
242 ok(err
== ERROR_SUCCESS
|| broken(err
== WSAEINVAL
) /* < win7 */, "got %u\n", err
);
244 SetLastError(0xdeadbeef);
245 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
246 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
247 err
= GetLastError();
248 if (request
== NULL
&& err
== ERROR_WINHTTP_NAME_NOT_RESOLVED
)
250 skip("Network unreachable, skipping.\n");
253 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", err
);
254 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
256 SetLastError(0xdeadbeef);
257 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
258 err
= GetLastError();
259 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
261 skip("Connection failed, skipping.\n");
264 ok(ret
, "WinHttpSendRequest failed: %u\n", err
);
265 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
267 SetLastError(0xdeadbeef);
268 ret
= WinHttpCloseHandle(request
);
269 err
= GetLastError();
270 ok(ret
, "WinHttpCloseHandle failed on closing request, got %u.\n", err
);
271 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
274 ret
= WinHttpCloseHandle(connection
);
275 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
276 ret
= WinHttpCloseHandle(session
);
277 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
281 static void test_empty_headers_param(void)
283 static const WCHAR empty
[] = {0};
284 HINTERNET ses
, con
, req
;
288 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
289 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
291 con
= WinHttpConnect(ses
, test_winehq
, 80, 0);
292 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
294 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
295 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
297 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
298 err
= GetLastError();
299 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
301 skip("connection failed, skipping\n");
304 ok(ret
, "failed to send request %u\n", GetLastError());
307 WinHttpCloseHandle(req
);
308 WinHttpCloseHandle(con
);
309 WinHttpCloseHandle(ses
);
312 static void test_SendRequest (void)
314 static const WCHAR content_type
[] =
315 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
316 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
317 static const WCHAR test_file
[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
318 static const WCHAR test_verb
[] = {'P','O','S','T',0};
319 static CHAR post_data
[] = "mode=Test";
320 static const char test_post
[] = "mode => Test\0\n";
321 HINTERNET session
, request
, connection
;
322 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
, err
;
329 total_len
= optional_len
= sizeof(post_data
);
330 memset(buffer
, 0xff, sizeof(buffer
));
332 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
333 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
334 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
336 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
337 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
339 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
340 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
341 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
343 skip("Network unreachable, skipping.\n");
346 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
347 if (!request
) goto done
;
349 context
= 0xdeadbeef;
350 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
351 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
354 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
355 err
= GetLastError();
356 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
358 skip("connection failed, skipping\n");
361 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
364 size
= sizeof(context
);
365 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
366 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
367 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
369 for (i
= 3; post_data
[i
]; i
++)
372 SetLastError(0xdeadbeef);
373 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
376 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
377 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
379 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
381 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
382 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
386 SetLastError(0xdeadbeef);
387 ret
= WinHttpReceiveResponse(request
, NULL
);
388 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == ERROR_NO_TOKEN
) /* < win7 */,
389 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
390 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
393 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
394 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
396 ok(bytes_rw
== sizeof(test_post
) - 1, "Read %u bytes\n", bytes_rw
);
397 ok(!memcmp(buffer
, test_post
, sizeof(test_post
) - 1), "Data read did not match.\n");
400 ret
= WinHttpCloseHandle(request
);
401 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
402 ret
= WinHttpCloseHandle(connection
);
403 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
404 ret
= WinHttpCloseHandle(session
);
405 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
408 static void test_WinHttpTimeFromSystemTime(void)
411 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
412 static const WCHAR expected_string
[] =
413 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
414 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
415 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
418 SetLastError(0xdeadbeef);
419 ret
= WinHttpTimeFromSystemTime(&time
, NULL
);
420 err
= GetLastError();
421 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
422 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
424 SetLastError(0xdeadbeef);
425 ret
= WinHttpTimeFromSystemTime(NULL
, time_string
);
426 err
= GetLastError();
427 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
428 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
430 SetLastError(0xdeadbeef);
431 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
432 err
= GetLastError();
433 ok(ret
, "WinHttpTimeFromSystemTime failed: %u\n", err
);
434 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
435 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
436 "Time string returned did not match expected time string.\n");
439 static void test_WinHttpTimeToSystemTime(void)
443 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
444 static const WCHAR time_string1
[] =
445 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
446 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
447 static const WCHAR time_string2
[] =
448 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
449 '1','0',' ','0','5',' ','5','2','\n',0};
452 SetLastError(0xdeadbeef);
453 ret
= WinHttpTimeToSystemTime(time_string1
, NULL
);
454 err
= GetLastError();
455 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
456 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
458 SetLastError(0xdeadbeef);
459 ret
= WinHttpTimeToSystemTime(NULL
, &time
);
460 err
= GetLastError();
461 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
462 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
464 SetLastError(0xdeadbeef);
465 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
466 err
= GetLastError();
467 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
468 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
469 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
470 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
472 SetLastError(0xdeadbeef);
473 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
474 err
= GetLastError();
475 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
476 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
477 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
478 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
481 static void test_WinHttpAddHeaders(void)
483 HINTERNET session
, request
, connection
;
485 WCHAR buffer
[MAX_PATH
];
486 WCHAR check_buffer
[MAX_PATH
];
487 DWORD err
, index
, len
, oldlen
;
489 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
490 static const WCHAR test_verb
[] = {'P','O','S','T',0};
491 static const WCHAR test_header_begin
[] =
492 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
493 static const WCHAR full_path_test_header_begin
[] =
494 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
495 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
496 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
497 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
498 static const WCHAR test_header_name2
[] = {'n','a','m','e',0};
499 static const WCHAR test_header_name3
[] = {'a',0};
500 static const WCHAR test_header_range
[] = {'R','a','n','g','e',0};
501 static const WCHAR test_header_range_bytes
[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
502 static const WCHAR test_header_bytes
[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
504 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
505 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
506 static const WCHAR test_flag_coalesce_comma
[] =
507 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
508 static const WCHAR test_flag_coalesce_comma_reverse
[] =
509 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
510 static const WCHAR test_flag_coalesce_semicolon
[] =
511 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
512 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
513 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
515 static const WCHAR field
[] = {'f','i','e','l','d',0};
516 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
517 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
518 static const WCHAR empty
[] = {0};
520 static const WCHAR test_headers
[][14] =
522 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
523 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
524 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
525 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
526 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
527 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
528 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
534 {' ','e',' ',':','f',0},
535 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
536 {'n','a','m','e',':',' ','v','a','l','u','e',0},
537 {'n','a','m','e',':',0}
539 static const WCHAR test_indices
[][6] =
541 {'t','e','s','t','1',0},
542 {'t','e','s','t','2',0},
543 {'t','e','s','t','3',0},
544 {'t','e','s','t','4',0}
547 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
548 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
549 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
551 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
552 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
554 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
555 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
556 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
558 skip("Network unreachable, skipping.\n");
561 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
564 len
= sizeof(buffer
);
565 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
566 test_header_name
, buffer
, &len
, &index
);
567 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
568 SetLastError(0xdeadbeef);
569 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
570 err
= GetLastError();
571 ok(ret
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, err
);
572 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
575 len
= sizeof(buffer
);
576 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
577 test_header_name
, buffer
, &len
, &index
);
578 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
579 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
580 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
581 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
583 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
584 test_header_name
, buffer
, &len
, &index
);
585 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
587 /* Try to fetch the header info with a buffer that's big enough to fit the
588 * string but not the NULL terminator.
591 len
= 5*sizeof(WCHAR
);
592 memset(check_buffer
, 0xab, sizeof(check_buffer
));
593 memcpy(buffer
, check_buffer
, sizeof(buffer
));
594 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
595 test_header_name
, buffer
, &len
, &index
);
596 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
597 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
598 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
599 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
601 /* Try with a NULL buffer */
603 len
= sizeof(buffer
);
604 SetLastError(0xdeadbeef);
605 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
606 test_header_name
, NULL
, &len
, &index
);
607 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
608 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
609 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
610 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
612 /* Try with a NULL buffer and a length that's too small */
615 SetLastError(0xdeadbeef);
616 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
617 test_header_name
, NULL
, &len
, &index
);
618 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
619 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
620 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
621 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
622 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
626 SetLastError(0xdeadbeef);
627 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
628 test_header_name
, NULL
, &len
, &index
);
629 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
630 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
631 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
632 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
633 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
638 len
= sizeof(buffer
);
639 memset(buffer
, 0xff, sizeof(buffer
));
640 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
641 test_header_name
, buffer
, &len
, &index
);
642 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
643 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
644 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
645 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
646 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
647 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
648 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
649 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
650 "WinHttpQueryHeaders returned invalid end of header string.\n");
651 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
655 SetLastError(0xdeadbeef);
656 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
657 test_header_name
, NULL
, &len
, &index
);
658 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
659 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
660 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
661 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
662 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
666 len
= sizeof(buffer
);
667 memset(buffer
, 0xff, sizeof(buffer
));
668 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
669 test_header_name
, buffer
, &len
, &index
);
670 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
671 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
672 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
673 "no double NULL terminator\n");
674 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
675 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
676 "invalid beginning of header string.\n");
677 ok(index
== 0, "header index was incremented\n");
679 /* tests for more indices */
680 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
681 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
684 len
= sizeof(buffer
);
685 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
686 test_header_name
, buffer
, &len
, &index
);
687 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
688 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
689 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
691 len
= sizeof(buffer
);
692 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
693 test_header_name
, buffer
, &len
, &index
);
694 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
698 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
699 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
702 len
= sizeof(buffer
);
703 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
704 test_header_name
, buffer
, &len
, &index
);
705 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
706 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
707 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
708 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
710 len
= sizeof(buffer
);
711 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
712 test_header_name
, buffer
, &len
, &index
);
713 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
714 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
717 /* add if new flag */
718 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
719 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
722 len
= sizeof(buffer
);
723 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
724 test_header_name
, buffer
, &len
, &index
);
725 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
726 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
727 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\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
== 2, "WinHttpQueryHeaders failed to increment index.\n");
734 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 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
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
742 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
743 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
746 len
= sizeof(buffer
);
747 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
748 test_header_name
, buffer
, &len
, &index
);
749 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
750 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
751 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
752 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
754 len
= sizeof(buffer
);
755 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
756 test_header_name
, buffer
, &len
, &index
);
757 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
758 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
759 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 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
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
766 /* coalesce with comma flag */
767 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
768 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
771 len
= sizeof(buffer
);
772 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
773 test_header_name
, buffer
, &len
, &index
);
774 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
775 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
776 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
777 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
778 "WinHttpQueryHeaders returned incorrect string.\n");
780 len
= sizeof(buffer
);
781 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
782 test_header_name
, buffer
, &len
, &index
);
783 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
784 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
785 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "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
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
793 /* coalesce with semicolon flag */
794 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
795 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
798 len
= sizeof(buffer
);
799 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
800 test_header_name
, buffer
, &len
, &index
);
801 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
802 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
803 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
804 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
805 "WinHttpQueryHeaders returned incorrect string.\n");
807 len
= sizeof(buffer
);
808 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
809 test_header_name
, buffer
, &len
, &index
);
810 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
811 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
812 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "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
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
819 /* add and replace flags */
820 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
821 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
824 len
= sizeof(buffer
);
825 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
826 test_header_name
, buffer
, &len
, &index
);
827 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
828 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
829 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\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
== 2, "WinHttpQueryHeaders failed to increment index.\n");
836 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 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
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
843 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
844 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
846 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
847 ok(ret
, "WinHttpAddRequestHeaders failed\n");
850 memset(buffer
, 0xff, sizeof(buffer
));
851 len
= sizeof(buffer
);
852 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
853 test_header_name3
, buffer
, &len
, &index
);
854 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
855 ok(!memcmp(buffer
, empty
, sizeof(empty
)), "unexpected result\n");
857 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
858 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
860 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
861 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
863 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
864 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
866 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
867 ok(ret
, "WinHttpAddRequestHeaders failed\n");
871 len
= sizeof(buffer
);
872 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
873 field
, buffer
, &len
, &index
);
874 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
875 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
877 SetLastError(0xdeadbeef);
878 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, 0,
879 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
880 err
= GetLastError();
881 ok(!ret
, "unexpected success\n");
882 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
884 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, ~0u,
885 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
886 ok(ret
, "failed to add header: %u\n", GetLastError());
889 len
= sizeof(buffer
);
890 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
891 test_header_range
, buffer
, &len
, &index
);
892 ok(ret
, "failed to get range header %u\n", GetLastError());
893 ok(!memcmp(buffer
, test_header_bytes
, sizeof(test_header_bytes
)), "incorrect string returned\n");
894 ok(len
== lstrlenW(test_header_bytes
) * sizeof(WCHAR
), "wrong length %u\n", len
);
895 ok(index
== 1, "wrong index %u\n", index
);
898 len
= sizeof(buffer
);
899 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
900 test_header_name2
, buffer
, &len
, &index
);
901 ok(!ret
, "unexpected success\n");
903 SetLastError(0xdeadbeef);
904 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
905 err
= GetLastError();
906 ok(!ret
, "unexpected success\n");
907 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
909 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
910 ok(ret
, "got %u\n", GetLastError());
913 len
= sizeof(buffer
);
914 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
915 test_header_name2
, buffer
, &len
, &index
);
916 ok(ret
, "got %u\n", GetLastError());
917 ok(index
== 1, "wrong index %u\n", index
);
918 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
920 ret
= WinHttpAddRequestHeaders(request
, test_headers
[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
921 ok(ret
, "got %u\n", GetLastError());
924 len
= sizeof(buffer
);
925 SetLastError(0xdeadbeef);
926 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
927 test_header_name2
, buffer
, &len
, &index
);
928 err
= GetLastError();
929 ok(!ret
, "unexpected success\n");
930 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
932 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], -1L, 0);
933 ok(ret
, "got %u\n", GetLastError());
936 len
= sizeof(buffer
);
937 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
938 test_header_name2
, buffer
, &len
, &index
);
939 ok(ret
, "got %u\n", GetLastError());
940 ok(index
== 1, "wrong index %u\n", index
);
941 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
943 ret
= WinHttpCloseHandle(request
);
944 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
946 ret
= WinHttpCloseHandle(connection
);
947 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
948 ret
= WinHttpCloseHandle(session
);
949 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
953 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
955 DWORD flags
= *(DWORD
*)buf
;
959 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
962 #define X(x) if (flags & x) trace("%s\n", #x);
963 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
964 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
965 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
966 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
967 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
968 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
969 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
973 static void test_secure_connection(void)
975 static const char data_start
[] = "<!DOCTYPE html PUBLIC";
976 HINTERNET ses
, con
, req
;
977 DWORD size
, status
, policy
, bitness
, read_size
, err
, available_size
;
980 WINHTTP_CERTIFICATE_INFO info
;
983 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
984 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
986 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
987 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
988 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
990 con
= WinHttpConnect(ses
, test_winehq
, 443, 0);
991 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
993 /* try without setting WINHTTP_FLAG_SECURE */
994 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
995 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
997 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
998 err
= GetLastError();
999 ok(!ret
, "unexpected success\n");
1000 ok(err
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
|| broken(err
== ERROR_INVALID_PARAMETER
) /* winxp */,
1001 "setting client cert context returned %u\n", err
);
1003 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1004 err
= GetLastError();
1005 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
1007 skip("Connection failed, skipping.\n");
1010 ok(ret
, "failed to send request %u\n", GetLastError());
1012 ret
= WinHttpReceiveResponse(req
, NULL
);
1013 ok(ret
, "failed to receive response %u\n", GetLastError());
1015 status
= 0xdeadbeef;
1016 size
= sizeof(status
);
1017 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1018 ok(ret
, "header query failed %u\n", GetLastError());
1019 ok(status
== HTTP_STATUS_BAD_REQUEST
, "got %u\n", status
);
1021 WinHttpCloseHandle(req
);
1023 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
1024 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1026 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1027 err
= GetLastError();
1028 ok(ret
|| broken(!ret
&& err
== ERROR_INVALID_PARAMETER
) /* winxp */, "failed to set client cert context %u\n", err
);
1030 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
1032 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1033 err
= GetLastError();
1034 if (!ret
&& (err
== ERROR_WINHTTP_SECURE_FAILURE
|| err
== ERROR_WINHTTP_CANNOT_CONNECT
||
1035 err
== ERROR_WINHTTP_TIMEOUT
))
1037 skip("secure connection failed, skipping remaining secure tests\n");
1040 ok(ret
, "failed to send request %u\n", GetLastError());
1042 size
= sizeof(cert
);
1043 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1044 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1045 if (ret
) CertFreeCertificateContext(cert
);
1047 size
= sizeof(bitness
);
1048 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
1049 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
1051 size
= sizeof(info
);
1052 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
1053 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
1057 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
1058 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
1059 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
1060 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
1061 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
1062 trace("dwKeySize %u\n", info
.dwKeySize
);
1063 LocalFree( info
.lpszSubjectInfo
);
1064 LocalFree( info
.lpszIssuerInfo
);
1067 ret
= WinHttpReceiveResponse(req
, NULL
);
1068 ok(ret
, "failed to receive response %u\n", GetLastError());
1071 ret
= WinHttpQueryDataAvailable(req
, &available_size
);
1072 ok(ret
, "failed to query available data %u\n", GetLastError());
1073 ok(available_size
> 2014, "available_size = %u\n", available_size
);
1075 status
= 0xdeadbeef;
1076 size
= sizeof(status
);
1077 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1078 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1079 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1082 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
1083 ok(!ret
, "succeeded unexpectedly\n");
1089 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
1090 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
1094 if (read_size
<= 32)
1095 ok(!memcmp(buffer
, data_start
, sizeof(data_start
)-1), "not expected: %.32s\n", buffer
);
1097 ok(read_size
>= available_size
, "read_size = %u, available_size = %u\n", read_size
, available_size
);
1100 WinHttpCloseHandle(req
);
1101 WinHttpCloseHandle(con
);
1102 WinHttpCloseHandle(ses
);
1105 static void test_request_parameter_defaults(void)
1107 static const WCHAR empty
[] = {0};
1108 HINTERNET ses
, con
, req
;
1109 DWORD size
, status
, error
;
1113 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1114 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1116 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1117 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1119 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1120 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1122 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1123 error
= GetLastError();
1124 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1126 skip("connection failed, skipping\n");
1129 ok(ret
, "failed to send request %u\n", GetLastError());
1131 ret
= WinHttpReceiveResponse(req
, NULL
);
1132 if (!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE
) /* win2k */
1134 win_skip("invalid response\n");
1137 ok(ret
, "failed to receive response %u\n", GetLastError());
1139 status
= 0xdeadbeef;
1140 size
= sizeof(status
);
1141 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1142 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1143 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1145 WinHttpCloseHandle(req
);
1147 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
1148 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1150 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1151 error
= GetLastError();
1152 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1154 skip("connection failed, skipping\n");
1157 ok(ret
, "failed to send request %u\n", GetLastError());
1159 ret
= WinHttpReceiveResponse(req
, NULL
);
1160 ok(ret
, "failed to receive response %u\n", GetLastError());
1163 SetLastError(0xdeadbeef);
1164 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
1165 error
= GetLastError();
1166 ok(!ret
, "succeeded unexpectedly\n");
1167 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
1169 version
= HeapAlloc(GetProcessHeap(), 0, size
);
1170 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
1171 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1172 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
1173 HeapFree(GetProcessHeap(), 0, version
);
1175 status
= 0xdeadbeef;
1176 size
= sizeof(status
);
1177 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1178 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1179 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1182 WinHttpCloseHandle(req
);
1183 WinHttpCloseHandle(con
);
1184 WinHttpCloseHandle(ses
);
1187 static const WCHAR Connections
[] = {
1188 'S','o','f','t','w','a','r','e','\\',
1189 'M','i','c','r','o','s','o','f','t','\\',
1190 'W','i','n','d','o','w','s','\\',
1191 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1192 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1193 'C','o','n','n','e','c','t','i','o','n','s',0 };
1194 static const WCHAR WinHttpSettings
[] = {
1195 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1197 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1203 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1208 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1212 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1222 static void set_proxy( REGSAM access
, BYTE
*buf
, DWORD len
, DWORD type
)
1225 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
))
1227 if (len
) RegSetValueExW( hkey
, WinHttpSettings
, 0, type
, buf
, len
);
1228 else RegDeleteValueW( hkey
, WinHttpSettings
);
1229 RegCloseKey( hkey
);
1233 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1236 IsWow64Process( GetCurrentProcess(), &wow64
);
1237 if (sizeof(void *) > sizeof(int) || wow64
)
1239 set_proxy( KEY_WRITE
|KEY_WOW64_64KEY
, buf
, len
, type
);
1240 set_proxy( KEY_WRITE
|KEY_WOW64_32KEY
, buf
, len
, type
);
1243 set_proxy( KEY_WRITE
, buf
, len
, type
);
1246 static void test_set_default_proxy_config(void)
1248 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1249 static WCHAR normalString
[] = { 'f','o','o',0 };
1251 BYTE
*saved_proxy_settings
= NULL
;
1252 WINHTTP_PROXY_INFO info
;
1255 /* FIXME: it would be simpler to read the current settings using
1256 * WinHttpGetDefaultProxyConfiguration and save them using
1257 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1259 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1260 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1261 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1262 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1263 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1264 * the lpszProxy and lpszProxyBypass values are ignored.
1265 * Thus, if a proxy is set with proxycfg, then calling
1266 * WinHttpGetDefaultProxyConfiguration followed by
1267 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1268 * getting deleted from the registry.
1270 * Instead I read the current registry value and restore it directly.
1272 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1275 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1276 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1281 /* Crashes on Vista and higher */
1282 SetLastError(0xdeadbeef);
1283 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1284 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1285 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1288 /* test with invalid access type */
1289 info
.dwAccessType
= 0xdeadbeef;
1290 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1291 SetLastError(0xdeadbeef);
1292 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1293 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1294 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1296 /* at a minimum, the proxy server must be set */
1297 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1298 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1299 SetLastError(0xdeadbeef);
1300 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1301 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1302 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1303 info
.lpszProxyBypass
= normalString
;
1304 SetLastError(0xdeadbeef);
1305 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1306 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1307 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1309 /* the proxy server can't have wide characters */
1310 info
.lpszProxy
= wideString
;
1311 SetLastError(0xdeadbeef);
1312 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1313 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1314 skip("couldn't set default proxy configuration: access denied\n");
1316 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1317 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1318 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1320 info
.lpszProxy
= normalString
;
1321 SetLastError(0xdeadbeef);
1322 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1323 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1324 skip("couldn't set default proxy configuration: access denied\n");
1327 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1328 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1329 "got %u\n", GetLastError());
1331 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1334 static void test_Timeouts (void)
1338 HINTERNET ses
, req
, con
;
1340 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1341 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1343 SetLastError(0xdeadbeef);
1344 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1345 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1346 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1348 SetLastError(0xdeadbeef);
1349 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1350 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1351 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1353 SetLastError(0xdeadbeef);
1354 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1355 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1356 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1358 SetLastError(0xdeadbeef);
1359 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1360 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1361 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1363 SetLastError(0xdeadbeef);
1364 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1365 ok(ret
, "%u\n", GetLastError());
1366 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1367 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1369 SetLastError(0xdeadbeef);
1370 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1371 ok(ret
, "%u\n", GetLastError());
1373 SetLastError(0xdeadbeef);
1374 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1375 ok(ret
, "%u\n", GetLastError());
1377 SetLastError(0xdeadbeef);
1379 size
= sizeof(DWORD
);
1380 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1381 ok(ret
, "%u\n", GetLastError());
1382 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1384 SetLastError(0xdeadbeef);
1386 size
= sizeof(DWORD
);
1387 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1388 ok(ret
, "%u\n", GetLastError());
1389 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1391 SetLastError(0xdeadbeef);
1393 size
= sizeof(DWORD
);
1394 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1395 ok(ret
, "%u\n", GetLastError());
1396 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1398 SetLastError(0xdeadbeef);
1400 size
= sizeof(DWORD
);
1401 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1402 ok(ret
, "%u\n", GetLastError());
1403 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1405 SetLastError(0xdeadbeef);
1407 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1408 ok(ret
, "%u\n", GetLastError());
1410 SetLastError(0xdeadbeef);
1412 size
= sizeof(DWORD
);
1413 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1414 ok(ret
, "%u\n", GetLastError());
1415 ok(value
== 0, "Expected 0, got %u\n", value
);
1417 SetLastError(0xdeadbeef);
1419 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1420 ok(ret
, "%u\n", GetLastError());
1422 SetLastError(0xdeadbeef);
1424 size
= sizeof(DWORD
);
1425 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1426 ok(ret
, "%u\n", GetLastError());
1427 ok(value
== 0, "Expected 0, got %u\n", value
);
1429 SetLastError(0xdeadbeef);
1431 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1432 ok(ret
, "%u\n", GetLastError());
1434 SetLastError(0xdeadbeef);
1436 size
= sizeof(DWORD
);
1437 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1438 ok(ret
, "%u\n", GetLastError());
1439 ok(value
== 0, "Expected 0, got %u\n", value
);
1441 SetLastError(0xdeadbeef);
1443 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1444 ok(ret
, "%u\n", GetLastError());
1446 SetLastError(0xdeadbeef);
1448 size
= sizeof(DWORD
);
1449 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1450 ok(ret
, "%u\n", GetLastError());
1451 ok(value
== 0, "Expected 0, got %u\n", value
);
1453 SetLastError(0xdeadbeef);
1455 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1456 ok(ret
, "%u\n", GetLastError());
1458 SetLastError(0xdeadbeef);
1460 size
= sizeof(DWORD
);
1461 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1462 ok(ret
, "%u\n", GetLastError());
1463 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1465 SetLastError(0xdeadbeef);
1467 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1468 ok(ret
, "%u\n", GetLastError());
1470 SetLastError(0xdeadbeef);
1472 size
= sizeof(DWORD
);
1473 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1474 ok(ret
, "%u\n", GetLastError());
1475 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1477 SetLastError(0xdeadbeef);
1479 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1480 ok(ret
, "%u\n", GetLastError());
1482 SetLastError(0xdeadbeef);
1484 size
= sizeof(DWORD
);
1485 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1486 ok(ret
, "%u\n", GetLastError());
1487 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1489 SetLastError(0xdeadbeef);
1491 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1492 ok(ret
, "%u\n", GetLastError());
1494 SetLastError(0xdeadbeef);
1496 size
= sizeof(DWORD
);
1497 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1498 ok(ret
, "%u\n", GetLastError());
1499 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1501 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1502 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1504 /* Timeout values should match the last one set for session */
1505 SetLastError(0xdeadbeef);
1507 size
= sizeof(DWORD
);
1508 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1509 ok(ret
, "%u\n", GetLastError());
1510 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1512 SetLastError(0xdeadbeef);
1514 size
= sizeof(DWORD
);
1515 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1516 ok(ret
, "%u\n", GetLastError());
1517 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1519 SetLastError(0xdeadbeef);
1521 size
= sizeof(DWORD
);
1522 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1523 ok(ret
, "%u\n", GetLastError());
1524 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1526 SetLastError(0xdeadbeef);
1528 size
= sizeof(DWORD
);
1529 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1530 ok(ret
, "%u\n", GetLastError());
1531 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1533 SetLastError(0xdeadbeef);
1534 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1535 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1536 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1538 SetLastError(0xdeadbeef);
1539 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1540 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1541 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1543 SetLastError(0xdeadbeef);
1544 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1545 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1546 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1548 SetLastError(0xdeadbeef);
1549 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1550 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1551 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1553 SetLastError(0xdeadbeef);
1554 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1555 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1556 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1558 SetLastError(0xdeadbeef);
1559 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
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_RESOLVE_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_CONNECT_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_SEND_TIMEOUT
, &value
, sizeof(value
));
1578 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1579 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1581 SetLastError(0xdeadbeef);
1583 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1584 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1585 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1587 /* Changing timeout values for session should affect the values for connection */
1588 SetLastError(0xdeadbeef);
1590 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1591 ok(ret
, "%u\n", GetLastError());
1593 SetLastError(0xdeadbeef);
1595 size
= sizeof(DWORD
);
1596 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1597 ok(ret
, "%u\n", GetLastError());
1598 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1600 SetLastError(0xdeadbeef);
1602 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1603 ok(ret
, "%u\n", GetLastError());
1605 SetLastError(0xdeadbeef);
1607 size
= sizeof(DWORD
);
1608 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1609 ok(ret
, "%u\n", GetLastError());
1610 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1612 SetLastError(0xdeadbeef);
1614 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1615 ok(ret
, "%u\n", GetLastError());
1617 SetLastError(0xdeadbeef);
1619 size
= sizeof(DWORD
);
1620 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1621 ok(ret
, "%u\n", GetLastError());
1622 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1624 SetLastError(0xdeadbeef);
1626 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1627 ok(ret
, "%u\n", GetLastError());
1629 SetLastError(0xdeadbeef);
1631 size
= sizeof(DWORD
);
1632 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1633 ok(ret
, "%u\n", GetLastError());
1634 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1636 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1637 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1639 /* Timeout values should match the last one set for session */
1640 SetLastError(0xdeadbeef);
1642 size
= sizeof(DWORD
);
1643 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1644 ok(ret
, "%u\n", GetLastError());
1645 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1647 SetLastError(0xdeadbeef);
1649 size
= sizeof(DWORD
);
1650 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1651 ok(ret
, "%u\n", GetLastError());
1652 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1654 SetLastError(0xdeadbeef);
1656 size
= sizeof(DWORD
);
1657 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1658 ok(ret
, "%u\n", GetLastError());
1659 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1661 SetLastError(0xdeadbeef);
1663 size
= sizeof(DWORD
);
1664 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1665 ok(ret
, "%u\n", GetLastError());
1666 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1668 SetLastError(0xdeadbeef);
1669 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1670 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1671 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1673 SetLastError(0xdeadbeef);
1674 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1675 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1676 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1678 SetLastError(0xdeadbeef);
1679 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1680 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1681 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1683 SetLastError(0xdeadbeef);
1684 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1685 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1686 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1688 SetLastError(0xdeadbeef);
1689 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1690 ok(ret
, "%u\n", GetLastError());
1692 SetLastError(0xdeadbeef);
1693 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1694 ok(ret
, "%u\n", GetLastError());
1696 SetLastError(0xdeadbeef);
1697 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1698 ok(ret
, "%u\n", GetLastError());
1700 SetLastError(0xdeadbeef);
1702 size
= sizeof(DWORD
);
1703 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1704 ok(ret
, "%u\n", GetLastError());
1705 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1707 SetLastError(0xdeadbeef);
1709 size
= sizeof(DWORD
);
1710 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1711 ok(ret
, "%u\n", GetLastError());
1712 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1714 SetLastError(0xdeadbeef);
1716 size
= sizeof(DWORD
);
1717 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1718 ok(ret
, "%u\n", GetLastError());
1719 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1721 SetLastError(0xdeadbeef);
1723 size
= sizeof(DWORD
);
1724 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1725 ok(ret
, "%u\n", GetLastError());
1726 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1728 SetLastError(0xdeadbeef);
1730 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1731 ok(ret
, "%u\n", GetLastError());
1733 SetLastError(0xdeadbeef);
1735 size
= sizeof(DWORD
);
1736 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1737 ok(ret
, "%u\n", GetLastError());
1738 ok(value
== 0, "Expected 0, got %u\n", value
);
1740 SetLastError(0xdeadbeef);
1742 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1743 ok(ret
, "%u\n", GetLastError());
1745 SetLastError(0xdeadbeef);
1747 size
= sizeof(DWORD
);
1748 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1749 ok(ret
, "%u\n", GetLastError());
1750 ok(value
== 0, "Expected 0, got %u\n", value
);
1752 SetLastError(0xdeadbeef);
1754 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1755 ok(ret
, "%u\n", GetLastError());
1757 SetLastError(0xdeadbeef);
1759 size
= sizeof(DWORD
);
1760 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1761 ok(ret
, "%u\n", GetLastError());
1762 ok(value
== 0, "Expected 0, got %u\n", value
);
1764 SetLastError(0xdeadbeef);
1766 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1767 ok(ret
, "%u\n", GetLastError());
1769 SetLastError(0xdeadbeef);
1771 size
= sizeof(DWORD
);
1772 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1773 ok(ret
, "%u\n", GetLastError());
1774 ok(value
== 0, "Expected 0, got %u\n", value
);
1776 SetLastError(0xdeadbeef);
1778 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1779 ok(ret
, "%u\n", GetLastError());
1781 SetLastError(0xdeadbeef);
1783 size
= sizeof(DWORD
);
1784 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1785 ok(ret
, "%u\n", GetLastError());
1786 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1788 SetLastError(0xdeadbeef);
1790 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1791 ok(ret
, "%u\n", GetLastError());
1793 SetLastError(0xdeadbeef);
1795 size
= sizeof(DWORD
);
1796 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1797 ok(ret
, "%u\n", GetLastError());
1798 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1800 SetLastError(0xdeadbeef);
1802 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1803 ok(ret
, "%u\n", GetLastError());
1805 SetLastError(0xdeadbeef);
1807 size
= sizeof(DWORD
);
1808 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1809 ok(ret
, "%u\n", GetLastError());
1810 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1812 SetLastError(0xdeadbeef);
1814 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1815 ok(ret
, "%u\n", GetLastError());
1817 SetLastError(0xdeadbeef);
1819 size
= sizeof(DWORD
);
1820 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1821 ok(ret
, "%u\n", GetLastError());
1822 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1824 /* Changing timeout values for session should not affect the values for a request,
1825 * neither should the other way around.
1827 SetLastError(0xdeadbeef);
1829 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1830 ok(ret
, "%u\n", GetLastError());
1832 SetLastError(0xdeadbeef);
1834 size
= sizeof(DWORD
);
1835 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1836 ok(ret
, "%u\n", GetLastError());
1837 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1839 SetLastError(0xdeadbeef);
1841 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1842 ok(ret
, "%u\n", GetLastError());
1844 SetLastError(0xdeadbeef);
1846 size
= sizeof(DWORD
);
1847 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1848 ok(ret
, "%u\n", GetLastError());
1849 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1851 SetLastError(0xdeadbeef);
1853 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1854 ok(ret
, "%u\n", GetLastError());
1856 SetLastError(0xdeadbeef);
1858 size
= sizeof(DWORD
);
1859 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1860 ok(ret
, "%u\n", GetLastError());
1861 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1863 SetLastError(0xdeadbeef);
1865 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1866 ok(ret
, "%u\n", GetLastError());
1868 SetLastError(0xdeadbeef);
1870 size
= sizeof(DWORD
);
1871 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1872 ok(ret
, "%u\n", GetLastError());
1873 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1875 SetLastError(0xdeadbeef);
1877 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1878 ok(ret
, "%u\n", GetLastError());
1880 SetLastError(0xdeadbeef);
1882 size
= sizeof(DWORD
);
1883 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1884 ok(ret
, "%u\n", GetLastError());
1885 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1887 SetLastError(0xdeadbeef);
1889 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1890 ok(ret
, "%u\n", GetLastError());
1892 SetLastError(0xdeadbeef);
1894 size
= sizeof(DWORD
);
1895 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1896 ok(ret
, "%u\n", GetLastError());
1897 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1899 SetLastError(0xdeadbeef);
1901 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1902 ok(ret
, "%u\n", GetLastError());
1904 SetLastError(0xdeadbeef);
1906 size
= sizeof(DWORD
);
1907 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1908 ok(ret
, "%u\n", GetLastError());
1909 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1911 SetLastError(0xdeadbeef);
1913 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1914 ok(ret
, "%u\n", GetLastError());
1916 SetLastError(0xdeadbeef);
1918 size
= sizeof(DWORD
);
1919 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1920 ok(ret
, "%u\n", GetLastError());
1921 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1923 WinHttpCloseHandle(req
);
1924 WinHttpCloseHandle(con
);
1925 WinHttpCloseHandle(ses
);
1928 static void test_resolve_timeout(void)
1930 static const WCHAR nxdomain
[] =
1931 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1932 HINTERNET ses
, con
, req
;
1936 if (! proxy_active())
1938 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1939 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1942 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1943 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1945 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1946 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1948 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1949 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1951 SetLastError(0xdeadbeef);
1952 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1955 skip("nxdomain returned success. Broken ISP redirects?\n");
1958 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1959 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1961 WinHttpCloseHandle(req
);
1962 WinHttpCloseHandle(con
);
1963 WinHttpCloseHandle(ses
);
1966 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1968 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1969 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1972 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1973 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1975 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1976 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1978 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1979 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1981 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1982 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
1984 skip("connection failed, skipping\n");
1987 ok(ret
, "failed to send request\n");
1990 WinHttpCloseHandle(req
);
1991 WinHttpCloseHandle(con
);
1992 WinHttpCloseHandle(ses
);
1995 static const char page1
[] =
1997 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1998 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2001 static const char okmsg
[] =
2002 "HTTP/1.1 200 OK\r\n"
2003 "Server: winetest\r\n"
2006 static const char notokmsg
[] =
2007 "HTTP/1.1 400 Bad Request\r\n"
2010 static const char cookiemsg
[] =
2011 "HTTP/1.1 200 OK\r\n"
2012 "Set-Cookie: name = value \r\n"
2013 "Set-Cookie: NAME = value \r\n"
2016 static const char cookiemsg2
[] =
2017 "HTTP/1.1 200 OK\r\n"
2018 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2021 static const char nocontentmsg
[] =
2022 "HTTP/1.1 204 No Content\r\n"
2023 "Server: winetest\r\n"
2026 static const char notmodified
[] =
2027 "HTTP/1.1 304 Not Modified\r\n"
2030 static const char noauthmsg
[] =
2031 "HTTP/1.1 401 Unauthorized\r\n"
2032 "Server: winetest\r\n"
2033 "Connection: close\r\n"
2034 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2035 "Content-Length: 12\r\n"
2036 "Content-Type: text/plain\r\n"
2039 static const char okauthmsg
[] =
2040 "HTTP/1.1 200 OK\r\n"
2041 "Server: winetest\r\n"
2042 "Connection: close\r\n"
2043 "Content-Length: 11\r\n"
2044 "Content-Type: text/plain\r\n"
2047 static const char headmsg
[] =
2048 "HTTP/1.1 200 OK\r\n"
2049 "Content-Length: 100\r\n"
2052 static const char unauthorized
[] = "Unauthorized";
2053 static const char hello_world
[] = "Hello World";
2061 #define BIG_BUFFER_LEN 0x2250
2063 static DWORD CALLBACK
server_thread(LPVOID param
)
2065 struct server_info
*si
= param
;
2066 int r
, c
= -1, i
, on
;
2068 struct sockaddr_in sa
;
2071 int last_request
= 0;
2073 WSAStartup(MAKEWORD(1,1), &wsaData
);
2075 s
= socket(AF_INET
, SOCK_STREAM
, 0);
2076 if (s
== INVALID_SOCKET
)
2080 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
2082 memset(&sa
, 0, sizeof sa
);
2083 sa
.sin_family
= AF_INET
;
2084 sa
.sin_port
= htons(si
->port
);
2085 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
2087 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
2092 SetEvent(si
->event
);
2095 if (c
== -1) c
= accept(s
, NULL
, NULL
);
2097 memset(buffer
, 0, sizeof buffer
);
2098 for(i
= 0; i
< sizeof buffer
- 1; i
++)
2100 r
= recv(c
, &buffer
[i
], 1, 0);
2103 if (i
< 4) continue;
2104 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
2105 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
2108 if (strstr(buffer
, "GET /basic"))
2110 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2111 send(c
, page1
, sizeof page1
- 1, 0);
2113 if (strstr(buffer
, "/auth"))
2115 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2117 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2118 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2122 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
2123 send(c
, unauthorized
, sizeof unauthorized
- 1, 0);
2127 if (strstr(buffer
, "/big"))
2129 char msg
[BIG_BUFFER_LEN
];
2130 memset(msg
, 'm', sizeof(msg
));
2131 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2132 send(c
, msg
, sizeof(msg
), 0);
2134 if (strstr(buffer
, "/no_headers"))
2136 send(c
, page1
, sizeof page1
- 1, 0);
2138 if (strstr(buffer
, "GET /no_content"))
2140 send(c
, nocontentmsg
, sizeof nocontentmsg
- 1, 0);
2143 if (strstr(buffer
, "GET /not_modified"))
2145 if (strstr(buffer
, "If-Modified-Since:")) send(c
, notmodified
, sizeof notmodified
- 1, 0);
2146 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2149 if (strstr(buffer
, "HEAD /head"))
2151 send(c
, headmsg
, sizeof headmsg
- 1, 0);
2154 if (strstr(buffer
, "GET /cookie5"))
2156 if (strstr(buffer
, "Cookie: name2=value\r\n"))
2157 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2159 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2161 if (strstr(buffer
, "GET /cookie4"))
2163 send(c
, cookiemsg2
, sizeof(cookiemsg2
) - 1, 0);
2165 if (strstr(buffer
, "GET /cookie3"))
2167 if (strstr(buffer
, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2168 broken(strstr(buffer
, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL
))
2169 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2171 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2173 if (strstr(buffer
, "GET /cookie2"))
2175 if (strstr(buffer
, "Cookie: NAME=value; name=value\r\n") ||
2176 broken(strstr(buffer
, "Cookie: name=value; NAME=value\r\n") != NULL
))
2177 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2179 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2181 else if (strstr(buffer
, "GET /cookie"))
2183 if (!strstr(buffer
, "Cookie: name=value\r\n")) send(c
, cookiemsg
, sizeof(cookiemsg
) - 1, 0);
2184 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2186 if (strstr(buffer
, "GET /quit"))
2188 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2189 send(c
, page1
, sizeof page1
- 1, 0);
2196 } while (!last_request
);
2202 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
2204 static const WCHAR test_header_end_clrf
[] = {'\r','\n','\r','\n',0};
2205 static const WCHAR test_header_end_raw
[] = {0,0};
2206 HINTERNET ses
, con
, req
;
2208 WCHAR buffer2
[0x100];
2209 DWORD count
, status
, size
, error
, supported
, first
, target
;
2212 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2213 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2215 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2216 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2218 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
2219 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2221 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2222 ok(ret
, "failed to send request %u\n", GetLastError());
2224 ret
= WinHttpReceiveResponse(req
, NULL
);
2225 ok(ret
, "failed to receive response %u\n", GetLastError());
2227 status
= 0xdeadbeef;
2228 size
= sizeof(status
);
2229 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2230 ok(ret
, "failed to query status code %u\n", GetLastError());
2231 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2233 supported
= first
= target
= 0xdeadbeef;
2234 SetLastError(0xdeadbeef);
2235 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2236 error
= GetLastError();
2237 ok(!ret
, "unexpected success\n");
2238 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2239 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2240 ok(first
== 0xdeadbeef, "got %x\n", first
);
2241 ok(target
== 0xdeadbeef, "got %x\n", target
);
2243 size
= sizeof(buffer2
);
2244 memset(buffer2
, 0, sizeof(buffer2
));
2245 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, buffer2
, &size
, NULL
);
2246 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2247 ok(!memcmp(buffer2
+ lstrlenW(buffer2
) - 4, test_header_end_clrf
, sizeof(test_header_end_clrf
)),
2248 "WinHttpQueryHeaders returned invalid end of header string\n");
2250 size
= sizeof(buffer2
);
2251 memset(buffer2
, 0, sizeof(buffer2
));
2252 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS
, NULL
, buffer2
, &size
, NULL
);
2253 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2254 ok(!memcmp(buffer2
+ (size
/ sizeof(WCHAR
)) - 1, test_header_end_raw
, sizeof(test_header_end_raw
)),
2255 "WinHttpQueryHeaders returned invalid end of header string\n");
2256 ok(buffer2
[(size
/ sizeof(WCHAR
)) - 2] != 0, "returned string has too many NULL characters\n");
2259 memset(buffer
, 0, sizeof(buffer
));
2260 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
2261 ok(ret
, "failed to read data %u\n", GetLastError());
2262 ok(count
== sizeof page1
- 1, "count was wrong\n");
2263 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
2265 WinHttpCloseHandle(req
);
2266 WinHttpCloseHandle(con
);
2267 WinHttpCloseHandle(ses
);
2270 static void test_basic_authentication(int port
)
2272 static const WCHAR authW
[] = {'/','a','u','t','h',0};
2273 static WCHAR userW
[] = {'u','s','e','r',0};
2274 static WCHAR passW
[] = {'p','w','d',0};
2275 static WCHAR pass2W
[] = {'p','w','d','2',0};
2276 HINTERNET ses
, con
, req
;
2277 DWORD status
, size
, error
, supported
, first
, target
;
2281 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2282 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2284 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2285 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2287 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2288 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2290 SetLastError(0xdeadbeef);
2291 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
2292 error
= GetLastError();
2293 ok(!ret
, "expected failure\n");
2294 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2296 SetLastError(0xdeadbeef);
2297 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
2298 error
= GetLastError();
2299 ok(!ret
, "expected failure\n");
2300 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2302 supported
= 0xdeadbeef;
2303 SetLastError(0xdeadbeef);
2304 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
2305 error
= GetLastError();
2306 ok(!ret
, "expected failure\n");
2307 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2308 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2310 supported
= first
= 0xdeadbeef;
2311 SetLastError(0xdeadbeef);
2312 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
2313 error
= GetLastError();
2314 ok(!ret
, "expected failure\n");
2315 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2316 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2317 ok(first
== 0xdeadbeef, "got %x\n", first
);
2319 supported
= first
= target
= 0xdeadbeef;
2320 SetLastError(0xdeadbeef);
2321 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2322 error
= GetLastError();
2323 ok(!ret
, "expected failure\n");
2324 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2325 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2326 ok(first
== 0xdeadbeef, "got %x\n", first
);
2327 ok(target
== 0xdeadbeef, "got %x\n", target
);
2329 supported
= first
= target
= 0xdeadbeef;
2330 SetLastError(0xdeadbeef);
2331 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
2332 error
= GetLastError();
2333 ok(!ret
, "expected failure\n");
2334 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2335 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2336 ok(first
== 0xdeadbeef, "got %x\n", first
);
2337 ok(target
== 0xdeadbeef, "got %x\n", target
);
2339 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2340 ok(ret
, "failed to send request %u\n", GetLastError());
2342 ret
= WinHttpReceiveResponse(req
, NULL
);
2343 ok(ret
, "failed to receive response %u\n", GetLastError());
2345 status
= 0xdeadbeef;
2346 size
= sizeof(status
);
2347 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2348 ok(ret
, "failed to query status code %u\n", GetLastError());
2349 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2352 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2353 error
= GetLastError();
2354 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2357 ok(size
== 12, "expected 12, got %u\n", size
);
2358 ok(!memcmp(buffer
, unauthorized
, 12), "got %s\n", buffer
);
2361 supported
= first
= target
= 0xdeadbeef;
2362 SetLastError(0xdeadbeef);
2363 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2364 error
= GetLastError();
2365 ok(ret
, "failed to query authentication schemes %u\n", error
);
2366 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2367 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2368 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2369 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2371 SetLastError(0xdeadbeef);
2372 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2373 error
= GetLastError();
2374 ok(ret
, "failed to set credentials %u\n", error
);
2375 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2377 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2378 ok(ret
, "failed to set credentials %u\n", GetLastError());
2380 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2381 ok(ret
, "failed to set credentials %u\n", GetLastError());
2383 SetLastError(0xdeadbeef);
2384 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2385 error
= GetLastError();
2386 ok(!ret
, "expected failure\n");
2387 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2389 SetLastError(0xdeadbeef);
2390 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2391 error
= GetLastError();
2392 ok(!ret
, "expected failure\n");
2393 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2395 SetLastError(0xdeadbeef);
2396 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2397 error
= GetLastError();
2398 ok(!ret
, "expected failure\n");
2399 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2401 SetLastError(0xdeadbeef);
2402 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2403 error
= GetLastError();
2404 ok(!ret
, "expected failure\n");
2405 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2407 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2408 ok(ret
, "failed to set credentials %u\n", GetLastError());
2410 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2411 ok(ret
, "failed to send request %u\n", GetLastError());
2413 ret
= WinHttpReceiveResponse(req
, NULL
);
2414 ok(ret
, "failed to receive response %u\n", GetLastError());
2416 status
= 0xdeadbeef;
2417 size
= sizeof(status
);
2418 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2419 ok(ret
, "failed to query status code %u\n", GetLastError());
2420 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2423 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2424 error
= GetLastError();
2425 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2428 ok(size
== 11, "expected 11, got %u\n", size
);
2429 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2432 WinHttpCloseHandle(req
);
2433 WinHttpCloseHandle(con
);
2434 WinHttpCloseHandle(ses
);
2436 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2438 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2439 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2441 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2442 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2444 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2445 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2447 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2448 ok(ret
, "failed to set credentials %u\n", GetLastError());
2450 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2451 ok(ret
, "failed to set username %u\n", GetLastError());
2453 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, pass2W
, lstrlenW(pass2W
));
2454 ok(ret
, "failed to set password %u\n", GetLastError());
2456 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2457 ok(ret
, "failed to send request %u\n", GetLastError());
2459 ret
= WinHttpReceiveResponse(req
, NULL
);
2460 ok(ret
, "failed to receive response %u\n", GetLastError());
2462 status
= 0xdeadbeef;
2463 size
= sizeof(status
);
2464 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2465 ok(ret
, "failed to query status code %u\n", GetLastError());
2466 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2468 WinHttpCloseHandle(req
);
2469 WinHttpCloseHandle(con
);
2470 WinHttpCloseHandle(ses
);
2472 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2473 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2475 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2476 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2478 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2479 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2481 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2482 ok(ret
, "failed to set username %u\n", GetLastError());
2484 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2485 ok(ret
, "failed to set password %u\n", GetLastError());
2487 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, pass2W
, NULL
);
2488 ok(ret
, "failed to set credentials %u\n", GetLastError());
2490 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2491 ok(ret
, "failed to send request %u\n", GetLastError());
2493 ret
= WinHttpReceiveResponse(req
, NULL
);
2494 ok(ret
, "failed to receive response %u\n", GetLastError());
2496 status
= 0xdeadbeef;
2497 size
= sizeof(status
);
2498 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2499 ok(ret
, "failed to query status code %u\n", GetLastError());
2500 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2502 WinHttpCloseHandle(req
);
2503 WinHttpCloseHandle(con
);
2504 WinHttpCloseHandle(ses
);
2507 static void test_no_headers(int port
)
2509 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2510 HINTERNET ses
, con
, req
;
2514 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2515 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2517 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2518 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2520 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2521 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2523 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2526 error
= GetLastError();
2527 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2531 SetLastError(0xdeadbeef);
2532 ret
= WinHttpReceiveResponse(req
, NULL
);
2533 error
= GetLastError();
2534 ok(!ret
, "expected failure\n");
2535 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2538 WinHttpCloseHandle(req
);
2539 WinHttpCloseHandle(con
);
2540 WinHttpCloseHandle(ses
);
2543 static void test_no_content(int port
)
2545 static const WCHAR no_contentW
[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2546 HINTERNET ses
, con
, req
;
2548 DWORD size
, len
= sizeof(buf
), bytes_read
, status
;
2551 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2552 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2554 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2555 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2557 req
= WinHttpOpenRequest(con
, NULL
, no_contentW
, NULL
, NULL
, NULL
, 0);
2558 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2561 SetLastError(0xdeadbeef);
2562 ret
= WinHttpQueryDataAvailable(req
, &size
);
2564 ok(!ret
, "expected error\n");
2565 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
,
2566 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2567 ok(size
== 12345 || broken(size
== 0) /* Win <= 2003 */,
2568 "expected 12345, got %u\n", size
);
2571 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2572 ok(ret
, "expected success\n");
2574 ret
= WinHttpReceiveResponse(req
, NULL
);
2575 ok(ret
, "expected success\n");
2577 status
= 0xdeadbeef;
2578 size
= sizeof(status
);
2579 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2580 NULL
, &status
, &size
, NULL
);
2581 ok(ret
, "expected success\n");
2582 ok(status
== HTTP_STATUS_NO_CONTENT
, "expected status 204, got %d\n", status
);
2584 SetLastError(0xdeadbeef);
2585 size
= sizeof(status
);
2587 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2588 NULL
, &status
, &size
, 0);
2589 ok(!ret
, "expected no content-length header\n");
2590 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError());
2591 ok(status
== 12345, "expected 0, got %d\n", status
);
2593 SetLastError(0xdeadbeef);
2595 ret
= WinHttpQueryDataAvailable(req
, &size
);
2596 ok(ret
, "expected success\n");
2597 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2598 "wrong error %u\n", GetLastError());
2599 ok(!size
, "expected 0, got %u\n", size
);
2601 SetLastError(0xdeadbeef);
2602 ret
= WinHttpReadData(req
, buf
, len
, &bytes_read
);
2603 ok(ret
, "expected success\n");
2604 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2605 "wrong error %u\n", GetLastError());
2606 ok(!bytes_read
, "expected 0, got %u\n", bytes_read
);
2609 ret
= WinHttpQueryDataAvailable(req
, &size
);
2610 ok(ret
, "expected success\n");
2611 ok(size
== 0, "expected 0, got %d\n", size
);
2613 WinHttpCloseHandle(req
);
2616 SetLastError(0xdeadbeef);
2617 ret
= WinHttpQueryDataAvailable(req
, &size
);
2618 ok(!ret
, "expected error\n");
2619 ok(GetLastError() == ERROR_INVALID_HANDLE
,
2620 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2621 ok(size
== 12345, "expected 12345, got %u\n", size
);
2623 WinHttpCloseHandle(con
);
2624 WinHttpCloseHandle(ses
);
2627 static void test_head_request(int port
)
2629 static const WCHAR verbW
[] = {'H','E','A','D',0};
2630 static const WCHAR headW
[] = {'/','h','e','a','d',0};
2631 HINTERNET ses
, con
, req
;
2633 DWORD size
, len
, count
, status
;
2636 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2637 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2639 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2640 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2642 req
= WinHttpOpenRequest(con
, verbW
, headW
, NULL
, NULL
, NULL
, 0);
2643 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2645 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2646 ok(ret
, "failed to send request %u\n", GetLastError());
2648 ret
= WinHttpReceiveResponse(req
, NULL
);
2649 ok(ret
, "failed to receive response %u\n", GetLastError());
2651 status
= 0xdeadbeef;
2652 size
= sizeof(status
);
2653 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2654 NULL
, &status
, &size
, NULL
);
2655 ok(ret
, "failed to get status code %u\n", GetLastError());
2656 ok(status
== HTTP_STATUS_OK
, "got %u\n", status
);
2660 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2661 NULL
, &len
, &size
, 0);
2662 ok(ret
, "failed to get content-length header %u\n", GetLastError());
2663 ok(len
== HTTP_STATUS_CONTINUE
, "got %u\n", len
);
2666 ret
= WinHttpQueryDataAvailable(req
, &count
);
2667 ok(ret
, "failed to query data available %u\n", GetLastError());
2668 ok(!count
, "got %u\n", count
);
2672 ret
= WinHttpReadData(req
, buf
, len
, &count
);
2673 ok(ret
, "failed to read data %u\n", GetLastError());
2674 ok(!count
, "got %u\n", count
);
2677 ret
= WinHttpQueryDataAvailable(req
, &count
);
2678 ok(ret
, "failed to query data available %u\n", GetLastError());
2679 ok(!count
, "got %u\n", count
);
2681 WinHttpCloseHandle(req
);
2682 WinHttpCloseHandle(con
);
2683 WinHttpCloseHandle(ses
);
2686 static void test_not_modified(int port
)
2688 static const WCHAR pathW
[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2689 static const WCHAR ifmodifiedW
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2690 static const WCHAR ifmodified2W
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2692 HINTERNET session
, request
, connection
;
2693 DWORD index
, len
, status
, size
, start
= GetTickCount();
2695 WCHAR today
[(sizeof(ifmodifiedW
) + WINHTTP_TIME_FORMAT_BUFSIZE
)/sizeof(WCHAR
) + 3], buffer
[32];
2697 memcpy(today
, ifmodifiedW
, sizeof(ifmodifiedW
));
2699 WinHttpTimeFromSystemTime(&st
, &today
[sizeof(ifmodifiedW
)/sizeof(WCHAR
)]);
2701 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
,
2702 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
2703 ok(session
!= NULL
, "WinHttpOpen failed: %u\n", GetLastError());
2705 connection
= WinHttpConnect(session
, localhostW
, port
, 0);
2706 ok(connection
!= NULL
, "WinHttpConnect failed: %u\n", GetLastError());
2708 request
= WinHttpOpenRequest(connection
, NULL
, pathW
, NULL
, WINHTTP_NO_REFERER
,
2709 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
2710 ok(request
!= NULL
, "WinHttpOpenrequest failed: %u\n", GetLastError());
2712 ret
= WinHttpSendRequest(request
, today
, 0, NULL
, 0, 0, 0);
2713 ok(ret
, "WinHttpSendRequest failed: %u\n", GetLastError());
2715 ret
= WinHttpReceiveResponse(request
, NULL
);
2716 ok(ret
, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2719 len
= sizeof(buffer
);
2720 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2721 ifmodified2W
, buffer
, &len
, &index
);
2722 ok(ret
, "failed to get header %u\n", GetLastError());
2724 status
= 0xdeadbeef;
2725 size
= sizeof(status
);
2726 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
,
2727 NULL
, &status
, &size
, NULL
);
2728 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2729 ok(status
== HTTP_STATUS_NOT_MODIFIED
, "got %u\n", status
);
2732 ret
= WinHttpQueryDataAvailable(request
, &size
);
2733 ok(ret
, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2734 ok(!size
, "got %u\n", size
);
2736 WinHttpCloseHandle(request
);
2737 WinHttpCloseHandle(connection
);
2738 WinHttpCloseHandle(session
);
2739 start
= GetTickCount() - start
;
2740 ok(start
<= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start
);
2743 static void test_bad_header( int port
)
2745 static const WCHAR bad_headerW
[] =
2746 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2747 't','e','x','t','/','h','t','m','l','\n','\r',0};
2748 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2749 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2751 HINTERNET ses
, con
, req
;
2755 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2756 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2758 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2759 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2761 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2762 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2764 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2765 ok( ret
, "failed to add header %u\n", GetLastError() );
2769 len
= sizeof(buffer
);
2770 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2771 content_typeW
, buffer
, &len
, &index
);
2772 ok( ret
, "failed to query headers %u\n", GetLastError() );
2773 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2775 WinHttpCloseHandle( req
);
2776 WinHttpCloseHandle( con
);
2777 WinHttpCloseHandle( ses
);
2780 static void test_multiple_reads(int port
)
2782 static const WCHAR bigW
[] = {'b','i','g',0};
2783 HINTERNET ses
, con
, req
;
2784 DWORD total_len
= 0;
2787 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2788 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2790 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2791 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2793 req
= WinHttpOpenRequest(con
, NULL
, bigW
, NULL
, NULL
, NULL
, 0);
2794 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2796 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2797 ok(ret
, "failed to send request %u\n", GetLastError());
2799 ret
= WinHttpReceiveResponse(req
, NULL
);
2800 ok(ret
== TRUE
, "expected success\n");
2804 DWORD len
= 0xdeadbeef;
2805 ret
= WinHttpQueryDataAvailable( req
, &len
);
2806 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2807 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2811 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
2813 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
2814 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
2816 HeapFree( GetProcessHeap(), 0, buf
);
2817 if (!bytes_read
) break;
2818 total_len
+= bytes_read
;
2822 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
2824 WinHttpCloseHandle(req
);
2825 WinHttpCloseHandle(con
);
2826 WinHttpCloseHandle(ses
);
2829 static void test_cookies( int port
)
2831 static const WCHAR cookieW
[] = {'/','c','o','o','k','i','e',0};
2832 static const WCHAR cookie2W
[] = {'/','c','o','o','k','i','e','2',0};
2833 static const WCHAR cookie3W
[] = {'/','c','o','o','k','i','e','3',0};
2834 static const WCHAR cookie4W
[] = {'/','c','o','o','k','i','e','4',0};
2835 static const WCHAR cookie5W
[] = {'/','c','o','o','k','i','e','5',0};
2836 static const WCHAR cookieheaderW
[] =
2837 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2838 HINTERNET ses
, con
, req
;
2842 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2843 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2845 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2846 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2848 req
= WinHttpOpenRequest( con
, NULL
, cookieW
, NULL
, NULL
, NULL
, 0 );
2849 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2851 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2852 ok( ret
, "failed to send request %u\n", GetLastError() );
2854 ret
= WinHttpReceiveResponse( req
, NULL
);
2855 ok( ret
, "failed to receive response %u\n", GetLastError() );
2857 status
= 0xdeadbeef;
2858 size
= sizeof(status
);
2859 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2860 ok( ret
, "failed to query status code %u\n", GetLastError() );
2861 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2863 WinHttpCloseHandle( req
);
2865 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2866 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2868 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2869 ok( ret
, "failed to send request %u\n", GetLastError() );
2871 ret
= WinHttpReceiveResponse( req
, NULL
);
2872 ok( ret
, "failed to receive response %u\n", GetLastError() );
2874 status
= 0xdeadbeef;
2875 size
= sizeof(status
);
2876 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2877 ok( ret
, "failed to query status code %u\n", GetLastError() );
2878 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2880 WinHttpCloseHandle( req
);
2881 WinHttpCloseHandle( con
);
2883 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2884 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2886 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2887 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2889 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2890 ok( ret
, "failed to send request %u\n", GetLastError() );
2892 ret
= WinHttpReceiveResponse( req
, NULL
);
2893 ok( ret
, "failed to receive response %u\n", GetLastError() );
2895 status
= 0xdeadbeef;
2896 size
= sizeof(status
);
2897 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2898 ok( ret
, "failed to query status code %u\n", GetLastError() );
2899 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2901 WinHttpCloseHandle( req
);
2903 req
= WinHttpOpenRequest( con
, NULL
, cookie3W
, NULL
, NULL
, NULL
, 0 );
2904 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2906 ret
= WinHttpSendRequest( req
, cookieheaderW
, ~0u, NULL
, 0, 0, 0 );
2907 ok( ret
, "failed to send request %u\n", GetLastError() );
2909 ret
= WinHttpReceiveResponse( req
, NULL
);
2910 ok( ret
, "failed to receive response %u\n", GetLastError() );
2912 status
= 0xdeadbeef;
2913 size
= sizeof(status
);
2914 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2915 ok( ret
, "failed to query status code %u\n", GetLastError() );
2916 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
), "request failed unexpectedly %u\n", status
);
2918 WinHttpCloseHandle( req
);
2919 WinHttpCloseHandle( con
);
2920 WinHttpCloseHandle( ses
);
2922 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2923 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2925 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2926 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2928 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2929 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2931 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2932 ok( ret
, "failed to send request %u\n", GetLastError() );
2934 ret
= WinHttpReceiveResponse( req
, NULL
);
2935 ok( ret
, "failed to receive response %u\n", GetLastError() );
2937 status
= 0xdeadbeef;
2938 size
= sizeof(status
);
2939 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2940 ok( ret
, "failed to query status code %u\n", GetLastError() );
2941 ok( status
== HTTP_STATUS_BAD_REQUEST
, "request failed unexpectedly %u\n", status
);
2943 WinHttpCloseHandle( req
);
2944 WinHttpCloseHandle( con
);
2945 WinHttpCloseHandle( ses
);
2947 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2948 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2950 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2951 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2953 req
= WinHttpOpenRequest( con
, NULL
, cookie4W
, NULL
, NULL
, NULL
, 0 );
2954 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2956 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2957 ok( ret
, "failed to send request %u\n", GetLastError() );
2959 ret
= WinHttpReceiveResponse( req
, NULL
);
2960 ok( ret
, "failed to receive response %u\n", GetLastError() );
2962 status
= 0xdeadbeef;
2963 size
= sizeof(status
);
2964 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2965 ok( ret
, "failed to query status code %u\n", GetLastError() );
2966 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2967 WinHttpCloseHandle( req
);
2969 req
= WinHttpOpenRequest( con
, NULL
, cookie5W
, NULL
, NULL
, NULL
, 0 );
2970 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2972 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2973 ok( ret
, "failed to send request %u\n", GetLastError() );
2975 ret
= WinHttpReceiveResponse( req
, NULL
);
2976 ok( ret
, "failed to receive response %u\n", GetLastError() );
2978 status
= 0xdeadbeef;
2979 size
= sizeof(status
);
2980 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2981 ok( ret
, "failed to query status code %u\n", GetLastError() );
2982 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
) /* < win7 */,
2983 "request failed unexpectedly %u\n", status
);
2985 WinHttpCloseHandle( req
);
2986 WinHttpCloseHandle( con
);
2987 WinHttpCloseHandle( ses
);
2990 static void test_connection_info( int port
)
2992 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2993 HINTERNET ses
, con
, req
;
2994 WINHTTP_CONNECTION_INFO info
;
2998 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2999 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3001 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3002 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3004 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
3005 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3007 size
= sizeof(info
);
3008 SetLastError( 0xdeadbeef );
3009 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3010 error
= GetLastError();
3011 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
3013 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
3016 ok( !ret
, "unexpected success\n" );
3017 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
3019 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3020 ok( ret
, "failed to send request %u\n", GetLastError() );
3023 SetLastError( 0xdeadbeef );
3024 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3025 error
= GetLastError();
3026 ok( !ret
, "unexpected success\n" );
3027 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
3029 size
= sizeof(info
);
3030 memset( &info
, 0, sizeof(info
) );
3031 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3032 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3033 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3035 ret
= WinHttpReceiveResponse( req
, NULL
);
3036 ok( ret
, "failed to receive response %u\n", GetLastError() );
3038 size
= sizeof(info
);
3039 memset( &info
, 0, sizeof(info
) );
3040 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3041 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3042 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3044 WinHttpCloseHandle( req
);
3045 WinHttpCloseHandle( con
);
3046 WinHttpCloseHandle( ses
);
3049 static void test_credentials(void)
3051 static WCHAR userW
[] = {'u','s','e','r',0};
3052 static WCHAR passW
[] = {'p','a','s','s',0};
3053 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
3054 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
3055 HINTERNET ses
, con
, req
;
3060 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
3061 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
3063 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
3064 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3066 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3067 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3069 size
= sizeof(buffer
)/sizeof(WCHAR
);
3070 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3071 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3072 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3073 ok(!size
, "expected 0, got %u\n", size
);
3075 size
= sizeof(buffer
)/sizeof(WCHAR
);
3076 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3077 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3078 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3079 ok(!size
, "expected 0, got %u\n", size
);
3081 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
3082 ok(ret
, "failed to set username %u\n", GetLastError());
3084 size
= sizeof(buffer
)/sizeof(WCHAR
);
3085 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3086 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3087 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3088 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3090 size
= sizeof(buffer
)/sizeof(WCHAR
);
3091 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3092 ok(ret
, "failed to query username %u\n", GetLastError());
3093 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3094 ok(!size
, "expected 0, got %u\n", size
);
3096 size
= sizeof(buffer
)/sizeof(WCHAR
);
3097 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3098 ok(ret
, "failed to query password %u\n", GetLastError());
3099 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3100 ok(!size
, "expected 0, got %u\n", size
);
3102 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
3103 ok(ret
, "failed to set proxy password %u\n", GetLastError());
3105 size
= sizeof(buffer
)/sizeof(WCHAR
);
3106 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3107 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3108 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3109 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3111 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
3112 ok(ret
, "failed to set username %u\n", GetLastError());
3114 size
= sizeof(buffer
)/sizeof(WCHAR
);
3115 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3116 ok(ret
, "failed to query username %u\n", GetLastError());
3117 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3118 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3120 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
3121 ok(ret
, "failed to set password %u\n", GetLastError());
3123 size
= sizeof(buffer
)/sizeof(WCHAR
);
3124 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3125 ok(ret
, "failed to query password %u\n", GetLastError());
3126 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3127 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3129 WinHttpCloseHandle(req
);
3131 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3132 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3134 SetLastError(0xdeadbeef);
3135 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
3136 error
= GetLastError();
3137 ok(!ret
, "expected failure\n");
3138 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3140 SetLastError(0xdeadbeef);
3141 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
3142 error
= GetLastError();
3143 ok(!ret
, "expected failure\n");
3144 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3146 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
3147 ok(ret
, "failed to set credentials %u\n", GetLastError());
3149 size
= sizeof(buffer
)/sizeof(WCHAR
);
3150 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3151 ok(ret
, "failed to query username %u\n", GetLastError());
3153 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3154 ok(!size
, "expected 0, got %u\n", size
);
3157 size
= sizeof(buffer
)/sizeof(WCHAR
);
3158 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3159 ok(ret
, "failed to query password %u\n", GetLastError());
3161 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3162 ok(!size
, "expected 0, got %u\n", size
);
3165 WinHttpCloseHandle(req
);
3166 WinHttpCloseHandle(con
);
3167 WinHttpCloseHandle(ses
);
3170 static void test_IWinHttpRequest(int port
)
3172 static const WCHAR data_start
[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3173 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
3174 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
3175 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3176 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3177 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3178 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3179 static const WCHAR method1W
[] = {'G','E','T',0};
3180 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
3181 static const WCHAR method3W
[] = {'P','O','S','T',0};
3182 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3183 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
3184 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
3185 static const WCHAR dateW
[] = {'D','a','t','e',0};
3186 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
3187 static const WCHAR utf8W
[] = {'u','t','f','-','8',0};
3188 static const WCHAR unauthW
[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3190 IWinHttpRequest
*req
;
3191 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
3192 BSTR date
, today
, connection
, value
= NULL
;
3193 VARIANT async
, empty
, timeout
, body
, body2
, proxy_server
, bypass_list
, data
, cp
;
3194 VARIANT_BOOL succeeded
;
3196 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
3198 IStream
*stream
, *stream2
;
3204 GetSystemTime( &st
);
3205 WinHttpTimeFromSystemTime( &st
, todayW
);
3207 CoInitialize( NULL
);
3208 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3209 ok( hr
== S_OK
, "got %08x\n", hr
);
3211 V_VT( &empty
) = VT_ERROR
;
3212 V_ERROR( &empty
) = 0xdeadbeef;
3214 V_VT( &async
) = VT_BOOL
;
3215 V_BOOL( &async
) = VARIANT_FALSE
;
3217 method
= SysAllocString( method3W
);
3218 url
= SysAllocString( url3W
);
3219 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3220 ok( hr
== S_OK
, "got %08x\n", hr
);
3221 SysFreeString( method
);
3222 SysFreeString( url
);
3224 V_VT( &data
) = VT_BSTR
;
3225 V_BSTR( &data
) = SysAllocString( test_dataW
);
3226 hr
= IWinHttpRequest_Send( req
, data
);
3227 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
3229 SysFreeString( V_BSTR( &data
) );
3231 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
3232 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3234 method
= SysAllocString( method1W
);
3235 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
3236 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3238 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
3239 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3241 url
= SysAllocString( url1W
);
3242 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
3243 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3245 hr
= IWinHttpRequest_Abort( req
);
3246 ok( hr
== S_OK
, "got %08x\n", hr
);
3248 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
3249 ok( hr
== S_OK
, "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 SysFreeString( url
);
3260 url
= SysAllocString( url2W
);
3261 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3262 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3264 SysFreeString( method
);
3265 method
= SysAllocString( method2W
);
3266 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3267 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3269 SysFreeString( method
);
3270 method
= SysAllocString( method1W
);
3271 SysFreeString( url
);
3272 url
= SysAllocString( url1W
);
3273 V_VT( &async
) = VT_ERROR
;
3274 V_ERROR( &async
) = DISP_E_PARAMNOTFOUND
;
3275 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3276 ok( hr
== S_OK
, "got %08x\n", hr
);
3278 V_VT( &cp
) = VT_ERROR
;
3279 V_ERROR( &cp
) = 0xdeadbeef;
3280 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3281 ok( hr
== S_OK
, "got %08x\n", hr
);
3282 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3283 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3285 V_VT( &cp
) = VT_UI4
;
3286 V_UI4( &cp
) = CP_ACP
;
3287 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3288 ok( hr
== S_OK
, "got %08x\n", hr
);
3290 V_VT( &cp
) = VT_ERROR
;
3291 V_ERROR( &cp
) = 0xdeadbeef;
3292 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3293 ok( hr
== S_OK
, "got %08x\n", hr
);
3294 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3295 ok( V_I4( &cp
) == CP_ACP
, "got %u\n", V_I4( &cp
) );
3297 value
= SysAllocString( utf8W
);
3298 V_VT( &cp
) = VT_BSTR
;
3299 V_BSTR( &cp
) = value
;
3300 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3301 ok( hr
== S_OK
, "got %08x\n", hr
);
3302 SysFreeString( value
);
3304 V_VT( &cp
) = VT_ERROR
;
3305 V_ERROR( &cp
) = 0xdeadbeef;
3306 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3307 ok( hr
== S_OK
, "got %08x\n", hr
);
3308 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3309 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3311 hr
= IWinHttpRequest_Abort( req
);
3312 ok( hr
== S_OK
, "got %08x\n", hr
);
3314 hr
= IWinHttpRequest_Send( req
, empty
);
3315 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3317 hr
= IWinHttpRequest_Abort( req
);
3318 ok( hr
== S_OK
, "got %08x\n", hr
);
3320 IWinHttpRequest_Release( req
);
3322 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3323 ok( hr
== S_OK
, "got %08x\n", hr
);
3325 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3326 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3328 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3329 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3331 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3332 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3334 hr
= IWinHttpRequest_get_Status( req
, &status
);
3335 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3337 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3338 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3340 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3341 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3343 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3344 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3346 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3347 ok( hr
== S_OK
, "got %08x\n", hr
);
3349 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3350 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3352 VariantInit( &proxy_server
);
3353 V_VT( &proxy_server
) = VT_ERROR
;
3354 VariantInit( &bypass_list
);
3355 V_VT( &bypass_list
) = VT_ERROR
;
3356 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3357 ok( hr
== S_OK
, "got %08x\n", hr
);
3359 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3360 ok( hr
== S_OK
, "got %08x\n", hr
);
3362 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3363 ok( hr
== S_OK
, "got %08x\n", hr
);
3365 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3366 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3368 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3369 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3371 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3372 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3374 connection
= SysAllocString( connectionW
);
3375 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3376 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3378 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3379 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3381 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
3382 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3384 date
= SysAllocString( dateW
);
3385 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3386 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3388 today
= SysAllocString( todayW
);
3389 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3390 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3392 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
3393 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3395 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3396 ok( hr
== S_OK
, "got %08x\n", hr
);
3398 SysFreeString( method
);
3399 method
= SysAllocString( method1W
);
3400 SysFreeString( url
);
3401 url
= SysAllocString( url1W
);
3402 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3403 ok( hr
== S_OK
, "got %08x\n", hr
);
3405 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3406 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3408 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3409 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3411 hr
= IWinHttpRequest_get_Status( req
, &status
);
3412 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3414 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3415 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3417 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3418 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3420 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3421 ok( hr
== S_OK
, "got %08x\n", hr
);
3423 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3424 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3426 username
= SysAllocString( usernameW
);
3427 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
3428 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3430 password
= SysAllocString( passwordW
);
3431 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
3432 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3434 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
3435 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3437 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3438 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3440 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3441 ok( hr
== S_OK
, "got %08x\n", hr
);
3443 V_VT( &proxy_server
) = VT_BSTR
;
3444 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
3445 V_VT( &bypass_list
) = VT_BSTR
;
3446 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
3447 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3448 ok( hr
== S_OK
, "got %08x\n", hr
);
3450 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
3451 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3453 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3454 ok( hr
== S_OK
, "got %08x\n", hr
);
3456 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3457 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3459 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3460 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3462 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3463 ok( hr
== S_OK
, "got %08x\n", hr
);
3465 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3466 ok( hr
== S_OK
, "got %08x\n", hr
);
3468 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3469 ok( hr
== S_OK
, "got %08x\n", hr
);
3471 hr
= IWinHttpRequest_Send( req
, empty
);
3472 ok( hr
== S_OK
, "got %08x\n", hr
);
3474 hr
= IWinHttpRequest_Send( req
, empty
);
3475 ok( hr
== S_OK
, "got %08x\n", hr
);
3477 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3478 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3480 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3481 ok( hr
== S_OK
, "got %08x\n", hr
);
3482 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3483 SysFreeString( response
);
3485 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3486 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3489 hr
= IWinHttpRequest_get_Status( req
, &status
);
3490 ok( hr
== S_OK
, "got %08x\n", hr
);
3491 trace("Status=%d\n", status
);
3493 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3494 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3496 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3497 ok( hr
== S_OK
, "got %08x\n", hr
);
3498 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
3499 SysFreeString( status_text
);
3501 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3502 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3504 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3505 ok( hr
== S_OK
, "got %08x\n", hr
);
3507 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3508 ok( hr
== S_OK
, "got %08x\n", hr
);
3510 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3511 ok( hr
== S_OK
, "got %08x\n", hr
);
3513 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3514 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3516 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3517 ok( hr
== S_OK
, "got %08x\n", hr
);
3518 SysFreeString( headers
);
3520 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3521 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3523 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3524 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3526 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3527 ok( hr
== S_OK
, "got %08x\n", hr
);
3528 SysFreeString( value
);
3530 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3531 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3533 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3534 ok( hr
== S_OK
, "got %08x\n", hr
);
3536 VariantInit( &timeout
);
3537 V_VT( &timeout
) = VT_I4
;
3538 V_I4( &timeout
) = 10;
3539 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3540 ok( hr
== S_OK
, "got %08x\n", hr
);
3542 hr
= IWinHttpRequest_get_Status( req
, &status
);
3543 ok( hr
== S_OK
, "got %08x\n", hr
);
3545 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3546 ok( hr
== S_OK
, "got %08x\n", hr
);
3547 SysFreeString( status_text
);
3549 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3550 ok( hr
== S_OK
, "got %08x\n", hr
);
3552 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3553 ok( hr
== S_OK
, "got %08x\n", hr
);
3555 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3556 ok( hr
== S_OK
, "got %08x\n", hr
);
3558 hr
= IWinHttpRequest_Send( req
, empty
);
3559 ok( hr
== S_OK
, "got %08x\n", hr
);
3561 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3562 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3564 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3565 ok( hr
== S_OK
, "got %08x\n", hr
);
3566 SysFreeString( response
);
3568 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3569 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3571 VariantInit( &body
);
3572 V_VT( &body
) = VT_ERROR
;
3573 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
3574 ok( hr
== S_OK
, "got %08x\n", hr
);
3575 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
3577 hr
= VariantClear( &body
);
3578 ok( hr
== S_OK
, "got %08x\n", hr
);
3580 VariantInit( &body
);
3581 V_VT( &body
) = VT_ERROR
;
3582 hr
= IWinHttpRequest_get_ResponseStream( req
, &body
);
3583 ok( hr
== S_OK
, "got %08x\n", hr
);
3584 ok( V_VT( &body
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body
) );
3586 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body
), &IID_IStream
, (void **)&stream
);
3587 ok( hr
== S_OK
, "got %08x\n", hr
);
3588 ok( V_UNKNOWN( &body
) == (IUnknown
*)stream
, "got different interface pointer\n" );
3592 hr
= IStream_Read( stream
, buf
, 128, &count
);
3593 ok( hr
== S_OK
, "got %08x\n", hr
);
3594 ok( count
!= 0xdeadbeef, "count not set\n" );
3595 ok( buf
[0], "no data\n" );
3597 VariantInit( &body2
);
3598 V_VT( &body2
) = VT_ERROR
;
3599 hr
= IWinHttpRequest_get_ResponseStream( req
, &body2
);
3600 ok( hr
== S_OK
, "got %08x\n", hr
);
3601 ok( V_VT( &body2
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body2
) );
3602 ok( V_UNKNOWN( &body
) != V_UNKNOWN( &body2
), "got same interface pointer\n" );
3604 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body2
), &IID_IStream
, (void **)&stream2
);
3605 ok( hr
== S_OK
, "got %08x\n", hr
);
3606 ok( V_UNKNOWN( &body2
) == (IUnknown
*)stream2
, "got different interface pointer\n" );
3607 IStream_Release( stream2
);
3609 hr
= VariantClear( &body
);
3610 ok( hr
== S_OK
, "got %08x\n", hr
);
3612 hr
= VariantClear( &body2
);
3613 ok( hr
== S_OK
, "got %08x\n", hr
);
3615 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3616 ok( hr
== S_OK
, "got %08x\n", hr
);
3618 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3619 ok( hr
== S_OK
, "got %08x\n", hr
);
3621 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3622 ok( hr
== S_OK
, "got %08x\n", hr
);
3623 SysFreeString( headers
);
3625 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3626 ok( hr
== S_OK
, "got %08x\n", hr
);
3627 SysFreeString( value
);
3629 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3630 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3632 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3633 ok( hr
== S_OK
, "got %08x\n", hr
);
3635 hr
= IWinHttpRequest_Send( req
, empty
);
3636 ok( hr
== S_OK
, "got %08x\n", hr
);
3638 hr
= IWinHttpRequest_Abort( req
);
3639 ok( hr
== S_OK
, "got %08x\n", hr
);
3641 hr
= IWinHttpRequest_Abort( req
);
3642 ok( hr
== S_OK
, "got %08x\n", hr
);
3644 IWinHttpRequest_Release( req
);
3647 hr
= IStream_Seek( stream
, pos
, STREAM_SEEK_SET
, NULL
);
3648 ok( hr
== S_OK
, "got %08x\n", hr
);
3652 hr
= IStream_Read( stream
, buf
, 128, &count
);
3653 ok( hr
== S_OK
, "got %08x\n", hr
);
3654 ok( count
!= 0xdeadbeef, "count not set\n" );
3655 ok( buf
[0], "no data\n" );
3656 IStream_Release( stream
);
3658 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3659 ok( hr
== S_OK
, "got %08x\n", hr
);
3661 V_VT( &async
) = VT_I4
;
3663 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3664 ok( hr
== S_OK
, "got %08x\n", hr
);
3666 hr
= IWinHttpRequest_Send( req
, empty
);
3667 ok( hr
== S_OK
, "got %08x\n", hr
);
3669 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3670 ok( hr
== S_OK
, "got %08x\n", hr
);
3672 IWinHttpRequest_Release( req
);
3674 SysFreeString( method
);
3675 SysFreeString( url
);
3676 SysFreeString( username
);
3677 SysFreeString( password
);
3678 SysFreeString( connection
);
3679 SysFreeString( date
);
3680 SysFreeString( today
);
3681 VariantClear( &proxy_server
);
3682 VariantClear( &bypass_list
);
3684 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3685 ok( hr
== S_OK
, "got %08x\n", hr
);
3687 url
= SysAllocString( test_winehq_https
);
3688 method
= SysAllocString( method3W
);
3689 V_VT( &async
) = VT_BOOL
;
3690 V_BOOL( &async
) = VARIANT_FALSE
;
3691 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3692 ok( hr
== S_OK
, "got %08x\n", hr
);
3693 SysFreeString( method
);
3694 SysFreeString( url
);
3696 hr
= IWinHttpRequest_Send( req
, empty
);
3697 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)), "got %08x\n", hr
);
3700 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3701 ok( hr
== S_OK
, "got %08x\n", hr
);
3702 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3703 SysFreeString( response
);
3706 IWinHttpRequest_Release( req
);
3708 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3709 ok( hr
== S_OK
, "got %08x\n", hr
);
3711 sprintf( buf
, "http://localhost:%d/auth", port
);
3712 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, bufW
, sizeof(bufW
)/sizeof(bufW
[0]) );
3713 url
= SysAllocString( bufW
);
3714 method
= SysAllocString( method3W
);
3715 V_VT( &async
) = VT_BOOL
;
3716 V_BOOL( &async
) = VARIANT_FALSE
;
3717 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3718 ok( hr
== S_OK
, "got %08x\n", hr
);
3719 SysFreeString( method
);
3720 SysFreeString( url
);
3722 hr
= IWinHttpRequest_get_Status( req
, &status
);
3723 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3725 V_VT( &data
) = VT_BSTR
;
3726 V_BSTR( &data
) = SysAllocString( test_dataW
);
3727 hr
= IWinHttpRequest_Send( req
, data
);
3728 ok( hr
== S_OK
, "got %08x\n", hr
);
3729 SysFreeString( V_BSTR( &data
) );
3731 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3732 ok( hr
== S_OK
, "got %08x\n", hr
);
3733 ok( !memcmp( response
, unauthW
, sizeof(unauthW
) ), "got %s\n", wine_dbgstr_w(response
) );
3734 SysFreeString( response
);
3736 status
= 0xdeadbeef;
3737 hr
= IWinHttpRequest_get_Status( req
, &status
);
3738 ok( hr
== S_OK
, "got %08x\n", hr
);
3739 ok( status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
3741 IWinHttpRequest_Release( req
);
3746 static void request_get_property(IWinHttpRequest
*request
, int property
, VARIANT
*ret
)
3752 memset(¶ms
, 0, sizeof(params
));
3753 params
.cNamedArgs
= 0;
3754 params
.rgdispidNamedArgs
= NULL
;
3756 params
.rgvarg
= &arg
;
3759 V_I4(&arg
) = property
;
3761 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3762 DISPATCH_PROPERTYGET
, ¶ms
, ret
, NULL
, NULL
);
3763 ok(hr
== S_OK
, "error %#x\n", hr
);
3766 static void test_IWinHttpRequest_Invoke(void)
3768 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
3769 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};
3770 WCHAR openW
[] = {'O','p','e','n',0};
3771 WCHAR optionW
[] = {'O','p','t','i','o','n',0};
3772 OLECHAR
*open
= openW
, *option
= optionW
;
3775 IWinHttpRequest
*request
;
3776 IDispatch
*dispatch
;
3779 VARIANT arg
[3], ret
;
3786 hr
= CLSIDFromProgID(regid
, &clsid
);
3787 ok(hr
== S_OK
, "CLSIDFromProgID error %#x\n", hr
);
3788 bret
= IsEqualIID(&clsid
, &CLSID_WinHttpRequest
);
3789 ok(bret
|| broken(!bret
) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid
));
3791 hr
= CoCreateInstance(&CLSID_WinHttpRequest
, 0, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&request
);
3792 ok(hr
== S_OK
, "error %#x\n", hr
);
3794 hr
= IWinHttpRequest_QueryInterface(request
, &IID_IDispatch
, (void **)&dispatch
);
3795 ok(hr
== S_OK
, "error %#x\n", hr
);
3796 IDispatch_Release(dispatch
);
3798 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &open
, 1, 0x0409, &id
);
3799 ok(hr
== S_OK
, "error %#x\n", hr
);
3800 ok(id
== DISPID_HTTPREQUEST_OPEN
, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id
);
3802 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &option
, 1, 0x0409, &id
);
3803 ok(hr
== S_OK
, "error %#x\n", hr
);
3804 ok(id
== DISPID_HTTPREQUEST_OPTION
, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id
);
3806 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3807 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3808 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3810 memset(¶ms
, 0, sizeof(params
));
3812 params
.cNamedArgs
= 0;
3813 params
.rgvarg
= arg
;
3814 V_VT(&arg
[0]) = VT_I4
;
3815 V_I4(&arg
[0]) = 1252;
3816 V_VT(&arg
[1]) = VT_R8
;
3817 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3819 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3820 DISPATCH_METHOD
, ¶ms
, NULL
, 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 memset(¶ms
, 0, sizeof(params
));
3829 params
.cNamedArgs
= 0;
3830 params
.rgvarg
= arg
;
3831 V_VT(&arg
[0]) = VT_I4
;
3832 V_I4(&arg
[0]) = 1252;
3833 V_VT(&arg
[1]) = VT_R8
;
3834 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3836 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3837 DISPATCH_METHOD
| DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3838 ok(hr
== S_OK
, "error %#x\n", hr
);
3840 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3841 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3842 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3844 memset(¶ms
, 0, sizeof(params
));
3846 params
.cNamedArgs
= 0;
3847 params
.rgvarg
= arg
;
3848 V_VT(&arg
[0]) = VT_I4
;
3849 V_I4(&arg
[0]) = 1252;
3850 V_VT(&arg
[1]) = VT_R8
;
3851 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3853 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3854 DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3855 ok(hr
== S_OK
, "error %#x\n", hr
);
3857 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3858 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3859 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3861 memset(¶ms
, 0, sizeof(params
));
3863 params
.cNamedArgs
= 0;
3864 params
.rgvarg
= arg
;
3865 V_VT(&arg
[0]) = VT_BSTR
;
3866 utf8
= SysAllocString(utf8W
);
3867 V_BSTR(&arg
[0]) = utf8
;
3868 V_VT(&arg
[1]) = VT_R8
;
3869 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3870 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3871 ok(hr
== S_OK
, "error %#x\n", hr
);
3873 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3874 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3875 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3878 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, &err
);
3879 ok(hr
== S_OK
, "error %#x\n", hr
);
3881 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3882 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3883 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3886 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3887 ok(hr
== S_OK
, "error %#x\n", hr
);
3889 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3890 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3891 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3893 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
3894 ok(hr
== S_OK
, "error %#x\n", hr
);
3896 hr
= IWinHttpRequest_Invoke(request
, 255, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
3897 ok(hr
== DISP_E_MEMBERNOTFOUND
, "error %#x\n", hr
);
3900 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3901 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
3904 if (0) /* crashes */
3905 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, &ret
, NULL
, &err
);
3908 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3909 ok(hr
== DISP_E_TYPEMISMATCH
, "error %#x\n", hr
);
3911 VariantInit(&arg
[2]);
3913 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
3915 ok(hr
== S_OK
, "error %#x\n", hr
);
3917 VariantInit(&arg
[0]);
3918 VariantInit(&arg
[1]);
3919 VariantInit(&arg
[2]);
3922 V_VT(&arg
[0]) = VT_I4
;
3923 V_I4(&arg
[0]) = WinHttpRequestOption_URLCodePage
;
3924 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3925 ok(hr
== S_OK
, "error %#x\n", hr
);
3927 V_VT(&ret
) = 0xdead;
3928 V_I4(&ret
) = 0xbeef;
3929 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, &ret
, NULL
, NULL
);
3930 ok(hr
== S_OK
, "error %#x\n", hr
);
3931 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3932 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3934 V_VT(&ret
) = 0xdead;
3935 V_I4(&ret
) = 0xbeef;
3936 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
3937 ok(hr
== S_OK
, "error %#x\n", hr
);
3938 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3939 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3941 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3942 ok(hr
== S_OK
, "error %#x\n", hr
);
3944 V_VT(&ret
) = 0xdead;
3945 V_I4(&ret
) = 0xbeef;
3946 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, &ret
, NULL
, NULL
);
3947 ok(hr
== S_OK
, "error %#x\n", hr
);
3948 ok(V_VT(&ret
) == VT_EMPTY
, "expected VT_EMPTY, got %d\n", V_VT(&ret
));
3949 ok(V_I4(&ret
) == 0xbeef || V_I4(&ret
) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret
));
3951 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, NULL
, NULL
, NULL
);
3952 ok(hr
== S_OK
, "error %#x\n", hr
);
3954 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3955 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
3958 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3960 ok(hr
== S_OK
, "error %#x\n", hr
);
3963 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
3964 ok(hr
== DISP_E_PARAMNOTFOUND
, "error %#x\n", hr
);
3966 SysFreeString(utf8
);
3969 V_VT(&arg
[0]) = VT_I4
;
3970 V_I4(&arg
[0]) = AutoLogonPolicy_Never
;
3972 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY
, &IID_NULL
, 0,
3973 DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
3974 ok(hr
== S_OK
, "error %#x\n", hr
);
3976 IWinHttpRequest_Release(request
);
3981 static void test_WinHttpDetectAutoProxyConfigUrl(void)
3987 if (0) /* crashes on some win2k systems */
3989 SetLastError(0xdeadbeef);
3990 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
3991 error
= GetLastError();
3992 ok( !ret
, "expected failure\n" );
3993 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
3996 SetLastError(0xdeadbeef);
3997 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
3998 error
= GetLastError();
3999 ok( !ret
, "expected failure\n" );
4000 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4002 if (0) /* crashes on some win2k systems */
4004 SetLastError(0xdeadbeef);
4005 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
4006 error
= GetLastError();
4007 ok( !ret
, "expected failure\n" );
4008 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4010 url
= (WCHAR
*)0xdeadbeef;
4011 SetLastError(0xdeadbeef);
4012 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
4013 error
= GetLastError();
4016 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4017 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4021 trace("%s\n", wine_dbgstr_w(url
));
4025 url
= (WCHAR
*)0xdeadbeef;
4026 SetLastError(0xdeadbeef);
4027 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
4028 error
= GetLastError();
4031 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4032 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4036 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4037 trace("%s\n", wine_dbgstr_w(url
));
4042 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
4046 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
4048 memset( &cfg
, 0, sizeof(cfg
) );
4050 SetLastError(0xdeadbeef);
4051 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
4052 error
= GetLastError();
4053 ok( !ret
, "expected failure\n" );
4054 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4056 SetLastError(0xdeadbeef);
4057 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
4058 error
= GetLastError();
4059 ok( ret
, "expected success\n" );
4060 ok( error
== ERROR_SUCCESS
|| broken(error
== ERROR_NO_TOKEN
) /* < win7 */, "got %u\n", error
);
4062 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
4063 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
4064 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
4065 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
4066 GlobalFree( cfg
.lpszAutoConfigUrl
);
4067 GlobalFree( cfg
.lpszProxy
);
4068 GlobalFree( cfg
.lpszProxyBypass
);
4071 static void test_WinHttpGetProxyForUrl(void)
4073 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4074 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4075 static const WCHAR emptyW
[] = {0};
4079 WINHTTP_AUTOPROXY_OPTIONS options
;
4080 WINHTTP_PROXY_INFO info
;
4082 memset( &options
, 0, sizeof(options
) );
4084 SetLastError(0xdeadbeef);
4085 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
4086 error
= GetLastError();
4087 ok( !ret
, "expected failure\n" );
4088 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
4090 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4091 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
4093 SetLastError(0xdeadbeef);
4094 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
4095 error
= GetLastError();
4096 ok( !ret
, "expected failure\n" );
4097 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4099 SetLastError(0xdeadbeef);
4100 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
4101 error
= GetLastError();
4102 ok( !ret
, "expected failure\n" );
4103 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4105 SetLastError(0xdeadbeef);
4106 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
4107 error
= GetLastError();
4108 ok( !ret
, "expected failure\n" );
4109 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4111 SetLastError(0xdeadbeef);
4112 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4113 error
= GetLastError();
4114 ok( !ret
, "expected failure\n" );
4115 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4117 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4118 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4120 SetLastError(0xdeadbeef);
4121 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
4122 error
= GetLastError();
4123 ok( !ret
, "expected failure\n" );
4124 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4126 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4127 options
.dwAutoDetectFlags
= 0;
4129 SetLastError(0xdeadbeef);
4130 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4131 error
= GetLastError();
4132 ok( !ret
, "expected failure\n" );
4133 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4135 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
4136 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4138 SetLastError(0xdeadbeef);
4139 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4140 error
= GetLastError();
4141 ok( !ret
, "expected failure\n" );
4142 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4144 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4145 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4147 memset( &info
, 0, sizeof(info
) );
4148 SetLastError(0xdeadbeef);
4149 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4150 error
= GetLastError();
4153 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4154 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4155 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4156 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4157 GlobalFree( info
.lpszProxy
);
4158 GlobalFree( info
.lpszProxyBypass
);
4161 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
4162 options
.dwAutoDetectFlags
= 0;
4163 options
.lpszAutoConfigUrl
= wpadW
;
4165 memset( &info
, 0, sizeof(info
) );
4166 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4169 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4170 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4171 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4172 GlobalFree( info
.lpszProxy
);
4173 GlobalFree( info
.lpszProxyBypass
);
4175 WinHttpCloseHandle( session
);
4178 static void test_chunked_read(void)
4180 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4181 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
4184 HINTERNET ses
, con
= NULL
, req
= NULL
;
4187 trace( "starting chunked read test\n" );
4189 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4190 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
4191 if (!ses
) goto done
;
4193 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
4194 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
4195 if (!con
) goto done
;
4197 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
4198 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4199 if (!req
) goto done
;
4201 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
4202 err
= GetLastError();
4203 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
4205 skip("connection failed, skipping\n");
4208 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4210 ret
= WinHttpReceiveResponse( req
, NULL
);
4211 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4214 len
= sizeof(header
);
4215 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
4216 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4217 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
4218 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
4221 len
= sizeof(header
);
4222 SetLastError( 0xdeadbeef );
4223 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
4224 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
4225 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
4227 trace( "entering query loop\n" );
4231 ret
= WinHttpQueryDataAvailable( req
, &len
);
4232 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4233 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4234 trace( "got %u available\n", len
);
4238 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
4240 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
4242 buf
[bytes_read
] = 0;
4243 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
4244 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
4245 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
4247 HeapFree( GetProcessHeap(), 0, buf
);
4248 if (!bytes_read
) break;
4255 if (req
) WinHttpCloseHandle( req
);
4256 if (con
) WinHttpCloseHandle( con
);
4257 if (ses
) WinHttpCloseHandle( ses
);
4260 START_TEST (winhttp
)
4262 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
4263 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
4264 struct server_info si
;
4270 test_WinHttpTimeFromSystemTime();
4271 test_WinHttpTimeToSystemTime();
4272 test_WinHttpAddHeaders();
4273 test_secure_connection();
4274 test_request_parameter_defaults();
4276 test_set_default_proxy_config();
4277 test_empty_headers_param();
4279 test_resolve_timeout();
4281 test_IWinHttpRequest_Invoke();
4282 test_WinHttpDetectAutoProxyConfigUrl();
4283 test_WinHttpGetIEProxyConfigForCurrentUser();
4284 test_WinHttpGetProxyForUrl();
4285 test_chunked_read();
4287 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
4290 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
4291 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
4293 ret
= WaitForSingleObject(si
.event
, 10000);
4294 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
4295 if (ret
!= WAIT_OBJECT_0
)
4298 test_IWinHttpRequest(si
.port
);
4299 test_connection_info(si
.port
);
4300 test_basic_request(si
.port
, NULL
, basicW
);
4301 test_no_headers(si
.port
);
4302 test_no_content(si
.port
);
4303 test_head_request(si
.port
);
4304 test_not_modified(si
.port
);
4305 test_basic_authentication(si
.port
);
4306 test_bad_header(si
.port
);
4307 test_multiple_reads(si
.port
);
4308 test_cookies(si
.port
);
4310 /* send the basic request again to shutdown the server thread */
4311 test_basic_request(si
.port
, NULL
, quitW
);
4313 WaitForSingleObject(thread
, 3000);