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
, disable
;
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());
353 /* writing more data than promised by the content-length header causes an error when the connection
354 is resued, so disable keep-alive */
355 disable
= WINHTTP_DISABLE_KEEP_ALIVE
;
356 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &disable
, sizeof(disable
));
357 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
360 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
361 err
= GetLastError();
362 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
364 skip("connection failed, skipping\n");
367 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
370 size
= sizeof(context
);
371 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
372 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
373 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
375 for (i
= 3; post_data
[i
]; i
++)
378 SetLastError(0xdeadbeef);
379 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
382 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
383 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
385 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
387 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
388 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
392 SetLastError(0xdeadbeef);
393 ret
= WinHttpReceiveResponse(request
, NULL
);
394 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == ERROR_NO_TOKEN
) /* < win7 */,
395 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
396 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
399 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
400 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
402 ok(bytes_rw
== sizeof(test_post
) - 1, "Read %u bytes\n", bytes_rw
);
403 ok(!memcmp(buffer
, test_post
, sizeof(test_post
) - 1), "Data read did not match.\n");
406 ret
= WinHttpCloseHandle(request
);
407 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
408 ret
= WinHttpCloseHandle(connection
);
409 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
410 ret
= WinHttpCloseHandle(session
);
411 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
414 static void test_WinHttpTimeFromSystemTime(void)
417 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
418 static const WCHAR expected_string
[] =
419 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
420 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
421 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
424 SetLastError(0xdeadbeef);
425 ret
= WinHttpTimeFromSystemTime(&time
, NULL
);
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(NULL
, time_string
);
432 err
= GetLastError();
433 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
434 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
436 SetLastError(0xdeadbeef);
437 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
438 err
= GetLastError();
439 ok(ret
, "WinHttpTimeFromSystemTime failed: %u\n", err
);
440 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
441 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
442 "Time string returned did not match expected time string.\n");
445 static void test_WinHttpTimeToSystemTime(void)
449 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
450 static const WCHAR time_string1
[] =
451 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
452 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
453 static const WCHAR time_string2
[] =
454 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
455 '1','0',' ','0','5',' ','5','2','\n',0};
458 SetLastError(0xdeadbeef);
459 ret
= WinHttpTimeToSystemTime(time_string1
, NULL
);
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(NULL
, &time
);
466 err
= GetLastError();
467 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
468 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
470 SetLastError(0xdeadbeef);
471 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
472 err
= GetLastError();
473 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
474 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
475 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
476 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
478 SetLastError(0xdeadbeef);
479 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
480 err
= GetLastError();
481 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
482 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
483 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
484 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
487 static void test_WinHttpAddHeaders(void)
489 HINTERNET session
, request
, connection
;
491 WCHAR buffer
[MAX_PATH
];
492 WCHAR check_buffer
[MAX_PATH
];
493 DWORD err
, index
, len
, oldlen
;
495 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
496 static const WCHAR test_verb
[] = {'P','O','S','T',0};
497 static const WCHAR test_header_begin
[] =
498 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
499 static const WCHAR full_path_test_header_begin
[] =
500 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
501 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
502 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
503 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
504 static const WCHAR test_header_name2
[] = {'n','a','m','e',0};
505 static const WCHAR test_header_name3
[] = {'a',0};
506 static const WCHAR test_header_range
[] = {'R','a','n','g','e',0};
507 static const WCHAR test_header_range_bytes
[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
508 static const WCHAR test_header_bytes
[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
510 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
511 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
512 static const WCHAR test_flag_coalesce_comma
[] =
513 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
514 static const WCHAR test_flag_coalesce_comma_reverse
[] =
515 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
516 static const WCHAR test_flag_coalesce_semicolon
[] =
517 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
518 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
519 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
521 static const WCHAR field
[] = {'f','i','e','l','d',0};
522 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
523 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
524 static const WCHAR empty
[] = {0};
526 static const WCHAR test_headers
[][14] =
528 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
529 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
530 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
531 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
532 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
533 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
534 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
540 {' ','e',' ',':','f',0},
541 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
542 {'n','a','m','e',':',' ','v','a','l','u','e',0},
543 {'n','a','m','e',':',0}
545 static const WCHAR test_indices
[][6] =
547 {'t','e','s','t','1',0},
548 {'t','e','s','t','2',0},
549 {'t','e','s','t','3',0},
550 {'t','e','s','t','4',0}
553 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
554 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
555 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
557 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
558 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
560 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
561 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
562 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
564 skip("Network unreachable, skipping.\n");
567 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
570 len
= sizeof(buffer
);
571 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
572 test_header_name
, buffer
, &len
, &index
);
573 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
574 SetLastError(0xdeadbeef);
575 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
576 err
= GetLastError();
577 ok(ret
, "WinHttpAddRequestHeaders failed to add new header, got %d with error %u.\n", ret
, err
);
578 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
581 len
= sizeof(buffer
);
582 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
583 test_header_name
, buffer
, &len
, &index
);
584 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
585 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
586 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
587 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
589 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
590 test_header_name
, buffer
, &len
, &index
);
591 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
593 /* Try to fetch the header info with a buffer that's big enough to fit the
594 * string but not the NULL terminator.
597 len
= 5*sizeof(WCHAR
);
598 memset(check_buffer
, 0xab, sizeof(check_buffer
));
599 memcpy(buffer
, check_buffer
, sizeof(buffer
));
600 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
601 test_header_name
, buffer
, &len
, &index
);
602 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
603 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
604 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
605 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
607 /* Try with a NULL buffer */
609 len
= sizeof(buffer
);
610 SetLastError(0xdeadbeef);
611 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
612 test_header_name
, NULL
, &len
, &index
);
613 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
614 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
615 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
616 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
618 /* Try with a NULL buffer and a length that's too small */
621 SetLastError(0xdeadbeef);
622 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
623 test_header_name
, NULL
, &len
, &index
);
624 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
625 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
626 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
627 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
628 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
632 SetLastError(0xdeadbeef);
633 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
634 test_header_name
, NULL
, &len
, &index
);
635 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
636 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
637 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
638 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
639 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
644 len
= sizeof(buffer
);
645 memset(buffer
, 0xff, sizeof(buffer
));
646 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
647 test_header_name
, buffer
, &len
, &index
);
648 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
649 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
650 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
651 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
652 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
653 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
654 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
655 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
656 "WinHttpQueryHeaders returned invalid end of header string.\n");
657 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
661 SetLastError(0xdeadbeef);
662 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
663 test_header_name
, NULL
, &len
, &index
);
664 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
665 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
666 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
667 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
668 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
672 len
= sizeof(buffer
);
673 memset(buffer
, 0xff, sizeof(buffer
));
674 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
675 test_header_name
, buffer
, &len
, &index
);
676 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
677 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
678 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
679 "no double NULL terminator\n");
680 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
681 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
682 "invalid beginning of header string.\n");
683 ok(index
== 0, "header index was incremented\n");
685 /* tests for more indices */
686 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
687 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
690 len
= sizeof(buffer
);
691 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
692 test_header_name
, buffer
, &len
, &index
);
693 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
694 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
695 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
697 len
= sizeof(buffer
);
698 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
699 test_header_name
, buffer
, &len
, &index
);
700 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
701 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
702 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
704 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
705 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
708 len
= sizeof(buffer
);
709 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
710 test_header_name
, buffer
, &len
, &index
);
711 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
712 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
713 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
714 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
716 len
= sizeof(buffer
);
717 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
718 test_header_name
, buffer
, &len
, &index
);
719 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
720 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
721 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
723 /* add if new flag */
724 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
725 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
728 len
= sizeof(buffer
);
729 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
730 test_header_name
, buffer
, &len
, &index
);
731 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
732 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
733 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
735 len
= sizeof(buffer
);
736 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
737 test_header_name
, buffer
, &len
, &index
);
738 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
739 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
740 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
742 len
= sizeof(buffer
);
743 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
744 test_header_name
, buffer
, &len
, &index
);
745 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
748 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
749 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
752 len
= sizeof(buffer
);
753 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
754 test_header_name
, buffer
, &len
, &index
);
755 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
756 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
757 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
758 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
760 len
= sizeof(buffer
);
761 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
762 test_header_name
, buffer
, &len
, &index
);
763 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
764 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
765 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
767 len
= sizeof(buffer
);
768 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
769 test_header_name
, buffer
, &len
, &index
);
770 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
772 /* coalesce with comma flag */
773 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
774 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
777 len
= sizeof(buffer
);
778 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
779 test_header_name
, buffer
, &len
, &index
);
780 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
781 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
782 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
783 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
784 "WinHttpQueryHeaders returned incorrect string.\n");
786 len
= sizeof(buffer
);
787 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
788 test_header_name
, buffer
, &len
, &index
);
789 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
790 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
791 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
793 len
= sizeof(buffer
);
794 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
795 test_header_name
, buffer
, &len
, &index
);
796 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
799 /* coalesce with semicolon flag */
800 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
801 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
804 len
= sizeof(buffer
);
805 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
806 test_header_name
, buffer
, &len
, &index
);
807 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
808 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
809 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
810 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
811 "WinHttpQueryHeaders returned incorrect string.\n");
813 len
= sizeof(buffer
);
814 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
815 test_header_name
, buffer
, &len
, &index
);
816 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
817 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
818 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
820 len
= sizeof(buffer
);
821 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
822 test_header_name
, buffer
, &len
, &index
);
823 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
825 /* add and replace flags */
826 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
827 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
830 len
= sizeof(buffer
);
831 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
832 test_header_name
, buffer
, &len
, &index
);
833 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
834 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
835 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
837 len
= sizeof(buffer
);
838 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
839 test_header_name
, buffer
, &len
, &index
);
840 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
841 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
842 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
844 len
= sizeof(buffer
);
845 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
846 test_header_name
, buffer
, &len
, &index
);
847 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
849 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
850 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
852 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
853 ok(ret
, "WinHttpAddRequestHeaders failed\n");
856 memset(buffer
, 0xff, sizeof(buffer
));
857 len
= sizeof(buffer
);
858 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
859 test_header_name3
, buffer
, &len
, &index
);
860 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
861 ok(!memcmp(buffer
, empty
, sizeof(empty
)), "unexpected result\n");
863 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
864 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
866 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
867 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
869 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
870 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
872 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
873 ok(ret
, "WinHttpAddRequestHeaders failed\n");
877 len
= sizeof(buffer
);
878 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
879 field
, buffer
, &len
, &index
);
880 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
881 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
883 SetLastError(0xdeadbeef);
884 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, 0,
885 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
886 err
= GetLastError();
887 ok(!ret
, "unexpected success\n");
888 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
890 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, ~0u,
891 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
892 ok(ret
, "failed to add header: %u\n", GetLastError());
895 len
= sizeof(buffer
);
896 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
897 test_header_range
, buffer
, &len
, &index
);
898 ok(ret
, "failed to get range header %u\n", GetLastError());
899 ok(!memcmp(buffer
, test_header_bytes
, sizeof(test_header_bytes
)), "incorrect string returned\n");
900 ok(len
== lstrlenW(test_header_bytes
) * sizeof(WCHAR
), "wrong length %u\n", len
);
901 ok(index
== 1, "wrong index %u\n", index
);
904 len
= sizeof(buffer
);
905 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
906 test_header_name2
, buffer
, &len
, &index
);
907 ok(!ret
, "unexpected success\n");
909 SetLastError(0xdeadbeef);
910 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
911 err
= GetLastError();
912 ok(!ret
, "unexpected success\n");
913 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
915 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
916 ok(ret
, "got %u\n", GetLastError());
919 len
= sizeof(buffer
);
920 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
921 test_header_name2
, buffer
, &len
, &index
);
922 ok(ret
, "got %u\n", GetLastError());
923 ok(index
== 1, "wrong index %u\n", index
);
924 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
926 ret
= WinHttpAddRequestHeaders(request
, test_headers
[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
927 ok(ret
, "got %u\n", GetLastError());
930 len
= sizeof(buffer
);
931 SetLastError(0xdeadbeef);
932 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
933 test_header_name2
, buffer
, &len
, &index
);
934 err
= GetLastError();
935 ok(!ret
, "unexpected success\n");
936 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
938 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], -1L, 0);
939 ok(ret
, "got %u\n", GetLastError());
942 len
= sizeof(buffer
);
943 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
944 test_header_name2
, buffer
, &len
, &index
);
945 ok(ret
, "got %u\n", GetLastError());
946 ok(index
== 1, "wrong index %u\n", index
);
947 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
949 ret
= WinHttpCloseHandle(request
);
950 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
952 ret
= WinHttpCloseHandle(connection
);
953 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
954 ret
= WinHttpCloseHandle(session
);
955 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
959 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
961 DWORD flags
= *(DWORD
*)buf
;
965 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
968 #define X(x) if (flags & x) trace("%s\n", #x);
969 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
970 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
971 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
972 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
973 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
974 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
975 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
979 static void test_secure_connection(void)
981 static const char data_start
[] = "<!DOCTYPE html PUBLIC";
982 HINTERNET ses
, con
, req
;
983 DWORD size
, status
, policy
, bitness
, read_size
, err
, available_size
, protocols
;
986 WINHTTP_CERTIFICATE_INFO info
;
989 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
990 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
992 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
993 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
994 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
996 protocols
= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
;
997 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SECURE_PROTOCOLS
, &protocols
, sizeof(protocols
));
998 err
= GetLastError();
999 ok(ret
|| err
== ERROR_INVALID_PARAMETER
/* < win7 */, "failed to set protocols %u\n", err
);
1001 con
= WinHttpConnect(ses
, test_winehq
, 443, 0);
1002 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1004 /* try without setting WINHTTP_FLAG_SECURE */
1005 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1006 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1008 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1009 err
= GetLastError();
1010 ok(!ret
, "unexpected success\n");
1011 ok(err
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
|| broken(err
== ERROR_INVALID_PARAMETER
) /* winxp */,
1012 "setting client cert context returned %u\n", err
);
1014 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1015 err
= GetLastError();
1016 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
1018 skip("Connection failed, skipping.\n");
1021 ok(ret
, "failed to send request %u\n", GetLastError());
1023 ret
= WinHttpReceiveResponse(req
, NULL
);
1024 ok(ret
, "failed to receive response %u\n", GetLastError());
1026 status
= 0xdeadbeef;
1027 size
= sizeof(status
);
1028 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1029 ok(ret
, "header query failed %u\n", GetLastError());
1030 ok(status
== HTTP_STATUS_BAD_REQUEST
, "got %u\n", status
);
1032 WinHttpCloseHandle(req
);
1034 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
1035 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1037 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1038 err
= GetLastError();
1039 ok(ret
|| broken(!ret
&& err
== ERROR_INVALID_PARAMETER
) /* winxp */, "failed to set client cert context %u\n", err
);
1041 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
1043 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1044 err
= GetLastError();
1045 if (!ret
&& (err
== ERROR_WINHTTP_SECURE_FAILURE
|| err
== ERROR_WINHTTP_CANNOT_CONNECT
||
1046 err
== ERROR_WINHTTP_TIMEOUT
))
1048 skip("secure connection failed, skipping remaining secure tests\n");
1051 ok(ret
, "failed to send request %u\n", GetLastError());
1053 size
= sizeof(cert
);
1054 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1055 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1056 if (ret
) CertFreeCertificateContext(cert
);
1058 size
= sizeof(bitness
);
1059 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
1060 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
1062 size
= sizeof(info
);
1063 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
1064 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
1068 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
1069 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
1070 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
1071 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
1072 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
1073 trace("dwKeySize %u\n", info
.dwKeySize
);
1074 LocalFree( info
.lpszSubjectInfo
);
1075 LocalFree( info
.lpszIssuerInfo
);
1078 ret
= WinHttpReceiveResponse(req
, NULL
);
1079 ok(ret
, "failed to receive response %u\n", GetLastError());
1082 ret
= WinHttpQueryDataAvailable(req
, &available_size
);
1083 ok(ret
, "failed to query available data %u\n", GetLastError());
1084 ok(available_size
> 2014, "available_size = %u\n", available_size
);
1086 status
= 0xdeadbeef;
1087 size
= sizeof(status
);
1088 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1089 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1090 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1093 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
1094 ok(!ret
, "succeeded unexpectedly\n");
1100 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
1101 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
1105 if (read_size
<= 32)
1106 ok(!memcmp(buffer
, data_start
, sizeof(data_start
)-1), "not expected: %.32s\n", buffer
);
1108 ok(read_size
>= available_size
, "read_size = %u, available_size = %u\n", read_size
, available_size
);
1111 WinHttpCloseHandle(req
);
1112 WinHttpCloseHandle(con
);
1113 WinHttpCloseHandle(ses
);
1116 static void test_request_parameter_defaults(void)
1118 static const WCHAR empty
[] = {0};
1119 HINTERNET ses
, con
, req
;
1120 DWORD size
, status
, error
;
1124 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1125 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1127 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1128 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1130 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1131 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1133 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1134 error
= GetLastError();
1135 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1137 skip("connection failed, skipping\n");
1140 ok(ret
, "failed to send request %u\n", GetLastError());
1142 ret
= WinHttpReceiveResponse(req
, NULL
);
1143 if (!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE
) /* win2k */
1145 win_skip("invalid response\n");
1148 ok(ret
, "failed to receive response %u\n", GetLastError());
1150 status
= 0xdeadbeef;
1151 size
= sizeof(status
);
1152 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1153 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1154 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1156 WinHttpCloseHandle(req
);
1158 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
1159 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1161 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1162 error
= GetLastError();
1163 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1165 skip("connection failed, skipping\n");
1168 ok(ret
, "failed to send request %u\n", GetLastError());
1170 ret
= WinHttpReceiveResponse(req
, NULL
);
1171 ok(ret
, "failed to receive response %u\n", GetLastError());
1174 SetLastError(0xdeadbeef);
1175 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
1176 error
= GetLastError();
1177 ok(!ret
, "succeeded unexpectedly\n");
1178 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
1180 version
= HeapAlloc(GetProcessHeap(), 0, size
);
1181 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
1182 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1183 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
1184 HeapFree(GetProcessHeap(), 0, version
);
1186 status
= 0xdeadbeef;
1187 size
= sizeof(status
);
1188 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1189 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1190 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1193 WinHttpCloseHandle(req
);
1194 WinHttpCloseHandle(con
);
1195 WinHttpCloseHandle(ses
);
1198 static const WCHAR Connections
[] = {
1199 'S','o','f','t','w','a','r','e','\\',
1200 'M','i','c','r','o','s','o','f','t','\\',
1201 'W','i','n','d','o','w','s','\\',
1202 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1203 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1204 'C','o','n','n','e','c','t','i','o','n','s',0 };
1205 static const WCHAR WinHttpSettings
[] = {
1206 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1208 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1214 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1219 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1223 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1233 static void set_proxy( REGSAM access
, BYTE
*buf
, DWORD len
, DWORD type
)
1236 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
))
1238 if (len
) RegSetValueExW( hkey
, WinHttpSettings
, 0, type
, buf
, len
);
1239 else RegDeleteValueW( hkey
, WinHttpSettings
);
1240 RegCloseKey( hkey
);
1244 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1247 IsWow64Process( GetCurrentProcess(), &wow64
);
1248 if (sizeof(void *) > sizeof(int) || wow64
)
1250 set_proxy( KEY_WRITE
|KEY_WOW64_64KEY
, buf
, len
, type
);
1251 set_proxy( KEY_WRITE
|KEY_WOW64_32KEY
, buf
, len
, type
);
1254 set_proxy( KEY_WRITE
, buf
, len
, type
);
1257 static void test_set_default_proxy_config(void)
1259 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1260 static WCHAR normalString
[] = { 'f','o','o',0 };
1262 BYTE
*saved_proxy_settings
= NULL
;
1263 WINHTTP_PROXY_INFO info
;
1266 /* FIXME: it would be simpler to read the current settings using
1267 * WinHttpGetDefaultProxyConfiguration and save them using
1268 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1270 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1271 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1272 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1273 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1274 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1275 * the lpszProxy and lpszProxyBypass values are ignored.
1276 * Thus, if a proxy is set with proxycfg, then calling
1277 * WinHttpGetDefaultProxyConfiguration followed by
1278 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1279 * getting deleted from the registry.
1281 * Instead I read the current registry value and restore it directly.
1283 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1286 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1287 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1292 /* Crashes on Vista and higher */
1293 SetLastError(0xdeadbeef);
1294 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1295 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1296 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1299 /* test with invalid access type */
1300 info
.dwAccessType
= 0xdeadbeef;
1301 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1302 SetLastError(0xdeadbeef);
1303 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1304 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1305 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1307 /* at a minimum, the proxy server must be set */
1308 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1309 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1310 SetLastError(0xdeadbeef);
1311 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1312 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1313 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1314 info
.lpszProxyBypass
= normalString
;
1315 SetLastError(0xdeadbeef);
1316 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1317 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1318 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1320 /* the proxy server can't have wide characters */
1321 info
.lpszProxy
= wideString
;
1322 SetLastError(0xdeadbeef);
1323 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1324 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1325 skip("couldn't set default proxy configuration: access denied\n");
1327 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1328 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1329 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1331 info
.lpszProxy
= normalString
;
1332 SetLastError(0xdeadbeef);
1333 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1334 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1335 skip("couldn't set default proxy configuration: access denied\n");
1338 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1339 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1340 "got %u\n", GetLastError());
1342 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1345 static void test_Timeouts (void)
1349 HINTERNET ses
, req
, con
;
1351 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1352 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1354 SetLastError(0xdeadbeef);
1355 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1356 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1357 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1359 SetLastError(0xdeadbeef);
1360 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1361 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1362 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1364 SetLastError(0xdeadbeef);
1365 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1366 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1367 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1369 SetLastError(0xdeadbeef);
1370 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1371 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1372 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1374 SetLastError(0xdeadbeef);
1375 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1376 ok(ret
, "%u\n", GetLastError());
1377 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1378 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1380 SetLastError(0xdeadbeef);
1381 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1382 ok(ret
, "%u\n", GetLastError());
1384 SetLastError(0xdeadbeef);
1385 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1386 ok(ret
, "%u\n", GetLastError());
1388 SetLastError(0xdeadbeef);
1390 size
= sizeof(DWORD
);
1391 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1392 ok(ret
, "%u\n", GetLastError());
1393 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1395 SetLastError(0xdeadbeef);
1397 size
= sizeof(DWORD
);
1398 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1399 ok(ret
, "%u\n", GetLastError());
1400 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1402 SetLastError(0xdeadbeef);
1404 size
= sizeof(DWORD
);
1405 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1406 ok(ret
, "%u\n", GetLastError());
1407 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1409 SetLastError(0xdeadbeef);
1411 size
= sizeof(DWORD
);
1412 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1413 ok(ret
, "%u\n", GetLastError());
1414 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1416 SetLastError(0xdeadbeef);
1418 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1419 ok(ret
, "%u\n", GetLastError());
1421 SetLastError(0xdeadbeef);
1423 size
= sizeof(DWORD
);
1424 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1425 ok(ret
, "%u\n", GetLastError());
1426 ok(value
== 0, "Expected 0, got %u\n", value
);
1428 SetLastError(0xdeadbeef);
1430 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1431 ok(ret
, "%u\n", GetLastError());
1433 SetLastError(0xdeadbeef);
1435 size
= sizeof(DWORD
);
1436 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1437 ok(ret
, "%u\n", GetLastError());
1438 ok(value
== 0, "Expected 0, got %u\n", value
);
1440 SetLastError(0xdeadbeef);
1442 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1443 ok(ret
, "%u\n", GetLastError());
1445 SetLastError(0xdeadbeef);
1447 size
= sizeof(DWORD
);
1448 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1449 ok(ret
, "%u\n", GetLastError());
1450 ok(value
== 0, "Expected 0, got %u\n", value
);
1452 SetLastError(0xdeadbeef);
1454 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1455 ok(ret
, "%u\n", GetLastError());
1457 SetLastError(0xdeadbeef);
1459 size
= sizeof(DWORD
);
1460 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1461 ok(ret
, "%u\n", GetLastError());
1462 ok(value
== 0, "Expected 0, got %u\n", value
);
1464 SetLastError(0xdeadbeef);
1466 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1467 ok(ret
, "%u\n", GetLastError());
1469 SetLastError(0xdeadbeef);
1471 size
= sizeof(DWORD
);
1472 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1473 ok(ret
, "%u\n", GetLastError());
1474 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1476 SetLastError(0xdeadbeef);
1478 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1479 ok(ret
, "%u\n", GetLastError());
1481 SetLastError(0xdeadbeef);
1483 size
= sizeof(DWORD
);
1484 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1485 ok(ret
, "%u\n", GetLastError());
1486 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1488 SetLastError(0xdeadbeef);
1490 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1491 ok(ret
, "%u\n", GetLastError());
1493 SetLastError(0xdeadbeef);
1495 size
= sizeof(DWORD
);
1496 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1497 ok(ret
, "%u\n", GetLastError());
1498 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1500 SetLastError(0xdeadbeef);
1502 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1503 ok(ret
, "%u\n", GetLastError());
1505 SetLastError(0xdeadbeef);
1507 size
= sizeof(DWORD
);
1508 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1509 ok(ret
, "%u\n", GetLastError());
1510 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1512 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1513 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1515 /* Timeout values should match the last one set for session */
1516 SetLastError(0xdeadbeef);
1518 size
= sizeof(DWORD
);
1519 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1520 ok(ret
, "%u\n", GetLastError());
1521 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1523 SetLastError(0xdeadbeef);
1525 size
= sizeof(DWORD
);
1526 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1527 ok(ret
, "%u\n", GetLastError());
1528 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1530 SetLastError(0xdeadbeef);
1532 size
= sizeof(DWORD
);
1533 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1534 ok(ret
, "%u\n", GetLastError());
1535 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1537 SetLastError(0xdeadbeef);
1539 size
= sizeof(DWORD
);
1540 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1541 ok(ret
, "%u\n", GetLastError());
1542 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1544 SetLastError(0xdeadbeef);
1545 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1546 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1547 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1549 SetLastError(0xdeadbeef);
1550 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1551 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1552 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1554 SetLastError(0xdeadbeef);
1555 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1556 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1557 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1559 SetLastError(0xdeadbeef);
1560 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1561 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1562 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1564 SetLastError(0xdeadbeef);
1565 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1566 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1567 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1569 SetLastError(0xdeadbeef);
1570 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1571 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1572 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1574 SetLastError(0xdeadbeef);
1576 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1577 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1578 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1580 SetLastError(0xdeadbeef);
1582 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1583 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1584 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1586 SetLastError(0xdeadbeef);
1588 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1589 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1590 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1592 SetLastError(0xdeadbeef);
1594 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1595 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1596 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1598 /* Changing timeout values for session should affect the values for connection */
1599 SetLastError(0xdeadbeef);
1601 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1602 ok(ret
, "%u\n", GetLastError());
1604 SetLastError(0xdeadbeef);
1606 size
= sizeof(DWORD
);
1607 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1608 ok(ret
, "%u\n", GetLastError());
1609 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1611 SetLastError(0xdeadbeef);
1613 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1614 ok(ret
, "%u\n", GetLastError());
1616 SetLastError(0xdeadbeef);
1618 size
= sizeof(DWORD
);
1619 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1620 ok(ret
, "%u\n", GetLastError());
1621 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1623 SetLastError(0xdeadbeef);
1625 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1626 ok(ret
, "%u\n", GetLastError());
1628 SetLastError(0xdeadbeef);
1630 size
= sizeof(DWORD
);
1631 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1632 ok(ret
, "%u\n", GetLastError());
1633 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1635 SetLastError(0xdeadbeef);
1637 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1638 ok(ret
, "%u\n", GetLastError());
1640 SetLastError(0xdeadbeef);
1642 size
= sizeof(DWORD
);
1643 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1644 ok(ret
, "%u\n", GetLastError());
1645 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1647 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1648 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1650 /* Timeout values should match the last one set for session */
1651 SetLastError(0xdeadbeef);
1653 size
= sizeof(DWORD
);
1654 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1655 ok(ret
, "%u\n", GetLastError());
1656 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1658 SetLastError(0xdeadbeef);
1660 size
= sizeof(DWORD
);
1661 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1662 ok(ret
, "%u\n", GetLastError());
1663 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1665 SetLastError(0xdeadbeef);
1667 size
= sizeof(DWORD
);
1668 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1669 ok(ret
, "%u\n", GetLastError());
1670 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1672 SetLastError(0xdeadbeef);
1674 size
= sizeof(DWORD
);
1675 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1676 ok(ret
, "%u\n", GetLastError());
1677 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1679 SetLastError(0xdeadbeef);
1680 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1681 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1682 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1684 SetLastError(0xdeadbeef);
1685 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1686 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1687 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1689 SetLastError(0xdeadbeef);
1690 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1691 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1692 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1694 SetLastError(0xdeadbeef);
1695 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1696 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1697 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1699 SetLastError(0xdeadbeef);
1700 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1701 ok(ret
, "%u\n", GetLastError());
1703 SetLastError(0xdeadbeef);
1704 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1705 ok(ret
, "%u\n", GetLastError());
1707 SetLastError(0xdeadbeef);
1708 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1709 ok(ret
, "%u\n", GetLastError());
1711 SetLastError(0xdeadbeef);
1713 size
= sizeof(DWORD
);
1714 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1715 ok(ret
, "%u\n", GetLastError());
1716 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1718 SetLastError(0xdeadbeef);
1720 size
= sizeof(DWORD
);
1721 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1722 ok(ret
, "%u\n", GetLastError());
1723 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1725 SetLastError(0xdeadbeef);
1727 size
= sizeof(DWORD
);
1728 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1729 ok(ret
, "%u\n", GetLastError());
1730 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1732 SetLastError(0xdeadbeef);
1734 size
= sizeof(DWORD
);
1735 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1736 ok(ret
, "%u\n", GetLastError());
1737 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1739 SetLastError(0xdeadbeef);
1741 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1742 ok(ret
, "%u\n", GetLastError());
1744 SetLastError(0xdeadbeef);
1746 size
= sizeof(DWORD
);
1747 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1748 ok(ret
, "%u\n", GetLastError());
1749 ok(value
== 0, "Expected 0, got %u\n", value
);
1751 SetLastError(0xdeadbeef);
1753 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1754 ok(ret
, "%u\n", GetLastError());
1756 SetLastError(0xdeadbeef);
1758 size
= sizeof(DWORD
);
1759 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1760 ok(ret
, "%u\n", GetLastError());
1761 ok(value
== 0, "Expected 0, got %u\n", value
);
1763 SetLastError(0xdeadbeef);
1765 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1766 ok(ret
, "%u\n", GetLastError());
1768 SetLastError(0xdeadbeef);
1770 size
= sizeof(DWORD
);
1771 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1772 ok(ret
, "%u\n", GetLastError());
1773 ok(value
== 0, "Expected 0, got %u\n", value
);
1775 SetLastError(0xdeadbeef);
1777 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1778 ok(ret
, "%u\n", GetLastError());
1780 SetLastError(0xdeadbeef);
1782 size
= sizeof(DWORD
);
1783 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1784 ok(ret
, "%u\n", GetLastError());
1785 ok(value
== 0, "Expected 0, got %u\n", value
);
1787 SetLastError(0xdeadbeef);
1789 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1790 ok(ret
, "%u\n", GetLastError());
1792 SetLastError(0xdeadbeef);
1794 size
= sizeof(DWORD
);
1795 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1796 ok(ret
, "%u\n", GetLastError());
1797 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1799 SetLastError(0xdeadbeef);
1801 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1802 ok(ret
, "%u\n", GetLastError());
1804 SetLastError(0xdeadbeef);
1806 size
= sizeof(DWORD
);
1807 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1808 ok(ret
, "%u\n", GetLastError());
1809 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1811 SetLastError(0xdeadbeef);
1813 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1814 ok(ret
, "%u\n", GetLastError());
1816 SetLastError(0xdeadbeef);
1818 size
= sizeof(DWORD
);
1819 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1820 ok(ret
, "%u\n", GetLastError());
1821 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1823 SetLastError(0xdeadbeef);
1825 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1826 ok(ret
, "%u\n", GetLastError());
1828 SetLastError(0xdeadbeef);
1830 size
= sizeof(DWORD
);
1831 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1832 ok(ret
, "%u\n", GetLastError());
1833 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1835 /* Changing timeout values for session should not affect the values for a request,
1836 * neither should the other way around.
1838 SetLastError(0xdeadbeef);
1840 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1841 ok(ret
, "%u\n", GetLastError());
1843 SetLastError(0xdeadbeef);
1845 size
= sizeof(DWORD
);
1846 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1847 ok(ret
, "%u\n", GetLastError());
1848 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1850 SetLastError(0xdeadbeef);
1852 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1853 ok(ret
, "%u\n", GetLastError());
1855 SetLastError(0xdeadbeef);
1857 size
= sizeof(DWORD
);
1858 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1859 ok(ret
, "%u\n", GetLastError());
1860 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1862 SetLastError(0xdeadbeef);
1864 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1865 ok(ret
, "%u\n", GetLastError());
1867 SetLastError(0xdeadbeef);
1869 size
= sizeof(DWORD
);
1870 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1871 ok(ret
, "%u\n", GetLastError());
1872 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1874 SetLastError(0xdeadbeef);
1876 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1877 ok(ret
, "%u\n", GetLastError());
1879 SetLastError(0xdeadbeef);
1881 size
= sizeof(DWORD
);
1882 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1883 ok(ret
, "%u\n", GetLastError());
1884 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1886 SetLastError(0xdeadbeef);
1888 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1889 ok(ret
, "%u\n", GetLastError());
1891 SetLastError(0xdeadbeef);
1893 size
= sizeof(DWORD
);
1894 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1895 ok(ret
, "%u\n", GetLastError());
1896 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1898 SetLastError(0xdeadbeef);
1900 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1901 ok(ret
, "%u\n", GetLastError());
1903 SetLastError(0xdeadbeef);
1905 size
= sizeof(DWORD
);
1906 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1907 ok(ret
, "%u\n", GetLastError());
1908 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1910 SetLastError(0xdeadbeef);
1912 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1913 ok(ret
, "%u\n", GetLastError());
1915 SetLastError(0xdeadbeef);
1917 size
= sizeof(DWORD
);
1918 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1919 ok(ret
, "%u\n", GetLastError());
1920 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1922 SetLastError(0xdeadbeef);
1924 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1925 ok(ret
, "%u\n", GetLastError());
1927 SetLastError(0xdeadbeef);
1929 size
= sizeof(DWORD
);
1930 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1931 ok(ret
, "%u\n", GetLastError());
1932 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1934 WinHttpCloseHandle(req
);
1935 WinHttpCloseHandle(con
);
1936 WinHttpCloseHandle(ses
);
1939 static void test_resolve_timeout(void)
1941 static const WCHAR nxdomain
[] =
1942 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1943 HINTERNET ses
, con
, req
;
1947 if (! proxy_active())
1949 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1950 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1953 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1954 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1956 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1957 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1959 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1960 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1962 SetLastError(0xdeadbeef);
1963 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1966 skip("nxdomain returned success. Broken ISP redirects?\n");
1969 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1970 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1972 WinHttpCloseHandle(req
);
1973 WinHttpCloseHandle(con
);
1974 WinHttpCloseHandle(ses
);
1977 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1979 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1980 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1983 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1984 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1986 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1987 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1989 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1990 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1992 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1993 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
1995 skip("connection failed, skipping\n");
1998 ok(ret
, "failed to send request\n");
2001 WinHttpCloseHandle(req
);
2002 WinHttpCloseHandle(con
);
2003 WinHttpCloseHandle(ses
);
2006 static const char page1
[] =
2008 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
2009 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2012 static const char okmsg
[] =
2013 "HTTP/1.1 200 OK\r\n"
2014 "Server: winetest\r\n"
2017 static const char notokmsg
[] =
2018 "HTTP/1.1 400 Bad Request\r\n"
2021 static const char cookiemsg
[] =
2022 "HTTP/1.1 200 OK\r\n"
2023 "Set-Cookie: name = value \r\n"
2024 "Set-Cookie: NAME = value \r\n"
2027 static const char cookiemsg2
[] =
2028 "HTTP/1.1 200 OK\r\n"
2029 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2032 static const char nocontentmsg
[] =
2033 "HTTP/1.1 204 No Content\r\n"
2034 "Server: winetest\r\n"
2037 static const char notmodified
[] =
2038 "HTTP/1.1 304 Not Modified\r\n"
2041 static const char noauthmsg
[] =
2042 "HTTP/1.1 401 Unauthorized\r\n"
2043 "Server: winetest\r\n"
2044 "Connection: close\r\n"
2045 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2046 "Content-Length: 12\r\n"
2047 "Content-Type: text/plain\r\n"
2050 static const char okauthmsg
[] =
2051 "HTTP/1.1 200 OK\r\n"
2052 "Server: winetest\r\n"
2053 "Connection: close\r\n"
2054 "Content-Length: 11\r\n"
2055 "Content-Type: text/plain\r\n"
2058 static const char headmsg
[] =
2059 "HTTP/1.1 200 OK\r\n"
2060 "Content-Length: 100\r\n"
2063 static const char multiauth
[] =
2064 "HTTP/1.1 401 Unauthorized\r\n"
2065 "Server: winetest\r\n"
2066 "WWW-Authenticate: Bearer\r\n"
2067 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2068 "WWW-Authenticate: NTLM\r\n"
2069 "Content-Length: 10\r\n"
2070 "Content-Type: text/plain\r\n"
2073 static const char largeauth
[] =
2074 "HTTP/1.1 401 Unauthorized\r\n"
2075 "Server: winetest\r\n"
2076 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2077 "WWW-Authenticate: NTLM\r\n"
2078 "Content-Length: 10240\r\n"
2079 "Content-Type: text/plain\r\n"
2082 static const char unauthorized
[] = "Unauthorized";
2083 static const char hello_world
[] = "Hello World";
2084 static const char auth_unseen
[] = "Auth Unseen";
2092 #define BIG_BUFFER_LEN 0x2250
2094 static DWORD CALLBACK
server_thread(LPVOID param
)
2096 struct server_info
*si
= param
;
2097 int r
, c
= -1, i
, on
;
2099 struct sockaddr_in sa
;
2102 int last_request
= 0;
2104 WSAStartup(MAKEWORD(1,1), &wsaData
);
2106 s
= socket(AF_INET
, SOCK_STREAM
, 0);
2107 if (s
== INVALID_SOCKET
)
2111 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
2113 memset(&sa
, 0, sizeof sa
);
2114 sa
.sin_family
= AF_INET
;
2115 sa
.sin_port
= htons(si
->port
);
2116 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
2118 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
2123 SetEvent(si
->event
);
2126 if (c
== -1) c
= accept(s
, NULL
, NULL
);
2128 memset(buffer
, 0, sizeof buffer
);
2129 for(i
= 0; i
< sizeof buffer
- 1; i
++)
2131 r
= recv(c
, &buffer
[i
], 1, 0);
2134 if (i
< 4) continue;
2135 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
2136 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
2139 if (strstr(buffer
, "GET /basic"))
2141 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2142 send(c
, page1
, sizeof page1
- 1, 0);
2144 if (strstr(buffer
, "/auth_with_creds"))
2146 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2147 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2148 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2150 send(c
, auth_unseen
, sizeof auth_unseen
- 1, 0);
2153 if (strstr(buffer
, "/auth"))
2155 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2157 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2158 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2162 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
2163 send(c
, unauthorized
, sizeof unauthorized
- 1, 0);
2167 if (strstr(buffer
, "/big"))
2169 char msg
[BIG_BUFFER_LEN
];
2170 memset(msg
, 'm', sizeof(msg
));
2171 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2172 send(c
, msg
, sizeof(msg
), 0);
2174 if (strstr(buffer
, "/no_headers"))
2176 send(c
, page1
, sizeof page1
- 1, 0);
2178 if (strstr(buffer
, "GET /no_content"))
2180 send(c
, nocontentmsg
, sizeof nocontentmsg
- 1, 0);
2183 if (strstr(buffer
, "GET /not_modified"))
2185 if (strstr(buffer
, "If-Modified-Since:")) send(c
, notmodified
, sizeof notmodified
- 1, 0);
2186 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2189 if (strstr(buffer
, "HEAD /head"))
2191 send(c
, headmsg
, sizeof headmsg
- 1, 0);
2194 if (strstr(buffer
, "GET /multiauth"))
2196 send(c
, multiauth
, sizeof multiauth
- 1, 0);
2198 if (strstr(buffer
, "GET /largeauth"))
2200 if (strstr(buffer
, "Authorization: NTLM"))
2201 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2204 send(c
, largeauth
, sizeof largeauth
- 1, 0);
2206 memset(buffer
, 'A', sizeof(buffer
));
2207 for (i
= 0; i
< (10240 / sizeof(buffer
)); i
++) send(c
, buffer
, sizeof(buffer
), 0);
2209 for (i
= 0; i
< 10240; i
++) send(c
, "A", 1, 0);
2214 if (strstr(buffer
, "GET /cookie5"))
2216 if (strstr(buffer
, "Cookie: name2=value\r\n"))
2217 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2219 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2221 if (strstr(buffer
, "GET /cookie4"))
2223 send(c
, cookiemsg2
, sizeof(cookiemsg2
) - 1, 0);
2225 if (strstr(buffer
, "GET /cookie3"))
2227 if (strstr(buffer
, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2228 broken(strstr(buffer
, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL
))
2229 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2231 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2233 if (strstr(buffer
, "GET /cookie2"))
2235 if (strstr(buffer
, "Cookie: NAME=value; name=value\r\n") ||
2236 broken(strstr(buffer
, "Cookie: name=value; NAME=value\r\n") != NULL
))
2237 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2239 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2241 else if (strstr(buffer
, "GET /cookie"))
2243 if (!strstr(buffer
, "Cookie: name=value\r\n")) send(c
, cookiemsg
, sizeof(cookiemsg
) - 1, 0);
2244 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2246 if (strstr(buffer
, "GET /quit"))
2248 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2249 send(c
, page1
, sizeof page1
- 1, 0);
2256 } while (!last_request
);
2262 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
2264 static const WCHAR test_header_end_clrf
[] = {'\r','\n','\r','\n',0};
2265 static const WCHAR test_header_end_raw
[] = {0,0};
2266 HINTERNET ses
, con
, req
;
2268 WCHAR buffer2
[0x100];
2269 DWORD count
, status
, size
, error
, supported
, first
, target
;
2272 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2273 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2275 SetLastError(0xdeadbeef);
2276 ret
= WinHttpSetOption(ses
, 0, buffer
, sizeof(buffer
));
2277 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_OPTION
, "got %u\n", GetLastError());
2279 SetLastError(0xdeadbeef);
2280 ret
= WinHttpQueryOption(ses
, 0, buffer
, &size
);
2281 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %u\n", GetLastError());
2283 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2284 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2286 SetLastError(0xdeadbeef);
2287 ret
= WinHttpSetOption(con
, 0, buffer
, sizeof(buffer
));
2288 todo_wine
ok(!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_OPTION
, "got %u\n", GetLastError());
2290 SetLastError(0xdeadbeef);
2291 ret
= WinHttpQueryOption(con
, 0, buffer
, &size
);
2292 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %u\n", GetLastError());
2294 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
2295 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2297 SetLastError(0xdeadbeef);
2298 ret
= WinHttpSetOption(req
, 0, buffer
, sizeof(buffer
));
2299 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_OPTION
, "got %u\n", GetLastError());
2301 SetLastError(0xdeadbeef);
2302 ret
= WinHttpQueryOption(req
, 0, buffer
, &size
);
2303 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %u\n", GetLastError());
2305 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2306 ok(ret
, "failed to send request %u\n", GetLastError());
2308 ret
= WinHttpReceiveResponse(req
, NULL
);
2309 ok(ret
, "failed to receive response %u\n", GetLastError());
2311 status
= 0xdeadbeef;
2312 size
= sizeof(status
);
2313 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2314 ok(ret
, "failed to query status code %u\n", GetLastError());
2315 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2317 supported
= first
= target
= 0xdeadbeef;
2318 SetLastError(0xdeadbeef);
2319 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2320 error
= GetLastError();
2321 ok(!ret
, "unexpected success\n");
2322 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2323 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2324 ok(first
== 0xdeadbeef, "got %x\n", first
);
2325 ok(target
== 0xdeadbeef, "got %x\n", target
);
2327 size
= sizeof(buffer2
);
2328 memset(buffer2
, 0, sizeof(buffer2
));
2329 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, buffer2
, &size
, NULL
);
2330 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2331 ok(!memcmp(buffer2
+ lstrlenW(buffer2
) - 4, test_header_end_clrf
, sizeof(test_header_end_clrf
)),
2332 "WinHttpQueryHeaders returned invalid end of header string\n");
2334 size
= sizeof(buffer2
);
2335 memset(buffer2
, 0, sizeof(buffer2
));
2336 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS
, NULL
, buffer2
, &size
, NULL
);
2337 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2338 ok(!memcmp(buffer2
+ (size
/ sizeof(WCHAR
)) - 1, test_header_end_raw
, sizeof(test_header_end_raw
)),
2339 "WinHttpQueryHeaders returned invalid end of header string\n");
2340 ok(buffer2
[(size
/ sizeof(WCHAR
)) - 2] != 0, "returned string has too many NULL characters\n");
2343 memset(buffer
, 0, sizeof(buffer
));
2344 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
2345 ok(ret
, "failed to read data %u\n", GetLastError());
2346 ok(count
== sizeof page1
- 1, "count was wrong\n");
2347 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
2349 WinHttpCloseHandle(req
);
2350 WinHttpCloseHandle(con
);
2351 WinHttpCloseHandle(ses
);
2354 static void test_basic_authentication(int port
)
2356 static const WCHAR authW
[] = {'/','a','u','t','h',0};
2357 static const WCHAR auth_with_credsW
[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0};
2358 static WCHAR userW
[] = {'u','s','e','r',0};
2359 static WCHAR passW
[] = {'p','w','d',0};
2360 static WCHAR pass2W
[] = {'p','w','d','2',0};
2361 HINTERNET ses
, con
, req
;
2362 DWORD status
, size
, error
, supported
, first
, target
;
2366 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2367 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2369 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2370 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2372 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2373 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2375 SetLastError(0xdeadbeef);
2376 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
2377 error
= GetLastError();
2378 ok(!ret
, "expected failure\n");
2379 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2381 SetLastError(0xdeadbeef);
2382 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
2383 error
= GetLastError();
2384 ok(!ret
, "expected failure\n");
2385 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2387 supported
= 0xdeadbeef;
2388 SetLastError(0xdeadbeef);
2389 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
2390 error
= GetLastError();
2391 ok(!ret
, "expected failure\n");
2392 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2393 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2395 supported
= first
= 0xdeadbeef;
2396 SetLastError(0xdeadbeef);
2397 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
2398 error
= GetLastError();
2399 ok(!ret
, "expected failure\n");
2400 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2401 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2402 ok(first
== 0xdeadbeef, "got %x\n", first
);
2404 supported
= first
= target
= 0xdeadbeef;
2405 SetLastError(0xdeadbeef);
2406 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2407 error
= GetLastError();
2408 ok(!ret
, "expected failure\n");
2409 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2410 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2411 ok(first
== 0xdeadbeef, "got %x\n", first
);
2412 ok(target
== 0xdeadbeef, "got %x\n", target
);
2414 supported
= first
= target
= 0xdeadbeef;
2415 SetLastError(0xdeadbeef);
2416 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
2417 error
= GetLastError();
2418 ok(!ret
, "expected failure\n");
2419 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2420 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2421 ok(first
== 0xdeadbeef, "got %x\n", first
);
2422 ok(target
== 0xdeadbeef, "got %x\n", target
);
2424 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2425 ok(ret
, "failed to send request %u\n", GetLastError());
2427 ret
= WinHttpReceiveResponse(req
, NULL
);
2428 ok(ret
, "failed to receive response %u\n", GetLastError());
2430 status
= 0xdeadbeef;
2431 size
= sizeof(status
);
2432 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2433 ok(ret
, "failed to query status code %u\n", GetLastError());
2434 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2437 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2438 error
= GetLastError();
2439 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2442 ok(size
== 12, "expected 12, got %u\n", size
);
2443 ok(!memcmp(buffer
, unauthorized
, 12), "got %s\n", buffer
);
2446 supported
= first
= target
= 0xdeadbeef;
2447 SetLastError(0xdeadbeef);
2448 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2449 error
= GetLastError();
2450 ok(ret
, "failed to query authentication schemes %u\n", error
);
2451 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2452 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2453 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2454 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2456 SetLastError(0xdeadbeef);
2457 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2458 error
= GetLastError();
2459 ok(ret
, "failed to set credentials %u\n", error
);
2460 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2462 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2463 ok(ret
, "failed to set credentials %u\n", GetLastError());
2465 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2466 ok(ret
, "failed to set credentials %u\n", GetLastError());
2468 SetLastError(0xdeadbeef);
2469 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2470 error
= GetLastError();
2471 ok(!ret
, "expected failure\n");
2472 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2474 SetLastError(0xdeadbeef);
2475 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2476 error
= GetLastError();
2477 ok(!ret
, "expected failure\n");
2478 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2480 SetLastError(0xdeadbeef);
2481 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2482 error
= GetLastError();
2483 ok(!ret
, "expected failure\n");
2484 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2486 SetLastError(0xdeadbeef);
2487 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2488 error
= GetLastError();
2489 ok(!ret
, "expected failure\n");
2490 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2492 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2493 ok(ret
, "failed to set credentials %u\n", GetLastError());
2495 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2496 ok(ret
, "failed to send request %u\n", GetLastError());
2498 ret
= WinHttpReceiveResponse(req
, NULL
);
2499 ok(ret
, "failed to receive response %u\n", GetLastError());
2501 status
= 0xdeadbeef;
2502 size
= sizeof(status
);
2503 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2504 ok(ret
, "failed to query status code %u\n", GetLastError());
2505 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2508 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2509 error
= GetLastError();
2510 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2513 ok(size
== 11, "expected 11, got %u\n", size
);
2514 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2517 WinHttpCloseHandle(req
);
2518 WinHttpCloseHandle(con
);
2519 WinHttpCloseHandle(ses
);
2521 /* now set the credentials first to show that they get sent with the first request */
2522 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2523 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2525 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2526 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2528 req
= WinHttpOpenRequest(con
, NULL
, auth_with_credsW
, NULL
, NULL
, NULL
, 0);
2529 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2531 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2532 ok(ret
, "failed to set credentials %u\n", GetLastError());
2534 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2535 ok(ret
, "failed to send request %u\n", GetLastError());
2537 ret
= WinHttpReceiveResponse(req
, NULL
);
2538 ok(ret
, "failed to receive response %u\n", GetLastError());
2540 status
= 0xdeadbeef;
2541 size
= sizeof(status
);
2542 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2543 ok(ret
, "failed to query status code %u\n", GetLastError());
2544 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2547 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2548 error
= GetLastError();
2549 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2552 ok(size
== 11, "expected 11, got %u\n", size
);
2553 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2556 WinHttpCloseHandle(req
);
2557 WinHttpCloseHandle(con
);
2558 WinHttpCloseHandle(ses
);
2560 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2562 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2563 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2565 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2566 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2568 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2569 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2571 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2572 ok(ret
, "failed to set credentials %u\n", GetLastError());
2574 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2575 ok(ret
, "failed to set username %u\n", GetLastError());
2577 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, pass2W
, lstrlenW(pass2W
));
2578 ok(ret
, "failed to set password %u\n", GetLastError());
2580 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2581 ok(ret
, "failed to send request %u\n", GetLastError());
2583 ret
= WinHttpReceiveResponse(req
, NULL
);
2584 ok(ret
, "failed to receive response %u\n", GetLastError());
2586 status
= 0xdeadbeef;
2587 size
= sizeof(status
);
2588 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2589 ok(ret
, "failed to query status code %u\n", GetLastError());
2590 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2592 WinHttpCloseHandle(req
);
2593 WinHttpCloseHandle(con
);
2594 WinHttpCloseHandle(ses
);
2596 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2597 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2599 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2600 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2602 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2603 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2605 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2606 ok(ret
, "failed to set username %u\n", GetLastError());
2608 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2609 ok(ret
, "failed to set password %u\n", GetLastError());
2611 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, pass2W
, NULL
);
2612 ok(ret
, "failed to set credentials %u\n", GetLastError());
2614 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2615 ok(ret
, "failed to send request %u\n", GetLastError());
2617 ret
= WinHttpReceiveResponse(req
, NULL
);
2618 ok(ret
, "failed to receive response %u\n", GetLastError());
2620 status
= 0xdeadbeef;
2621 size
= sizeof(status
);
2622 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2623 ok(ret
, "failed to query status code %u\n", GetLastError());
2624 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2626 WinHttpCloseHandle(req
);
2627 WinHttpCloseHandle(con
);
2628 WinHttpCloseHandle(ses
);
2631 static void test_multi_authentication(int port
)
2633 static const WCHAR multiauthW
[] = {'/','m','u','l','t','i','a','u','t','h',0};
2634 static const WCHAR getW
[] = {'G','E','T',0};
2635 HINTERNET ses
, con
, req
;
2636 DWORD supported
, first
, target
;
2639 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2640 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2642 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2643 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2645 req
= WinHttpOpenRequest(con
, getW
, multiauthW
, NULL
, NULL
, NULL
, 0);
2646 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2648 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0,
2649 WINHTTP_NO_REQUEST_DATA
,0, 0, 0 );
2650 ok(ret
, "expected success\n");
2652 ret
= WinHttpReceiveResponse(req
, NULL
);
2653 ok(ret
, "expected success\n");
2655 supported
= first
= target
= 0xdeadbeef;
2656 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2657 ok(ret
, "expected success\n");
2658 ok(supported
== (WINHTTP_AUTH_SCHEME_BASIC
| WINHTTP_AUTH_SCHEME_NTLM
), "got %x\n", supported
);
2659 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2660 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2662 WinHttpCloseHandle(req
);
2663 WinHttpCloseHandle(con
);
2664 WinHttpCloseHandle(ses
);
2667 static void test_large_data_authentication(int port
)
2669 static const WCHAR largeauthW
[] = {'/','l','a','r','g','e','a','u','t','h',0};
2670 static const WCHAR getW
[] = {'G','E','T',0};
2671 static WCHAR userW
[] = {'u','s','e','r',0};
2672 static WCHAR passW
[] = {'p','w','d',0};
2673 HINTERNET ses
, con
, req
;
2677 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2678 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2680 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2681 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2683 req
= WinHttpOpenRequest(con
, getW
, largeauthW
, NULL
, NULL
, NULL
, 0);
2684 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2686 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, WINHTTP_NO_REQUEST_DATA
, 0, 0, 0);
2687 ok(ret
, "expected success\n");
2689 ret
= WinHttpReceiveResponse(req
, NULL
);
2690 ok(ret
, "expected success\n");
2692 size
= sizeof(status
);
2693 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
,
2694 &status
, &size
, NULL
);
2695 ok(ret
, "expected success\n");
2696 ok(status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
2698 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, userW
, passW
, NULL
);
2699 ok(ret
, "expected success\n");
2701 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, WINHTTP_NO_REQUEST_DATA
, 0, 0, 0);
2702 ok(ret
, "expected success %d\n", GetLastError());
2704 ret
= WinHttpReceiveResponse(req
, NULL
);
2705 ok(ret
, "expected success\n");
2707 size
= sizeof(status
);
2708 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
,
2709 &status
, &size
, NULL
);
2710 ok(ret
, "expected success\n");
2711 ok(status
== HTTP_STATUS_OK
, "got %d\n", status
);
2713 WinHttpCloseHandle(req
);
2714 WinHttpCloseHandle(con
);
2715 WinHttpCloseHandle(ses
);
2718 static void test_no_headers(int port
)
2720 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2721 HINTERNET ses
, con
, req
;
2725 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2726 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2728 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2729 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2731 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2732 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2734 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2737 error
= GetLastError();
2738 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2742 SetLastError(0xdeadbeef);
2743 ret
= WinHttpReceiveResponse(req
, NULL
);
2744 error
= GetLastError();
2745 ok(!ret
, "expected failure\n");
2746 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2749 WinHttpCloseHandle(req
);
2750 WinHttpCloseHandle(con
);
2751 WinHttpCloseHandle(ses
);
2754 static void test_no_content(int port
)
2756 static const WCHAR no_contentW
[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2757 HINTERNET ses
, con
, req
;
2759 DWORD size
, len
= sizeof(buf
), bytes_read
, status
;
2762 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2763 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2765 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2766 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2768 req
= WinHttpOpenRequest(con
, NULL
, no_contentW
, NULL
, NULL
, NULL
, 0);
2769 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2772 SetLastError(0xdeadbeef);
2773 ret
= WinHttpQueryDataAvailable(req
, &size
);
2775 ok(!ret
, "expected error\n");
2776 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
,
2777 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2778 ok(size
== 12345 || broken(size
== 0) /* Win <= 2003 */,
2779 "expected 12345, got %u\n", size
);
2782 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2783 ok(ret
, "expected success\n");
2785 ret
= WinHttpReceiveResponse(req
, NULL
);
2786 ok(ret
, "expected success\n");
2788 status
= 0xdeadbeef;
2789 size
= sizeof(status
);
2790 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2791 NULL
, &status
, &size
, NULL
);
2792 ok(ret
, "expected success\n");
2793 ok(status
== HTTP_STATUS_NO_CONTENT
, "expected status 204, got %d\n", status
);
2795 SetLastError(0xdeadbeef);
2796 size
= sizeof(status
);
2798 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2799 NULL
, &status
, &size
, 0);
2800 ok(!ret
, "expected no content-length header\n");
2801 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError());
2802 ok(status
== 12345, "expected 0, got %d\n", status
);
2804 SetLastError(0xdeadbeef);
2806 ret
= WinHttpQueryDataAvailable(req
, &size
);
2807 ok(ret
, "expected success\n");
2808 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2809 "wrong error %u\n", GetLastError());
2810 ok(!size
, "expected 0, got %u\n", size
);
2812 SetLastError(0xdeadbeef);
2813 ret
= WinHttpReadData(req
, buf
, len
, &bytes_read
);
2814 ok(ret
, "expected success\n");
2815 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2816 "wrong error %u\n", GetLastError());
2817 ok(!bytes_read
, "expected 0, got %u\n", bytes_read
);
2820 ret
= WinHttpQueryDataAvailable(req
, &size
);
2821 ok(ret
, "expected success\n");
2822 ok(size
== 0, "expected 0, got %d\n", size
);
2824 WinHttpCloseHandle(req
);
2827 SetLastError(0xdeadbeef);
2828 ret
= WinHttpQueryDataAvailable(req
, &size
);
2829 ok(!ret
, "expected error\n");
2830 ok(GetLastError() == ERROR_INVALID_HANDLE
,
2831 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2832 ok(size
== 12345, "expected 12345, got %u\n", size
);
2834 WinHttpCloseHandle(con
);
2835 WinHttpCloseHandle(ses
);
2838 static void test_head_request(int port
)
2840 static const WCHAR verbW
[] = {'H','E','A','D',0};
2841 static const WCHAR headW
[] = {'/','h','e','a','d',0};
2842 HINTERNET ses
, con
, req
;
2844 DWORD size
, len
, count
, status
;
2847 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2848 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2850 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2851 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2853 req
= WinHttpOpenRequest(con
, verbW
, headW
, NULL
, NULL
, NULL
, 0);
2854 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2856 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2857 ok(ret
, "failed to send request %u\n", GetLastError());
2859 ret
= WinHttpReceiveResponse(req
, NULL
);
2860 ok(ret
, "failed to receive response %u\n", GetLastError());
2862 status
= 0xdeadbeef;
2863 size
= sizeof(status
);
2864 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2865 NULL
, &status
, &size
, NULL
);
2866 ok(ret
, "failed to get status code %u\n", GetLastError());
2867 ok(status
== HTTP_STATUS_OK
, "got %u\n", status
);
2871 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2872 NULL
, &len
, &size
, 0);
2873 ok(ret
, "failed to get content-length header %u\n", GetLastError());
2874 ok(len
== HTTP_STATUS_CONTINUE
, "got %u\n", len
);
2877 ret
= WinHttpQueryDataAvailable(req
, &count
);
2878 ok(ret
, "failed to query data available %u\n", GetLastError());
2879 ok(!count
, "got %u\n", count
);
2883 ret
= WinHttpReadData(req
, buf
, len
, &count
);
2884 ok(ret
, "failed to read data %u\n", GetLastError());
2885 ok(!count
, "got %u\n", count
);
2888 ret
= WinHttpQueryDataAvailable(req
, &count
);
2889 ok(ret
, "failed to query data available %u\n", GetLastError());
2890 ok(!count
, "got %u\n", count
);
2892 WinHttpCloseHandle(req
);
2893 WinHttpCloseHandle(con
);
2894 WinHttpCloseHandle(ses
);
2897 static void test_not_modified(int port
)
2899 static const WCHAR pathW
[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2900 static const WCHAR ifmodifiedW
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2901 static const WCHAR ifmodified2W
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2903 HINTERNET session
, request
, connection
;
2904 DWORD index
, len
, status
, size
, start
= GetTickCount();
2906 WCHAR today
[(sizeof(ifmodifiedW
) + WINHTTP_TIME_FORMAT_BUFSIZE
)/sizeof(WCHAR
) + 3], buffer
[32];
2908 memcpy(today
, ifmodifiedW
, sizeof(ifmodifiedW
));
2910 WinHttpTimeFromSystemTime(&st
, &today
[sizeof(ifmodifiedW
)/sizeof(WCHAR
)]);
2912 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
,
2913 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
2914 ok(session
!= NULL
, "WinHttpOpen failed: %u\n", GetLastError());
2916 connection
= WinHttpConnect(session
, localhostW
, port
, 0);
2917 ok(connection
!= NULL
, "WinHttpConnect failed: %u\n", GetLastError());
2919 request
= WinHttpOpenRequest(connection
, NULL
, pathW
, NULL
, WINHTTP_NO_REFERER
,
2920 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
2921 ok(request
!= NULL
, "WinHttpOpenrequest failed: %u\n", GetLastError());
2923 ret
= WinHttpSendRequest(request
, today
, 0, NULL
, 0, 0, 0);
2924 ok(ret
, "WinHttpSendRequest failed: %u\n", GetLastError());
2926 ret
= WinHttpReceiveResponse(request
, NULL
);
2927 ok(ret
, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2930 len
= sizeof(buffer
);
2931 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2932 ifmodified2W
, buffer
, &len
, &index
);
2933 ok(ret
, "failed to get header %u\n", GetLastError());
2935 status
= 0xdeadbeef;
2936 size
= sizeof(status
);
2937 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
,
2938 NULL
, &status
, &size
, NULL
);
2939 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2940 ok(status
== HTTP_STATUS_NOT_MODIFIED
, "got %u\n", status
);
2943 ret
= WinHttpQueryDataAvailable(request
, &size
);
2944 ok(ret
, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2945 ok(!size
, "got %u\n", size
);
2947 WinHttpCloseHandle(request
);
2948 WinHttpCloseHandle(connection
);
2949 WinHttpCloseHandle(session
);
2950 start
= GetTickCount() - start
;
2951 ok(start
<= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start
);
2954 static void test_bad_header( int port
)
2956 static const WCHAR bad_headerW
[] =
2957 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2958 't','e','x','t','/','h','t','m','l','\n','\r',0};
2959 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2960 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2962 HINTERNET ses
, con
, req
;
2966 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2967 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2969 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2970 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2972 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2973 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2975 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2976 ok( ret
, "failed to add header %u\n", GetLastError() );
2980 len
= sizeof(buffer
);
2981 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2982 content_typeW
, buffer
, &len
, &index
);
2983 ok( ret
, "failed to query headers %u\n", GetLastError() );
2984 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2986 WinHttpCloseHandle( req
);
2987 WinHttpCloseHandle( con
);
2988 WinHttpCloseHandle( ses
);
2991 static void test_multiple_reads(int port
)
2993 static const WCHAR bigW
[] = {'b','i','g',0};
2994 HINTERNET ses
, con
, req
;
2995 DWORD total_len
= 0;
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
, bigW
, NULL
, NULL
, NULL
, 0);
3005 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3007 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
3008 ok(ret
, "failed to send request %u\n", GetLastError());
3010 ret
= WinHttpReceiveResponse(req
, NULL
);
3011 ok(ret
== TRUE
, "expected success\n");
3015 DWORD len
= 0xdeadbeef;
3016 ret
= WinHttpQueryDataAvailable( req
, &len
);
3017 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3018 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3022 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
3024 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
3025 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
3027 HeapFree( GetProcessHeap(), 0, buf
);
3028 if (!bytes_read
) break;
3029 total_len
+= bytes_read
;
3033 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
3035 WinHttpCloseHandle(req
);
3036 WinHttpCloseHandle(con
);
3037 WinHttpCloseHandle(ses
);
3040 static void test_cookies( int port
)
3042 static const WCHAR cookieW
[] = {'/','c','o','o','k','i','e',0};
3043 static const WCHAR cookie2W
[] = {'/','c','o','o','k','i','e','2',0};
3044 static const WCHAR cookie3W
[] = {'/','c','o','o','k','i','e','3',0};
3045 static const WCHAR cookie4W
[] = {'/','c','o','o','k','i','e','4',0};
3046 static const WCHAR cookie5W
[] = {'/','c','o','o','k','i','e','5',0};
3047 static const WCHAR cookieheaderW
[] =
3048 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
3049 HINTERNET ses
, con
, req
;
3053 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3054 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3056 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3057 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3059 req
= WinHttpOpenRequest( con
, NULL
, cookieW
, NULL
, NULL
, NULL
, 0 );
3060 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3062 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3063 ok( ret
, "failed to send request %u\n", GetLastError() );
3065 ret
= WinHttpReceiveResponse( req
, NULL
);
3066 ok( ret
, "failed to receive response %u\n", GetLastError() );
3068 status
= 0xdeadbeef;
3069 size
= sizeof(status
);
3070 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3071 ok( ret
, "failed to query status code %u\n", GetLastError() );
3072 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3074 WinHttpCloseHandle( req
);
3076 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3077 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3079 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3080 ok( ret
, "failed to send request %u\n", GetLastError() );
3082 ret
= WinHttpReceiveResponse( req
, NULL
);
3083 ok( ret
, "failed to receive response %u\n", GetLastError() );
3085 status
= 0xdeadbeef;
3086 size
= sizeof(status
);
3087 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3088 ok( ret
, "failed to query status code %u\n", GetLastError() );
3089 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3091 WinHttpCloseHandle( req
);
3092 WinHttpCloseHandle( con
);
3094 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3095 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3097 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3098 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3100 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3101 ok( ret
, "failed to send request %u\n", GetLastError() );
3103 ret
= WinHttpReceiveResponse( req
, NULL
);
3104 ok( ret
, "failed to receive response %u\n", GetLastError() );
3106 status
= 0xdeadbeef;
3107 size
= sizeof(status
);
3108 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3109 ok( ret
, "failed to query status code %u\n", GetLastError() );
3110 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3112 WinHttpCloseHandle( req
);
3114 req
= WinHttpOpenRequest( con
, NULL
, cookie3W
, NULL
, NULL
, NULL
, 0 );
3115 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3117 ret
= WinHttpSendRequest( req
, cookieheaderW
, ~0u, NULL
, 0, 0, 0 );
3118 ok( ret
, "failed to send request %u\n", GetLastError() );
3120 ret
= WinHttpReceiveResponse( req
, NULL
);
3121 ok( ret
, "failed to receive response %u\n", GetLastError() );
3123 status
= 0xdeadbeef;
3124 size
= sizeof(status
);
3125 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3126 ok( ret
, "failed to query status code %u\n", GetLastError() );
3127 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
), "request failed unexpectedly %u\n", status
);
3129 WinHttpCloseHandle( req
);
3130 WinHttpCloseHandle( con
);
3131 WinHttpCloseHandle( ses
);
3133 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3134 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3136 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3137 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3139 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3140 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3142 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3143 ok( ret
, "failed to send request %u\n", GetLastError() );
3145 ret
= WinHttpReceiveResponse( req
, NULL
);
3146 ok( ret
, "failed to receive response %u\n", GetLastError() );
3148 status
= 0xdeadbeef;
3149 size
= sizeof(status
);
3150 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3151 ok( ret
, "failed to query status code %u\n", GetLastError() );
3152 ok( status
== HTTP_STATUS_BAD_REQUEST
, "request failed unexpectedly %u\n", status
);
3154 WinHttpCloseHandle( req
);
3155 WinHttpCloseHandle( con
);
3156 WinHttpCloseHandle( ses
);
3158 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3159 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3161 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3162 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3164 req
= WinHttpOpenRequest( con
, NULL
, cookie4W
, NULL
, NULL
, NULL
, 0 );
3165 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3167 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3168 ok( ret
, "failed to send request %u\n", GetLastError() );
3170 ret
= WinHttpReceiveResponse( req
, NULL
);
3171 ok( ret
, "failed to receive response %u\n", GetLastError() );
3173 status
= 0xdeadbeef;
3174 size
= sizeof(status
);
3175 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3176 ok( ret
, "failed to query status code %u\n", GetLastError() );
3177 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3178 WinHttpCloseHandle( req
);
3180 req
= WinHttpOpenRequest( con
, NULL
, cookie5W
, NULL
, NULL
, NULL
, 0 );
3181 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3183 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3184 ok( ret
, "failed to send request %u\n", GetLastError() );
3186 ret
= WinHttpReceiveResponse( req
, NULL
);
3187 ok( ret
, "failed to receive response %u\n", GetLastError() );
3189 status
= 0xdeadbeef;
3190 size
= sizeof(status
);
3191 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3192 ok( ret
, "failed to query status code %u\n", GetLastError() );
3193 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
) /* < win7 */,
3194 "request failed unexpectedly %u\n", status
);
3196 WinHttpCloseHandle( req
);
3197 WinHttpCloseHandle( con
);
3198 WinHttpCloseHandle( ses
);
3201 static void test_connection_info( int port
)
3203 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
3204 HINTERNET ses
, con
, req
;
3205 WINHTTP_CONNECTION_INFO info
;
3209 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3210 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3212 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3213 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3215 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
3216 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3218 size
= sizeof(info
);
3219 SetLastError( 0xdeadbeef );
3220 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3221 error
= GetLastError();
3222 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
3224 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
3227 ok( !ret
, "unexpected success\n" );
3228 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
3230 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3231 ok( ret
, "failed to send request %u\n", GetLastError() );
3234 SetLastError( 0xdeadbeef );
3235 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3236 error
= GetLastError();
3237 ok( !ret
, "unexpected success\n" );
3238 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
3240 size
= sizeof(info
);
3241 memset( &info
, 0, sizeof(info
) );
3242 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3243 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3244 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3246 ret
= WinHttpReceiveResponse( req
, NULL
);
3247 ok( ret
, "failed to receive response %u\n", GetLastError() );
3249 size
= sizeof(info
);
3250 memset( &info
, 0, sizeof(info
) );
3251 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3252 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3253 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3255 WinHttpCloseHandle( req
);
3256 WinHttpCloseHandle( con
);
3257 WinHttpCloseHandle( ses
);
3260 static void test_credentials(void)
3262 static WCHAR userW
[] = {'u','s','e','r',0};
3263 static WCHAR passW
[] = {'p','a','s','s',0};
3264 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
3265 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
3266 HINTERNET ses
, con
, req
;
3271 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
3272 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
3274 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
3275 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3277 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3278 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3280 size
= sizeof(buffer
)/sizeof(WCHAR
);
3281 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3282 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3283 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3284 ok(!size
, "expected 0, got %u\n", size
);
3286 size
= sizeof(buffer
)/sizeof(WCHAR
);
3287 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3288 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3289 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3290 ok(!size
, "expected 0, got %u\n", size
);
3292 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
3293 ok(ret
, "failed to set username %u\n", GetLastError());
3295 size
= sizeof(buffer
)/sizeof(WCHAR
);
3296 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3297 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3298 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3299 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3301 size
= sizeof(buffer
)/sizeof(WCHAR
);
3302 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3303 ok(ret
, "failed to query username %u\n", GetLastError());
3304 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3305 ok(!size
, "expected 0, got %u\n", size
);
3307 size
= sizeof(buffer
)/sizeof(WCHAR
);
3308 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3309 ok(ret
, "failed to query password %u\n", GetLastError());
3310 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3311 ok(!size
, "expected 0, got %u\n", size
);
3313 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
3314 ok(ret
, "failed to set proxy password %u\n", GetLastError());
3316 size
= sizeof(buffer
)/sizeof(WCHAR
);
3317 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3318 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3319 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3320 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3322 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
3323 ok(ret
, "failed to set username %u\n", GetLastError());
3325 size
= sizeof(buffer
)/sizeof(WCHAR
);
3326 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3327 ok(ret
, "failed to query username %u\n", GetLastError());
3328 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3329 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3331 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
3332 ok(ret
, "failed to set password %u\n", GetLastError());
3334 size
= sizeof(buffer
)/sizeof(WCHAR
);
3335 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3336 ok(ret
, "failed to query password %u\n", GetLastError());
3337 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3338 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3340 WinHttpCloseHandle(req
);
3342 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3343 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3345 SetLastError(0xdeadbeef);
3346 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
3347 error
= GetLastError();
3348 ok(!ret
, "expected failure\n");
3349 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3351 SetLastError(0xdeadbeef);
3352 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
3353 error
= GetLastError();
3354 ok(!ret
, "expected failure\n");
3355 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3357 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
3358 ok(ret
, "failed to set credentials %u\n", GetLastError());
3360 size
= sizeof(buffer
)/sizeof(WCHAR
);
3361 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3362 ok(ret
, "failed to query username %u\n", GetLastError());
3364 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3365 ok(!size
, "expected 0, got %u\n", size
);
3368 size
= sizeof(buffer
)/sizeof(WCHAR
);
3369 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3370 ok(ret
, "failed to query password %u\n", GetLastError());
3372 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3373 ok(!size
, "expected 0, got %u\n", size
);
3376 WinHttpCloseHandle(req
);
3377 WinHttpCloseHandle(con
);
3378 WinHttpCloseHandle(ses
);
3381 static void test_IWinHttpRequest(int port
)
3383 static const WCHAR data_start
[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3384 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
3385 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
3386 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3387 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3388 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3389 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3390 static const WCHAR method1W
[] = {'G','E','T',0};
3391 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
3392 static const WCHAR method3W
[] = {'P','O','S','T',0};
3393 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3394 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
3395 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
3396 static const WCHAR dateW
[] = {'D','a','t','e',0};
3397 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
3398 static const WCHAR utf8W
[] = {'u','t','f','-','8',0};
3399 static const WCHAR unauthW
[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3401 IWinHttpRequest
*req
;
3402 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
3403 BSTR date
, today
, connection
, value
= NULL
;
3404 VARIANT async
, empty
, timeout
, body
, body2
, proxy_server
, bypass_list
, data
, cp
;
3405 VARIANT_BOOL succeeded
;
3407 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
3409 IStream
*stream
, *stream2
;
3415 GetSystemTime( &st
);
3416 WinHttpTimeFromSystemTime( &st
, todayW
);
3418 CoInitialize( NULL
);
3419 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3420 ok( hr
== S_OK
, "got %08x\n", hr
);
3422 V_VT( &empty
) = VT_ERROR
;
3423 V_ERROR( &empty
) = 0xdeadbeef;
3425 V_VT( &async
) = VT_BOOL
;
3426 V_BOOL( &async
) = VARIANT_FALSE
;
3428 method
= SysAllocString( method3W
);
3429 url
= SysAllocString( url3W
);
3430 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3431 ok( hr
== S_OK
, "got %08x\n", hr
);
3432 SysFreeString( method
);
3433 SysFreeString( url
);
3435 V_VT( &data
) = VT_BSTR
;
3436 V_BSTR( &data
) = SysAllocString( test_dataW
);
3437 hr
= IWinHttpRequest_Send( req
, data
);
3438 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
3440 SysFreeString( V_BSTR( &data
) );
3442 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
3443 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3445 method
= SysAllocString( method1W
);
3446 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
3447 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3449 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
3450 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3452 url
= SysAllocString( url1W
);
3453 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
3454 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3456 hr
= IWinHttpRequest_Abort( req
);
3457 ok( hr
== S_OK
, "got %08x\n", hr
);
3459 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
3460 ok( hr
== S_OK
, "got %08x\n", hr
);
3462 hr
= IWinHttpRequest_Abort( req
);
3463 ok( hr
== S_OK
, "got %08x\n", hr
);
3465 IWinHttpRequest_Release( req
);
3467 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3468 ok( hr
== S_OK
, "got %08x\n", hr
);
3470 SysFreeString( url
);
3471 url
= SysAllocString( url2W
);
3472 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3473 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3475 SysFreeString( method
);
3476 method
= SysAllocString( method2W
);
3477 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3478 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3480 SysFreeString( method
);
3481 method
= SysAllocString( method1W
);
3482 SysFreeString( url
);
3483 url
= SysAllocString( url1W
);
3484 V_VT( &async
) = VT_ERROR
;
3485 V_ERROR( &async
) = DISP_E_PARAMNOTFOUND
;
3486 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3487 ok( hr
== S_OK
, "got %08x\n", hr
);
3489 V_VT( &cp
) = VT_ERROR
;
3490 V_ERROR( &cp
) = 0xdeadbeef;
3491 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3492 ok( hr
== S_OK
, "got %08x\n", hr
);
3493 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3494 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3496 V_VT( &cp
) = VT_UI4
;
3497 V_UI4( &cp
) = CP_ACP
;
3498 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3499 ok( hr
== S_OK
, "got %08x\n", hr
);
3501 V_VT( &cp
) = VT_ERROR
;
3502 V_ERROR( &cp
) = 0xdeadbeef;
3503 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3504 ok( hr
== S_OK
, "got %08x\n", hr
);
3505 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3506 ok( V_I4( &cp
) == CP_ACP
, "got %u\n", V_I4( &cp
) );
3508 value
= SysAllocString( utf8W
);
3509 V_VT( &cp
) = VT_BSTR
;
3510 V_BSTR( &cp
) = value
;
3511 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3512 ok( hr
== S_OK
, "got %08x\n", hr
);
3513 SysFreeString( value
);
3515 V_VT( &cp
) = VT_ERROR
;
3516 V_ERROR( &cp
) = 0xdeadbeef;
3517 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3518 ok( hr
== S_OK
, "got %08x\n", hr
);
3519 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3520 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3522 hr
= IWinHttpRequest_Abort( req
);
3523 ok( hr
== S_OK
, "got %08x\n", hr
);
3525 hr
= IWinHttpRequest_Send( req
, empty
);
3526 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3528 hr
= IWinHttpRequest_Abort( req
);
3529 ok( hr
== S_OK
, "got %08x\n", hr
);
3531 IWinHttpRequest_Release( req
);
3533 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3534 ok( hr
== S_OK
, "got %08x\n", hr
);
3536 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3537 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3539 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3540 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3542 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3543 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3545 hr
= IWinHttpRequest_get_Status( req
, &status
);
3546 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3548 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3549 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3551 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3552 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3554 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3555 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3557 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3558 ok( hr
== S_OK
, "got %08x\n", hr
);
3560 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3561 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3563 VariantInit( &proxy_server
);
3564 V_VT( &proxy_server
) = VT_ERROR
;
3565 VariantInit( &bypass_list
);
3566 V_VT( &bypass_list
) = VT_ERROR
;
3567 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3568 ok( hr
== S_OK
, "got %08x\n", hr
);
3570 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3571 ok( hr
== S_OK
, "got %08x\n", hr
);
3573 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3574 ok( hr
== S_OK
, "got %08x\n", hr
);
3576 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3577 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3579 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3580 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3582 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3583 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3585 connection
= SysAllocString( connectionW
);
3586 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3587 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3589 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3590 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3592 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
3593 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3595 date
= SysAllocString( dateW
);
3596 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3597 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3599 today
= SysAllocString( todayW
);
3600 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3601 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3603 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
3604 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3606 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3607 ok( hr
== S_OK
, "got %08x\n", hr
);
3609 SysFreeString( method
);
3610 method
= SysAllocString( method1W
);
3611 SysFreeString( url
);
3612 url
= SysAllocString( url1W
);
3613 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3614 ok( hr
== S_OK
, "got %08x\n", hr
);
3616 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3617 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3619 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3620 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3622 hr
= IWinHttpRequest_get_Status( req
, &status
);
3623 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3625 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3626 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3628 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3629 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3631 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3632 ok( hr
== S_OK
, "got %08x\n", hr
);
3634 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3635 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3637 username
= SysAllocString( usernameW
);
3638 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
3639 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3641 password
= SysAllocString( passwordW
);
3642 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
3643 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3645 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
3646 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3648 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3649 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3651 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3652 ok( hr
== S_OK
, "got %08x\n", hr
);
3654 V_VT( &proxy_server
) = VT_BSTR
;
3655 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
3656 V_VT( &bypass_list
) = VT_BSTR
;
3657 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
3658 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3659 ok( hr
== S_OK
, "got %08x\n", hr
);
3661 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
3662 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3664 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3665 ok( hr
== S_OK
, "got %08x\n", hr
);
3667 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3668 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3670 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3671 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3673 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3674 ok( hr
== S_OK
, "got %08x\n", hr
);
3676 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3677 ok( hr
== S_OK
, "got %08x\n", hr
);
3679 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3680 ok( hr
== S_OK
, "got %08x\n", hr
);
3682 hr
= IWinHttpRequest_Send( req
, empty
);
3683 ok( hr
== S_OK
, "got %08x\n", hr
);
3685 hr
= IWinHttpRequest_Send( req
, empty
);
3686 ok( hr
== S_OK
, "got %08x\n", hr
);
3688 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3689 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3691 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3692 ok( hr
== S_OK
, "got %08x\n", hr
);
3693 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3694 SysFreeString( response
);
3696 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3697 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3700 hr
= IWinHttpRequest_get_Status( req
, &status
);
3701 ok( hr
== S_OK
, "got %08x\n", hr
);
3702 trace("Status=%d\n", status
);
3704 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3705 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3707 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3708 ok( hr
== S_OK
, "got %08x\n", hr
);
3709 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
3710 SysFreeString( status_text
);
3712 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3713 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3715 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3716 ok( hr
== S_OK
, "got %08x\n", hr
);
3718 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3719 ok( hr
== S_OK
, "got %08x\n", hr
);
3721 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3722 ok( hr
== S_OK
, "got %08x\n", hr
);
3724 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3725 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3727 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3728 ok( hr
== S_OK
, "got %08x\n", hr
);
3729 SysFreeString( headers
);
3731 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3732 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3734 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3735 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3737 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3738 ok( hr
== S_OK
, "got %08x\n", hr
);
3739 SysFreeString( value
);
3741 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3742 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3744 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3745 ok( hr
== S_OK
, "got %08x\n", hr
);
3747 VariantInit( &timeout
);
3748 V_VT( &timeout
) = VT_I4
;
3749 V_I4( &timeout
) = 10;
3750 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3751 ok( hr
== S_OK
, "got %08x\n", hr
);
3753 hr
= IWinHttpRequest_get_Status( req
, &status
);
3754 ok( hr
== S_OK
, "got %08x\n", hr
);
3756 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3757 ok( hr
== S_OK
, "got %08x\n", hr
);
3758 SysFreeString( status_text
);
3760 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3761 ok( hr
== S_OK
, "got %08x\n", hr
);
3763 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3764 ok( hr
== S_OK
, "got %08x\n", hr
);
3766 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3767 ok( hr
== S_OK
, "got %08x\n", hr
);
3769 hr
= IWinHttpRequest_Send( req
, empty
);
3770 ok( hr
== S_OK
, "got %08x\n", hr
);
3772 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3773 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3775 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3776 ok( hr
== S_OK
, "got %08x\n", hr
);
3777 SysFreeString( response
);
3779 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3780 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3782 VariantInit( &body
);
3783 V_VT( &body
) = VT_ERROR
;
3784 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
3785 ok( hr
== S_OK
, "got %08x\n", hr
);
3786 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
3788 hr
= VariantClear( &body
);
3789 ok( hr
== S_OK
, "got %08x\n", hr
);
3791 VariantInit( &body
);
3792 V_VT( &body
) = VT_ERROR
;
3793 hr
= IWinHttpRequest_get_ResponseStream( req
, &body
);
3794 ok( hr
== S_OK
, "got %08x\n", hr
);
3795 ok( V_VT( &body
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body
) );
3797 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body
), &IID_IStream
, (void **)&stream
);
3798 ok( hr
== S_OK
, "got %08x\n", hr
);
3799 ok( V_UNKNOWN( &body
) == (IUnknown
*)stream
, "got different interface pointer\n" );
3803 hr
= IStream_Read( stream
, buf
, 128, &count
);
3804 ok( hr
== S_OK
, "got %08x\n", hr
);
3805 ok( count
!= 0xdeadbeef, "count not set\n" );
3806 ok( buf
[0], "no data\n" );
3808 VariantInit( &body2
);
3809 V_VT( &body2
) = VT_ERROR
;
3810 hr
= IWinHttpRequest_get_ResponseStream( req
, &body2
);
3811 ok( hr
== S_OK
, "got %08x\n", hr
);
3812 ok( V_VT( &body2
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body2
) );
3813 ok( V_UNKNOWN( &body
) != V_UNKNOWN( &body2
), "got same interface pointer\n" );
3815 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body2
), &IID_IStream
, (void **)&stream2
);
3816 ok( hr
== S_OK
, "got %08x\n", hr
);
3817 ok( V_UNKNOWN( &body2
) == (IUnknown
*)stream2
, "got different interface pointer\n" );
3818 IStream_Release( stream2
);
3820 hr
= VariantClear( &body
);
3821 ok( hr
== S_OK
, "got %08x\n", hr
);
3823 hr
= VariantClear( &body2
);
3824 ok( hr
== S_OK
, "got %08x\n", hr
);
3826 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3827 ok( hr
== S_OK
, "got %08x\n", hr
);
3829 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3830 ok( hr
== S_OK
, "got %08x\n", hr
);
3832 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3833 ok( hr
== S_OK
, "got %08x\n", hr
);
3834 SysFreeString( headers
);
3836 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3837 ok( hr
== S_OK
, "got %08x\n", hr
);
3838 SysFreeString( value
);
3840 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3841 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3843 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3844 ok( hr
== S_OK
, "got %08x\n", hr
);
3846 hr
= IWinHttpRequest_Send( req
, empty
);
3847 ok( hr
== S_OK
, "got %08x\n", hr
);
3849 hr
= IWinHttpRequest_Abort( req
);
3850 ok( hr
== S_OK
, "got %08x\n", hr
);
3852 hr
= IWinHttpRequest_Abort( req
);
3853 ok( hr
== S_OK
, "got %08x\n", hr
);
3855 IWinHttpRequest_Release( req
);
3858 hr
= IStream_Seek( stream
, pos
, STREAM_SEEK_SET
, NULL
);
3859 ok( hr
== S_OK
, "got %08x\n", hr
);
3863 hr
= IStream_Read( stream
, buf
, 128, &count
);
3864 ok( hr
== S_OK
, "got %08x\n", hr
);
3865 ok( count
!= 0xdeadbeef, "count not set\n" );
3866 ok( buf
[0], "no data\n" );
3867 IStream_Release( stream
);
3869 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3870 ok( hr
== S_OK
, "got %08x\n", hr
);
3872 V_VT( &async
) = VT_I4
;
3874 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3875 ok( hr
== S_OK
, "got %08x\n", hr
);
3877 hr
= IWinHttpRequest_Send( req
, empty
);
3878 ok( hr
== S_OK
, "got %08x\n", hr
);
3880 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3881 ok( hr
== S_OK
, "got %08x\n", hr
);
3883 IWinHttpRequest_Release( req
);
3885 SysFreeString( method
);
3886 SysFreeString( url
);
3887 SysFreeString( username
);
3888 SysFreeString( password
);
3889 SysFreeString( connection
);
3890 SysFreeString( date
);
3891 SysFreeString( today
);
3892 VariantClear( &proxy_server
);
3893 VariantClear( &bypass_list
);
3895 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3896 ok( hr
== S_OK
, "got %08x\n", hr
);
3898 url
= SysAllocString( test_winehq_https
);
3899 method
= SysAllocString( method3W
);
3900 V_VT( &async
) = VT_BOOL
;
3901 V_BOOL( &async
) = VARIANT_FALSE
;
3902 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3903 ok( hr
== S_OK
, "got %08x\n", hr
);
3904 SysFreeString( method
);
3905 SysFreeString( url
);
3907 hr
= IWinHttpRequest_Send( req
, empty
);
3908 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)), "got %08x\n", hr
);
3911 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3912 ok( hr
== S_OK
, "got %08x\n", hr
);
3913 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3914 SysFreeString( response
);
3917 IWinHttpRequest_Release( req
);
3919 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3920 ok( hr
== S_OK
, "got %08x\n", hr
);
3922 sprintf( buf
, "http://localhost:%d/auth", port
);
3923 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, bufW
, sizeof(bufW
)/sizeof(bufW
[0]) );
3924 url
= SysAllocString( bufW
);
3925 method
= SysAllocString( method3W
);
3926 V_VT( &async
) = VT_BOOL
;
3927 V_BOOL( &async
) = VARIANT_FALSE
;
3928 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3929 ok( hr
== S_OK
, "got %08x\n", hr
);
3930 SysFreeString( method
);
3931 SysFreeString( url
);
3933 hr
= IWinHttpRequest_get_Status( req
, &status
);
3934 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3936 V_VT( &data
) = VT_BSTR
;
3937 V_BSTR( &data
) = SysAllocString( test_dataW
);
3938 hr
= IWinHttpRequest_Send( req
, data
);
3939 ok( hr
== S_OK
, "got %08x\n", hr
);
3940 SysFreeString( V_BSTR( &data
) );
3942 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3943 ok( hr
== S_OK
, "got %08x\n", hr
);
3944 ok( !memcmp( response
, unauthW
, sizeof(unauthW
) ), "got %s\n", wine_dbgstr_w(response
) );
3945 SysFreeString( response
);
3947 status
= 0xdeadbeef;
3948 hr
= IWinHttpRequest_get_Status( req
, &status
);
3949 ok( hr
== S_OK
, "got %08x\n", hr
);
3950 ok( status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
3952 IWinHttpRequest_Release( req
);
3957 static void request_get_property(IWinHttpRequest
*request
, int property
, VARIANT
*ret
)
3963 memset(¶ms
, 0, sizeof(params
));
3964 params
.cNamedArgs
= 0;
3965 params
.rgdispidNamedArgs
= NULL
;
3967 params
.rgvarg
= &arg
;
3970 V_I4(&arg
) = property
;
3972 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3973 DISPATCH_PROPERTYGET
, ¶ms
, ret
, NULL
, NULL
);
3974 ok(hr
== S_OK
, "error %#x\n", hr
);
3977 static void test_IWinHttpRequest_Invoke(void)
3979 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
3980 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};
3981 WCHAR openW
[] = {'O','p','e','n',0};
3982 WCHAR optionW
[] = {'O','p','t','i','o','n',0};
3983 OLECHAR
*open
= openW
, *option
= optionW
;
3986 IWinHttpRequest
*request
;
3987 IDispatch
*dispatch
;
3990 VARIANT arg
[3], ret
;
3997 hr
= CLSIDFromProgID(regid
, &clsid
);
3998 ok(hr
== S_OK
, "CLSIDFromProgID error %#x\n", hr
);
3999 bret
= IsEqualIID(&clsid
, &CLSID_WinHttpRequest
);
4000 ok(bret
|| broken(!bret
) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid
));
4002 hr
= CoCreateInstance(&CLSID_WinHttpRequest
, 0, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&request
);
4003 ok(hr
== S_OK
, "error %#x\n", hr
);
4005 hr
= IWinHttpRequest_QueryInterface(request
, &IID_IDispatch
, (void **)&dispatch
);
4006 ok(hr
== S_OK
, "error %#x\n", hr
);
4007 IDispatch_Release(dispatch
);
4009 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &open
, 1, 0x0409, &id
);
4010 ok(hr
== S_OK
, "error %#x\n", hr
);
4011 ok(id
== DISPID_HTTPREQUEST_OPEN
, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id
);
4013 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &option
, 1, 0x0409, &id
);
4014 ok(hr
== S_OK
, "error %#x\n", hr
);
4015 ok(id
== DISPID_HTTPREQUEST_OPTION
, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id
);
4017 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4018 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4019 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4021 memset(¶ms
, 0, sizeof(params
));
4023 params
.cNamedArgs
= 0;
4024 params
.rgvarg
= arg
;
4025 V_VT(&arg
[0]) = VT_I4
;
4026 V_I4(&arg
[0]) = 1252;
4027 V_VT(&arg
[1]) = VT_R8
;
4028 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4030 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4031 DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
4032 ok(hr
== S_OK
, "error %#x\n", hr
);
4034 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4035 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4036 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4038 memset(¶ms
, 0, sizeof(params
));
4040 params
.cNamedArgs
= 0;
4041 params
.rgvarg
= arg
;
4042 V_VT(&arg
[0]) = VT_I4
;
4043 V_I4(&arg
[0]) = 1252;
4044 V_VT(&arg
[1]) = VT_R8
;
4045 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4047 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4048 DISPATCH_METHOD
| DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
4049 ok(hr
== S_OK
, "error %#x\n", hr
);
4051 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4052 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4053 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4055 memset(¶ms
, 0, sizeof(params
));
4057 params
.cNamedArgs
= 0;
4058 params
.rgvarg
= arg
;
4059 V_VT(&arg
[0]) = VT_I4
;
4060 V_I4(&arg
[0]) = 1252;
4061 V_VT(&arg
[1]) = VT_R8
;
4062 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4064 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4065 DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
4066 ok(hr
== S_OK
, "error %#x\n", hr
);
4068 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4069 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4070 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4072 memset(¶ms
, 0, sizeof(params
));
4074 params
.cNamedArgs
= 0;
4075 params
.rgvarg
= arg
;
4076 V_VT(&arg
[0]) = VT_BSTR
;
4077 utf8
= SysAllocString(utf8W
);
4078 V_BSTR(&arg
[0]) = utf8
;
4079 V_VT(&arg
[1]) = VT_R8
;
4080 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4081 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
4082 ok(hr
== S_OK
, "error %#x\n", hr
);
4084 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4085 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4086 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4089 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, &err
);
4090 ok(hr
== S_OK
, "error %#x\n", hr
);
4092 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4093 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4094 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4097 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4098 ok(hr
== S_OK
, "error %#x\n", hr
);
4100 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4101 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4102 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4104 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
4105 ok(hr
== S_OK
, "error %#x\n", hr
);
4107 hr
= IWinHttpRequest_Invoke(request
, 255, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
4108 ok(hr
== DISP_E_MEMBERNOTFOUND
, "error %#x\n", hr
);
4111 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4112 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
4115 if (0) /* crashes */
4116 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, &ret
, NULL
, &err
);
4119 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4120 ok(hr
== DISP_E_TYPEMISMATCH
, "error %#x\n", hr
);
4122 VariantInit(&arg
[2]);
4124 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4126 ok(hr
== S_OK
, "error %#x\n", hr
);
4128 VariantInit(&arg
[0]);
4129 VariantInit(&arg
[1]);
4130 VariantInit(&arg
[2]);
4133 V_VT(&arg
[0]) = VT_I4
;
4134 V_I4(&arg
[0]) = WinHttpRequestOption_URLCodePage
;
4135 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4136 ok(hr
== S_OK
, "error %#x\n", hr
);
4138 V_VT(&ret
) = 0xdead;
4139 V_I4(&ret
) = 0xbeef;
4140 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, &ret
, NULL
, NULL
);
4141 ok(hr
== S_OK
, "error %#x\n", hr
);
4142 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4143 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4145 V_VT(&ret
) = 0xdead;
4146 V_I4(&ret
) = 0xbeef;
4147 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
4148 ok(hr
== S_OK
, "error %#x\n", hr
);
4149 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4150 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4152 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4153 ok(hr
== S_OK
, "error %#x\n", hr
);
4155 V_VT(&ret
) = 0xdead;
4156 V_I4(&ret
) = 0xbeef;
4157 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, &ret
, NULL
, NULL
);
4158 ok(hr
== S_OK
, "error %#x\n", hr
);
4159 ok(V_VT(&ret
) == VT_EMPTY
, "expected VT_EMPTY, got %d\n", V_VT(&ret
));
4160 ok(V_I4(&ret
) == 0xbeef || V_I4(&ret
) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret
));
4162 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, NULL
, NULL
, NULL
);
4163 ok(hr
== S_OK
, "error %#x\n", hr
);
4165 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4166 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
4169 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4171 ok(hr
== S_OK
, "error %#x\n", hr
);
4174 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4175 ok(hr
== DISP_E_PARAMNOTFOUND
, "error %#x\n", hr
);
4177 SysFreeString(utf8
);
4180 V_VT(&arg
[0]) = VT_I4
;
4181 V_I4(&arg
[0]) = AutoLogonPolicy_Never
;
4183 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY
, &IID_NULL
, 0,
4184 DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
4185 ok(hr
== S_OK
, "error %#x\n", hr
);
4187 IWinHttpRequest_Release(request
);
4192 static void test_WinHttpDetectAutoProxyConfigUrl(void)
4198 if (0) /* crashes on some win2k systems */
4200 SetLastError(0xdeadbeef);
4201 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
4202 error
= GetLastError();
4203 ok( !ret
, "expected failure\n" );
4204 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4207 SetLastError(0xdeadbeef);
4208 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
4209 error
= GetLastError();
4210 ok( !ret
, "expected failure\n" );
4211 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4213 if (0) /* crashes on some win2k systems */
4215 SetLastError(0xdeadbeef);
4216 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
4217 error
= GetLastError();
4218 ok( !ret
, "expected failure\n" );
4219 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4221 url
= (WCHAR
*)0xdeadbeef;
4222 SetLastError(0xdeadbeef);
4223 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
4224 error
= GetLastError();
4227 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4228 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4232 trace("%s\n", wine_dbgstr_w(url
));
4236 url
= (WCHAR
*)0xdeadbeef;
4237 SetLastError(0xdeadbeef);
4238 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
4239 error
= GetLastError();
4242 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4243 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4247 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4248 trace("%s\n", wine_dbgstr_w(url
));
4253 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
4257 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
4259 memset( &cfg
, 0, sizeof(cfg
) );
4261 SetLastError(0xdeadbeef);
4262 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
4263 error
= GetLastError();
4264 ok( !ret
, "expected failure\n" );
4265 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4267 SetLastError(0xdeadbeef);
4268 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
4269 error
= GetLastError();
4270 ok( ret
, "expected success\n" );
4271 ok( error
== ERROR_SUCCESS
|| broken(error
== ERROR_NO_TOKEN
) /* < win7 */, "got %u\n", error
);
4273 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
4274 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
4275 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
4276 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
4277 GlobalFree( cfg
.lpszAutoConfigUrl
);
4278 GlobalFree( cfg
.lpszProxy
);
4279 GlobalFree( cfg
.lpszProxyBypass
);
4282 static void test_WinHttpGetProxyForUrl(void)
4284 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4285 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4286 static const WCHAR emptyW
[] = {0};
4290 WINHTTP_AUTOPROXY_OPTIONS options
;
4291 WINHTTP_PROXY_INFO info
;
4293 memset( &options
, 0, sizeof(options
) );
4295 SetLastError(0xdeadbeef);
4296 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
4297 error
= GetLastError();
4298 ok( !ret
, "expected failure\n" );
4299 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
4301 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4302 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
4304 SetLastError(0xdeadbeef);
4305 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
4306 error
= GetLastError();
4307 ok( !ret
, "expected failure\n" );
4308 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4310 SetLastError(0xdeadbeef);
4311 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
4312 error
= GetLastError();
4313 ok( !ret
, "expected failure\n" );
4314 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4316 SetLastError(0xdeadbeef);
4317 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
4318 error
= GetLastError();
4319 ok( !ret
, "expected failure\n" );
4320 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4322 SetLastError(0xdeadbeef);
4323 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4324 error
= GetLastError();
4325 ok( !ret
, "expected failure\n" );
4326 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4328 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4329 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4331 SetLastError(0xdeadbeef);
4332 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
4333 error
= GetLastError();
4334 ok( !ret
, "expected failure\n" );
4335 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4337 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4338 options
.dwAutoDetectFlags
= 0;
4340 SetLastError(0xdeadbeef);
4341 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4342 error
= GetLastError();
4343 ok( !ret
, "expected failure\n" );
4344 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4346 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
4347 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4349 SetLastError(0xdeadbeef);
4350 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4351 error
= GetLastError();
4352 ok( !ret
, "expected failure\n" );
4353 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4355 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4356 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4358 memset( &info
, 0, sizeof(info
) );
4359 SetLastError(0xdeadbeef);
4360 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4361 error
= GetLastError();
4364 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4365 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4366 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4367 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4368 GlobalFree( info
.lpszProxy
);
4369 GlobalFree( info
.lpszProxyBypass
);
4372 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
4373 options
.dwAutoDetectFlags
= 0;
4374 options
.lpszAutoConfigUrl
= wpadW
;
4376 memset( &info
, 0, sizeof(info
) );
4377 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4380 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4381 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4382 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4383 GlobalFree( info
.lpszProxy
);
4384 GlobalFree( info
.lpszProxyBypass
);
4386 WinHttpCloseHandle( session
);
4389 static void test_chunked_read(void)
4391 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4392 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
4395 HINTERNET ses
, con
= NULL
, req
= NULL
;
4398 trace( "starting chunked read test\n" );
4400 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4401 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
4402 if (!ses
) goto done
;
4404 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
4405 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
4406 if (!con
) goto done
;
4408 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
4409 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4410 if (!req
) goto done
;
4412 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
4413 err
= GetLastError();
4414 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
4416 skip("connection failed, skipping\n");
4419 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4421 ret
= WinHttpReceiveResponse( req
, NULL
);
4422 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4425 len
= sizeof(header
);
4426 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
4427 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4428 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
4429 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
4432 len
= sizeof(header
);
4433 SetLastError( 0xdeadbeef );
4434 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
4435 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
4436 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
4438 trace( "entering query loop\n" );
4442 ret
= WinHttpQueryDataAvailable( req
, &len
);
4443 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4444 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4445 trace( "got %u available\n", len
);
4449 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
4451 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
4453 buf
[bytes_read
] = 0;
4454 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
4455 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
4456 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
4458 HeapFree( GetProcessHeap(), 0, buf
);
4459 if (!bytes_read
) break;
4466 if (req
) WinHttpCloseHandle( req
);
4467 if (con
) WinHttpCloseHandle( con
);
4468 if (ses
) WinHttpCloseHandle( ses
);
4471 START_TEST (winhttp
)
4473 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
4474 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
4475 struct server_info si
;
4481 test_WinHttpTimeFromSystemTime();
4482 test_WinHttpTimeToSystemTime();
4483 test_WinHttpAddHeaders();
4484 test_secure_connection();
4485 test_request_parameter_defaults();
4487 test_set_default_proxy_config();
4488 test_empty_headers_param();
4490 test_resolve_timeout();
4492 test_IWinHttpRequest_Invoke();
4493 test_WinHttpDetectAutoProxyConfigUrl();
4494 test_WinHttpGetIEProxyConfigForCurrentUser();
4495 test_WinHttpGetProxyForUrl();
4496 test_chunked_read();
4498 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
4501 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
4502 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
4504 ret
= WaitForSingleObject(si
.event
, 10000);
4505 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
4506 if (ret
!= WAIT_OBJECT_0
)
4508 CloseHandle(thread
);
4512 test_IWinHttpRequest(si
.port
);
4513 test_connection_info(si
.port
);
4514 test_basic_request(si
.port
, NULL
, basicW
);
4515 test_no_headers(si
.port
);
4516 test_no_content(si
.port
);
4517 test_head_request(si
.port
);
4518 test_not_modified(si
.port
);
4519 test_basic_authentication(si
.port
);
4520 test_multi_authentication(si
.port
);
4521 test_large_data_authentication(si
.port
);
4522 test_bad_header(si
.port
);
4523 test_multiple_reads(si
.port
);
4524 test_cookies(si
.port
);
4526 /* send the basic request again to shutdown the server thread */
4527 test_basic_request(si
.port
, NULL
, quitW
);
4529 WaitForSingleObject(thread
, 3000);
4530 CloseHandle(thread
);