4 * Copyright 2008 Google (Zac Brown)
5 * Copyright 2015 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include <httprequest.h>
33 #include <httprequestid.h>
35 #include "wine/test.h"
37 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
39 static const WCHAR test_useragent
[] =
40 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
41 static const WCHAR test_winehq
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
42 static const WCHAR test_winehq_https
[] = {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','4','4','3',0};
43 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
45 static BOOL
proxy_active(void)
47 WINHTTP_PROXY_INFO proxy_info
;
50 SetLastError(0xdeadbeef);
51 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
53 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
54 "got %u\n", GetLastError());
55 active
= (proxy_info
.lpszProxy
!= NULL
);
57 GlobalFree(proxy_info
.lpszProxy
);
58 if (proxy_info
.lpszProxyBypass
!= NULL
)
59 GlobalFree(proxy_info
.lpszProxyBypass
);
67 static void test_QueryOption(void)
70 HINTERNET session
, request
, connection
;
73 SetLastError(0xdeadbeef);
74 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
75 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
77 SetLastError(0xdeadbeef);
78 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
79 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
80 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
81 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
84 SetLastError(0xdeadbeef);
85 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
86 ok(!ret
, "should fail to query option\n");
87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
89 ok(size
== 4, "expected 4, got %u\n", size
);
92 size
= sizeof(feature
) - 1;
93 SetLastError(0xdeadbeef);
94 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
95 ok(!ret
, "should fail to query option\n");
96 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
97 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
98 ok(size
== 4, "expected 4, got %u\n", size
);
100 feature
= 0xdeadbeef;
101 size
= sizeof(feature
) + 1;
102 SetLastError(0xdeadbeef);
103 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
104 ok(ret
, "failed to query option %u\n", GetLastError());
105 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
106 "got %u\n", GetLastError());
107 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
108 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
109 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
111 SetLastError(0xdeadbeef);
112 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
113 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
114 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
115 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
117 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
118 SetLastError(0xdeadbeef);
119 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
120 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
121 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
122 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
124 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
125 SetLastError(0xdeadbeef);
126 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
127 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
128 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
129 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
131 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
132 SetLastError(0xdeadbeef);
133 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
134 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
136 feature
= 0xdeadbeef;
137 size
= sizeof(feature
);
138 SetLastError(0xdeadbeef);
139 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
140 ok(ret
, "failed to query option %u\n", GetLastError());
141 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
142 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
144 feature
= WINHTTP_DISABLE_COOKIES
;
145 SetLastError(0xdeadbeef);
146 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
147 ok(!ret
, "should fail to set disable feature for a session\n");
148 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
149 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151 SetLastError(0xdeadbeef);
152 connection
= WinHttpConnect(session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
153 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
155 feature
= WINHTTP_DISABLE_COOKIES
;
156 SetLastError(0xdeadbeef);
157 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
158 ok(!ret
, "should fail to set disable feature for a connection\n");
159 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
160 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
162 SetLastError(0xdeadbeef);
163 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
164 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
165 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
167 skip("Network unreachable, skipping the test\n");
171 feature
= 0xdeadbeef;
172 size
= sizeof(feature
);
173 SetLastError(0xdeadbeef);
174 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
175 ok(!ret
, "should fail to query disable feature for a request\n");
176 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
177 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
180 size
= sizeof(feature
);
181 SetLastError(0xdeadbeef);
182 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
183 ok(ret
, "failed to set feature %u\n", GetLastError());
185 feature
= 0xffffffff;
186 size
= sizeof(feature
);
187 SetLastError(0xdeadbeef);
188 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
189 ok(ret
, "failed to set feature %u\n", GetLastError());
191 feature
= WINHTTP_DISABLE_COOKIES
;
192 size
= sizeof(feature
);
193 SetLastError(0xdeadbeef);
194 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
195 ok(ret
, "failed to set feature %u\n", GetLastError());
198 SetLastError(0xdeadbeef);
199 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
200 ok(!ret
, "should fail to query disable feature for a request\n");
201 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
202 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
204 SetLastError(0xdeadbeef);
205 ret
= WinHttpCloseHandle(request
);
206 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
209 SetLastError(0xdeadbeef);
210 ret
= WinHttpCloseHandle(connection
);
211 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
212 SetLastError(0xdeadbeef);
213 ret
= WinHttpCloseHandle(session
);
214 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
217 static void test_OpenRequest (void)
220 HINTERNET session
, request
, connection
;
223 SetLastError(0xdeadbeef);
224 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
225 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
226 err
= GetLastError();
227 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
228 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
230 /* Test with a bad server name */
231 SetLastError(0xdeadbeef);
232 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
233 err
= GetLastError();
234 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
235 ok(err
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err
);
237 /* Test with a valid server name */
238 SetLastError(0xdeadbeef);
239 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
240 err
= GetLastError();
241 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", err
);
242 ok(err
== ERROR_SUCCESS
|| broken(err
== WSAEINVAL
) /* < win7 */, "got %u\n", err
);
244 SetLastError(0xdeadbeef);
245 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
246 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
247 err
= GetLastError();
248 if (request
== NULL
&& err
== ERROR_WINHTTP_NAME_NOT_RESOLVED
)
250 skip("Network unreachable, skipping.\n");
253 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", err
);
254 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
256 SetLastError(0xdeadbeef);
257 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
258 err
= GetLastError();
259 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
261 skip("Connection failed, skipping.\n");
264 ok(ret
, "WinHttpSendRequest failed: %u\n", err
);
265 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
267 SetLastError(0xdeadbeef);
268 ret
= WinHttpCloseHandle(request
);
269 err
= GetLastError();
270 ok(ret
, "WinHttpCloseHandle failed on closing request, got %u.\n", err
);
271 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
274 ret
= WinHttpCloseHandle(connection
);
275 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
276 ret
= WinHttpCloseHandle(session
);
277 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
281 static void test_empty_headers_param(void)
283 static const WCHAR empty
[] = {0};
284 HINTERNET ses
, con
, req
;
288 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
289 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
291 con
= WinHttpConnect(ses
, test_winehq
, 80, 0);
292 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
294 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
295 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
297 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
298 err
= GetLastError();
299 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
301 skip("connection failed, skipping\n");
304 ok(ret
, "failed to send request %u\n", GetLastError());
307 WinHttpCloseHandle(req
);
308 WinHttpCloseHandle(con
);
309 WinHttpCloseHandle(ses
);
312 static void test_SendRequest (void)
314 static const WCHAR content_type
[] =
315 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
316 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
317 static const WCHAR test_file
[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
318 static const WCHAR test_verb
[] = {'P','O','S','T',0};
319 static CHAR post_data
[] = "mode=Test";
320 static const char test_post
[] = "mode => Test\0\n";
321 HINTERNET session
, request
, connection
;
322 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
, err
;
329 total_len
= optional_len
= sizeof(post_data
);
330 memset(buffer
, 0xff, sizeof(buffer
));
332 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
333 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
334 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
336 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
337 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
339 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
340 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
341 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
343 skip("Network unreachable, skipping.\n");
346 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
347 if (!request
) goto done
;
349 context
= 0xdeadbeef;
350 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
351 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
354 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
355 err
= GetLastError();
356 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
358 skip("connection failed, skipping\n");
361 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
364 size
= sizeof(context
);
365 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
366 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
367 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
369 for (i
= 3; post_data
[i
]; i
++)
372 SetLastError(0xdeadbeef);
373 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
376 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
377 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
379 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
381 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
382 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
386 SetLastError(0xdeadbeef);
387 ret
= WinHttpReceiveResponse(request
, NULL
);
388 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == ERROR_NO_TOKEN
) /* < win7 */,
389 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
390 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
393 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
394 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
396 ok(bytes_rw
== sizeof(test_post
) - 1, "Read %u bytes\n", bytes_rw
);
397 ok(!memcmp(buffer
, test_post
, sizeof(test_post
) - 1), "Data read did not match.\n");
400 ret
= WinHttpCloseHandle(request
);
401 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
402 ret
= WinHttpCloseHandle(connection
);
403 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
404 ret
= WinHttpCloseHandle(session
);
405 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
408 static void test_WinHttpTimeFromSystemTime(void)
411 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
412 static const WCHAR expected_string
[] =
413 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
414 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
415 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
418 SetLastError(0xdeadbeef);
419 ret
= WinHttpTimeFromSystemTime(&time
, NULL
);
420 err
= GetLastError();
421 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
422 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
424 SetLastError(0xdeadbeef);
425 ret
= WinHttpTimeFromSystemTime(NULL
, time_string
);
426 err
= GetLastError();
427 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
428 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
430 SetLastError(0xdeadbeef);
431 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
432 err
= GetLastError();
433 ok(ret
, "WinHttpTimeFromSystemTime failed: %u\n", err
);
434 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
435 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
436 "Time string returned did not match expected time string.\n");
439 static void test_WinHttpTimeToSystemTime(void)
443 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
444 static const WCHAR time_string1
[] =
445 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
446 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
447 static const WCHAR time_string2
[] =
448 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
449 '1','0',' ','0','5',' ','5','2','\n',0};
452 SetLastError(0xdeadbeef);
453 ret
= WinHttpTimeToSystemTime(time_string1
, NULL
);
454 err
= GetLastError();
455 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
456 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
458 SetLastError(0xdeadbeef);
459 ret
= WinHttpTimeToSystemTime(NULL
, &time
);
460 err
= GetLastError();
461 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
462 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
464 SetLastError(0xdeadbeef);
465 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
466 err
= GetLastError();
467 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
468 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
469 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
470 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
472 SetLastError(0xdeadbeef);
473 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
474 err
= GetLastError();
475 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
476 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
477 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
478 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
481 static void test_WinHttpAddHeaders(void)
483 HINTERNET session
, request
, connection
;
485 WCHAR buffer
[MAX_PATH
];
486 WCHAR check_buffer
[MAX_PATH
];
487 DWORD err
, index
, len
, oldlen
;
489 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
490 static const WCHAR test_verb
[] = {'P','O','S','T',0};
491 static const WCHAR test_header_begin
[] =
492 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
493 static const WCHAR full_path_test_header_begin
[] =
494 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
495 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
496 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
497 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
498 static const WCHAR test_header_name2
[] = {'n','a','m','e',0};
499 static const WCHAR test_header_name3
[] = {'a',0};
500 static const WCHAR test_header_range
[] = {'R','a','n','g','e',0};
501 static const WCHAR test_header_range_bytes
[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
502 static const WCHAR test_header_bytes
[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
504 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
505 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
506 static const WCHAR test_flag_coalesce_comma
[] =
507 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
508 static const WCHAR test_flag_coalesce_comma_reverse
[] =
509 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
510 static const WCHAR test_flag_coalesce_semicolon
[] =
511 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
512 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
513 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
515 static const WCHAR field
[] = {'f','i','e','l','d',0};
516 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
517 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
518 static const WCHAR empty
[] = {0};
520 static const WCHAR test_headers
[][14] =
522 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
523 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
524 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
525 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
526 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
527 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
528 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
534 {' ','e',' ',':','f',0},
535 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
536 {'n','a','m','e',':',' ','v','a','l','u','e',0},
537 {'n','a','m','e',':',0}
539 static const WCHAR test_indices
[][6] =
541 {'t','e','s','t','1',0},
542 {'t','e','s','t','2',0},
543 {'t','e','s','t','3',0},
544 {'t','e','s','t','4',0}
547 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
548 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
549 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
551 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
552 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
554 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
555 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
556 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
558 skip("Network unreachable, skipping.\n");
561 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
564 len
= sizeof(buffer
);
565 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
566 test_header_name
, buffer
, &len
, &index
);
567 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
568 SetLastError(0xdeadbeef);
569 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
570 err
= GetLastError();
571 ok(ret
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, err
);
572 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
575 len
= sizeof(buffer
);
576 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
577 test_header_name
, buffer
, &len
, &index
);
578 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
579 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
580 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
581 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
583 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
584 test_header_name
, buffer
, &len
, &index
);
585 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
587 /* Try to fetch the header info with a buffer that's big enough to fit the
588 * string but not the NULL terminator.
591 len
= 5*sizeof(WCHAR
);
592 memset(check_buffer
, 0xab, sizeof(check_buffer
));
593 memcpy(buffer
, check_buffer
, sizeof(buffer
));
594 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
595 test_header_name
, buffer
, &len
, &index
);
596 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
597 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
598 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
599 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
601 /* Try with a NULL buffer */
603 len
= sizeof(buffer
);
604 SetLastError(0xdeadbeef);
605 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
606 test_header_name
, NULL
, &len
, &index
);
607 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
608 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
609 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
610 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
612 /* Try with a NULL buffer and a length that's too small */
615 SetLastError(0xdeadbeef);
616 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
617 test_header_name
, NULL
, &len
, &index
);
618 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
619 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
620 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
621 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
622 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
626 SetLastError(0xdeadbeef);
627 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
628 test_header_name
, NULL
, &len
, &index
);
629 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
630 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
631 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
632 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
633 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
638 len
= sizeof(buffer
);
639 memset(buffer
, 0xff, sizeof(buffer
));
640 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
641 test_header_name
, buffer
, &len
, &index
);
642 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
643 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
644 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
645 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
646 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
647 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
648 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
649 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
650 "WinHttpQueryHeaders returned invalid end of header string.\n");
651 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
655 SetLastError(0xdeadbeef);
656 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
657 test_header_name
, NULL
, &len
, &index
);
658 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
659 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
660 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
661 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
662 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
666 len
= sizeof(buffer
);
667 memset(buffer
, 0xff, sizeof(buffer
));
668 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
669 test_header_name
, buffer
, &len
, &index
);
670 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
671 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
672 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
673 "no double NULL terminator\n");
674 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
675 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
676 "invalid beginning of header string.\n");
677 ok(index
== 0, "header index was incremented\n");
679 /* tests for more indices */
680 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
681 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
684 len
= sizeof(buffer
);
685 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
686 test_header_name
, buffer
, &len
, &index
);
687 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
688 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
689 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
691 len
= sizeof(buffer
);
692 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
693 test_header_name
, buffer
, &len
, &index
);
694 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
698 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
699 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
702 len
= sizeof(buffer
);
703 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
704 test_header_name
, buffer
, &len
, &index
);
705 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
706 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
707 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
708 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
710 len
= sizeof(buffer
);
711 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
712 test_header_name
, buffer
, &len
, &index
);
713 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
714 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
715 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
717 /* add if new flag */
718 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
719 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
722 len
= sizeof(buffer
);
723 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
724 test_header_name
, buffer
, &len
, &index
);
725 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
726 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
727 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
729 len
= sizeof(buffer
);
730 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
731 test_header_name
, buffer
, &len
, &index
);
732 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
733 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
734 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
736 len
= sizeof(buffer
);
737 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
738 test_header_name
, buffer
, &len
, &index
);
739 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
742 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
743 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
746 len
= sizeof(buffer
);
747 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
748 test_header_name
, buffer
, &len
, &index
);
749 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
750 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
751 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
752 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
754 len
= sizeof(buffer
);
755 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
756 test_header_name
, buffer
, &len
, &index
);
757 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
758 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
759 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
761 len
= sizeof(buffer
);
762 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
763 test_header_name
, buffer
, &len
, &index
);
764 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
766 /* coalesce with comma flag */
767 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
768 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
771 len
= sizeof(buffer
);
772 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
773 test_header_name
, buffer
, &len
, &index
);
774 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
775 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
776 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
777 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
778 "WinHttpQueryHeaders returned incorrect string.\n");
780 len
= sizeof(buffer
);
781 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
782 test_header_name
, buffer
, &len
, &index
);
783 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
784 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
785 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
787 len
= sizeof(buffer
);
788 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
789 test_header_name
, buffer
, &len
, &index
);
790 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
793 /* coalesce with semicolon flag */
794 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
795 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
798 len
= sizeof(buffer
);
799 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
800 test_header_name
, buffer
, &len
, &index
);
801 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
802 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
803 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
804 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
805 "WinHttpQueryHeaders returned incorrect string.\n");
807 len
= sizeof(buffer
);
808 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
809 test_header_name
, buffer
, &len
, &index
);
810 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
811 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
812 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
814 len
= sizeof(buffer
);
815 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
816 test_header_name
, buffer
, &len
, &index
);
817 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
819 /* add and replace flags */
820 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
821 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
824 len
= sizeof(buffer
);
825 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
826 test_header_name
, buffer
, &len
, &index
);
827 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
828 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
829 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
831 len
= sizeof(buffer
);
832 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
833 test_header_name
, buffer
, &len
, &index
);
834 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
835 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
836 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
838 len
= sizeof(buffer
);
839 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
840 test_header_name
, buffer
, &len
, &index
);
841 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
843 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
844 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
846 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
847 ok(ret
, "WinHttpAddRequestHeaders failed\n");
850 memset(buffer
, 0xff, sizeof(buffer
));
851 len
= sizeof(buffer
);
852 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
853 test_header_name3
, buffer
, &len
, &index
);
854 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
855 ok(!memcmp(buffer
, empty
, sizeof(empty
)), "unexpected result\n");
857 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
858 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
860 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
861 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
863 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
864 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
866 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
867 ok(ret
, "WinHttpAddRequestHeaders failed\n");
871 len
= sizeof(buffer
);
872 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
873 field
, buffer
, &len
, &index
);
874 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
875 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
877 SetLastError(0xdeadbeef);
878 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, 0,
879 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
880 err
= GetLastError();
881 ok(!ret
, "unexpected success\n");
882 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
884 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, ~0u,
885 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
886 ok(ret
, "failed to add header: %u\n", GetLastError());
889 len
= sizeof(buffer
);
890 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
891 test_header_range
, buffer
, &len
, &index
);
892 ok(ret
, "failed to get range header %u\n", GetLastError());
893 ok(!memcmp(buffer
, test_header_bytes
, sizeof(test_header_bytes
)), "incorrect string returned\n");
894 ok(len
== lstrlenW(test_header_bytes
) * sizeof(WCHAR
), "wrong length %u\n", len
);
895 ok(index
== 1, "wrong index %u\n", index
);
898 len
= sizeof(buffer
);
899 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
900 test_header_name2
, buffer
, &len
, &index
);
901 ok(!ret
, "unexpected success\n");
903 SetLastError(0xdeadbeef);
904 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
905 err
= GetLastError();
906 ok(!ret
, "unexpected success\n");
907 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
909 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
910 ok(ret
, "got %u\n", GetLastError());
913 len
= sizeof(buffer
);
914 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
915 test_header_name2
, buffer
, &len
, &index
);
916 ok(ret
, "got %u\n", GetLastError());
917 ok(index
== 1, "wrong index %u\n", index
);
918 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
920 ret
= WinHttpAddRequestHeaders(request
, test_headers
[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
921 ok(ret
, "got %u\n", GetLastError());
924 len
= sizeof(buffer
);
925 SetLastError(0xdeadbeef);
926 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
927 test_header_name2
, buffer
, &len
, &index
);
928 err
= GetLastError();
929 ok(!ret
, "unexpected success\n");
930 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
932 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], -1L, 0);
933 ok(ret
, "got %u\n", GetLastError());
936 len
= sizeof(buffer
);
937 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
938 test_header_name2
, buffer
, &len
, &index
);
939 ok(ret
, "got %u\n", GetLastError());
940 ok(index
== 1, "wrong index %u\n", index
);
941 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
943 ret
= WinHttpCloseHandle(request
);
944 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
946 ret
= WinHttpCloseHandle(connection
);
947 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
948 ret
= WinHttpCloseHandle(session
);
949 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
953 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
955 DWORD flags
= *(DWORD
*)buf
;
959 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
962 #define X(x) if (flags & x) trace("%s\n", #x);
963 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
964 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
965 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
966 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
967 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
968 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
969 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
973 static void test_secure_connection(void)
975 static const char data_start
[] = "<!DOCTYPE html PUBLIC";
976 HINTERNET ses
, con
, req
;
977 DWORD size
, status
, policy
, bitness
, read_size
, err
, available_size
, protocols
;
980 WINHTTP_CERTIFICATE_INFO info
;
983 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
984 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
986 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
987 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
988 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
990 protocols
= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
;
991 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SECURE_PROTOCOLS
, &protocols
, sizeof(protocols
));
992 err
= GetLastError();
993 ok(ret
|| (!ret
&& err
== ERROR_INVALID_PARAMETER
) /* < win7 */, "failed to set protocols %u\n", err
);
995 con
= WinHttpConnect(ses
, test_winehq
, 443, 0);
996 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
998 /* try without setting WINHTTP_FLAG_SECURE */
999 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1000 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1002 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1003 err
= GetLastError();
1004 ok(!ret
, "unexpected success\n");
1005 ok(err
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
|| broken(err
== ERROR_INVALID_PARAMETER
) /* winxp */,
1006 "setting client cert context returned %u\n", err
);
1008 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1009 err
= GetLastError();
1010 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
1012 skip("Connection failed, skipping.\n");
1015 ok(ret
, "failed to send request %u\n", GetLastError());
1017 ret
= WinHttpReceiveResponse(req
, NULL
);
1018 ok(ret
, "failed to receive response %u\n", GetLastError());
1020 status
= 0xdeadbeef;
1021 size
= sizeof(status
);
1022 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1023 ok(ret
, "header query failed %u\n", GetLastError());
1024 ok(status
== HTTP_STATUS_BAD_REQUEST
, "got %u\n", status
);
1026 WinHttpCloseHandle(req
);
1028 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
1029 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1031 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1032 err
= GetLastError();
1033 ok(ret
|| broken(!ret
&& err
== ERROR_INVALID_PARAMETER
) /* winxp */, "failed to set client cert context %u\n", err
);
1035 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
1037 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1038 err
= GetLastError();
1039 if (!ret
&& (err
== ERROR_WINHTTP_SECURE_FAILURE
|| err
== ERROR_WINHTTP_CANNOT_CONNECT
||
1040 err
== ERROR_WINHTTP_TIMEOUT
))
1042 skip("secure connection failed, skipping remaining secure tests\n");
1045 ok(ret
, "failed to send request %u\n", GetLastError());
1047 size
= sizeof(cert
);
1048 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1049 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1050 if (ret
) CertFreeCertificateContext(cert
);
1052 size
= sizeof(bitness
);
1053 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
1054 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
1056 size
= sizeof(info
);
1057 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
1058 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
1062 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
1063 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
1064 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
1065 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
1066 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
1067 trace("dwKeySize %u\n", info
.dwKeySize
);
1068 LocalFree( info
.lpszSubjectInfo
);
1069 LocalFree( info
.lpszIssuerInfo
);
1072 ret
= WinHttpReceiveResponse(req
, NULL
);
1073 ok(ret
, "failed to receive response %u\n", GetLastError());
1076 ret
= WinHttpQueryDataAvailable(req
, &available_size
);
1077 ok(ret
, "failed to query available data %u\n", GetLastError());
1078 ok(available_size
> 2014, "available_size = %u\n", available_size
);
1080 status
= 0xdeadbeef;
1081 size
= sizeof(status
);
1082 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1083 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1084 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1087 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
1088 ok(!ret
, "succeeded unexpectedly\n");
1094 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
1095 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
1099 if (read_size
<= 32)
1100 ok(!memcmp(buffer
, data_start
, sizeof(data_start
)-1), "not expected: %.32s\n", buffer
);
1102 ok(read_size
>= available_size
, "read_size = %u, available_size = %u\n", read_size
, available_size
);
1105 WinHttpCloseHandle(req
);
1106 WinHttpCloseHandle(con
);
1107 WinHttpCloseHandle(ses
);
1110 static void test_request_parameter_defaults(void)
1112 static const WCHAR empty
[] = {0};
1113 HINTERNET ses
, con
, req
;
1114 DWORD size
, status
, error
;
1118 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1119 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1121 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1122 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1124 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1125 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1127 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1128 error
= GetLastError();
1129 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1131 skip("connection failed, skipping\n");
1134 ok(ret
, "failed to send request %u\n", GetLastError());
1136 ret
= WinHttpReceiveResponse(req
, NULL
);
1137 if (!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE
) /* win2k */
1139 win_skip("invalid response\n");
1142 ok(ret
, "failed to receive response %u\n", GetLastError());
1144 status
= 0xdeadbeef;
1145 size
= sizeof(status
);
1146 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1147 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1148 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1150 WinHttpCloseHandle(req
);
1152 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
1153 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1155 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1156 error
= GetLastError();
1157 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1159 skip("connection failed, skipping\n");
1162 ok(ret
, "failed to send request %u\n", GetLastError());
1164 ret
= WinHttpReceiveResponse(req
, NULL
);
1165 ok(ret
, "failed to receive response %u\n", GetLastError());
1168 SetLastError(0xdeadbeef);
1169 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
1170 error
= GetLastError();
1171 ok(!ret
, "succeeded unexpectedly\n");
1172 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
1174 version
= HeapAlloc(GetProcessHeap(), 0, size
);
1175 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
1176 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1177 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
1178 HeapFree(GetProcessHeap(), 0, version
);
1180 status
= 0xdeadbeef;
1181 size
= sizeof(status
);
1182 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1183 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1184 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1187 WinHttpCloseHandle(req
);
1188 WinHttpCloseHandle(con
);
1189 WinHttpCloseHandle(ses
);
1192 static const WCHAR Connections
[] = {
1193 'S','o','f','t','w','a','r','e','\\',
1194 'M','i','c','r','o','s','o','f','t','\\',
1195 'W','i','n','d','o','w','s','\\',
1196 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1197 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1198 'C','o','n','n','e','c','t','i','o','n','s',0 };
1199 static const WCHAR WinHttpSettings
[] = {
1200 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1202 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1208 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1213 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1217 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1227 static void set_proxy( REGSAM access
, BYTE
*buf
, DWORD len
, DWORD type
)
1230 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
))
1232 if (len
) RegSetValueExW( hkey
, WinHttpSettings
, 0, type
, buf
, len
);
1233 else RegDeleteValueW( hkey
, WinHttpSettings
);
1234 RegCloseKey( hkey
);
1238 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1241 IsWow64Process( GetCurrentProcess(), &wow64
);
1242 if (sizeof(void *) > sizeof(int) || wow64
)
1244 set_proxy( KEY_WRITE
|KEY_WOW64_64KEY
, buf
, len
, type
);
1245 set_proxy( KEY_WRITE
|KEY_WOW64_32KEY
, buf
, len
, type
);
1248 set_proxy( KEY_WRITE
, buf
, len
, type
);
1251 static void test_set_default_proxy_config(void)
1253 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1254 static WCHAR normalString
[] = { 'f','o','o',0 };
1256 BYTE
*saved_proxy_settings
= NULL
;
1257 WINHTTP_PROXY_INFO info
;
1260 /* FIXME: it would be simpler to read the current settings using
1261 * WinHttpGetDefaultProxyConfiguration and save them using
1262 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1264 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1265 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1266 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1267 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1268 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1269 * the lpszProxy and lpszProxyBypass values are ignored.
1270 * Thus, if a proxy is set with proxycfg, then calling
1271 * WinHttpGetDefaultProxyConfiguration followed by
1272 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1273 * getting deleted from the registry.
1275 * Instead I read the current registry value and restore it directly.
1277 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1280 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1281 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1286 /* Crashes on Vista and higher */
1287 SetLastError(0xdeadbeef);
1288 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1289 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1290 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1293 /* test with invalid access type */
1294 info
.dwAccessType
= 0xdeadbeef;
1295 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1296 SetLastError(0xdeadbeef);
1297 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1298 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1299 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1301 /* at a minimum, the proxy server must be set */
1302 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1303 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1304 SetLastError(0xdeadbeef);
1305 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1306 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1307 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1308 info
.lpszProxyBypass
= normalString
;
1309 SetLastError(0xdeadbeef);
1310 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1311 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1312 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1314 /* the proxy server can't have wide characters */
1315 info
.lpszProxy
= wideString
;
1316 SetLastError(0xdeadbeef);
1317 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1318 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1319 skip("couldn't set default proxy configuration: access denied\n");
1321 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1322 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1323 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1325 info
.lpszProxy
= normalString
;
1326 SetLastError(0xdeadbeef);
1327 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1328 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1329 skip("couldn't set default proxy configuration: access denied\n");
1332 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1333 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1334 "got %u\n", GetLastError());
1336 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1339 static void test_Timeouts (void)
1343 HINTERNET ses
, req
, con
;
1345 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1346 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1348 SetLastError(0xdeadbeef);
1349 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1350 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1351 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1353 SetLastError(0xdeadbeef);
1354 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1355 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1356 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1358 SetLastError(0xdeadbeef);
1359 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1360 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1361 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1363 SetLastError(0xdeadbeef);
1364 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1365 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1366 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1368 SetLastError(0xdeadbeef);
1369 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1370 ok(ret
, "%u\n", GetLastError());
1371 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1372 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1374 SetLastError(0xdeadbeef);
1375 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1376 ok(ret
, "%u\n", GetLastError());
1378 SetLastError(0xdeadbeef);
1379 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1380 ok(ret
, "%u\n", GetLastError());
1382 SetLastError(0xdeadbeef);
1384 size
= sizeof(DWORD
);
1385 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1386 ok(ret
, "%u\n", GetLastError());
1387 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1389 SetLastError(0xdeadbeef);
1391 size
= sizeof(DWORD
);
1392 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1393 ok(ret
, "%u\n", GetLastError());
1394 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1396 SetLastError(0xdeadbeef);
1398 size
= sizeof(DWORD
);
1399 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1400 ok(ret
, "%u\n", GetLastError());
1401 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1403 SetLastError(0xdeadbeef);
1405 size
= sizeof(DWORD
);
1406 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1407 ok(ret
, "%u\n", GetLastError());
1408 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1410 SetLastError(0xdeadbeef);
1412 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1413 ok(ret
, "%u\n", GetLastError());
1415 SetLastError(0xdeadbeef);
1417 size
= sizeof(DWORD
);
1418 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1419 ok(ret
, "%u\n", GetLastError());
1420 ok(value
== 0, "Expected 0, got %u\n", value
);
1422 SetLastError(0xdeadbeef);
1424 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1425 ok(ret
, "%u\n", GetLastError());
1427 SetLastError(0xdeadbeef);
1429 size
= sizeof(DWORD
);
1430 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1431 ok(ret
, "%u\n", GetLastError());
1432 ok(value
== 0, "Expected 0, got %u\n", value
);
1434 SetLastError(0xdeadbeef);
1436 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1437 ok(ret
, "%u\n", GetLastError());
1439 SetLastError(0xdeadbeef);
1441 size
= sizeof(DWORD
);
1442 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1443 ok(ret
, "%u\n", GetLastError());
1444 ok(value
== 0, "Expected 0, got %u\n", value
);
1446 SetLastError(0xdeadbeef);
1448 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1449 ok(ret
, "%u\n", GetLastError());
1451 SetLastError(0xdeadbeef);
1453 size
= sizeof(DWORD
);
1454 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1455 ok(ret
, "%u\n", GetLastError());
1456 ok(value
== 0, "Expected 0, got %u\n", value
);
1458 SetLastError(0xdeadbeef);
1460 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1461 ok(ret
, "%u\n", GetLastError());
1463 SetLastError(0xdeadbeef);
1465 size
= sizeof(DWORD
);
1466 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1467 ok(ret
, "%u\n", GetLastError());
1468 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1470 SetLastError(0xdeadbeef);
1472 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1473 ok(ret
, "%u\n", GetLastError());
1475 SetLastError(0xdeadbeef);
1477 size
= sizeof(DWORD
);
1478 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1479 ok(ret
, "%u\n", GetLastError());
1480 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1482 SetLastError(0xdeadbeef);
1484 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1485 ok(ret
, "%u\n", GetLastError());
1487 SetLastError(0xdeadbeef);
1489 size
= sizeof(DWORD
);
1490 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1491 ok(ret
, "%u\n", GetLastError());
1492 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1494 SetLastError(0xdeadbeef);
1496 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1497 ok(ret
, "%u\n", GetLastError());
1499 SetLastError(0xdeadbeef);
1501 size
= sizeof(DWORD
);
1502 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1503 ok(ret
, "%u\n", GetLastError());
1504 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1506 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1507 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1509 /* Timeout values should match the last one set for session */
1510 SetLastError(0xdeadbeef);
1512 size
= sizeof(DWORD
);
1513 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1514 ok(ret
, "%u\n", GetLastError());
1515 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1517 SetLastError(0xdeadbeef);
1519 size
= sizeof(DWORD
);
1520 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1521 ok(ret
, "%u\n", GetLastError());
1522 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1524 SetLastError(0xdeadbeef);
1526 size
= sizeof(DWORD
);
1527 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1528 ok(ret
, "%u\n", GetLastError());
1529 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1531 SetLastError(0xdeadbeef);
1533 size
= sizeof(DWORD
);
1534 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1535 ok(ret
, "%u\n", GetLastError());
1536 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1538 SetLastError(0xdeadbeef);
1539 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1540 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1541 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1543 SetLastError(0xdeadbeef);
1544 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1545 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1546 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1548 SetLastError(0xdeadbeef);
1549 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1550 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1551 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1553 SetLastError(0xdeadbeef);
1554 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1555 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1556 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1558 SetLastError(0xdeadbeef);
1559 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1560 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1561 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1563 SetLastError(0xdeadbeef);
1564 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1565 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1566 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1568 SetLastError(0xdeadbeef);
1570 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
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_CONNECT_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_SEND_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_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1589 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1590 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1592 /* Changing timeout values for session should affect the values for connection */
1593 SetLastError(0xdeadbeef);
1595 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1596 ok(ret
, "%u\n", GetLastError());
1598 SetLastError(0xdeadbeef);
1600 size
= sizeof(DWORD
);
1601 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1602 ok(ret
, "%u\n", GetLastError());
1603 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1605 SetLastError(0xdeadbeef);
1607 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1608 ok(ret
, "%u\n", GetLastError());
1610 SetLastError(0xdeadbeef);
1612 size
= sizeof(DWORD
);
1613 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1614 ok(ret
, "%u\n", GetLastError());
1615 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1617 SetLastError(0xdeadbeef);
1619 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1620 ok(ret
, "%u\n", GetLastError());
1622 SetLastError(0xdeadbeef);
1624 size
= sizeof(DWORD
);
1625 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1626 ok(ret
, "%u\n", GetLastError());
1627 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1629 SetLastError(0xdeadbeef);
1631 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1632 ok(ret
, "%u\n", GetLastError());
1634 SetLastError(0xdeadbeef);
1636 size
= sizeof(DWORD
);
1637 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1638 ok(ret
, "%u\n", GetLastError());
1639 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1641 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1642 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1644 /* Timeout values should match the last one set for session */
1645 SetLastError(0xdeadbeef);
1647 size
= sizeof(DWORD
);
1648 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1649 ok(ret
, "%u\n", GetLastError());
1650 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1652 SetLastError(0xdeadbeef);
1654 size
= sizeof(DWORD
);
1655 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1656 ok(ret
, "%u\n", GetLastError());
1657 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1659 SetLastError(0xdeadbeef);
1661 size
= sizeof(DWORD
);
1662 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1663 ok(ret
, "%u\n", GetLastError());
1664 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1666 SetLastError(0xdeadbeef);
1668 size
= sizeof(DWORD
);
1669 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1670 ok(ret
, "%u\n", GetLastError());
1671 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1673 SetLastError(0xdeadbeef);
1674 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1675 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1676 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1678 SetLastError(0xdeadbeef);
1679 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1680 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1681 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1683 SetLastError(0xdeadbeef);
1684 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1685 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1686 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1688 SetLastError(0xdeadbeef);
1689 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1690 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1691 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1693 SetLastError(0xdeadbeef);
1694 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1695 ok(ret
, "%u\n", GetLastError());
1697 SetLastError(0xdeadbeef);
1698 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1699 ok(ret
, "%u\n", GetLastError());
1701 SetLastError(0xdeadbeef);
1702 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1703 ok(ret
, "%u\n", GetLastError());
1705 SetLastError(0xdeadbeef);
1707 size
= sizeof(DWORD
);
1708 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1709 ok(ret
, "%u\n", GetLastError());
1710 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1712 SetLastError(0xdeadbeef);
1714 size
= sizeof(DWORD
);
1715 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1716 ok(ret
, "%u\n", GetLastError());
1717 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1719 SetLastError(0xdeadbeef);
1721 size
= sizeof(DWORD
);
1722 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1723 ok(ret
, "%u\n", GetLastError());
1724 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1726 SetLastError(0xdeadbeef);
1728 size
= sizeof(DWORD
);
1729 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1730 ok(ret
, "%u\n", GetLastError());
1731 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1733 SetLastError(0xdeadbeef);
1735 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1736 ok(ret
, "%u\n", GetLastError());
1738 SetLastError(0xdeadbeef);
1740 size
= sizeof(DWORD
);
1741 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1742 ok(ret
, "%u\n", GetLastError());
1743 ok(value
== 0, "Expected 0, got %u\n", value
);
1745 SetLastError(0xdeadbeef);
1747 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1748 ok(ret
, "%u\n", GetLastError());
1750 SetLastError(0xdeadbeef);
1752 size
= sizeof(DWORD
);
1753 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1754 ok(ret
, "%u\n", GetLastError());
1755 ok(value
== 0, "Expected 0, got %u\n", value
);
1757 SetLastError(0xdeadbeef);
1759 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1760 ok(ret
, "%u\n", GetLastError());
1762 SetLastError(0xdeadbeef);
1764 size
= sizeof(DWORD
);
1765 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1766 ok(ret
, "%u\n", GetLastError());
1767 ok(value
== 0, "Expected 0, got %u\n", value
);
1769 SetLastError(0xdeadbeef);
1771 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1772 ok(ret
, "%u\n", GetLastError());
1774 SetLastError(0xdeadbeef);
1776 size
= sizeof(DWORD
);
1777 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1778 ok(ret
, "%u\n", GetLastError());
1779 ok(value
== 0, "Expected 0, got %u\n", value
);
1781 SetLastError(0xdeadbeef);
1783 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1784 ok(ret
, "%u\n", GetLastError());
1786 SetLastError(0xdeadbeef);
1788 size
= sizeof(DWORD
);
1789 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1790 ok(ret
, "%u\n", GetLastError());
1791 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1793 SetLastError(0xdeadbeef);
1795 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1796 ok(ret
, "%u\n", GetLastError());
1798 SetLastError(0xdeadbeef);
1800 size
= sizeof(DWORD
);
1801 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1802 ok(ret
, "%u\n", GetLastError());
1803 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1805 SetLastError(0xdeadbeef);
1807 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1808 ok(ret
, "%u\n", GetLastError());
1810 SetLastError(0xdeadbeef);
1812 size
= sizeof(DWORD
);
1813 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1814 ok(ret
, "%u\n", GetLastError());
1815 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1817 SetLastError(0xdeadbeef);
1819 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1820 ok(ret
, "%u\n", GetLastError());
1822 SetLastError(0xdeadbeef);
1824 size
= sizeof(DWORD
);
1825 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1826 ok(ret
, "%u\n", GetLastError());
1827 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1829 /* Changing timeout values for session should not affect the values for a request,
1830 * neither should the other way around.
1832 SetLastError(0xdeadbeef);
1834 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1835 ok(ret
, "%u\n", GetLastError());
1837 SetLastError(0xdeadbeef);
1839 size
= sizeof(DWORD
);
1840 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1841 ok(ret
, "%u\n", GetLastError());
1842 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1844 SetLastError(0xdeadbeef);
1846 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1847 ok(ret
, "%u\n", GetLastError());
1849 SetLastError(0xdeadbeef);
1851 size
= sizeof(DWORD
);
1852 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1853 ok(ret
, "%u\n", GetLastError());
1854 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1856 SetLastError(0xdeadbeef);
1858 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1859 ok(ret
, "%u\n", GetLastError());
1861 SetLastError(0xdeadbeef);
1863 size
= sizeof(DWORD
);
1864 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1865 ok(ret
, "%u\n", GetLastError());
1866 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1868 SetLastError(0xdeadbeef);
1870 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1871 ok(ret
, "%u\n", GetLastError());
1873 SetLastError(0xdeadbeef);
1875 size
= sizeof(DWORD
);
1876 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1877 ok(ret
, "%u\n", GetLastError());
1878 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1880 SetLastError(0xdeadbeef);
1882 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1883 ok(ret
, "%u\n", GetLastError());
1885 SetLastError(0xdeadbeef);
1887 size
= sizeof(DWORD
);
1888 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1889 ok(ret
, "%u\n", GetLastError());
1890 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1892 SetLastError(0xdeadbeef);
1894 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1895 ok(ret
, "%u\n", GetLastError());
1897 SetLastError(0xdeadbeef);
1899 size
= sizeof(DWORD
);
1900 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1901 ok(ret
, "%u\n", GetLastError());
1902 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1904 SetLastError(0xdeadbeef);
1906 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1907 ok(ret
, "%u\n", GetLastError());
1909 SetLastError(0xdeadbeef);
1911 size
= sizeof(DWORD
);
1912 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1913 ok(ret
, "%u\n", GetLastError());
1914 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1916 SetLastError(0xdeadbeef);
1918 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1919 ok(ret
, "%u\n", GetLastError());
1921 SetLastError(0xdeadbeef);
1923 size
= sizeof(DWORD
);
1924 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1925 ok(ret
, "%u\n", GetLastError());
1926 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1928 WinHttpCloseHandle(req
);
1929 WinHttpCloseHandle(con
);
1930 WinHttpCloseHandle(ses
);
1933 static void test_resolve_timeout(void)
1935 static const WCHAR nxdomain
[] =
1936 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1937 HINTERNET ses
, con
, req
;
1941 if (! proxy_active())
1943 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1944 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1947 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1948 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1950 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1951 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1953 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1954 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1956 SetLastError(0xdeadbeef);
1957 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1960 skip("nxdomain returned success. Broken ISP redirects?\n");
1963 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1964 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1966 WinHttpCloseHandle(req
);
1967 WinHttpCloseHandle(con
);
1968 WinHttpCloseHandle(ses
);
1971 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1973 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1974 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1977 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1978 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1980 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1981 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1983 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1984 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1986 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1987 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
1989 skip("connection failed, skipping\n");
1992 ok(ret
, "failed to send request\n");
1995 WinHttpCloseHandle(req
);
1996 WinHttpCloseHandle(con
);
1997 WinHttpCloseHandle(ses
);
2000 static const char page1
[] =
2002 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
2003 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2006 static const char okmsg
[] =
2007 "HTTP/1.1 200 OK\r\n"
2008 "Server: winetest\r\n"
2011 static const char notokmsg
[] =
2012 "HTTP/1.1 400 Bad Request\r\n"
2015 static const char cookiemsg
[] =
2016 "HTTP/1.1 200 OK\r\n"
2017 "Set-Cookie: name = value \r\n"
2018 "Set-Cookie: NAME = value \r\n"
2021 static const char cookiemsg2
[] =
2022 "HTTP/1.1 200 OK\r\n"
2023 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2026 static const char nocontentmsg
[] =
2027 "HTTP/1.1 204 No Content\r\n"
2028 "Server: winetest\r\n"
2031 static const char notmodified
[] =
2032 "HTTP/1.1 304 Not Modified\r\n"
2035 static const char noauthmsg
[] =
2036 "HTTP/1.1 401 Unauthorized\r\n"
2037 "Server: winetest\r\n"
2038 "Connection: close\r\n"
2039 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2040 "Content-Length: 12\r\n"
2041 "Content-Type: text/plain\r\n"
2044 static const char okauthmsg
[] =
2045 "HTTP/1.1 200 OK\r\n"
2046 "Server: winetest\r\n"
2047 "Connection: close\r\n"
2048 "Content-Length: 11\r\n"
2049 "Content-Type: text/plain\r\n"
2052 static const char headmsg
[] =
2053 "HTTP/1.1 200 OK\r\n"
2054 "Content-Length: 100\r\n"
2057 static const char multiauth
[] =
2058 "HTTP/1.1 401 Unauthorized\r\n"
2059 "Server: winetest\r\n"
2060 "WWW-Authenticate: Bearer\r\n"
2061 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2062 "WWW-Authenticate: NTLM\r\n"
2063 "Content-Length: 10\r\n"
2064 "Content-Type: text/plain\r\n"
2067 static const char largeauth
[] =
2068 "HTTP/1.1 401 Unauthorized\r\n"
2069 "Server: winetest\r\n"
2070 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2071 "WWW-Authenticate: NTLM\r\n"
2072 "Content-Length: 10240\r\n"
2073 "Content-Type: text/plain\r\n"
2076 static const char unauthorized
[] = "Unauthorized";
2077 static const char hello_world
[] = "Hello World";
2085 #define BIG_BUFFER_LEN 0x2250
2087 static DWORD CALLBACK
server_thread(LPVOID param
)
2089 struct server_info
*si
= param
;
2090 int r
, c
= -1, i
, on
;
2092 struct sockaddr_in sa
;
2095 int last_request
= 0;
2097 WSAStartup(MAKEWORD(1,1), &wsaData
);
2099 s
= socket(AF_INET
, SOCK_STREAM
, 0);
2100 if (s
== INVALID_SOCKET
)
2104 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
2106 memset(&sa
, 0, sizeof sa
);
2107 sa
.sin_family
= AF_INET
;
2108 sa
.sin_port
= htons(si
->port
);
2109 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
2111 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
2116 SetEvent(si
->event
);
2119 if (c
== -1) c
= accept(s
, NULL
, NULL
);
2121 memset(buffer
, 0, sizeof buffer
);
2122 for(i
= 0; i
< sizeof buffer
- 1; i
++)
2124 r
= recv(c
, &buffer
[i
], 1, 0);
2127 if (i
< 4) continue;
2128 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
2129 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
2132 if (strstr(buffer
, "GET /basic"))
2134 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2135 send(c
, page1
, sizeof page1
- 1, 0);
2137 if (strstr(buffer
, "/auth"))
2139 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2141 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2142 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2146 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
2147 send(c
, unauthorized
, sizeof unauthorized
- 1, 0);
2151 if (strstr(buffer
, "/big"))
2153 char msg
[BIG_BUFFER_LEN
];
2154 memset(msg
, 'm', sizeof(msg
));
2155 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2156 send(c
, msg
, sizeof(msg
), 0);
2158 if (strstr(buffer
, "/no_headers"))
2160 send(c
, page1
, sizeof page1
- 1, 0);
2162 if (strstr(buffer
, "GET /no_content"))
2164 send(c
, nocontentmsg
, sizeof nocontentmsg
- 1, 0);
2167 if (strstr(buffer
, "GET /not_modified"))
2169 if (strstr(buffer
, "If-Modified-Since:")) send(c
, notmodified
, sizeof notmodified
- 1, 0);
2170 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2173 if (strstr(buffer
, "HEAD /head"))
2175 send(c
, headmsg
, sizeof headmsg
- 1, 0);
2178 if (strstr(buffer
, "GET /multiauth"))
2180 send(c
, multiauth
, sizeof multiauth
- 1, 0);
2182 if (strstr(buffer
, "GET /largeauth"))
2184 if (strstr(buffer
, "Authorization: NTLM"))
2185 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2188 send(c
, largeauth
, sizeof largeauth
- 1, 0);
2189 for (i
= 0; i
< 10240; i
++) send(c
, "A", 1, 0);
2193 if (strstr(buffer
, "GET /cookie5"))
2195 if (strstr(buffer
, "Cookie: name2=value\r\n"))
2196 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2198 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2200 if (strstr(buffer
, "GET /cookie4"))
2202 send(c
, cookiemsg2
, sizeof(cookiemsg2
) - 1, 0);
2204 if (strstr(buffer
, "GET /cookie3"))
2206 if (strstr(buffer
, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2207 broken(strstr(buffer
, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL
))
2208 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2210 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2212 if (strstr(buffer
, "GET /cookie2"))
2214 if (strstr(buffer
, "Cookie: NAME=value; name=value\r\n") ||
2215 broken(strstr(buffer
, "Cookie: name=value; NAME=value\r\n") != NULL
))
2216 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2218 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2220 else if (strstr(buffer
, "GET /cookie"))
2222 if (!strstr(buffer
, "Cookie: name=value\r\n")) send(c
, cookiemsg
, sizeof(cookiemsg
) - 1, 0);
2223 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2225 if (strstr(buffer
, "GET /quit"))
2227 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2228 send(c
, page1
, sizeof page1
- 1, 0);
2235 } while (!last_request
);
2241 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
2243 static const WCHAR test_header_end_clrf
[] = {'\r','\n','\r','\n',0};
2244 static const WCHAR test_header_end_raw
[] = {0,0};
2245 HINTERNET ses
, con
, req
;
2247 WCHAR buffer2
[0x100];
2248 DWORD count
, status
, size
, error
, supported
, first
, target
;
2251 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2252 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2254 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2255 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2257 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
2258 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2260 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2261 ok(ret
, "failed to send request %u\n", GetLastError());
2263 ret
= WinHttpReceiveResponse(req
, NULL
);
2264 ok(ret
, "failed to receive response %u\n", GetLastError());
2266 status
= 0xdeadbeef;
2267 size
= sizeof(status
);
2268 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2269 ok(ret
, "failed to query status code %u\n", GetLastError());
2270 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2272 supported
= first
= target
= 0xdeadbeef;
2273 SetLastError(0xdeadbeef);
2274 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2275 error
= GetLastError();
2276 ok(!ret
, "unexpected success\n");
2277 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2278 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2279 ok(first
== 0xdeadbeef, "got %x\n", first
);
2280 ok(target
== 0xdeadbeef, "got %x\n", target
);
2282 size
= sizeof(buffer2
);
2283 memset(buffer2
, 0, sizeof(buffer2
));
2284 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, buffer2
, &size
, NULL
);
2285 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2286 ok(!memcmp(buffer2
+ lstrlenW(buffer2
) - 4, test_header_end_clrf
, sizeof(test_header_end_clrf
)),
2287 "WinHttpQueryHeaders returned invalid end of header string\n");
2289 size
= sizeof(buffer2
);
2290 memset(buffer2
, 0, sizeof(buffer2
));
2291 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS
, NULL
, buffer2
, &size
, NULL
);
2292 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2293 ok(!memcmp(buffer2
+ (size
/ sizeof(WCHAR
)) - 1, test_header_end_raw
, sizeof(test_header_end_raw
)),
2294 "WinHttpQueryHeaders returned invalid end of header string\n");
2295 ok(buffer2
[(size
/ sizeof(WCHAR
)) - 2] != 0, "returned string has too many NULL characters\n");
2298 memset(buffer
, 0, sizeof(buffer
));
2299 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
2300 ok(ret
, "failed to read data %u\n", GetLastError());
2301 ok(count
== sizeof page1
- 1, "count was wrong\n");
2302 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
2304 WinHttpCloseHandle(req
);
2305 WinHttpCloseHandle(con
);
2306 WinHttpCloseHandle(ses
);
2309 static void test_basic_authentication(int port
)
2311 static const WCHAR authW
[] = {'/','a','u','t','h',0};
2312 static WCHAR userW
[] = {'u','s','e','r',0};
2313 static WCHAR passW
[] = {'p','w','d',0};
2314 static WCHAR pass2W
[] = {'p','w','d','2',0};
2315 HINTERNET ses
, con
, req
;
2316 DWORD status
, size
, error
, supported
, first
, target
;
2320 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2321 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2323 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2324 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2326 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2327 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2329 SetLastError(0xdeadbeef);
2330 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
2331 error
= GetLastError();
2332 ok(!ret
, "expected failure\n");
2333 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2335 SetLastError(0xdeadbeef);
2336 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
2337 error
= GetLastError();
2338 ok(!ret
, "expected failure\n");
2339 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2341 supported
= 0xdeadbeef;
2342 SetLastError(0xdeadbeef);
2343 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
2344 error
= GetLastError();
2345 ok(!ret
, "expected failure\n");
2346 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2347 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2349 supported
= first
= 0xdeadbeef;
2350 SetLastError(0xdeadbeef);
2351 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
2352 error
= GetLastError();
2353 ok(!ret
, "expected failure\n");
2354 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2355 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2356 ok(first
== 0xdeadbeef, "got %x\n", first
);
2358 supported
= first
= target
= 0xdeadbeef;
2359 SetLastError(0xdeadbeef);
2360 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2361 error
= GetLastError();
2362 ok(!ret
, "expected failure\n");
2363 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2364 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2365 ok(first
== 0xdeadbeef, "got %x\n", first
);
2366 ok(target
== 0xdeadbeef, "got %x\n", target
);
2368 supported
= first
= target
= 0xdeadbeef;
2369 SetLastError(0xdeadbeef);
2370 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
2371 error
= GetLastError();
2372 ok(!ret
, "expected failure\n");
2373 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2374 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2375 ok(first
== 0xdeadbeef, "got %x\n", first
);
2376 ok(target
== 0xdeadbeef, "got %x\n", target
);
2378 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2379 ok(ret
, "failed to send request %u\n", GetLastError());
2381 ret
= WinHttpReceiveResponse(req
, NULL
);
2382 ok(ret
, "failed to receive response %u\n", GetLastError());
2384 status
= 0xdeadbeef;
2385 size
= sizeof(status
);
2386 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2387 ok(ret
, "failed to query status code %u\n", GetLastError());
2388 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2391 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2392 error
= GetLastError();
2393 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2396 ok(size
== 12, "expected 12, got %u\n", size
);
2397 ok(!memcmp(buffer
, unauthorized
, 12), "got %s\n", buffer
);
2400 supported
= first
= target
= 0xdeadbeef;
2401 SetLastError(0xdeadbeef);
2402 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2403 error
= GetLastError();
2404 ok(ret
, "failed to query authentication schemes %u\n", error
);
2405 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2406 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2407 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2408 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2410 SetLastError(0xdeadbeef);
2411 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2412 error
= GetLastError();
2413 ok(ret
, "failed to set credentials %u\n", error
);
2414 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2416 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2417 ok(ret
, "failed to set credentials %u\n", GetLastError());
2419 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2420 ok(ret
, "failed to set credentials %u\n", GetLastError());
2422 SetLastError(0xdeadbeef);
2423 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2424 error
= GetLastError();
2425 ok(!ret
, "expected failure\n");
2426 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2428 SetLastError(0xdeadbeef);
2429 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2430 error
= GetLastError();
2431 ok(!ret
, "expected failure\n");
2432 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2434 SetLastError(0xdeadbeef);
2435 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2436 error
= GetLastError();
2437 ok(!ret
, "expected failure\n");
2438 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2440 SetLastError(0xdeadbeef);
2441 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2442 error
= GetLastError();
2443 ok(!ret
, "expected failure\n");
2444 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2446 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2447 ok(ret
, "failed to set credentials %u\n", GetLastError());
2449 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2450 ok(ret
, "failed to send request %u\n", GetLastError());
2452 ret
= WinHttpReceiveResponse(req
, NULL
);
2453 ok(ret
, "failed to receive response %u\n", GetLastError());
2455 status
= 0xdeadbeef;
2456 size
= sizeof(status
);
2457 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2458 ok(ret
, "failed to query status code %u\n", GetLastError());
2459 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2462 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2463 error
= GetLastError();
2464 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2467 ok(size
== 11, "expected 11, got %u\n", size
);
2468 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2471 WinHttpCloseHandle(req
);
2472 WinHttpCloseHandle(con
);
2473 WinHttpCloseHandle(ses
);
2475 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2477 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2478 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2480 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2481 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2483 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2484 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2486 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2487 ok(ret
, "failed to set credentials %u\n", GetLastError());
2489 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2490 ok(ret
, "failed to set username %u\n", GetLastError());
2492 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, pass2W
, lstrlenW(pass2W
));
2493 ok(ret
, "failed to set password %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
);
2507 WinHttpCloseHandle(req
);
2508 WinHttpCloseHandle(con
);
2509 WinHttpCloseHandle(ses
);
2511 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2512 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2514 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2515 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2517 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2518 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2520 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2521 ok(ret
, "failed to set username %u\n", GetLastError());
2523 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2524 ok(ret
, "failed to set password %u\n", GetLastError());
2526 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, pass2W
, NULL
);
2527 ok(ret
, "failed to set credentials %u\n", GetLastError());
2529 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2530 ok(ret
, "failed to send request %u\n", GetLastError());
2532 ret
= WinHttpReceiveResponse(req
, NULL
);
2533 ok(ret
, "failed to receive response %u\n", GetLastError());
2535 status
= 0xdeadbeef;
2536 size
= sizeof(status
);
2537 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2538 ok(ret
, "failed to query status code %u\n", GetLastError());
2539 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2541 WinHttpCloseHandle(req
);
2542 WinHttpCloseHandle(con
);
2543 WinHttpCloseHandle(ses
);
2546 static void test_multi_authentication(int port
)
2548 static const WCHAR multiauthW
[] = {'/','m','u','l','t','i','a','u','t','h',0};
2549 static const WCHAR getW
[] = {'G','E','T',0};
2550 HINTERNET ses
, con
, req
;
2551 DWORD supported
, first
, target
;
2554 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2555 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2557 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2558 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2560 req
= WinHttpOpenRequest(con
, getW
, multiauthW
, NULL
, NULL
, NULL
, 0);
2561 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2563 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0,
2564 WINHTTP_NO_REQUEST_DATA
,0, 0, 0 );
2565 ok(ret
, "expected success\n");
2567 ret
= WinHttpReceiveResponse(req
, NULL
);
2568 ok(ret
, "expected success\n");
2570 supported
= first
= target
= 0xdeadbeef;
2571 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2572 ok(ret
, "expected success\n");
2573 ok(supported
== (WINHTTP_AUTH_SCHEME_BASIC
| WINHTTP_AUTH_SCHEME_NTLM
), "got %x\n", supported
);
2574 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2575 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2577 WinHttpCloseHandle(req
);
2578 WinHttpCloseHandle(con
);
2579 WinHttpCloseHandle(ses
);
2582 static void test_large_data_authentication(int port
)
2584 static const WCHAR largeauthW
[] = {'/','l','a','r','g','e','a','u','t','h',0};
2585 static const WCHAR getW
[] = {'G','E','T',0};
2586 static WCHAR userW
[] = {'u','s','e','r',0};
2587 static WCHAR passW
[] = {'p','w','d',0};
2588 HINTERNET ses
, con
, req
;
2592 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2593 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2595 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2596 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2598 req
= WinHttpOpenRequest(con
, getW
, largeauthW
, NULL
, NULL
, NULL
, 0);
2599 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2601 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, WINHTTP_NO_REQUEST_DATA
, 0, 0, 0);
2602 ok(ret
, "expected success\n");
2604 ret
= WinHttpReceiveResponse(req
, NULL
);
2605 ok(ret
, "expected success\n");
2607 size
= sizeof(status
);
2608 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
,
2609 &status
, &size
, NULL
);
2610 ok(ret
, "expected success\n");
2611 ok(status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
2613 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, userW
, passW
, NULL
);
2614 ok(ret
, "expected success\n");
2616 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, WINHTTP_NO_REQUEST_DATA
, 0, 0, 0);
2617 ok(ret
, "expected success %d\n", GetLastError());
2619 ret
= WinHttpReceiveResponse(req
, NULL
);
2620 ok(ret
, "expected success\n");
2622 size
= sizeof(status
);
2623 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
,
2624 &status
, &size
, NULL
);
2625 ok(ret
, "expected success\n");
2626 ok(status
== HTTP_STATUS_OK
, "got %d\n", status
);
2628 WinHttpCloseHandle(req
);
2629 WinHttpCloseHandle(con
);
2630 WinHttpCloseHandle(ses
);
2633 static void test_no_headers(int port
)
2635 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2636 HINTERNET ses
, con
, req
;
2640 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2641 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2643 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2644 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2646 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2647 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2649 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2652 error
= GetLastError();
2653 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2657 SetLastError(0xdeadbeef);
2658 ret
= WinHttpReceiveResponse(req
, NULL
);
2659 error
= GetLastError();
2660 ok(!ret
, "expected failure\n");
2661 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2664 WinHttpCloseHandle(req
);
2665 WinHttpCloseHandle(con
);
2666 WinHttpCloseHandle(ses
);
2669 static void test_no_content(int port
)
2671 static const WCHAR no_contentW
[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2672 HINTERNET ses
, con
, req
;
2674 DWORD size
, len
= sizeof(buf
), bytes_read
, status
;
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
, NULL
, no_contentW
, NULL
, NULL
, NULL
, 0);
2684 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2687 SetLastError(0xdeadbeef);
2688 ret
= WinHttpQueryDataAvailable(req
, &size
);
2690 ok(!ret
, "expected error\n");
2691 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
,
2692 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2693 ok(size
== 12345 || broken(size
== 0) /* Win <= 2003 */,
2694 "expected 12345, got %u\n", size
);
2697 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2698 ok(ret
, "expected success\n");
2700 ret
= WinHttpReceiveResponse(req
, NULL
);
2701 ok(ret
, "expected success\n");
2703 status
= 0xdeadbeef;
2704 size
= sizeof(status
);
2705 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2706 NULL
, &status
, &size
, NULL
);
2707 ok(ret
, "expected success\n");
2708 ok(status
== HTTP_STATUS_NO_CONTENT
, "expected status 204, got %d\n", status
);
2710 SetLastError(0xdeadbeef);
2711 size
= sizeof(status
);
2713 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2714 NULL
, &status
, &size
, 0);
2715 ok(!ret
, "expected no content-length header\n");
2716 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError());
2717 ok(status
== 12345, "expected 0, got %d\n", status
);
2719 SetLastError(0xdeadbeef);
2721 ret
= WinHttpQueryDataAvailable(req
, &size
);
2722 ok(ret
, "expected success\n");
2723 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2724 "wrong error %u\n", GetLastError());
2725 ok(!size
, "expected 0, got %u\n", size
);
2727 SetLastError(0xdeadbeef);
2728 ret
= WinHttpReadData(req
, buf
, len
, &bytes_read
);
2729 ok(ret
, "expected success\n");
2730 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2731 "wrong error %u\n", GetLastError());
2732 ok(!bytes_read
, "expected 0, got %u\n", bytes_read
);
2735 ret
= WinHttpQueryDataAvailable(req
, &size
);
2736 ok(ret
, "expected success\n");
2737 ok(size
== 0, "expected 0, got %d\n", size
);
2739 WinHttpCloseHandle(req
);
2742 SetLastError(0xdeadbeef);
2743 ret
= WinHttpQueryDataAvailable(req
, &size
);
2744 ok(!ret
, "expected error\n");
2745 ok(GetLastError() == ERROR_INVALID_HANDLE
,
2746 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2747 ok(size
== 12345, "expected 12345, got %u\n", size
);
2749 WinHttpCloseHandle(con
);
2750 WinHttpCloseHandle(ses
);
2753 static void test_head_request(int port
)
2755 static const WCHAR verbW
[] = {'H','E','A','D',0};
2756 static const WCHAR headW
[] = {'/','h','e','a','d',0};
2757 HINTERNET ses
, con
, req
;
2759 DWORD size
, len
, count
, 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
, verbW
, headW
, NULL
, NULL
, NULL
, 0);
2769 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2771 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2772 ok(ret
, "failed to send request %u\n", GetLastError());
2774 ret
= WinHttpReceiveResponse(req
, NULL
);
2775 ok(ret
, "failed to receive response %u\n", GetLastError());
2777 status
= 0xdeadbeef;
2778 size
= sizeof(status
);
2779 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2780 NULL
, &status
, &size
, NULL
);
2781 ok(ret
, "failed to get status code %u\n", GetLastError());
2782 ok(status
== HTTP_STATUS_OK
, "got %u\n", status
);
2786 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2787 NULL
, &len
, &size
, 0);
2788 ok(ret
, "failed to get content-length header %u\n", GetLastError());
2789 ok(len
== HTTP_STATUS_CONTINUE
, "got %u\n", len
);
2792 ret
= WinHttpQueryDataAvailable(req
, &count
);
2793 ok(ret
, "failed to query data available %u\n", GetLastError());
2794 ok(!count
, "got %u\n", count
);
2798 ret
= WinHttpReadData(req
, buf
, len
, &count
);
2799 ok(ret
, "failed to read data %u\n", GetLastError());
2800 ok(!count
, "got %u\n", count
);
2803 ret
= WinHttpQueryDataAvailable(req
, &count
);
2804 ok(ret
, "failed to query data available %u\n", GetLastError());
2805 ok(!count
, "got %u\n", count
);
2807 WinHttpCloseHandle(req
);
2808 WinHttpCloseHandle(con
);
2809 WinHttpCloseHandle(ses
);
2812 static void test_not_modified(int port
)
2814 static const WCHAR pathW
[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2815 static const WCHAR ifmodifiedW
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2816 static const WCHAR ifmodified2W
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2818 HINTERNET session
, request
, connection
;
2819 DWORD index
, len
, status
, size
, start
= GetTickCount();
2821 WCHAR today
[(sizeof(ifmodifiedW
) + WINHTTP_TIME_FORMAT_BUFSIZE
)/sizeof(WCHAR
) + 3], buffer
[32];
2823 memcpy(today
, ifmodifiedW
, sizeof(ifmodifiedW
));
2825 WinHttpTimeFromSystemTime(&st
, &today
[sizeof(ifmodifiedW
)/sizeof(WCHAR
)]);
2827 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
,
2828 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
2829 ok(session
!= NULL
, "WinHttpOpen failed: %u\n", GetLastError());
2831 connection
= WinHttpConnect(session
, localhostW
, port
, 0);
2832 ok(connection
!= NULL
, "WinHttpConnect failed: %u\n", GetLastError());
2834 request
= WinHttpOpenRequest(connection
, NULL
, pathW
, NULL
, WINHTTP_NO_REFERER
,
2835 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
2836 ok(request
!= NULL
, "WinHttpOpenrequest failed: %u\n", GetLastError());
2838 ret
= WinHttpSendRequest(request
, today
, 0, NULL
, 0, 0, 0);
2839 ok(ret
, "WinHttpSendRequest failed: %u\n", GetLastError());
2841 ret
= WinHttpReceiveResponse(request
, NULL
);
2842 ok(ret
, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2845 len
= sizeof(buffer
);
2846 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2847 ifmodified2W
, buffer
, &len
, &index
);
2848 ok(ret
, "failed to get header %u\n", GetLastError());
2850 status
= 0xdeadbeef;
2851 size
= sizeof(status
);
2852 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
,
2853 NULL
, &status
, &size
, NULL
);
2854 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2855 ok(status
== HTTP_STATUS_NOT_MODIFIED
, "got %u\n", status
);
2858 ret
= WinHttpQueryDataAvailable(request
, &size
);
2859 ok(ret
, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2860 ok(!size
, "got %u\n", size
);
2862 WinHttpCloseHandle(request
);
2863 WinHttpCloseHandle(connection
);
2864 WinHttpCloseHandle(session
);
2865 start
= GetTickCount() - start
;
2866 ok(start
<= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start
);
2869 static void test_bad_header( int port
)
2871 static const WCHAR bad_headerW
[] =
2872 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2873 't','e','x','t','/','h','t','m','l','\n','\r',0};
2874 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2875 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2877 HINTERNET ses
, con
, req
;
2881 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2882 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2884 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2885 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2887 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2888 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2890 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2891 ok( ret
, "failed to add header %u\n", GetLastError() );
2895 len
= sizeof(buffer
);
2896 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2897 content_typeW
, buffer
, &len
, &index
);
2898 ok( ret
, "failed to query headers %u\n", GetLastError() );
2899 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2901 WinHttpCloseHandle( req
);
2902 WinHttpCloseHandle( con
);
2903 WinHttpCloseHandle( ses
);
2906 static void test_multiple_reads(int port
)
2908 static const WCHAR bigW
[] = {'b','i','g',0};
2909 HINTERNET ses
, con
, req
;
2910 DWORD total_len
= 0;
2913 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2914 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2916 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2917 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2919 req
= WinHttpOpenRequest(con
, NULL
, bigW
, NULL
, NULL
, NULL
, 0);
2920 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2922 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2923 ok(ret
, "failed to send request %u\n", GetLastError());
2925 ret
= WinHttpReceiveResponse(req
, NULL
);
2926 ok(ret
== TRUE
, "expected success\n");
2930 DWORD len
= 0xdeadbeef;
2931 ret
= WinHttpQueryDataAvailable( req
, &len
);
2932 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2933 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2937 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
2939 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
2940 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
2942 HeapFree( GetProcessHeap(), 0, buf
);
2943 if (!bytes_read
) break;
2944 total_len
+= bytes_read
;
2948 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
2950 WinHttpCloseHandle(req
);
2951 WinHttpCloseHandle(con
);
2952 WinHttpCloseHandle(ses
);
2955 static void test_cookies( int port
)
2957 static const WCHAR cookieW
[] = {'/','c','o','o','k','i','e',0};
2958 static const WCHAR cookie2W
[] = {'/','c','o','o','k','i','e','2',0};
2959 static const WCHAR cookie3W
[] = {'/','c','o','o','k','i','e','3',0};
2960 static const WCHAR cookie4W
[] = {'/','c','o','o','k','i','e','4',0};
2961 static const WCHAR cookie5W
[] = {'/','c','o','o','k','i','e','5',0};
2962 static const WCHAR cookieheaderW
[] =
2963 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
2964 HINTERNET ses
, con
, req
;
2968 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
2969 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2971 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2972 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2974 req
= WinHttpOpenRequest( con
, NULL
, cookieW
, NULL
, NULL
, NULL
, 0 );
2975 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2977 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2978 ok( ret
, "failed to send request %u\n", GetLastError() );
2980 ret
= WinHttpReceiveResponse( req
, NULL
);
2981 ok( ret
, "failed to receive response %u\n", GetLastError() );
2983 status
= 0xdeadbeef;
2984 size
= sizeof(status
);
2985 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2986 ok( ret
, "failed to query status code %u\n", GetLastError() );
2987 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2989 WinHttpCloseHandle( req
);
2991 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
2992 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2994 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2995 ok( ret
, "failed to send request %u\n", GetLastError() );
2997 ret
= WinHttpReceiveResponse( req
, NULL
);
2998 ok( ret
, "failed to receive response %u\n", GetLastError() );
3000 status
= 0xdeadbeef;
3001 size
= sizeof(status
);
3002 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3003 ok( ret
, "failed to query status code %u\n", GetLastError() );
3004 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3006 WinHttpCloseHandle( req
);
3007 WinHttpCloseHandle( con
);
3009 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3010 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3012 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3013 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3015 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3016 ok( ret
, "failed to send request %u\n", GetLastError() );
3018 ret
= WinHttpReceiveResponse( req
, NULL
);
3019 ok( ret
, "failed to receive response %u\n", GetLastError() );
3021 status
= 0xdeadbeef;
3022 size
= sizeof(status
);
3023 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3024 ok( ret
, "failed to query status code %u\n", GetLastError() );
3025 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3027 WinHttpCloseHandle( req
);
3029 req
= WinHttpOpenRequest( con
, NULL
, cookie3W
, NULL
, NULL
, NULL
, 0 );
3030 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3032 ret
= WinHttpSendRequest( req
, cookieheaderW
, ~0u, NULL
, 0, 0, 0 );
3033 ok( ret
, "failed to send request %u\n", GetLastError() );
3035 ret
= WinHttpReceiveResponse( req
, NULL
);
3036 ok( ret
, "failed to receive response %u\n", GetLastError() );
3038 status
= 0xdeadbeef;
3039 size
= sizeof(status
);
3040 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3041 ok( ret
, "failed to query status code %u\n", GetLastError() );
3042 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
), "request failed unexpectedly %u\n", status
);
3044 WinHttpCloseHandle( req
);
3045 WinHttpCloseHandle( con
);
3046 WinHttpCloseHandle( ses
);
3048 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3049 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3051 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3052 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3054 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3055 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3057 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3058 ok( ret
, "failed to send request %u\n", GetLastError() );
3060 ret
= WinHttpReceiveResponse( req
, NULL
);
3061 ok( ret
, "failed to receive response %u\n", GetLastError() );
3063 status
= 0xdeadbeef;
3064 size
= sizeof(status
);
3065 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3066 ok( ret
, "failed to query status code %u\n", GetLastError() );
3067 ok( status
== HTTP_STATUS_BAD_REQUEST
, "request failed unexpectedly %u\n", status
);
3069 WinHttpCloseHandle( req
);
3070 WinHttpCloseHandle( con
);
3071 WinHttpCloseHandle( ses
);
3073 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3074 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3076 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3077 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3079 req
= WinHttpOpenRequest( con
, NULL
, cookie4W
, NULL
, NULL
, NULL
, 0 );
3080 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3082 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3083 ok( ret
, "failed to send request %u\n", GetLastError() );
3085 ret
= WinHttpReceiveResponse( req
, NULL
);
3086 ok( ret
, "failed to receive response %u\n", GetLastError() );
3088 status
= 0xdeadbeef;
3089 size
= sizeof(status
);
3090 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3091 ok( ret
, "failed to query status code %u\n", GetLastError() );
3092 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3093 WinHttpCloseHandle( req
);
3095 req
= WinHttpOpenRequest( con
, NULL
, cookie5W
, NULL
, NULL
, NULL
, 0 );
3096 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3098 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3099 ok( ret
, "failed to send request %u\n", GetLastError() );
3101 ret
= WinHttpReceiveResponse( req
, NULL
);
3102 ok( ret
, "failed to receive response %u\n", GetLastError() );
3104 status
= 0xdeadbeef;
3105 size
= sizeof(status
);
3106 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3107 ok( ret
, "failed to query status code %u\n", GetLastError() );
3108 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
) /* < win7 */,
3109 "request failed unexpectedly %u\n", status
);
3111 WinHttpCloseHandle( req
);
3112 WinHttpCloseHandle( con
);
3113 WinHttpCloseHandle( ses
);
3116 static void test_connection_info( int port
)
3118 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
3119 HINTERNET ses
, con
, req
;
3120 WINHTTP_CONNECTION_INFO info
;
3124 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3125 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3127 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3128 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3130 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
3131 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3133 size
= sizeof(info
);
3134 SetLastError( 0xdeadbeef );
3135 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3136 error
= GetLastError();
3137 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
3139 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
3142 ok( !ret
, "unexpected success\n" );
3143 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
3145 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3146 ok( ret
, "failed to send request %u\n", GetLastError() );
3149 SetLastError( 0xdeadbeef );
3150 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3151 error
= GetLastError();
3152 ok( !ret
, "unexpected success\n" );
3153 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
3155 size
= sizeof(info
);
3156 memset( &info
, 0, sizeof(info
) );
3157 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3158 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3159 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3161 ret
= WinHttpReceiveResponse( req
, NULL
);
3162 ok( ret
, "failed to receive response %u\n", GetLastError() );
3164 size
= sizeof(info
);
3165 memset( &info
, 0, sizeof(info
) );
3166 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3167 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3168 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3170 WinHttpCloseHandle( req
);
3171 WinHttpCloseHandle( con
);
3172 WinHttpCloseHandle( ses
);
3175 static void test_credentials(void)
3177 static WCHAR userW
[] = {'u','s','e','r',0};
3178 static WCHAR passW
[] = {'p','a','s','s',0};
3179 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
3180 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
3181 HINTERNET ses
, con
, req
;
3186 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
3187 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
3189 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
3190 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3192 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3193 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3195 size
= sizeof(buffer
)/sizeof(WCHAR
);
3196 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3197 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3198 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3199 ok(!size
, "expected 0, got %u\n", size
);
3201 size
= sizeof(buffer
)/sizeof(WCHAR
);
3202 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3203 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3204 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3205 ok(!size
, "expected 0, got %u\n", size
);
3207 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
3208 ok(ret
, "failed to set username %u\n", GetLastError());
3210 size
= sizeof(buffer
)/sizeof(WCHAR
);
3211 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3212 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3213 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3214 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3216 size
= sizeof(buffer
)/sizeof(WCHAR
);
3217 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3218 ok(ret
, "failed to query username %u\n", GetLastError());
3219 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3220 ok(!size
, "expected 0, got %u\n", size
);
3222 size
= sizeof(buffer
)/sizeof(WCHAR
);
3223 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3224 ok(ret
, "failed to query password %u\n", GetLastError());
3225 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3226 ok(!size
, "expected 0, got %u\n", size
);
3228 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
3229 ok(ret
, "failed to set proxy password %u\n", GetLastError());
3231 size
= sizeof(buffer
)/sizeof(WCHAR
);
3232 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3233 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3234 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3235 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3237 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
3238 ok(ret
, "failed to set username %u\n", GetLastError());
3240 size
= sizeof(buffer
)/sizeof(WCHAR
);
3241 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3242 ok(ret
, "failed to query username %u\n", GetLastError());
3243 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3244 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3246 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
3247 ok(ret
, "failed to set password %u\n", GetLastError());
3249 size
= sizeof(buffer
)/sizeof(WCHAR
);
3250 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3251 ok(ret
, "failed to query password %u\n", GetLastError());
3252 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3253 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3255 WinHttpCloseHandle(req
);
3257 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3258 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3260 SetLastError(0xdeadbeef);
3261 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
3262 error
= GetLastError();
3263 ok(!ret
, "expected failure\n");
3264 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3266 SetLastError(0xdeadbeef);
3267 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
3268 error
= GetLastError();
3269 ok(!ret
, "expected failure\n");
3270 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3272 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
3273 ok(ret
, "failed to set credentials %u\n", GetLastError());
3275 size
= sizeof(buffer
)/sizeof(WCHAR
);
3276 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3277 ok(ret
, "failed to query username %u\n", GetLastError());
3279 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3280 ok(!size
, "expected 0, got %u\n", size
);
3283 size
= sizeof(buffer
)/sizeof(WCHAR
);
3284 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3285 ok(ret
, "failed to query password %u\n", GetLastError());
3287 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3288 ok(!size
, "expected 0, got %u\n", size
);
3291 WinHttpCloseHandle(req
);
3292 WinHttpCloseHandle(con
);
3293 WinHttpCloseHandle(ses
);
3296 static void test_IWinHttpRequest(int port
)
3298 static const WCHAR data_start
[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3299 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
3300 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
3301 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3302 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3303 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3304 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3305 static const WCHAR method1W
[] = {'G','E','T',0};
3306 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
3307 static const WCHAR method3W
[] = {'P','O','S','T',0};
3308 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3309 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
3310 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
3311 static const WCHAR dateW
[] = {'D','a','t','e',0};
3312 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
3313 static const WCHAR utf8W
[] = {'u','t','f','-','8',0};
3314 static const WCHAR unauthW
[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3316 IWinHttpRequest
*req
;
3317 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
3318 BSTR date
, today
, connection
, value
= NULL
;
3319 VARIANT async
, empty
, timeout
, body
, body2
, proxy_server
, bypass_list
, data
, cp
;
3320 VARIANT_BOOL succeeded
;
3322 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
3324 IStream
*stream
, *stream2
;
3330 GetSystemTime( &st
);
3331 WinHttpTimeFromSystemTime( &st
, todayW
);
3333 CoInitialize( NULL
);
3334 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3335 ok( hr
== S_OK
, "got %08x\n", hr
);
3337 V_VT( &empty
) = VT_ERROR
;
3338 V_ERROR( &empty
) = 0xdeadbeef;
3340 V_VT( &async
) = VT_BOOL
;
3341 V_BOOL( &async
) = VARIANT_FALSE
;
3343 method
= SysAllocString( method3W
);
3344 url
= SysAllocString( url3W
);
3345 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3346 ok( hr
== S_OK
, "got %08x\n", hr
);
3347 SysFreeString( method
);
3348 SysFreeString( url
);
3350 V_VT( &data
) = VT_BSTR
;
3351 V_BSTR( &data
) = SysAllocString( test_dataW
);
3352 hr
= IWinHttpRequest_Send( req
, data
);
3353 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
3355 SysFreeString( V_BSTR( &data
) );
3357 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
3358 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3360 method
= SysAllocString( method1W
);
3361 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
3362 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3364 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
3365 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3367 url
= SysAllocString( url1W
);
3368 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
3369 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3371 hr
= IWinHttpRequest_Abort( req
);
3372 ok( hr
== S_OK
, "got %08x\n", hr
);
3374 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
3375 ok( hr
== S_OK
, "got %08x\n", hr
);
3377 hr
= IWinHttpRequest_Abort( req
);
3378 ok( hr
== S_OK
, "got %08x\n", hr
);
3380 IWinHttpRequest_Release( req
);
3382 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3383 ok( hr
== S_OK
, "got %08x\n", hr
);
3385 SysFreeString( url
);
3386 url
= SysAllocString( url2W
);
3387 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3388 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3390 SysFreeString( method
);
3391 method
= SysAllocString( method2W
);
3392 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3393 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3395 SysFreeString( method
);
3396 method
= SysAllocString( method1W
);
3397 SysFreeString( url
);
3398 url
= SysAllocString( url1W
);
3399 V_VT( &async
) = VT_ERROR
;
3400 V_ERROR( &async
) = DISP_E_PARAMNOTFOUND
;
3401 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3402 ok( hr
== S_OK
, "got %08x\n", hr
);
3404 V_VT( &cp
) = VT_ERROR
;
3405 V_ERROR( &cp
) = 0xdeadbeef;
3406 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3407 ok( hr
== S_OK
, "got %08x\n", hr
);
3408 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3409 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3411 V_VT( &cp
) = VT_UI4
;
3412 V_UI4( &cp
) = CP_ACP
;
3413 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3414 ok( hr
== S_OK
, "got %08x\n", hr
);
3416 V_VT( &cp
) = VT_ERROR
;
3417 V_ERROR( &cp
) = 0xdeadbeef;
3418 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3419 ok( hr
== S_OK
, "got %08x\n", hr
);
3420 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3421 ok( V_I4( &cp
) == CP_ACP
, "got %u\n", V_I4( &cp
) );
3423 value
= SysAllocString( utf8W
);
3424 V_VT( &cp
) = VT_BSTR
;
3425 V_BSTR( &cp
) = value
;
3426 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3427 ok( hr
== S_OK
, "got %08x\n", hr
);
3428 SysFreeString( value
);
3430 V_VT( &cp
) = VT_ERROR
;
3431 V_ERROR( &cp
) = 0xdeadbeef;
3432 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3433 ok( hr
== S_OK
, "got %08x\n", hr
);
3434 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3435 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3437 hr
= IWinHttpRequest_Abort( req
);
3438 ok( hr
== S_OK
, "got %08x\n", hr
);
3440 hr
= IWinHttpRequest_Send( req
, empty
);
3441 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3443 hr
= IWinHttpRequest_Abort( req
);
3444 ok( hr
== S_OK
, "got %08x\n", hr
);
3446 IWinHttpRequest_Release( req
);
3448 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3449 ok( hr
== S_OK
, "got %08x\n", hr
);
3451 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3452 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3454 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3455 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3457 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3458 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3460 hr
= IWinHttpRequest_get_Status( req
, &status
);
3461 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3463 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3464 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3466 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3467 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3469 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3470 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3472 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3473 ok( hr
== S_OK
, "got %08x\n", hr
);
3475 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3476 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3478 VariantInit( &proxy_server
);
3479 V_VT( &proxy_server
) = VT_ERROR
;
3480 VariantInit( &bypass_list
);
3481 V_VT( &bypass_list
) = VT_ERROR
;
3482 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3483 ok( hr
== S_OK
, "got %08x\n", hr
);
3485 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3486 ok( hr
== S_OK
, "got %08x\n", hr
);
3488 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3489 ok( hr
== S_OK
, "got %08x\n", hr
);
3491 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3492 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3494 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3495 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3497 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3498 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3500 connection
= SysAllocString( connectionW
);
3501 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3502 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3504 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3505 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3507 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
3508 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3510 date
= SysAllocString( dateW
);
3511 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3512 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3514 today
= SysAllocString( todayW
);
3515 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3516 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3518 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
3519 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3521 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3522 ok( hr
== S_OK
, "got %08x\n", hr
);
3524 SysFreeString( method
);
3525 method
= SysAllocString( method1W
);
3526 SysFreeString( url
);
3527 url
= SysAllocString( url1W
);
3528 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3529 ok( hr
== S_OK
, "got %08x\n", hr
);
3531 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3532 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3534 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3535 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3537 hr
= IWinHttpRequest_get_Status( req
, &status
);
3538 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3540 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3541 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3543 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3544 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3546 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3547 ok( hr
== S_OK
, "got %08x\n", hr
);
3549 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3550 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3552 username
= SysAllocString( usernameW
);
3553 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
3554 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3556 password
= SysAllocString( passwordW
);
3557 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
3558 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3560 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
3561 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3563 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3564 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3566 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3567 ok( hr
== S_OK
, "got %08x\n", hr
);
3569 V_VT( &proxy_server
) = VT_BSTR
;
3570 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
3571 V_VT( &bypass_list
) = VT_BSTR
;
3572 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
3573 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3574 ok( hr
== S_OK
, "got %08x\n", hr
);
3576 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
3577 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3579 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3580 ok( hr
== S_OK
, "got %08x\n", hr
);
3582 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3583 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3585 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3586 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3588 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3589 ok( hr
== S_OK
, "got %08x\n", hr
);
3591 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3592 ok( hr
== S_OK
, "got %08x\n", hr
);
3594 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3595 ok( hr
== S_OK
, "got %08x\n", hr
);
3597 hr
= IWinHttpRequest_Send( req
, empty
);
3598 ok( hr
== S_OK
, "got %08x\n", hr
);
3600 hr
= IWinHttpRequest_Send( req
, empty
);
3601 ok( hr
== S_OK
, "got %08x\n", hr
);
3603 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3604 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3606 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3607 ok( hr
== S_OK
, "got %08x\n", hr
);
3608 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3609 SysFreeString( response
);
3611 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3612 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3615 hr
= IWinHttpRequest_get_Status( req
, &status
);
3616 ok( hr
== S_OK
, "got %08x\n", hr
);
3617 trace("Status=%d\n", status
);
3619 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3620 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3622 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3623 ok( hr
== S_OK
, "got %08x\n", hr
);
3624 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
3625 SysFreeString( status_text
);
3627 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3628 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3630 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3631 ok( hr
== S_OK
, "got %08x\n", hr
);
3633 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3634 ok( hr
== S_OK
, "got %08x\n", hr
);
3636 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3637 ok( hr
== S_OK
, "got %08x\n", hr
);
3639 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3640 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3642 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3643 ok( hr
== S_OK
, "got %08x\n", hr
);
3644 SysFreeString( headers
);
3646 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3647 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3649 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3650 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3652 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3653 ok( hr
== S_OK
, "got %08x\n", hr
);
3654 SysFreeString( value
);
3656 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3657 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3659 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3660 ok( hr
== S_OK
, "got %08x\n", hr
);
3662 VariantInit( &timeout
);
3663 V_VT( &timeout
) = VT_I4
;
3664 V_I4( &timeout
) = 10;
3665 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3666 ok( hr
== S_OK
, "got %08x\n", hr
);
3668 hr
= IWinHttpRequest_get_Status( req
, &status
);
3669 ok( hr
== S_OK
, "got %08x\n", hr
);
3671 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3672 ok( hr
== S_OK
, "got %08x\n", hr
);
3673 SysFreeString( status_text
);
3675 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3676 ok( hr
== S_OK
, "got %08x\n", hr
);
3678 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3679 ok( hr
== S_OK
, "got %08x\n", hr
);
3681 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3682 ok( hr
== S_OK
, "got %08x\n", hr
);
3684 hr
= IWinHttpRequest_Send( req
, empty
);
3685 ok( hr
== S_OK
, "got %08x\n", hr
);
3687 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3688 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3690 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3691 ok( hr
== S_OK
, "got %08x\n", hr
);
3692 SysFreeString( response
);
3694 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3695 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3697 VariantInit( &body
);
3698 V_VT( &body
) = VT_ERROR
;
3699 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
3700 ok( hr
== S_OK
, "got %08x\n", hr
);
3701 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
3703 hr
= VariantClear( &body
);
3704 ok( hr
== S_OK
, "got %08x\n", hr
);
3706 VariantInit( &body
);
3707 V_VT( &body
) = VT_ERROR
;
3708 hr
= IWinHttpRequest_get_ResponseStream( req
, &body
);
3709 ok( hr
== S_OK
, "got %08x\n", hr
);
3710 ok( V_VT( &body
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body
) );
3712 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body
), &IID_IStream
, (void **)&stream
);
3713 ok( hr
== S_OK
, "got %08x\n", hr
);
3714 ok( V_UNKNOWN( &body
) == (IUnknown
*)stream
, "got different interface pointer\n" );
3718 hr
= IStream_Read( stream
, buf
, 128, &count
);
3719 ok( hr
== S_OK
, "got %08x\n", hr
);
3720 ok( count
!= 0xdeadbeef, "count not set\n" );
3721 ok( buf
[0], "no data\n" );
3723 VariantInit( &body2
);
3724 V_VT( &body2
) = VT_ERROR
;
3725 hr
= IWinHttpRequest_get_ResponseStream( req
, &body2
);
3726 ok( hr
== S_OK
, "got %08x\n", hr
);
3727 ok( V_VT( &body2
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body2
) );
3728 ok( V_UNKNOWN( &body
) != V_UNKNOWN( &body2
), "got same interface pointer\n" );
3730 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body2
), &IID_IStream
, (void **)&stream2
);
3731 ok( hr
== S_OK
, "got %08x\n", hr
);
3732 ok( V_UNKNOWN( &body2
) == (IUnknown
*)stream2
, "got different interface pointer\n" );
3733 IStream_Release( stream2
);
3735 hr
= VariantClear( &body
);
3736 ok( hr
== S_OK
, "got %08x\n", hr
);
3738 hr
= VariantClear( &body2
);
3739 ok( hr
== S_OK
, "got %08x\n", hr
);
3741 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3742 ok( hr
== S_OK
, "got %08x\n", hr
);
3744 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3745 ok( hr
== S_OK
, "got %08x\n", hr
);
3747 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3748 ok( hr
== S_OK
, "got %08x\n", hr
);
3749 SysFreeString( headers
);
3751 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3752 ok( hr
== S_OK
, "got %08x\n", hr
);
3753 SysFreeString( value
);
3755 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3756 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3758 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3759 ok( hr
== S_OK
, "got %08x\n", hr
);
3761 hr
= IWinHttpRequest_Send( req
, empty
);
3762 ok( hr
== S_OK
, "got %08x\n", hr
);
3764 hr
= IWinHttpRequest_Abort( req
);
3765 ok( hr
== S_OK
, "got %08x\n", hr
);
3767 hr
= IWinHttpRequest_Abort( req
);
3768 ok( hr
== S_OK
, "got %08x\n", hr
);
3770 IWinHttpRequest_Release( req
);
3773 hr
= IStream_Seek( stream
, pos
, STREAM_SEEK_SET
, NULL
);
3774 ok( hr
== S_OK
, "got %08x\n", hr
);
3778 hr
= IStream_Read( stream
, buf
, 128, &count
);
3779 ok( hr
== S_OK
, "got %08x\n", hr
);
3780 ok( count
!= 0xdeadbeef, "count not set\n" );
3781 ok( buf
[0], "no data\n" );
3782 IStream_Release( stream
);
3784 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3785 ok( hr
== S_OK
, "got %08x\n", hr
);
3787 V_VT( &async
) = VT_I4
;
3789 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3790 ok( hr
== S_OK
, "got %08x\n", hr
);
3792 hr
= IWinHttpRequest_Send( req
, empty
);
3793 ok( hr
== S_OK
, "got %08x\n", hr
);
3795 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3796 ok( hr
== S_OK
, "got %08x\n", hr
);
3798 IWinHttpRequest_Release( req
);
3800 SysFreeString( method
);
3801 SysFreeString( url
);
3802 SysFreeString( username
);
3803 SysFreeString( password
);
3804 SysFreeString( connection
);
3805 SysFreeString( date
);
3806 SysFreeString( today
);
3807 VariantClear( &proxy_server
);
3808 VariantClear( &bypass_list
);
3810 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3811 ok( hr
== S_OK
, "got %08x\n", hr
);
3813 url
= SysAllocString( test_winehq_https
);
3814 method
= SysAllocString( method3W
);
3815 V_VT( &async
) = VT_BOOL
;
3816 V_BOOL( &async
) = VARIANT_FALSE
;
3817 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3818 ok( hr
== S_OK
, "got %08x\n", hr
);
3819 SysFreeString( method
);
3820 SysFreeString( url
);
3822 hr
= IWinHttpRequest_Send( req
, empty
);
3823 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)), "got %08x\n", hr
);
3826 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3827 ok( hr
== S_OK
, "got %08x\n", hr
);
3828 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3829 SysFreeString( response
);
3832 IWinHttpRequest_Release( req
);
3834 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3835 ok( hr
== S_OK
, "got %08x\n", hr
);
3837 sprintf( buf
, "http://localhost:%d/auth", port
);
3838 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, bufW
, sizeof(bufW
)/sizeof(bufW
[0]) );
3839 url
= SysAllocString( bufW
);
3840 method
= SysAllocString( method3W
);
3841 V_VT( &async
) = VT_BOOL
;
3842 V_BOOL( &async
) = VARIANT_FALSE
;
3843 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3844 ok( hr
== S_OK
, "got %08x\n", hr
);
3845 SysFreeString( method
);
3846 SysFreeString( url
);
3848 hr
= IWinHttpRequest_get_Status( req
, &status
);
3849 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3851 V_VT( &data
) = VT_BSTR
;
3852 V_BSTR( &data
) = SysAllocString( test_dataW
);
3853 hr
= IWinHttpRequest_Send( req
, data
);
3854 ok( hr
== S_OK
, "got %08x\n", hr
);
3855 SysFreeString( V_BSTR( &data
) );
3857 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3858 ok( hr
== S_OK
, "got %08x\n", hr
);
3859 ok( !memcmp( response
, unauthW
, sizeof(unauthW
) ), "got %s\n", wine_dbgstr_w(response
) );
3860 SysFreeString( response
);
3862 status
= 0xdeadbeef;
3863 hr
= IWinHttpRequest_get_Status( req
, &status
);
3864 ok( hr
== S_OK
, "got %08x\n", hr
);
3865 ok( status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
3867 IWinHttpRequest_Release( req
);
3872 static void request_get_property(IWinHttpRequest
*request
, int property
, VARIANT
*ret
)
3878 memset(¶ms
, 0, sizeof(params
));
3879 params
.cNamedArgs
= 0;
3880 params
.rgdispidNamedArgs
= NULL
;
3882 params
.rgvarg
= &arg
;
3885 V_I4(&arg
) = property
;
3887 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3888 DISPATCH_PROPERTYGET
, ¶ms
, ret
, NULL
, NULL
);
3889 ok(hr
== S_OK
, "error %#x\n", hr
);
3892 static void test_IWinHttpRequest_Invoke(void)
3894 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
3895 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};
3896 WCHAR openW
[] = {'O','p','e','n',0};
3897 WCHAR optionW
[] = {'O','p','t','i','o','n',0};
3898 OLECHAR
*open
= openW
, *option
= optionW
;
3901 IWinHttpRequest
*request
;
3902 IDispatch
*dispatch
;
3905 VARIANT arg
[3], ret
;
3912 hr
= CLSIDFromProgID(regid
, &clsid
);
3913 ok(hr
== S_OK
, "CLSIDFromProgID error %#x\n", hr
);
3914 bret
= IsEqualIID(&clsid
, &CLSID_WinHttpRequest
);
3915 ok(bret
|| broken(!bret
) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid
));
3917 hr
= CoCreateInstance(&CLSID_WinHttpRequest
, 0, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&request
);
3918 ok(hr
== S_OK
, "error %#x\n", hr
);
3920 hr
= IWinHttpRequest_QueryInterface(request
, &IID_IDispatch
, (void **)&dispatch
);
3921 ok(hr
== S_OK
, "error %#x\n", hr
);
3922 IDispatch_Release(dispatch
);
3924 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &open
, 1, 0x0409, &id
);
3925 ok(hr
== S_OK
, "error %#x\n", hr
);
3926 ok(id
== DISPID_HTTPREQUEST_OPEN
, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id
);
3928 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &option
, 1, 0x0409, &id
);
3929 ok(hr
== S_OK
, "error %#x\n", hr
);
3930 ok(id
== DISPID_HTTPREQUEST_OPTION
, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id
);
3932 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3933 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3934 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3936 memset(¶ms
, 0, sizeof(params
));
3938 params
.cNamedArgs
= 0;
3939 params
.rgvarg
= arg
;
3940 V_VT(&arg
[0]) = VT_I4
;
3941 V_I4(&arg
[0]) = 1252;
3942 V_VT(&arg
[1]) = VT_R8
;
3943 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3945 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3946 DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3947 ok(hr
== S_OK
, "error %#x\n", hr
);
3949 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3950 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3951 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3953 memset(¶ms
, 0, sizeof(params
));
3955 params
.cNamedArgs
= 0;
3956 params
.rgvarg
= arg
;
3957 V_VT(&arg
[0]) = VT_I4
;
3958 V_I4(&arg
[0]) = 1252;
3959 V_VT(&arg
[1]) = VT_R8
;
3960 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3962 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3963 DISPATCH_METHOD
| DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3964 ok(hr
== S_OK
, "error %#x\n", hr
);
3966 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3967 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3968 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
3970 memset(¶ms
, 0, sizeof(params
));
3972 params
.cNamedArgs
= 0;
3973 params
.rgvarg
= arg
;
3974 V_VT(&arg
[0]) = VT_I4
;
3975 V_I4(&arg
[0]) = 1252;
3976 V_VT(&arg
[1]) = VT_R8
;
3977 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3979 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
3980 DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
3981 ok(hr
== S_OK
, "error %#x\n", hr
);
3983 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
3984 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
3985 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
3987 memset(¶ms
, 0, sizeof(params
));
3989 params
.cNamedArgs
= 0;
3990 params
.rgvarg
= arg
;
3991 V_VT(&arg
[0]) = VT_BSTR
;
3992 utf8
= SysAllocString(utf8W
);
3993 V_BSTR(&arg
[0]) = utf8
;
3994 V_VT(&arg
[1]) = VT_R8
;
3995 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
3996 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
3997 ok(hr
== S_OK
, "error %#x\n", hr
);
3999 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4000 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4001 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4004 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, &err
);
4005 ok(hr
== S_OK
, "error %#x\n", hr
);
4007 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4008 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4009 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4012 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4013 ok(hr
== S_OK
, "error %#x\n", hr
);
4015 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4016 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4017 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4019 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
4020 ok(hr
== S_OK
, "error %#x\n", hr
);
4022 hr
= IWinHttpRequest_Invoke(request
, 255, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
4023 ok(hr
== DISP_E_MEMBERNOTFOUND
, "error %#x\n", hr
);
4026 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4027 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
4030 if (0) /* crashes */
4031 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, &ret
, NULL
, &err
);
4034 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4035 ok(hr
== DISP_E_TYPEMISMATCH
, "error %#x\n", hr
);
4037 VariantInit(&arg
[2]);
4039 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4041 ok(hr
== S_OK
, "error %#x\n", hr
);
4043 VariantInit(&arg
[0]);
4044 VariantInit(&arg
[1]);
4045 VariantInit(&arg
[2]);
4048 V_VT(&arg
[0]) = VT_I4
;
4049 V_I4(&arg
[0]) = WinHttpRequestOption_URLCodePage
;
4050 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4051 ok(hr
== S_OK
, "error %#x\n", hr
);
4053 V_VT(&ret
) = 0xdead;
4054 V_I4(&ret
) = 0xbeef;
4055 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, &ret
, NULL
, NULL
);
4056 ok(hr
== S_OK
, "error %#x\n", hr
);
4057 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4058 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4060 V_VT(&ret
) = 0xdead;
4061 V_I4(&ret
) = 0xbeef;
4062 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
4063 ok(hr
== S_OK
, "error %#x\n", hr
);
4064 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4065 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4067 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4068 ok(hr
== S_OK
, "error %#x\n", hr
);
4070 V_VT(&ret
) = 0xdead;
4071 V_I4(&ret
) = 0xbeef;
4072 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, &ret
, NULL
, NULL
);
4073 ok(hr
== S_OK
, "error %#x\n", hr
);
4074 ok(V_VT(&ret
) == VT_EMPTY
, "expected VT_EMPTY, got %d\n", V_VT(&ret
));
4075 ok(V_I4(&ret
) == 0xbeef || V_I4(&ret
) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret
));
4077 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, NULL
, NULL
, NULL
);
4078 ok(hr
== S_OK
, "error %#x\n", hr
);
4080 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4081 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
4084 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4086 ok(hr
== S_OK
, "error %#x\n", hr
);
4089 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4090 ok(hr
== DISP_E_PARAMNOTFOUND
, "error %#x\n", hr
);
4092 SysFreeString(utf8
);
4095 V_VT(&arg
[0]) = VT_I4
;
4096 V_I4(&arg
[0]) = AutoLogonPolicy_Never
;
4098 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY
, &IID_NULL
, 0,
4099 DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
4100 ok(hr
== S_OK
, "error %#x\n", hr
);
4102 IWinHttpRequest_Release(request
);
4107 static void test_WinHttpDetectAutoProxyConfigUrl(void)
4113 if (0) /* crashes on some win2k systems */
4115 SetLastError(0xdeadbeef);
4116 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
4117 error
= GetLastError();
4118 ok( !ret
, "expected failure\n" );
4119 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4122 SetLastError(0xdeadbeef);
4123 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
4124 error
= GetLastError();
4125 ok( !ret
, "expected failure\n" );
4126 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4128 if (0) /* crashes on some win2k systems */
4130 SetLastError(0xdeadbeef);
4131 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
4132 error
= GetLastError();
4133 ok( !ret
, "expected failure\n" );
4134 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4136 url
= (WCHAR
*)0xdeadbeef;
4137 SetLastError(0xdeadbeef);
4138 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
4139 error
= GetLastError();
4142 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4143 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4147 trace("%s\n", wine_dbgstr_w(url
));
4151 url
= (WCHAR
*)0xdeadbeef;
4152 SetLastError(0xdeadbeef);
4153 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
4154 error
= GetLastError();
4157 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4158 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4162 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4163 trace("%s\n", wine_dbgstr_w(url
));
4168 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
4172 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
4174 memset( &cfg
, 0, sizeof(cfg
) );
4176 SetLastError(0xdeadbeef);
4177 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
4178 error
= GetLastError();
4179 ok( !ret
, "expected failure\n" );
4180 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4182 SetLastError(0xdeadbeef);
4183 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
4184 error
= GetLastError();
4185 ok( ret
, "expected success\n" );
4186 ok( error
== ERROR_SUCCESS
|| broken(error
== ERROR_NO_TOKEN
) /* < win7 */, "got %u\n", error
);
4188 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
4189 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
4190 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
4191 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
4192 GlobalFree( cfg
.lpszAutoConfigUrl
);
4193 GlobalFree( cfg
.lpszProxy
);
4194 GlobalFree( cfg
.lpszProxyBypass
);
4197 static void test_WinHttpGetProxyForUrl(void)
4199 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4200 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4201 static const WCHAR emptyW
[] = {0};
4205 WINHTTP_AUTOPROXY_OPTIONS options
;
4206 WINHTTP_PROXY_INFO info
;
4208 memset( &options
, 0, sizeof(options
) );
4210 SetLastError(0xdeadbeef);
4211 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
4212 error
= GetLastError();
4213 ok( !ret
, "expected failure\n" );
4214 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
4216 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4217 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
4219 SetLastError(0xdeadbeef);
4220 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
4221 error
= GetLastError();
4222 ok( !ret
, "expected failure\n" );
4223 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4225 SetLastError(0xdeadbeef);
4226 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
4227 error
= GetLastError();
4228 ok( !ret
, "expected failure\n" );
4229 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4231 SetLastError(0xdeadbeef);
4232 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
4233 error
= GetLastError();
4234 ok( !ret
, "expected failure\n" );
4235 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4237 SetLastError(0xdeadbeef);
4238 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4239 error
= GetLastError();
4240 ok( !ret
, "expected failure\n" );
4241 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4243 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4244 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4246 SetLastError(0xdeadbeef);
4247 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
4248 error
= GetLastError();
4249 ok( !ret
, "expected failure\n" );
4250 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4252 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4253 options
.dwAutoDetectFlags
= 0;
4255 SetLastError(0xdeadbeef);
4256 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4257 error
= GetLastError();
4258 ok( !ret
, "expected failure\n" );
4259 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4261 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
4262 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4264 SetLastError(0xdeadbeef);
4265 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4266 error
= GetLastError();
4267 ok( !ret
, "expected failure\n" );
4268 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4270 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4271 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4273 memset( &info
, 0, sizeof(info
) );
4274 SetLastError(0xdeadbeef);
4275 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4276 error
= GetLastError();
4279 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4280 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4281 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4282 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4283 GlobalFree( info
.lpszProxy
);
4284 GlobalFree( info
.lpszProxyBypass
);
4287 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
4288 options
.dwAutoDetectFlags
= 0;
4289 options
.lpszAutoConfigUrl
= wpadW
;
4291 memset( &info
, 0, sizeof(info
) );
4292 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4295 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4296 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4297 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4298 GlobalFree( info
.lpszProxy
);
4299 GlobalFree( info
.lpszProxyBypass
);
4301 WinHttpCloseHandle( session
);
4304 static void test_chunked_read(void)
4306 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4307 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
4310 HINTERNET ses
, con
= NULL
, req
= NULL
;
4313 trace( "starting chunked read test\n" );
4315 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4316 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
4317 if (!ses
) goto done
;
4319 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
4320 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
4321 if (!con
) goto done
;
4323 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
4324 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4325 if (!req
) goto done
;
4327 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
4328 err
= GetLastError();
4329 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
4331 skip("connection failed, skipping\n");
4334 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4336 ret
= WinHttpReceiveResponse( req
, NULL
);
4337 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4340 len
= sizeof(header
);
4341 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
4342 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4343 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
4344 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
4347 len
= sizeof(header
);
4348 SetLastError( 0xdeadbeef );
4349 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
4350 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
4351 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
4353 trace( "entering query loop\n" );
4357 ret
= WinHttpQueryDataAvailable( req
, &len
);
4358 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4359 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4360 trace( "got %u available\n", len
);
4364 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
4366 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
4368 buf
[bytes_read
] = 0;
4369 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
4370 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
4371 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
4373 HeapFree( GetProcessHeap(), 0, buf
);
4374 if (!bytes_read
) break;
4381 if (req
) WinHttpCloseHandle( req
);
4382 if (con
) WinHttpCloseHandle( con
);
4383 if (ses
) WinHttpCloseHandle( ses
);
4386 START_TEST (winhttp
)
4388 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
4389 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
4390 struct server_info si
;
4396 test_WinHttpTimeFromSystemTime();
4397 test_WinHttpTimeToSystemTime();
4398 test_WinHttpAddHeaders();
4399 test_secure_connection();
4400 test_request_parameter_defaults();
4402 test_set_default_proxy_config();
4403 test_empty_headers_param();
4405 test_resolve_timeout();
4407 test_IWinHttpRequest_Invoke();
4408 test_WinHttpDetectAutoProxyConfigUrl();
4409 test_WinHttpGetIEProxyConfigForCurrentUser();
4410 test_WinHttpGetProxyForUrl();
4411 test_chunked_read();
4413 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
4416 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
4417 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
4419 ret
= WaitForSingleObject(si
.event
, 10000);
4420 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
4421 if (ret
!= WAIT_OBJECT_0
)
4424 test_IWinHttpRequest(si
.port
);
4425 test_connection_info(si
.port
);
4426 test_basic_request(si
.port
, NULL
, basicW
);
4427 test_no_headers(si
.port
);
4428 test_no_content(si
.port
);
4429 test_head_request(si
.port
);
4430 test_not_modified(si
.port
);
4431 test_basic_authentication(si
.port
);
4432 test_multi_authentication(si
.port
);
4433 test_large_data_authentication(si
.port
);
4434 test_bad_header(si
.port
);
4435 test_multiple_reads(si
.port
);
4436 test_cookies(si
.port
);
4438 /* send the basic request again to shutdown the server thread */
4439 test_basic_request(si
.port
, NULL
, quitW
);
4441 WaitForSingleObject(thread
, 3000);