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"
36 #include "wine/heap.h"
38 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
40 static const WCHAR test_useragent
[] =
41 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
42 static const WCHAR test_winehq
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
43 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};
44 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
46 static WCHAR
*a2w(const char *str
)
48 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
49 WCHAR
*ret
= heap_alloc(len
* sizeof(WCHAR
));
50 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
54 static int strcmp_wa(const WCHAR
*str1
, const char *stra
)
56 WCHAR
*str2
= a2w(stra
);
57 int r
= lstrcmpW(str1
, str2
);
62 static BOOL
proxy_active(void)
64 WINHTTP_PROXY_INFO proxy_info
;
67 SetLastError(0xdeadbeef);
68 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
70 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
71 "got %u\n", GetLastError());
72 active
= (proxy_info
.lpszProxy
!= NULL
);
74 GlobalFree(proxy_info
.lpszProxy
);
75 if (proxy_info
.lpszProxyBypass
!= NULL
)
76 GlobalFree(proxy_info
.lpszProxyBypass
);
84 static void test_QueryOption(void)
87 HINTERNET session
, request
, connection
;
90 SetLastError(0xdeadbeef);
91 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
92 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
94 SetLastError(0xdeadbeef);
95 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
96 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
97 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
98 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
101 SetLastError(0xdeadbeef);
102 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
103 ok(!ret
, "should fail to query option\n");
104 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
105 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
106 ok(size
== 4, "expected 4, got %u\n", size
);
108 feature
= 0xdeadbeef;
109 size
= sizeof(feature
) - 1;
110 SetLastError(0xdeadbeef);
111 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
112 ok(!ret
, "should fail to query option\n");
113 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
114 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
115 ok(size
== 4, "expected 4, got %u\n", size
);
117 feature
= 0xdeadbeef;
118 size
= sizeof(feature
) + 1;
119 SetLastError(0xdeadbeef);
120 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
121 ok(ret
, "failed to query option %u\n", GetLastError());
122 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
123 "got %u\n", GetLastError());
124 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
125 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
126 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
128 SetLastError(0xdeadbeef);
129 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
130 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
131 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
132 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
134 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
135 SetLastError(0xdeadbeef);
136 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
137 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
138 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
139 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
141 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
142 SetLastError(0xdeadbeef);
143 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
144 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
145 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
146 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
148 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
149 SetLastError(0xdeadbeef);
150 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
151 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
153 feature
= 0xdeadbeef;
154 size
= sizeof(feature
);
155 SetLastError(0xdeadbeef);
156 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
157 ok(ret
, "failed to query option %u\n", GetLastError());
158 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
159 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
161 feature
= WINHTTP_DISABLE_COOKIES
;
162 SetLastError(0xdeadbeef);
163 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
164 ok(!ret
, "should fail to set disable feature for a session\n");
165 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
166 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
168 SetLastError(0xdeadbeef);
169 connection
= WinHttpConnect(session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
170 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
172 feature
= WINHTTP_DISABLE_COOKIES
;
173 SetLastError(0xdeadbeef);
174 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
175 ok(!ret
, "should fail to set disable feature for a connection\n");
176 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
177 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
179 SetLastError(0xdeadbeef);
180 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
181 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
182 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
184 skip("Network unreachable, skipping the test\n");
188 feature
= 0xdeadbeef;
189 size
= sizeof(feature
);
190 SetLastError(0xdeadbeef);
191 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
192 ok(!ret
, "should fail to query disable feature for a request\n");
193 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
194 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
197 size
= sizeof(feature
);
198 SetLastError(0xdeadbeef);
199 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
200 ok(ret
, "failed to set feature %u\n", GetLastError());
202 feature
= 0xffffffff;
203 size
= sizeof(feature
);
204 SetLastError(0xdeadbeef);
205 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
206 ok(ret
, "failed to set feature %u\n", GetLastError());
208 feature
= WINHTTP_DISABLE_COOKIES
;
209 size
= sizeof(feature
);
210 SetLastError(0xdeadbeef);
211 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
212 ok(ret
, "failed to set feature %u\n", GetLastError());
215 SetLastError(0xdeadbeef);
216 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
217 ok(!ret
, "should fail to query disable feature for a request\n");
218 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
219 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
221 feature
= 0xdeadbeef;
222 size
= sizeof(feature
);
223 SetLastError(0xdeadbeef);
224 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_ENABLE_FEATURE
, &feature
, &size
);
225 ok(!ret
, "should fail to query enabled features for a request\n");
226 ok(feature
== 0xdeadbeef, "expect feature 0xdeadbeef, got %u\n", feature
);
227 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
229 feature
= WINHTTP_ENABLE_SSL_REVOCATION
;
230 SetLastError(0xdeadbeef);
231 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_ENABLE_FEATURE
, 0, sizeof(feature
));
232 ok(!ret
, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
233 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
235 SetLastError(0xdeadbeef);
236 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_ENABLE_FEATURE
, &feature
, 0);
237 ok(!ret
, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
238 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
240 SetLastError(0xdeadbeef);
241 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_ENABLE_FEATURE
, &feature
, sizeof(feature
));
242 ok(ret
, "failed to set feature\n");
243 ok(GetLastError() == NO_ERROR
|| broken(GetLastError() == 0xdeadbeef), /* Doesn't set error code on Vista or older */
244 "expected NO_ERROR, got %u\n", GetLastError());
246 feature
= 0xdeadbeef;
247 SetLastError(0xdeadbeef);
248 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_ENABLE_FEATURE
, &feature
, sizeof(feature
));
249 ok(!ret
, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
250 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
253 size
= sizeof(feature
);
254 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONNECT_RETRIES
, &feature
, sizeof(feature
));
255 ok(ret
, "failed to set WINHTTP_OPTION_CONNECT_RETRIES %u\n", GetLastError());
257 SetLastError(0xdeadbeef);
258 ret
= WinHttpCloseHandle(request
);
259 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
262 SetLastError(0xdeadbeef);
263 ret
= WinHttpCloseHandle(connection
);
264 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
265 SetLastError(0xdeadbeef);
266 ret
= WinHttpCloseHandle(session
);
267 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
270 static void test_OpenRequest (void)
273 HINTERNET session
, request
, connection
;
276 SetLastError(0xdeadbeef);
277 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
278 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
279 err
= GetLastError();
280 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
281 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
283 /* Test with a bad server name */
284 SetLastError(0xdeadbeef);
285 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
286 err
= GetLastError();
287 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
288 ok(err
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err
);
290 /* Test with a valid server name */
291 SetLastError(0xdeadbeef);
292 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
293 err
= GetLastError();
294 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", err
);
295 ok(err
== ERROR_SUCCESS
|| broken(err
== WSAEINVAL
) /* < win7 */, "got %u\n", err
);
297 SetLastError(0xdeadbeef);
298 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
299 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
300 err
= GetLastError();
301 if (request
== NULL
&& err
== ERROR_WINHTTP_NAME_NOT_RESOLVED
)
303 skip("Network unreachable, skipping.\n");
306 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", err
);
307 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
309 SetLastError(0xdeadbeef);
310 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
311 err
= GetLastError();
312 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
314 skip("Connection failed, skipping.\n");
317 ok(ret
, "WinHttpSendRequest failed: %u\n", err
);
318 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
320 SetLastError(0xdeadbeef);
321 ret
= WinHttpCloseHandle(request
);
322 err
= GetLastError();
323 ok(ret
, "WinHttpCloseHandle failed on closing request, got %u.\n", err
);
324 ok(err
== ERROR_SUCCESS
, "got %u\n", err
);
327 ret
= WinHttpCloseHandle(connection
);
328 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
329 ret
= WinHttpCloseHandle(session
);
330 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
334 static void test_empty_headers_param(void)
336 static const WCHAR empty
[] = {0};
337 HINTERNET ses
, con
, req
;
341 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
342 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
344 con
= WinHttpConnect(ses
, test_winehq
, 80, 0);
345 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
347 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
348 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
350 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
351 err
= GetLastError();
352 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
354 skip("connection failed, skipping\n");
357 ok(ret
, "failed to send request %u\n", GetLastError());
360 WinHttpCloseHandle(req
);
361 WinHttpCloseHandle(con
);
362 WinHttpCloseHandle(ses
);
365 static void test_SendRequest (void)
367 static const WCHAR content_type
[] =
368 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
369 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
370 static const WCHAR test_file
[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
371 static const WCHAR test_verb
[] = {'P','O','S','T',0};
372 static CHAR post_data
[] = "mode=Test";
373 static const char test_post
[] = "mode => Test\0\n";
374 HINTERNET session
, request
, connection
;
375 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
, err
, disable
;
382 total_len
= optional_len
= sizeof(post_data
);
383 memset(buffer
, 0xff, sizeof(buffer
));
385 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
386 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
387 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
389 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
390 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
392 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
393 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
394 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
396 skip("Network unreachable, skipping.\n");
399 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
400 if (!request
) goto done
;
402 context
= 0xdeadbeef;
403 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
404 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
406 /* writing more data than promised by the content-length header causes an error when the connection
407 is resued, so disable keep-alive */
408 disable
= WINHTTP_DISABLE_KEEP_ALIVE
;
409 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &disable
, sizeof(disable
));
410 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
413 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
414 err
= GetLastError();
415 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
417 skip("connection failed, skipping\n");
420 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
423 size
= sizeof(context
);
424 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
425 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
426 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
428 for (i
= 3; post_data
[i
]; i
++)
431 SetLastError(0xdeadbeef);
432 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
435 ok(GetLastError() == ERROR_SUCCESS
, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
436 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
438 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
440 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
441 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
445 SetLastError(0xdeadbeef);
446 ret
= WinHttpReceiveResponse(request
, NULL
);
447 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == ERROR_NO_TOKEN
) /* < win7 */,
448 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
449 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
452 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
453 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
455 ok(bytes_rw
== sizeof(test_post
) - 1, "Read %u bytes\n", bytes_rw
);
456 ok(!memcmp(buffer
, test_post
, sizeof(test_post
) - 1), "Data read did not match.\n");
459 ret
= WinHttpCloseHandle(request
);
460 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
461 ret
= WinHttpCloseHandle(connection
);
462 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
463 ret
= WinHttpCloseHandle(session
);
464 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
467 static void test_WinHttpTimeFromSystemTime(void)
470 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
471 static const WCHAR expected_string
[] =
472 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
473 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
474 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
477 SetLastError(0xdeadbeef);
478 ret
= WinHttpTimeFromSystemTime(&time
, NULL
);
479 err
= GetLastError();
480 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
481 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
483 SetLastError(0xdeadbeef);
484 ret
= WinHttpTimeFromSystemTime(NULL
, time_string
);
485 err
= GetLastError();
486 ok(!ret
, "WinHttpTimeFromSystemTime succeeded\n");
487 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
489 SetLastError(0xdeadbeef);
490 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
491 err
= GetLastError();
492 ok(ret
, "WinHttpTimeFromSystemTime failed: %u\n", err
);
493 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
494 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
495 "Time string returned did not match expected time string.\n");
498 static void test_WinHttpTimeToSystemTime(void)
502 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
503 static const WCHAR time_string1
[] =
504 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
505 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
506 static const WCHAR time_string2
[] =
507 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
508 '1','0',' ','0','5',' ','5','2','\n',0};
511 SetLastError(0xdeadbeef);
512 ret
= WinHttpTimeToSystemTime(time_string1
, NULL
);
513 err
= GetLastError();
514 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
515 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
517 SetLastError(0xdeadbeef);
518 ret
= WinHttpTimeToSystemTime(NULL
, &time
);
519 err
= GetLastError();
520 ok(!ret
, "WinHttpTimeToSystemTime succeeded\n");
521 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
523 SetLastError(0xdeadbeef);
524 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
525 err
= GetLastError();
526 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
527 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
528 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
529 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
531 SetLastError(0xdeadbeef);
532 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
533 err
= GetLastError();
534 ok(ret
, "WinHttpTimeToSystemTime failed: %u\n", err
);
535 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
536 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
537 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
540 static void test_WinHttpAddHeaders(void)
542 HINTERNET session
, request
, connection
;
544 WCHAR buffer
[MAX_PATH
];
545 WCHAR check_buffer
[MAX_PATH
];
546 DWORD err
, index
, len
, oldlen
;
548 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
549 static const WCHAR test_verb
[] = {'P','O','S','T',0};
550 static const WCHAR test_header_begin
[] =
551 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
552 static const WCHAR full_path_test_header_begin
[] =
553 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
554 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
555 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
556 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
557 static const WCHAR test_header_name2
[] = {'n','a','m','e',0};
558 static const WCHAR test_header_name3
[] = {'a',0};
559 static const WCHAR test_header_range
[] = {'R','a','n','g','e',0};
560 static const WCHAR test_header_range_bytes
[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
561 static const WCHAR test_header_bytes
[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
563 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
564 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
565 static const WCHAR test_flag_coalesce_comma
[] =
566 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
567 static const WCHAR test_flag_coalesce_comma_reverse
[] =
568 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
569 static const WCHAR test_flag_coalesce_semicolon
[] =
570 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
571 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
572 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
574 static const WCHAR field
[] = {'f','i','e','l','d',0};
575 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
576 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
577 static const WCHAR empty
[] = {0};
579 static const WCHAR test_headers
[][14] =
581 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
582 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
583 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
584 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
585 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
586 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
587 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
593 {' ','e',' ',':','f',0},
594 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
595 {'n','a','m','e',':',' ','v','a','l','u','e',0},
596 {'n','a','m','e',':',0}
598 static const WCHAR test_indices
[][6] =
600 {'t','e','s','t','1',0},
601 {'t','e','s','t','2',0},
602 {'t','e','s','t','3',0},
603 {'t','e','s','t','4',0}
606 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
607 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
608 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
610 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
611 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
613 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
614 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
615 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
617 skip("Network unreachable, skipping.\n");
620 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
623 len
= sizeof(buffer
);
624 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
625 test_header_name
, buffer
, &len
, &index
);
626 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
627 SetLastError(0xdeadbeef);
628 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
629 err
= GetLastError();
630 ok(ret
, "WinHttpAddRequestHeaders failed to add new header, got %d with error %u.\n", ret
, err
);
631 ok(err
== ERROR_SUCCESS
|| broken(err
== 0xdeadbeef) /* < win7 */, "got %u\n", err
);
634 len
= sizeof(buffer
);
635 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
636 test_header_name
, buffer
, &len
, &index
);
637 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
638 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
639 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
640 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
642 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
643 test_header_name
, buffer
, &len
, &index
);
644 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
646 /* Try to fetch the header info with a buffer that's big enough to fit the
647 * string but not the NULL terminator.
650 len
= 5*sizeof(WCHAR
);
651 memset(check_buffer
, 0xab, sizeof(check_buffer
));
652 memcpy(buffer
, check_buffer
, sizeof(buffer
));
653 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
654 test_header_name
, buffer
, &len
, &index
);
655 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
656 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
657 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
658 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
660 /* Try with a NULL buffer */
662 len
= sizeof(buffer
);
663 SetLastError(0xdeadbeef);
664 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
665 test_header_name
, NULL
, &len
, &index
);
666 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
667 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
668 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
669 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
671 /* Try with a NULL buffer and a length that's too small */
674 SetLastError(0xdeadbeef);
675 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
676 test_header_name
, NULL
, &len
, &index
);
677 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
678 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
679 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
680 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
681 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
685 SetLastError(0xdeadbeef);
686 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
687 test_header_name
, NULL
, &len
, &index
);
688 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
689 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
690 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
691 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
692 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
697 len
= sizeof(buffer
);
698 memset(buffer
, 0xff, sizeof(buffer
));
699 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
700 test_header_name
, buffer
, &len
, &index
);
701 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
702 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
703 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
704 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
705 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
706 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
707 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
708 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
709 "WinHttpQueryHeaders returned invalid end of header string.\n");
710 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
714 SetLastError(0xdeadbeef);
715 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
716 test_header_name
, NULL
, &len
, &index
);
717 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
718 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
719 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
720 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
721 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
725 len
= sizeof(buffer
);
726 memset(buffer
, 0xff, sizeof(buffer
));
727 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
728 test_header_name
, buffer
, &len
, &index
);
729 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
730 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
731 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
732 "no double NULL terminator\n");
733 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
734 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
735 "invalid beginning of header string.\n");
736 ok(index
== 0, "header index was incremented\n");
738 /* tests for more indices */
739 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
740 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
743 len
= sizeof(buffer
);
744 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
745 test_header_name
, buffer
, &len
, &index
);
746 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
747 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
748 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
750 len
= sizeof(buffer
);
751 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
752 test_header_name
, buffer
, &len
, &index
);
753 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
754 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
755 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
757 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
758 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
761 len
= sizeof(buffer
);
762 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
763 test_header_name
, buffer
, &len
, &index
);
764 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
765 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
766 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
767 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
769 len
= sizeof(buffer
);
770 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
771 test_header_name
, buffer
, &len
, &index
);
772 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
773 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
774 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
776 /* add if new flag */
777 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
778 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
781 len
= sizeof(buffer
);
782 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
783 test_header_name
, buffer
, &len
, &index
);
784 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
785 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
786 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
788 len
= sizeof(buffer
);
789 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
790 test_header_name
, buffer
, &len
, &index
);
791 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
792 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
793 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
795 len
= sizeof(buffer
);
796 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
797 test_header_name
, buffer
, &len
, &index
);
798 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
801 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
802 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
805 len
= sizeof(buffer
);
806 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
807 test_header_name
, buffer
, &len
, &index
);
808 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
809 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
810 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
811 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
813 len
= sizeof(buffer
);
814 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
815 test_header_name
, buffer
, &len
, &index
);
816 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
817 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
818 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
820 len
= sizeof(buffer
);
821 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
822 test_header_name
, buffer
, &len
, &index
);
823 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
825 /* coalesce with comma flag */
826 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
827 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
830 len
= sizeof(buffer
);
831 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
832 test_header_name
, buffer
, &len
, &index
);
833 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
834 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
835 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
836 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
837 "WinHttpQueryHeaders returned incorrect string.\n");
839 len
= sizeof(buffer
);
840 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
841 test_header_name
, buffer
, &len
, &index
);
842 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
843 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
844 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
846 len
= sizeof(buffer
);
847 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
848 test_header_name
, buffer
, &len
, &index
);
849 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
852 /* coalesce with semicolon flag */
853 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
854 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
857 len
= sizeof(buffer
);
858 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
859 test_header_name
, buffer
, &len
, &index
);
860 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
861 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
862 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
863 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
864 "WinHttpQueryHeaders returned incorrect string.\n");
866 len
= sizeof(buffer
);
867 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
868 test_header_name
, buffer
, &len
, &index
);
869 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
870 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
871 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
873 len
= sizeof(buffer
);
874 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
875 test_header_name
, buffer
, &len
, &index
);
876 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
878 /* add and replace flags */
879 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
880 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
883 len
= sizeof(buffer
);
884 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
885 test_header_name
, buffer
, &len
, &index
);
886 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
887 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
888 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
890 len
= sizeof(buffer
);
891 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
892 test_header_name
, buffer
, &len
, &index
);
893 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
894 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
895 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
897 len
= sizeof(buffer
);
898 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
899 test_header_name
, buffer
, &len
, &index
);
900 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
902 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
903 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
905 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
906 ok(ret
, "WinHttpAddRequestHeaders failed\n");
909 memset(buffer
, 0xff, sizeof(buffer
));
910 len
= sizeof(buffer
);
911 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
912 test_header_name3
, buffer
, &len
, &index
);
913 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
914 ok(!memcmp(buffer
, empty
, sizeof(empty
)), "unexpected result\n");
916 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
917 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
919 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
920 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
922 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
923 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
925 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
926 ok(ret
, "WinHttpAddRequestHeaders failed\n");
930 len
= sizeof(buffer
);
931 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
932 field
, buffer
, &len
, &index
);
933 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
934 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
936 SetLastError(0xdeadbeef);
937 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, 0,
938 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
939 err
= GetLastError();
940 ok(!ret
, "unexpected success\n");
941 ok(err
== ERROR_INVALID_PARAMETER
, "got %u\n", err
);
943 ret
= WinHttpAddRequestHeaders(request
, test_header_range_bytes
, ~0u,
944 WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
945 ok(ret
, "failed to add header: %u\n", GetLastError());
948 len
= sizeof(buffer
);
949 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
950 test_header_range
, buffer
, &len
, &index
);
951 ok(ret
, "failed to get range header %u\n", GetLastError());
952 ok(!memcmp(buffer
, test_header_bytes
, sizeof(test_header_bytes
)), "incorrect string returned\n");
953 ok(len
== lstrlenW(test_header_bytes
) * sizeof(WCHAR
), "wrong length %u\n", len
);
954 ok(index
== 1, "wrong index %u\n", index
);
957 len
= sizeof(buffer
);
958 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
959 test_header_name2
, buffer
, &len
, &index
);
960 ok(!ret
, "unexpected success\n");
962 SetLastError(0xdeadbeef);
963 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
964 err
= GetLastError();
965 ok(!ret
, "unexpected success\n");
966 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
968 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
969 ok(ret
, "got %u\n", GetLastError());
972 len
= sizeof(buffer
);
973 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
974 test_header_name2
, buffer
, &len
, &index
);
975 ok(ret
, "got %u\n", GetLastError());
976 ok(index
== 1, "wrong index %u\n", index
);
977 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
979 ret
= WinHttpAddRequestHeaders(request
, test_headers
[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE
);
980 ok(ret
, "got %u\n", GetLastError());
983 len
= sizeof(buffer
);
984 SetLastError(0xdeadbeef);
985 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
986 test_header_name2
, buffer
, &len
, &index
);
987 err
= GetLastError();
988 ok(!ret
, "unexpected success\n");
989 ok(err
== ERROR_WINHTTP_HEADER_NOT_FOUND
, "got %u\n", err
);
991 ret
= WinHttpAddRequestHeaders(request
, test_headers
[14], -1L, 0);
992 ok(ret
, "got %u\n", GetLastError());
995 len
= sizeof(buffer
);
996 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
997 test_header_name2
, buffer
, &len
, &index
);
998 ok(ret
, "got %u\n", GetLastError());
999 ok(index
== 1, "wrong index %u\n", index
);
1000 ok(!memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "incorrect string\n");
1002 ret
= WinHttpCloseHandle(request
);
1003 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
1005 ret
= WinHttpCloseHandle(connection
);
1006 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
1007 ret
= WinHttpCloseHandle(session
);
1008 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
1012 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
1014 DWORD flags
= *(DWORD
*)buf
;
1018 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
1021 #define X(x) if (flags & x) trace("%s\n", #x);
1022 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
1023 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
1024 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
1025 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
1026 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
1027 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
1028 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
1032 static void test_secure_connection(void)
1034 static const char data_start
[] = "<!DOCTYPE html PUBLIC";
1035 HINTERNET ses
, con
, req
;
1036 DWORD size
, status
, policy
, bitness
, read_size
, err
, available_size
, protocols
;
1039 WINHTTP_CERTIFICATE_INFO info
;
1042 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1043 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1045 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
1046 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
1047 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
1049 protocols
= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
;
1050 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SECURE_PROTOCOLS
, &protocols
, sizeof(protocols
));
1051 err
= GetLastError();
1052 ok(ret
|| err
== ERROR_INVALID_PARAMETER
/* < win7 */, "failed to set protocols %u\n", err
);
1054 con
= WinHttpConnect(ses
, test_winehq
, 443, 0);
1055 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1057 /* try without setting WINHTTP_FLAG_SECURE */
1058 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1059 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1061 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1062 err
= GetLastError();
1063 ok(!ret
, "unexpected success\n");
1064 ok(err
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
|| broken(err
== ERROR_INVALID_PARAMETER
) /* winxp */,
1065 "setting client cert context returned %u\n", err
);
1067 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1068 err
= GetLastError();
1069 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
1071 skip("Connection failed, skipping.\n");
1074 ok(ret
, "failed to send request %u\n", GetLastError());
1076 ret
= WinHttpReceiveResponse(req
, NULL
);
1077 ok(ret
, "failed to receive response %u\n", GetLastError());
1079 status
= 0xdeadbeef;
1080 size
= sizeof(status
);
1081 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1082 ok(ret
, "header query failed %u\n", GetLastError());
1083 ok(status
== HTTP_STATUS_BAD_REQUEST
, "got %u\n", status
);
1085 WinHttpCloseHandle(req
);
1087 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
1088 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1090 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CLIENT_CERT_CONTEXT
, WINHTTP_NO_CLIENT_CERT_CONTEXT
, 0);
1091 err
= GetLastError();
1092 ok(ret
|| broken(!ret
&& err
== ERROR_INVALID_PARAMETER
) /* winxp */, "failed to set client cert context %u\n", err
);
1094 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
1096 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1097 err
= GetLastError();
1098 if (!ret
&& (err
== ERROR_WINHTTP_SECURE_FAILURE
|| err
== ERROR_WINHTTP_CANNOT_CONNECT
||
1099 err
== ERROR_WINHTTP_TIMEOUT
))
1101 skip("secure connection failed, skipping remaining secure tests\n");
1104 ok(ret
, "failed to send request %u\n", GetLastError());
1106 size
= sizeof(cert
);
1107 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1108 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1109 if (ret
) CertFreeCertificateContext(cert
);
1111 size
= sizeof(bitness
);
1112 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
1113 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
1115 size
= sizeof(info
);
1116 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
1117 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
1121 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
1122 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
1123 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
1124 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
1125 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
1126 trace("dwKeySize %u\n", info
.dwKeySize
);
1127 LocalFree( info
.lpszSubjectInfo
);
1128 LocalFree( info
.lpszIssuerInfo
);
1131 ret
= WinHttpReceiveResponse(req
, NULL
);
1132 ok(ret
, "failed to receive response %u\n", GetLastError());
1135 ret
= WinHttpQueryDataAvailable(req
, &available_size
);
1136 ok(ret
, "failed to query available data %u\n", GetLastError());
1137 ok(available_size
> 2014, "available_size = %u\n", available_size
);
1139 status
= 0xdeadbeef;
1140 size
= sizeof(status
);
1141 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1142 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1143 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1146 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
1147 ok(!ret
, "succeeded unexpectedly\n");
1153 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
1154 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
1158 if (read_size
<= 32)
1159 ok(!memcmp(buffer
, data_start
, sizeof(data_start
)-1), "not expected: %.32s\n", buffer
);
1161 ok(read_size
>= available_size
, "read_size = %u, available_size = %u\n", read_size
, available_size
);
1163 size
= sizeof(cert
);
1164 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
1165 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
1166 if (ret
) CertFreeCertificateContext(cert
);
1169 WinHttpCloseHandle(req
);
1170 WinHttpCloseHandle(con
);
1171 WinHttpCloseHandle(ses
);
1174 static void test_request_parameter_defaults(void)
1176 static const WCHAR empty
[] = {0};
1177 HINTERNET ses
, con
, req
;
1178 DWORD size
, status
, error
;
1182 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1183 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1185 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1186 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1188 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1189 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1191 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1192 error
= GetLastError();
1193 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1195 skip("connection failed, skipping\n");
1198 ok(ret
, "failed to send request %u\n", GetLastError());
1200 ret
= WinHttpReceiveResponse(req
, NULL
);
1201 if (!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE
) /* win2k */
1203 win_skip("invalid response\n");
1206 ok(ret
, "failed to receive response %u\n", GetLastError());
1208 status
= 0xdeadbeef;
1209 size
= sizeof(status
);
1210 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1211 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1212 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1214 WinHttpCloseHandle(req
);
1216 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
1217 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1219 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1220 error
= GetLastError();
1221 if (!ret
&& (error
== ERROR_WINHTTP_CANNOT_CONNECT
|| error
== ERROR_WINHTTP_TIMEOUT
))
1223 skip("connection failed, skipping\n");
1226 ok(ret
, "failed to send request %u\n", GetLastError());
1228 ret
= WinHttpReceiveResponse(req
, NULL
);
1229 ok(ret
, "failed to receive response %u\n", GetLastError());
1232 SetLastError(0xdeadbeef);
1233 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
1234 error
= GetLastError();
1235 ok(!ret
, "succeeded unexpectedly\n");
1236 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
1238 version
= HeapAlloc(GetProcessHeap(), 0, size
);
1239 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
1240 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1241 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
1242 HeapFree(GetProcessHeap(), 0, version
);
1244 status
= 0xdeadbeef;
1245 size
= sizeof(status
);
1246 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1247 ok(ret
, "failed unexpectedly %u\n", GetLastError());
1248 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
1251 WinHttpCloseHandle(req
);
1252 WinHttpCloseHandle(con
);
1253 WinHttpCloseHandle(ses
);
1256 static const WCHAR Connections
[] = {
1257 'S','o','f','t','w','a','r','e','\\',
1258 'M','i','c','r','o','s','o','f','t','\\',
1259 'W','i','n','d','o','w','s','\\',
1260 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1261 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1262 'C','o','n','n','e','c','t','i','o','n','s',0 };
1263 static const WCHAR WinHttpSettings
[] = {
1264 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1266 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
1272 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
1277 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1281 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1291 static void set_proxy( REGSAM access
, BYTE
*buf
, DWORD len
, DWORD type
)
1294 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0, access
, NULL
, &hkey
, NULL
))
1296 if (len
) RegSetValueExW( hkey
, WinHttpSettings
, 0, type
, buf
, len
);
1297 else RegDeleteValueW( hkey
, WinHttpSettings
);
1298 RegCloseKey( hkey
);
1302 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1305 IsWow64Process( GetCurrentProcess(), &wow64
);
1306 if (sizeof(void *) > sizeof(int) || wow64
)
1308 set_proxy( KEY_WRITE
|KEY_WOW64_64KEY
, buf
, len
, type
);
1309 set_proxy( KEY_WRITE
|KEY_WOW64_32KEY
, buf
, len
, type
);
1312 set_proxy( KEY_WRITE
, buf
, len
, type
);
1315 static void test_set_default_proxy_config(void)
1317 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1318 static WCHAR normalString
[] = { 'f','o','o',0 };
1320 BYTE
*saved_proxy_settings
= NULL
;
1321 WINHTTP_PROXY_INFO info
;
1324 /* FIXME: it would be simpler to read the current settings using
1325 * WinHttpGetDefaultProxyConfiguration and save them using
1326 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1328 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1329 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1330 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1331 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1332 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1333 * the lpszProxy and lpszProxyBypass values are ignored.
1334 * Thus, if a proxy is set with proxycfg, then calling
1335 * WinHttpGetDefaultProxyConfiguration followed by
1336 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1337 * getting deleted from the registry.
1339 * Instead I read the current registry value and restore it directly.
1341 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1344 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1345 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1350 /* Crashes on Vista and higher */
1351 SetLastError(0xdeadbeef);
1352 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1353 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1354 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1357 /* test with invalid access type */
1358 info
.dwAccessType
= 0xdeadbeef;
1359 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1360 SetLastError(0xdeadbeef);
1361 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1362 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1363 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1365 /* at a minimum, the proxy server must be set */
1366 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1367 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1368 SetLastError(0xdeadbeef);
1369 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1370 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1371 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1372 info
.lpszProxyBypass
= normalString
;
1373 SetLastError(0xdeadbeef);
1374 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1375 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1376 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1378 /* the proxy server can't have wide characters */
1379 info
.lpszProxy
= wideString
;
1380 SetLastError(0xdeadbeef);
1381 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1382 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1383 skip("couldn't set default proxy configuration: access denied\n");
1385 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1386 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1387 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1389 info
.lpszProxy
= normalString
;
1390 SetLastError(0xdeadbeef);
1391 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1392 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1393 skip("couldn't set default proxy configuration: access denied\n");
1396 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1397 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1398 "got %u\n", GetLastError());
1400 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1403 static void test_timeouts(void)
1407 HINTERNET ses
, req
, con
;
1409 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1410 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1412 SetLastError(0xdeadbeef);
1413 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1414 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1415 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1417 SetLastError(0xdeadbeef);
1418 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1419 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1420 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1422 SetLastError(0xdeadbeef);
1423 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1424 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1425 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1427 SetLastError(0xdeadbeef);
1428 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1429 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1430 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1432 SetLastError(0xdeadbeef);
1433 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1434 ok(ret
, "%u\n", GetLastError());
1435 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1436 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1438 SetLastError(0xdeadbeef);
1439 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1440 ok(ret
, "%u\n", GetLastError());
1442 SetLastError(0xdeadbeef);
1443 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1444 ok(ret
, "%u\n", GetLastError());
1446 SetLastError(0xdeadbeef);
1448 size
= sizeof(DWORD
);
1449 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1450 ok(ret
, "%u\n", GetLastError());
1451 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1453 SetLastError(0xdeadbeef);
1455 size
= sizeof(DWORD
);
1456 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1457 ok(ret
, "%u\n", GetLastError());
1458 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1460 SetLastError(0xdeadbeef);
1462 size
= sizeof(DWORD
);
1463 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1464 ok(ret
, "%u\n", GetLastError());
1465 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1467 SetLastError(0xdeadbeef);
1469 size
= sizeof(DWORD
);
1470 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1471 ok(ret
, "%u\n", GetLastError());
1472 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1474 SetLastError(0xdeadbeef);
1476 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1477 ok(ret
, "%u\n", GetLastError());
1479 SetLastError(0xdeadbeef);
1481 size
= sizeof(DWORD
);
1482 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1483 ok(ret
, "%u\n", GetLastError());
1484 ok(value
== 0, "Expected 0, got %u\n", value
);
1486 SetLastError(0xdeadbeef);
1488 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1489 ok(ret
, "%u\n", GetLastError());
1491 SetLastError(0xdeadbeef);
1493 size
= sizeof(DWORD
);
1494 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1495 ok(ret
, "%u\n", GetLastError());
1496 ok(value
== 0, "Expected 0, got %u\n", value
);
1498 SetLastError(0xdeadbeef);
1500 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1501 ok(ret
, "%u\n", GetLastError());
1503 SetLastError(0xdeadbeef);
1505 size
= sizeof(DWORD
);
1506 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1507 ok(ret
, "%u\n", GetLastError());
1508 ok(value
== 0, "Expected 0, got %u\n", value
);
1510 SetLastError(0xdeadbeef);
1512 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1513 ok(ret
, "%u\n", GetLastError());
1515 SetLastError(0xdeadbeef);
1517 size
= sizeof(DWORD
);
1518 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1519 ok(ret
, "%u\n", GetLastError());
1520 ok(value
== 0, "Expected 0, got %u\n", value
);
1522 SetLastError(0xdeadbeef);
1524 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1525 ok(ret
, "%u\n", GetLastError());
1527 SetLastError(0xdeadbeef);
1529 size
= sizeof(DWORD
);
1530 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1531 ok(ret
, "%u\n", GetLastError());
1532 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1534 SetLastError(0xdeadbeef);
1536 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1537 ok(ret
, "%u\n", GetLastError());
1539 SetLastError(0xdeadbeef);
1541 size
= sizeof(DWORD
);
1542 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1543 ok(ret
, "%u\n", GetLastError());
1544 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1546 SetLastError(0xdeadbeef);
1548 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1549 ok(ret
, "%u\n", GetLastError());
1551 SetLastError(0xdeadbeef);
1553 size
= sizeof(DWORD
);
1554 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1555 ok(ret
, "%u\n", GetLastError());
1556 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1558 SetLastError(0xdeadbeef);
1560 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1561 ok(ret
, "%u\n", GetLastError());
1563 SetLastError(0xdeadbeef);
1565 size
= sizeof(DWORD
);
1566 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1567 ok(ret
, "%u\n", GetLastError());
1568 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1570 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1571 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1573 /* Timeout values should match the last one set for session */
1574 SetLastError(0xdeadbeef);
1576 size
= sizeof(DWORD
);
1577 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1578 ok(ret
, "%u\n", GetLastError());
1579 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1581 SetLastError(0xdeadbeef);
1583 size
= sizeof(DWORD
);
1584 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1585 ok(ret
, "%u\n", GetLastError());
1586 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1588 SetLastError(0xdeadbeef);
1590 size
= sizeof(DWORD
);
1591 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1592 ok(ret
, "%u\n", GetLastError());
1593 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1595 SetLastError(0xdeadbeef);
1597 size
= sizeof(DWORD
);
1598 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1599 ok(ret
, "%u\n", GetLastError());
1600 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1602 SetLastError(0xdeadbeef);
1603 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1604 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1605 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1607 SetLastError(0xdeadbeef);
1608 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1609 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1610 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1612 SetLastError(0xdeadbeef);
1613 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1614 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1615 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1617 SetLastError(0xdeadbeef);
1618 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1619 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1620 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1622 SetLastError(0xdeadbeef);
1623 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1624 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1625 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1627 SetLastError(0xdeadbeef);
1628 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1629 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1630 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1632 SetLastError(0xdeadbeef);
1634 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1635 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1636 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1638 SetLastError(0xdeadbeef);
1640 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1641 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1642 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1644 SetLastError(0xdeadbeef);
1646 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1647 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1648 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1650 SetLastError(0xdeadbeef);
1652 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1653 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1654 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1656 /* Changing timeout values for session should affect the values for connection */
1657 SetLastError(0xdeadbeef);
1659 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1660 ok(ret
, "%u\n", GetLastError());
1662 SetLastError(0xdeadbeef);
1664 size
= sizeof(DWORD
);
1665 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1666 ok(ret
, "%u\n", GetLastError());
1667 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1669 SetLastError(0xdeadbeef);
1671 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1672 ok(ret
, "%u\n", GetLastError());
1674 SetLastError(0xdeadbeef);
1676 size
= sizeof(DWORD
);
1677 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1678 ok(ret
, "%u\n", GetLastError());
1679 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1681 SetLastError(0xdeadbeef);
1683 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1684 ok(ret
, "%u\n", GetLastError());
1686 SetLastError(0xdeadbeef);
1688 size
= sizeof(DWORD
);
1689 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1690 ok(ret
, "%u\n", GetLastError());
1691 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1693 SetLastError(0xdeadbeef);
1695 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1696 ok(ret
, "%u\n", GetLastError());
1698 SetLastError(0xdeadbeef);
1700 size
= sizeof(DWORD
);
1701 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1702 ok(ret
, "%u\n", GetLastError());
1703 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1705 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1706 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1708 /* Timeout values should match the last one set for session */
1709 SetLastError(0xdeadbeef);
1711 size
= sizeof(DWORD
);
1712 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1713 ok(ret
, "%u\n", GetLastError());
1714 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1716 SetLastError(0xdeadbeef);
1718 size
= sizeof(DWORD
);
1719 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1720 ok(ret
, "%u\n", GetLastError());
1721 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1723 SetLastError(0xdeadbeef);
1725 size
= sizeof(DWORD
);
1726 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1727 ok(ret
, "%u\n", GetLastError());
1728 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1730 SetLastError(0xdeadbeef);
1732 size
= sizeof(DWORD
);
1733 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1734 ok(ret
, "%u\n", GetLastError());
1735 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1737 SetLastError(0xdeadbeef);
1738 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1739 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1740 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1742 SetLastError(0xdeadbeef);
1743 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1744 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1745 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1747 SetLastError(0xdeadbeef);
1748 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1749 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1750 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1752 SetLastError(0xdeadbeef);
1753 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1754 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1755 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1757 SetLastError(0xdeadbeef);
1758 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1759 ok(ret
, "%u\n", GetLastError());
1761 SetLastError(0xdeadbeef);
1762 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1763 ok(ret
, "%u\n", GetLastError());
1765 SetLastError(0xdeadbeef);
1766 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1767 ok(ret
, "%u\n", GetLastError());
1769 SetLastError(0xdeadbeef);
1771 size
= sizeof(DWORD
);
1772 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1773 ok(ret
, "%u\n", GetLastError());
1774 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1776 SetLastError(0xdeadbeef);
1778 size
= sizeof(DWORD
);
1779 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1780 ok(ret
, "%u\n", GetLastError());
1781 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1783 SetLastError(0xdeadbeef);
1785 size
= sizeof(DWORD
);
1786 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1787 ok(ret
, "%u\n", GetLastError());
1788 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1790 SetLastError(0xdeadbeef);
1792 size
= sizeof(DWORD
);
1793 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1794 ok(ret
, "%u\n", GetLastError());
1795 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1797 SetLastError(0xdeadbeef);
1799 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1800 ok(ret
, "%u\n", GetLastError());
1802 SetLastError(0xdeadbeef);
1804 size
= sizeof(DWORD
);
1805 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1806 ok(ret
, "%u\n", GetLastError());
1807 ok(value
== 0, "Expected 0, got %u\n", value
);
1809 SetLastError(0xdeadbeef);
1811 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1812 ok(ret
, "%u\n", GetLastError());
1814 SetLastError(0xdeadbeef);
1816 size
= sizeof(DWORD
);
1817 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1818 ok(ret
, "%u\n", GetLastError());
1819 ok(value
== 0, "Expected 0, got %u\n", value
);
1821 SetLastError(0xdeadbeef);
1823 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1824 ok(ret
, "%u\n", GetLastError());
1826 SetLastError(0xdeadbeef);
1828 size
= sizeof(DWORD
);
1829 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1830 ok(ret
, "%u\n", GetLastError());
1831 ok(value
== 0, "Expected 0, got %u\n", value
);
1833 SetLastError(0xdeadbeef);
1835 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1836 ok(ret
, "%u\n", GetLastError());
1838 SetLastError(0xdeadbeef);
1840 size
= sizeof(DWORD
);
1841 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1842 ok(ret
, "%u\n", GetLastError());
1843 ok(value
== 0, "Expected 0, got %u\n", value
);
1845 SetLastError(0xdeadbeef);
1847 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1848 ok(ret
, "%u\n", GetLastError());
1850 SetLastError(0xdeadbeef);
1852 size
= sizeof(DWORD
);
1853 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1854 ok(ret
, "%u\n", GetLastError());
1855 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1857 SetLastError(0xdeadbeef);
1859 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1860 ok(ret
, "%u\n", GetLastError());
1862 SetLastError(0xdeadbeef);
1864 size
= sizeof(DWORD
);
1865 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1866 ok(ret
, "%u\n", GetLastError());
1867 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1869 SetLastError(0xdeadbeef);
1871 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1872 ok(ret
, "%u\n", GetLastError());
1874 SetLastError(0xdeadbeef);
1876 size
= sizeof(DWORD
);
1877 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1878 ok(ret
, "%u\n", GetLastError());
1879 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1881 SetLastError(0xdeadbeef);
1883 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1884 ok(ret
, "%u\n", GetLastError());
1886 SetLastError(0xdeadbeef);
1888 size
= sizeof(DWORD
);
1889 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1890 ok(ret
, "%u\n", GetLastError());
1891 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1893 /* Changing timeout values for session should not affect the values for a request,
1894 * neither should the other way around.
1896 SetLastError(0xdeadbeef);
1898 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1899 ok(ret
, "%u\n", GetLastError());
1901 SetLastError(0xdeadbeef);
1903 size
= sizeof(DWORD
);
1904 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1905 ok(ret
, "%u\n", GetLastError());
1906 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1908 SetLastError(0xdeadbeef);
1910 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1911 ok(ret
, "%u\n", GetLastError());
1913 SetLastError(0xdeadbeef);
1915 size
= sizeof(DWORD
);
1916 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1917 ok(ret
, "%u\n", GetLastError());
1918 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1920 SetLastError(0xdeadbeef);
1922 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1923 ok(ret
, "%u\n", GetLastError());
1925 SetLastError(0xdeadbeef);
1927 size
= sizeof(DWORD
);
1928 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1929 ok(ret
, "%u\n", GetLastError());
1930 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1932 SetLastError(0xdeadbeef);
1934 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1935 ok(ret
, "%u\n", GetLastError());
1937 SetLastError(0xdeadbeef);
1939 size
= sizeof(DWORD
);
1940 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1941 ok(ret
, "%u\n", GetLastError());
1942 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1944 SetLastError(0xdeadbeef);
1946 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1947 ok(ret
, "%u\n", GetLastError());
1949 SetLastError(0xdeadbeef);
1951 size
= sizeof(DWORD
);
1952 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1953 ok(ret
, "%u\n", GetLastError());
1954 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1956 SetLastError(0xdeadbeef);
1958 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1959 ok(ret
, "%u\n", GetLastError());
1961 SetLastError(0xdeadbeef);
1963 size
= sizeof(DWORD
);
1964 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1965 ok(ret
, "%u\n", GetLastError());
1966 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1968 SetLastError(0xdeadbeef);
1970 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1971 ok(ret
, "%u\n", GetLastError());
1973 SetLastError(0xdeadbeef);
1975 size
= sizeof(DWORD
);
1976 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1977 ok(ret
, "%u\n", GetLastError());
1978 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1980 SetLastError(0xdeadbeef);
1982 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1983 ok(ret
, "%u\n", GetLastError());
1985 SetLastError(0xdeadbeef);
1987 size
= sizeof(DWORD
);
1988 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1989 ok(ret
, "%u\n", GetLastError());
1990 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1992 /* response timeout */
1993 SetLastError(0xdeadbeef);
1995 size
= sizeof(value
);
1996 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, &size
);
1997 ok(ret
, "%u\n", GetLastError());
1998 ok(value
== ~0u, "got %u\n", value
);
2000 SetLastError(0xdeadbeef);
2002 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, sizeof(value
));
2003 ok(ret
, "%u\n", GetLastError());
2005 SetLastError(0xdeadbeef);
2007 size
= sizeof(value
);
2008 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, &size
);
2009 ok(ret
, "%u\n", GetLastError());
2010 todo_wine
ok(value
== 0xbeefdead, "got %u\n", value
);
2012 SetLastError(0xdeadbeef);
2014 size
= sizeof(value
);
2015 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, &size
);
2016 ok(ret
, "%u\n", GetLastError());
2017 ok(value
== ~0u, "got %u\n", value
);
2019 SetLastError(0xdeadbeef);
2021 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, sizeof(value
));
2022 ok(!ret
, "expected failure\n");
2023 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
, "got %u\n", GetLastError());
2025 SetLastError(0xdeadbeef);
2027 size
= sizeof(value
);
2028 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, &size
);
2029 ok(ret
, "%u\n", GetLastError());
2030 ok(value
== ~0u, "got %u\n", value
);
2032 SetLastError(0xdeadbeef);
2034 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, sizeof(value
));
2035 ok(ret
, "%u\n", GetLastError());
2037 SetLastError(0xdeadbeef);
2039 size
= sizeof(value
);
2040 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, &size
);
2041 ok(ret
, "%u\n", GetLastError());
2042 todo_wine
ok(value
== 48879, "got %u\n", value
);
2044 SetLastError(0xdeadbeef);
2046 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, sizeof(value
));
2047 ok(ret
, "%u\n", GetLastError());
2049 SetLastError(0xdeadbeef);
2051 size
= sizeof(value
);
2052 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT
, &value
, &size
);
2053 ok(ret
, "%u\n", GetLastError());
2054 ok(value
== 48880, "got %u\n", value
);
2056 WinHttpCloseHandle(req
);
2057 WinHttpCloseHandle(con
);
2058 WinHttpCloseHandle(ses
);
2061 static void test_resolve_timeout(void)
2063 static const WCHAR nxdomain
[] =
2064 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
2065 HINTERNET ses
, con
, req
;
2069 if (! proxy_active())
2071 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
2072 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2075 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
2076 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
2078 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
2079 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2081 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2082 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2084 SetLastError(0xdeadbeef);
2085 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2088 skip("nxdomain returned success. Broken ISP redirects?\n");
2091 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
2092 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
2094 WinHttpCloseHandle(req
);
2095 WinHttpCloseHandle(con
);
2096 WinHttpCloseHandle(ses
);
2099 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
2101 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
2102 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2105 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
2106 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
2108 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
2109 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2111 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2112 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2114 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2115 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
2117 skip("connection failed, skipping\n");
2120 ok(ret
, "failed to send request\n");
2123 WinHttpCloseHandle(req
);
2124 WinHttpCloseHandle(con
);
2125 WinHttpCloseHandle(ses
);
2128 static const char page1
[] =
2130 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
2131 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2134 static const char okmsg
[] =
2135 "HTTP/1.1 200 OK\r\n"
2136 "Server: winetest\r\n"
2139 static const char notokmsg
[] =
2140 "HTTP/1.1 400 Bad Request\r\n"
2143 static const char cookiemsg
[] =
2144 "HTTP/1.1 200 OK\r\n"
2145 "Set-Cookie: name = value \r\n"
2146 "Set-Cookie: NAME = value \r\n"
2149 static const char cookiemsg2
[] =
2150 "HTTP/1.1 200 OK\r\n"
2151 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2154 static const char nocontentmsg
[] =
2155 "HTTP/1.1 204 No Content\r\n"
2156 "Server: winetest\r\n"
2159 static const char notmodified
[] =
2160 "HTTP/1.1 304 Not Modified\r\n"
2163 static const char noauthmsg
[] =
2164 "HTTP/1.1 401 Unauthorized\r\n"
2165 "Server: winetest\r\n"
2166 "Connection: close\r\n"
2167 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2168 "Content-Length: 12\r\n"
2169 "Content-Type: text/plain\r\n"
2172 static const char okauthmsg
[] =
2173 "HTTP/1.1 200 OK\r\n"
2174 "Server: winetest\r\n"
2175 "Connection: close\r\n"
2176 "Content-Length: 11\r\n"
2177 "Content-Type: text/plain\r\n"
2180 static const char headmsg
[] =
2181 "HTTP/1.1 200 OK\r\n"
2182 "Content-Length: 100\r\n"
2185 static const char multiauth
[] =
2186 "HTTP/1.1 401 Unauthorized\r\n"
2187 "Server: winetest\r\n"
2188 "WWW-Authenticate: Bearer\r\n"
2189 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2190 "WWW-Authenticate: NTLM\r\n"
2191 "Content-Length: 10\r\n"
2192 "Content-Type: text/plain\r\n"
2195 static const char largeauth
[] =
2196 "HTTP/1.1 401 Unauthorized\r\n"
2197 "Server: winetest\r\n"
2198 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2199 "WWW-Authenticate: NTLM\r\n"
2200 "Content-Length: 10240\r\n"
2201 "Content-Type: text/plain\r\n"
2204 static const char unauthorized
[] = "Unauthorized";
2205 static const char hello_world
[] = "Hello World";
2206 static const char auth_unseen
[] = "Auth Unseen";
2214 #define BIG_BUFFER_LEN 0x2250
2216 static DWORD CALLBACK
server_thread(LPVOID param
)
2218 struct server_info
*si
= param
;
2219 int r
, c
= -1, i
, on
;
2221 struct sockaddr_in sa
;
2224 int last_request
= 0;
2226 WSAStartup(MAKEWORD(1,1), &wsaData
);
2228 s
= socket(AF_INET
, SOCK_STREAM
, 0);
2229 if (s
== INVALID_SOCKET
)
2233 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
2235 memset(&sa
, 0, sizeof sa
);
2236 sa
.sin_family
= AF_INET
;
2237 sa
.sin_port
= htons(si
->port
);
2238 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
2240 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
2245 SetEvent(si
->event
);
2248 if (c
== -1) c
= accept(s
, NULL
, NULL
);
2250 memset(buffer
, 0, sizeof buffer
);
2251 for(i
= 0; i
< sizeof buffer
- 1; i
++)
2253 r
= recv(c
, &buffer
[i
], 1, 0);
2256 if (i
< 4) continue;
2257 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
2258 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
2261 if (strstr(buffer
, "GET /basic"))
2263 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2264 send(c
, page1
, sizeof page1
- 1, 0);
2266 if (strstr(buffer
, "/auth_with_creds"))
2268 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2269 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2270 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2272 send(c
, auth_unseen
, sizeof auth_unseen
- 1, 0);
2275 if (strstr(buffer
, "/auth"))
2277 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
2279 send(c
, okauthmsg
, sizeof okauthmsg
- 1, 0);
2280 send(c
, hello_world
, sizeof hello_world
- 1, 0);
2284 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
2285 send(c
, unauthorized
, sizeof unauthorized
- 1, 0);
2289 if (strstr(buffer
, "/big"))
2291 char msg
[BIG_BUFFER_LEN
];
2292 memset(msg
, 'm', sizeof(msg
));
2293 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2294 send(c
, msg
, sizeof(msg
), 0);
2296 if (strstr(buffer
, "/no_headers"))
2298 send(c
, page1
, sizeof page1
- 1, 0);
2300 if (strstr(buffer
, "GET /no_content"))
2302 send(c
, nocontentmsg
, sizeof nocontentmsg
- 1, 0);
2305 if (strstr(buffer
, "GET /not_modified"))
2307 if (strstr(buffer
, "If-Modified-Since:")) send(c
, notmodified
, sizeof notmodified
- 1, 0);
2308 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2311 if (strstr(buffer
, "HEAD /head"))
2313 send(c
, headmsg
, sizeof headmsg
- 1, 0);
2316 if (strstr(buffer
, "GET /multiauth"))
2318 send(c
, multiauth
, sizeof multiauth
- 1, 0);
2320 if (strstr(buffer
, "GET /largeauth"))
2322 if (strstr(buffer
, "Authorization: NTLM"))
2323 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2326 send(c
, largeauth
, sizeof largeauth
- 1, 0);
2327 for (i
= 0; i
< 10240; i
++) send(c
, "A", 1, 0);
2331 if (strstr(buffer
, "GET /cookie5"))
2333 if (strstr(buffer
, "Cookie: name2=value\r\n"))
2334 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2336 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2338 if (strstr(buffer
, "GET /cookie4"))
2340 send(c
, cookiemsg2
, sizeof(cookiemsg2
) - 1, 0);
2342 if (strstr(buffer
, "GET /cookie3"))
2344 if (strstr(buffer
, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2345 broken(strstr(buffer
, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL
))
2346 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2348 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2350 if (strstr(buffer
, "GET /cookie2"))
2352 if (strstr(buffer
, "Cookie: NAME=value; name=value\r\n") ||
2353 broken(strstr(buffer
, "Cookie: name=value; NAME=value\r\n") != NULL
))
2354 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2356 send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2358 else if (strstr(buffer
, "GET /cookie"))
2360 if (!strstr(buffer
, "Cookie: name=value\r\n")) send(c
, cookiemsg
, sizeof(cookiemsg
) - 1, 0);
2361 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2363 else if (strstr(buffer
, "GET /escape"))
2365 static const char res
[] = "%0D%0A%1F%7F%3C%20%one?%1F%7F%20!%22%23$%&'()*+,-./:;%3C=%3E?@%5B%5C%5D"
2366 "%5E_%60%7B%7C%7D~%0D%0A ";
2367 static const char res2
[] = "%0D%0A%1F%7F%3C%20%25two?%1F%7F%20!%22%23$%25&'()*+,-./:;%3C=%3E?@%5B%5C%5D"
2368 "%5E_%60%7B%7C%7D~%0D%0A ";
2369 static const char res3
[] = "\x1f\x7f<%20%three?\x1f\x7f%20!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
2370 static const char res4
[] = "%0D%0A%1F%7F%3C%20%four?\x1f\x7f%20!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
2372 if (strstr(buffer
+ 11, res
) || strstr(buffer
+ 11, res2
) || strstr(buffer
+ 11, res3
) ||
2373 strstr(buffer
+ 11, res4
)) send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
2374 else send(c
, notokmsg
, sizeof(notokmsg
) - 1, 0);
2376 if (strstr(buffer
, "GET /quit"))
2378 send(c
, okmsg
, sizeof okmsg
- 1, 0);
2379 send(c
, page1
, sizeof page1
- 1, 0);
2386 } while (!last_request
);
2392 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
2394 static const WCHAR test_header_end_clrf
[] = {'\r','\n','\r','\n',0};
2395 static const WCHAR test_header_end_raw
[] = {0,0};
2396 HINTERNET ses
, con
, req
;
2398 WCHAR buffer2
[0x100];
2399 DWORD count
, status
, size
, error
, supported
, first
, target
;
2402 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2403 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2405 SetLastError(0xdeadbeef);
2406 ret
= WinHttpSetOption(ses
, 0, buffer
, sizeof(buffer
));
2407 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_OPTION
, "got %u\n", GetLastError());
2409 SetLastError(0xdeadbeef);
2410 ret
= WinHttpQueryOption(ses
, 0, buffer
, &size
);
2411 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %u\n", GetLastError());
2413 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2414 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2416 SetLastError(0xdeadbeef);
2417 ret
= WinHttpSetOption(con
, 0, buffer
, sizeof(buffer
));
2418 todo_wine
ok(!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_OPTION
, "got %u\n", GetLastError());
2420 SetLastError(0xdeadbeef);
2421 ret
= WinHttpQueryOption(con
, 0, buffer
, &size
);
2422 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %u\n", GetLastError());
2424 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
2425 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2427 SetLastError(0xdeadbeef);
2428 ret
= WinHttpSetOption(req
, 0, buffer
, sizeof(buffer
));
2429 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INVALID_OPTION
, "got %u\n", GetLastError());
2431 SetLastError(0xdeadbeef);
2432 ret
= WinHttpQueryOption(req
, 0, buffer
, &size
);
2433 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "got %u\n", GetLastError());
2435 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2436 ok(ret
, "failed to send request %u\n", GetLastError());
2438 ret
= WinHttpReceiveResponse(req
, NULL
);
2439 ok(ret
, "failed to receive response %u\n", GetLastError());
2441 status
= 0xdeadbeef;
2442 size
= sizeof(status
);
2443 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2444 ok(ret
, "failed to query status code %u\n", GetLastError());
2445 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2447 supported
= first
= target
= 0xdeadbeef;
2448 SetLastError(0xdeadbeef);
2449 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2450 error
= GetLastError();
2451 ok(!ret
, "unexpected success\n");
2452 ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2453 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2454 ok(first
== 0xdeadbeef, "got %x\n", first
);
2455 ok(target
== 0xdeadbeef, "got %x\n", target
);
2457 size
= sizeof(buffer2
);
2458 memset(buffer2
, 0, sizeof(buffer2
));
2459 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, buffer2
, &size
, NULL
);
2460 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2461 ok(!memcmp(buffer2
+ lstrlenW(buffer2
) - 4, test_header_end_clrf
, sizeof(test_header_end_clrf
)),
2462 "WinHttpQueryHeaders returned invalid end of header string\n");
2464 size
= sizeof(buffer2
);
2465 memset(buffer2
, 0, sizeof(buffer2
));
2466 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS
, NULL
, buffer2
, &size
, NULL
);
2467 ok(ret
, "failed to query for raw headers: %u\n", GetLastError());
2468 ok(!memcmp(buffer2
+ (size
/ sizeof(WCHAR
)) - 1, test_header_end_raw
, sizeof(test_header_end_raw
)),
2469 "WinHttpQueryHeaders returned invalid end of header string\n");
2470 ok(buffer2
[(size
/ sizeof(WCHAR
)) - 2] != 0, "returned string has too many NULL characters\n");
2473 memset(buffer
, 0, sizeof(buffer
));
2474 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
2475 ok(ret
, "failed to read data %u\n", GetLastError());
2476 ok(count
== sizeof page1
- 1, "count was wrong\n");
2477 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
2479 WinHttpCloseHandle(req
);
2480 WinHttpCloseHandle(con
);
2481 WinHttpCloseHandle(ses
);
2484 static void test_basic_authentication(int port
)
2486 static const WCHAR authW
[] = {'/','a','u','t','h',0};
2487 static const WCHAR auth_with_credsW
[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0};
2488 static WCHAR userW
[] = {'u','s','e','r',0};
2489 static WCHAR passW
[] = {'p','w','d',0};
2490 static WCHAR pass2W
[] = {'p','w','d','2',0};
2491 HINTERNET ses
, con
, req
;
2492 DWORD status
, size
, error
, supported
, first
, target
;
2496 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2497 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2499 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2500 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2502 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2503 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2505 SetLastError(0xdeadbeef);
2506 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
2507 error
= GetLastError();
2508 ok(!ret
, "expected failure\n");
2509 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2511 SetLastError(0xdeadbeef);
2512 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
2513 error
= GetLastError();
2514 ok(!ret
, "expected failure\n");
2515 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2517 supported
= 0xdeadbeef;
2518 SetLastError(0xdeadbeef);
2519 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
2520 error
= GetLastError();
2521 ok(!ret
, "expected failure\n");
2522 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2523 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2525 supported
= first
= 0xdeadbeef;
2526 SetLastError(0xdeadbeef);
2527 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
2528 error
= GetLastError();
2529 ok(!ret
, "expected failure\n");
2530 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
2531 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2532 ok(first
== 0xdeadbeef, "got %x\n", first
);
2534 supported
= first
= target
= 0xdeadbeef;
2535 SetLastError(0xdeadbeef);
2536 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2537 error
= GetLastError();
2538 ok(!ret
, "expected failure\n");
2539 ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
2540 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2541 ok(first
== 0xdeadbeef, "got %x\n", first
);
2542 ok(target
== 0xdeadbeef, "got %x\n", target
);
2544 supported
= first
= target
= 0xdeadbeef;
2545 SetLastError(0xdeadbeef);
2546 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
2547 error
= GetLastError();
2548 ok(!ret
, "expected failure\n");
2549 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
2550 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
2551 ok(first
== 0xdeadbeef, "got %x\n", first
);
2552 ok(target
== 0xdeadbeef, "got %x\n", target
);
2554 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2555 ok(ret
, "failed to send request %u\n", GetLastError());
2557 ret
= WinHttpReceiveResponse(req
, NULL
);
2558 ok(ret
, "failed to receive response %u\n", GetLastError());
2560 status
= 0xdeadbeef;
2561 size
= sizeof(status
);
2562 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2563 ok(ret
, "failed to query status code %u\n", GetLastError());
2564 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2567 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2568 error
= GetLastError();
2569 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2572 ok(size
== 12, "expected 12, got %u\n", size
);
2573 ok(!memcmp(buffer
, unauthorized
, 12), "got %s\n", buffer
);
2576 supported
= first
= target
= 0xdeadbeef;
2577 SetLastError(0xdeadbeef);
2578 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2579 error
= GetLastError();
2580 ok(ret
, "failed to query authentication schemes %u\n", error
);
2581 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2582 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2583 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2584 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2586 SetLastError(0xdeadbeef);
2587 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2588 error
= GetLastError();
2589 ok(ret
, "failed to set credentials %u\n", error
);
2590 ok(error
== ERROR_SUCCESS
|| broken(error
== 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error
);
2592 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2593 ok(ret
, "failed to set credentials %u\n", GetLastError());
2595 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2596 ok(ret
, "failed to set credentials %u\n", GetLastError());
2598 SetLastError(0xdeadbeef);
2599 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2600 error
= GetLastError();
2601 ok(!ret
, "expected failure\n");
2602 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2604 SetLastError(0xdeadbeef);
2605 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2606 error
= GetLastError();
2607 ok(!ret
, "expected failure\n");
2608 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2610 SetLastError(0xdeadbeef);
2611 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2612 error
= GetLastError();
2613 ok(!ret
, "expected failure\n");
2614 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2616 SetLastError(0xdeadbeef);
2617 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2618 error
= GetLastError();
2619 ok(!ret
, "expected failure\n");
2620 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2622 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2623 ok(ret
, "failed to set credentials %u\n", GetLastError());
2625 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2626 ok(ret
, "failed to send request %u\n", GetLastError());
2628 ret
= WinHttpReceiveResponse(req
, NULL
);
2629 ok(ret
, "failed to receive response %u\n", GetLastError());
2631 status
= 0xdeadbeef;
2632 size
= sizeof(status
);
2633 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2634 ok(ret
, "failed to query status code %u\n", GetLastError());
2635 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2638 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2639 error
= GetLastError();
2640 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2643 ok(size
== 11, "expected 11, got %u\n", size
);
2644 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2647 WinHttpCloseHandle(req
);
2648 WinHttpCloseHandle(con
);
2649 WinHttpCloseHandle(ses
);
2651 /* now set the credentials first to show that they get sent with the first request */
2652 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2653 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2655 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2656 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2658 req
= WinHttpOpenRequest(con
, NULL
, auth_with_credsW
, NULL
, NULL
, NULL
, 0);
2659 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2661 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2662 ok(ret
, "failed to set credentials %u\n", GetLastError());
2664 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2665 ok(ret
, "failed to send request %u\n", GetLastError());
2667 ret
= WinHttpReceiveResponse(req
, NULL
);
2668 ok(ret
, "failed to receive response %u\n", GetLastError());
2670 status
= 0xdeadbeef;
2671 size
= sizeof(status
);
2672 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2673 ok(ret
, "failed to query status code %u\n", GetLastError());
2674 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2677 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
2678 error
= GetLastError();
2679 ok(ret
|| broken(error
== ERROR_WINHTTP_SHUTDOWN
|| error
== ERROR_WINHTTP_TIMEOUT
) /* XP */, "failed to read data %u\n", GetLastError());
2682 ok(size
== 11, "expected 11, got %u\n", size
);
2683 ok(!memcmp(buffer
, hello_world
, 11), "got %s\n", buffer
);
2686 WinHttpCloseHandle(req
);
2687 WinHttpCloseHandle(con
);
2688 WinHttpCloseHandle(ses
);
2690 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2692 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2693 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2695 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2696 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2698 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2699 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2701 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2702 ok(ret
, "failed to set credentials %u\n", GetLastError());
2704 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2705 ok(ret
, "failed to set username %u\n", GetLastError());
2707 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, pass2W
, lstrlenW(pass2W
));
2708 ok(ret
, "failed to set password %u\n", GetLastError());
2710 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2711 ok(ret
, "failed to send request %u\n", GetLastError());
2713 ret
= WinHttpReceiveResponse(req
, NULL
);
2714 ok(ret
, "failed to receive response %u\n", GetLastError());
2716 status
= 0xdeadbeef;
2717 size
= sizeof(status
);
2718 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2719 ok(ret
, "failed to query status code %u\n", GetLastError());
2720 ok(status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
2722 WinHttpCloseHandle(req
);
2723 WinHttpCloseHandle(con
);
2724 WinHttpCloseHandle(ses
);
2726 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2727 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2729 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2730 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2732 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
2733 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2735 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2736 ok(ret
, "failed to set username %u\n", GetLastError());
2738 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2739 ok(ret
, "failed to set password %u\n", GetLastError());
2741 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, pass2W
, NULL
);
2742 ok(ret
, "failed to set credentials %u\n", GetLastError());
2744 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2745 ok(ret
, "failed to send request %u\n", GetLastError());
2747 ret
= WinHttpReceiveResponse(req
, NULL
);
2748 ok(ret
, "failed to receive response %u\n", GetLastError());
2750 status
= 0xdeadbeef;
2751 size
= sizeof(status
);
2752 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2753 ok(ret
, "failed to query status code %u\n", GetLastError());
2754 ok(status
== HTTP_STATUS_DENIED
, "request failed unexpectedly %u\n", status
);
2756 WinHttpCloseHandle(req
);
2757 WinHttpCloseHandle(con
);
2758 WinHttpCloseHandle(ses
);
2761 static void test_multi_authentication(int port
)
2763 static const WCHAR multiauthW
[] = {'/','m','u','l','t','i','a','u','t','h',0};
2764 static const WCHAR www_authenticateW
[] =
2765 {'W','W','W','-','A','u','t','h','e','n','t','i','c','a','t','e',0};
2766 static const WCHAR getW
[] = {'G','E','T',0};
2767 HINTERNET ses
, con
, req
;
2768 DWORD supported
, first
, target
, size
, index
;
2772 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2773 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2775 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2776 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2778 req
= WinHttpOpenRequest(con
, getW
, multiauthW
, NULL
, NULL
, NULL
, 0);
2779 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2781 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0,
2782 WINHTTP_NO_REQUEST_DATA
,0, 0, 0 );
2783 ok(ret
, "expected success\n");
2785 ret
= WinHttpReceiveResponse(req
, NULL
);
2786 ok(ret
, "expected success\n");
2788 supported
= first
= target
= 0xdeadbeef;
2789 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2790 ok(ret
, "expected success\n");
2791 ok(supported
== (WINHTTP_AUTH_SCHEME_BASIC
| WINHTTP_AUTH_SCHEME_NTLM
), "got %x\n", supported
);
2792 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2793 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2797 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CUSTOM
, www_authenticateW
, buf
, &size
, &index
);
2798 ok(ret
, "expected success\n");
2799 ok(!strcmp_wa(buf
, "Bearer"), "buf = %s\n", wine_dbgstr_w(buf
));
2800 ok(size
== lstrlenW(buf
) * sizeof(WCHAR
), "size = %u\n", size
);
2801 ok(index
== 1, "index = %u\n", index
);
2805 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CUSTOM
, www_authenticateW
, NULL
, &size
, &index
);
2806 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
2807 "WinHttpQueryHeaders returned %x(%u)\n", ret
, GetLastError());
2808 ok(size
== (lstrlenW(buf
) + 1) * sizeof(WCHAR
), "size = %u\n", size
);
2809 ok(index
== 0, "index = %u\n", index
);
2811 WinHttpCloseHandle(req
);
2812 WinHttpCloseHandle(con
);
2813 WinHttpCloseHandle(ses
);
2816 static void test_large_data_authentication(int port
)
2818 static const WCHAR largeauthW
[] = {'/','l','a','r','g','e','a','u','t','h',0};
2819 static const WCHAR getW
[] = {'G','E','T',0};
2820 static WCHAR userW
[] = {'u','s','e','r',0};
2821 static WCHAR passW
[] = {'p','w','d',0};
2822 HINTERNET ses
, con
, req
;
2826 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2827 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2829 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2830 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2832 req
= WinHttpOpenRequest(con
, getW
, largeauthW
, NULL
, NULL
, NULL
, 0);
2833 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2835 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, WINHTTP_NO_REQUEST_DATA
, 0, 0, 0);
2836 ok(ret
, "expected success\n");
2838 ret
= WinHttpReceiveResponse(req
, NULL
);
2839 ok(ret
, "expected success\n");
2841 size
= sizeof(status
);
2842 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
,
2843 &status
, &size
, NULL
);
2844 ok(ret
, "expected success\n");
2845 ok(status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
2847 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, userW
, passW
, NULL
);
2848 ok(ret
, "expected success\n");
2850 ret
= WinHttpSendRequest(req
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, WINHTTP_NO_REQUEST_DATA
, 0, 0, 0);
2851 ok(ret
, "expected success %d\n", GetLastError());
2853 ret
= WinHttpReceiveResponse(req
, NULL
);
2854 ok(ret
, "expected success\n");
2856 size
= sizeof(status
);
2857 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
,
2858 &status
, &size
, NULL
);
2859 ok(ret
, "expected success\n");
2860 ok(status
== HTTP_STATUS_OK
, "got %d\n", status
);
2862 WinHttpCloseHandle(req
);
2863 WinHttpCloseHandle(con
);
2864 WinHttpCloseHandle(ses
);
2867 static void test_no_headers(int port
)
2869 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2870 HINTERNET ses
, con
, req
;
2874 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2875 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2877 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2878 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2880 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2881 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2883 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2886 error
= GetLastError();
2887 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2891 SetLastError(0xdeadbeef);
2892 ret
= WinHttpReceiveResponse(req
, NULL
);
2893 error
= GetLastError();
2894 ok(!ret
, "expected failure\n");
2895 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2898 WinHttpCloseHandle(req
);
2899 WinHttpCloseHandle(con
);
2900 WinHttpCloseHandle(ses
);
2903 static void test_no_content(int port
)
2905 static const WCHAR no_contentW
[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2906 HINTERNET ses
, con
, req
;
2908 DWORD size
, len
= sizeof(buf
), bytes_read
, status
;
2911 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2912 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2914 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2915 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2917 req
= WinHttpOpenRequest(con
, NULL
, no_contentW
, NULL
, NULL
, NULL
, 0);
2918 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2921 SetLastError(0xdeadbeef);
2922 ret
= WinHttpQueryDataAvailable(req
, &size
);
2924 ok(!ret
, "expected error\n");
2925 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE
,
2926 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2927 ok(size
== 12345 || broken(size
== 0) /* Win <= 2003 */,
2928 "expected 12345, got %u\n", size
);
2931 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2932 ok(ret
, "expected success\n");
2934 ret
= WinHttpReceiveResponse(req
, NULL
);
2935 ok(ret
, "expected success\n");
2937 status
= 0xdeadbeef;
2938 size
= sizeof(status
);
2939 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
2940 NULL
, &status
, &size
, NULL
);
2941 ok(ret
, "expected success\n");
2942 ok(status
== HTTP_STATUS_NO_CONTENT
, "expected status 204, got %d\n", status
);
2944 SetLastError(0xdeadbeef);
2945 size
= sizeof(status
);
2947 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
2948 NULL
, &status
, &size
, 0);
2949 ok(!ret
, "expected no content-length header\n");
2950 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError());
2951 ok(status
== 12345, "expected 0, got %d\n", status
);
2953 SetLastError(0xdeadbeef);
2955 ret
= WinHttpQueryDataAvailable(req
, &size
);
2956 ok(ret
, "expected success\n");
2957 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2958 "wrong error %u\n", GetLastError());
2959 ok(!size
, "expected 0, got %u\n", size
);
2961 SetLastError(0xdeadbeef);
2962 ret
= WinHttpReadData(req
, buf
, len
, &bytes_read
);
2963 ok(ret
, "expected success\n");
2964 ok(GetLastError() == ERROR_SUCCESS
|| broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2965 "wrong error %u\n", GetLastError());
2966 ok(!bytes_read
, "expected 0, got %u\n", bytes_read
);
2969 ret
= WinHttpQueryDataAvailable(req
, &size
);
2970 ok(ret
, "expected success\n");
2971 ok(size
== 0, "expected 0, got %d\n", size
);
2973 WinHttpCloseHandle(req
);
2976 SetLastError(0xdeadbeef);
2977 ret
= WinHttpQueryDataAvailable(req
, &size
);
2978 ok(!ret
, "expected error\n");
2979 ok(GetLastError() == ERROR_INVALID_HANDLE
,
2980 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2981 ok(size
== 12345, "expected 12345, got %u\n", size
);
2983 WinHttpCloseHandle(con
);
2984 WinHttpCloseHandle(ses
);
2987 static void test_head_request(int port
)
2989 static const WCHAR verbW
[] = {'H','E','A','D',0};
2990 static const WCHAR headW
[] = {'/','h','e','a','d',0};
2991 HINTERNET ses
, con
, req
;
2993 DWORD size
, len
, count
, status
;
2996 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
2997 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2999 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
3000 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3002 req
= WinHttpOpenRequest(con
, verbW
, headW
, NULL
, NULL
, NULL
, 0);
3003 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3005 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
3006 ok(ret
, "failed to send request %u\n", GetLastError());
3008 ret
= WinHttpReceiveResponse(req
, NULL
);
3009 ok(ret
, "failed to receive response %u\n", GetLastError());
3011 status
= 0xdeadbeef;
3012 size
= sizeof(status
);
3013 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
,
3014 NULL
, &status
, &size
, NULL
);
3015 ok(ret
, "failed to get status code %u\n", GetLastError());
3016 ok(status
== HTTP_STATUS_OK
, "got %u\n", status
);
3020 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_CONTENT_LENGTH
| WINHTTP_QUERY_FLAG_NUMBER
,
3021 NULL
, &len
, &size
, 0);
3022 ok(ret
, "failed to get content-length header %u\n", GetLastError());
3023 ok(len
== HTTP_STATUS_CONTINUE
, "got %u\n", len
);
3026 ret
= WinHttpQueryDataAvailable(req
, &count
);
3027 ok(ret
, "failed to query data available %u\n", GetLastError());
3028 ok(!count
, "got %u\n", count
);
3032 ret
= WinHttpReadData(req
, buf
, len
, &count
);
3033 ok(ret
, "failed to read data %u\n", GetLastError());
3034 ok(!count
, "got %u\n", count
);
3037 ret
= WinHttpQueryDataAvailable(req
, &count
);
3038 ok(ret
, "failed to query data available %u\n", GetLastError());
3039 ok(!count
, "got %u\n", count
);
3041 WinHttpCloseHandle(req
);
3042 WinHttpCloseHandle(con
);
3043 WinHttpCloseHandle(ses
);
3046 static void test_not_modified(int port
)
3048 static const WCHAR pathW
[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
3049 static const WCHAR ifmodifiedW
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
3050 static const WCHAR ifmodified2W
[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
3052 HINTERNET session
, request
, connection
;
3053 DWORD index
, len
, status
, size
, start
= GetTickCount();
3055 WCHAR today
[(sizeof(ifmodifiedW
) + WINHTTP_TIME_FORMAT_BUFSIZE
)/sizeof(WCHAR
) + 3], buffer
[32];
3057 memcpy(today
, ifmodifiedW
, sizeof(ifmodifiedW
));
3059 WinHttpTimeFromSystemTime(&st
, &today
[ARRAY_SIZE(ifmodifiedW
)]);
3061 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
,
3062 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
3063 ok(session
!= NULL
, "WinHttpOpen failed: %u\n", GetLastError());
3065 connection
= WinHttpConnect(session
, localhostW
, port
, 0);
3066 ok(connection
!= NULL
, "WinHttpConnect failed: %u\n", GetLastError());
3068 request
= WinHttpOpenRequest(connection
, NULL
, pathW
, NULL
, WINHTTP_NO_REFERER
,
3069 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
3070 ok(request
!= NULL
, "WinHttpOpenrequest failed: %u\n", GetLastError());
3072 ret
= WinHttpSendRequest(request
, today
, 0, NULL
, 0, 0, 0);
3073 ok(ret
, "WinHttpSendRequest failed: %u\n", GetLastError());
3075 ret
= WinHttpReceiveResponse(request
, NULL
);
3076 ok(ret
, "WinHttpReceiveResponse failed: %u\n", GetLastError());
3079 len
= sizeof(buffer
);
3080 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
3081 ifmodified2W
, buffer
, &len
, &index
);
3082 ok(ret
, "failed to get header %u\n", GetLastError());
3084 status
= 0xdeadbeef;
3085 size
= sizeof(status
);
3086 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
,
3087 NULL
, &status
, &size
, NULL
);
3088 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
3089 ok(status
== HTTP_STATUS_NOT_MODIFIED
, "got %u\n", status
);
3092 ret
= WinHttpQueryDataAvailable(request
, &size
);
3093 ok(ret
, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
3094 ok(!size
, "got %u\n", size
);
3096 WinHttpCloseHandle(request
);
3097 WinHttpCloseHandle(connection
);
3098 WinHttpCloseHandle(session
);
3099 start
= GetTickCount() - start
;
3100 ok(start
<= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start
);
3103 static void test_bad_header( int port
)
3105 static const WCHAR bad_headerW
[] =
3106 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
3107 't','e','x','t','/','h','t','m','l','\n','\r',0};
3108 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
3109 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
3111 HINTERNET ses
, con
, req
;
3115 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3116 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3118 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3119 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3121 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
3122 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3124 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
3125 ok( ret
, "failed to add header %u\n", GetLastError() );
3129 len
= sizeof(buffer
);
3130 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
3131 content_typeW
, buffer
, &len
, &index
);
3132 ok( ret
, "failed to query headers %u\n", GetLastError() );
3133 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
3134 ok( index
== 1, "index = %u\n", index
);
3136 WinHttpCloseHandle( req
);
3137 WinHttpCloseHandle( con
);
3138 WinHttpCloseHandle( ses
);
3141 static void test_multiple_reads(int port
)
3143 static const WCHAR bigW
[] = {'b','i','g',0};
3144 HINTERNET ses
, con
, req
;
3145 DWORD total_len
= 0;
3148 ses
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0);
3149 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
3151 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
3152 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3154 req
= WinHttpOpenRequest(con
, NULL
, bigW
, NULL
, NULL
, NULL
, 0);
3155 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3157 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
3158 ok(ret
, "failed to send request %u\n", GetLastError());
3160 ret
= WinHttpReceiveResponse(req
, NULL
);
3161 ok(ret
== TRUE
, "expected success\n");
3165 DWORD len
= 0xdeadbeef;
3166 ret
= WinHttpQueryDataAvailable( req
, &len
);
3167 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3168 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3172 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
3174 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
3175 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
3177 HeapFree( GetProcessHeap(), 0, buf
);
3178 if (!bytes_read
) break;
3179 total_len
+= bytes_read
;
3183 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
3185 WinHttpCloseHandle(req
);
3186 WinHttpCloseHandle(con
);
3187 WinHttpCloseHandle(ses
);
3190 static void test_cookies( int port
)
3192 static const WCHAR cookieW
[] = {'/','c','o','o','k','i','e',0};
3193 static const WCHAR cookie2W
[] = {'/','c','o','o','k','i','e','2',0};
3194 static const WCHAR cookie3W
[] = {'/','c','o','o','k','i','e','3',0};
3195 static const WCHAR cookie4W
[] = {'/','c','o','o','k','i','e','4',0};
3196 static const WCHAR cookie5W
[] = {'/','c','o','o','k','i','e','5',0};
3197 static const WCHAR cookieheaderW
[] =
3198 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
3199 HINTERNET ses
, con
, req
;
3203 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3204 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3206 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3207 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3209 req
= WinHttpOpenRequest( con
, NULL
, cookieW
, NULL
, NULL
, NULL
, 0 );
3210 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3212 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3213 ok( ret
, "failed to send request %u\n", GetLastError() );
3215 ret
= WinHttpReceiveResponse( req
, NULL
);
3216 ok( ret
, "failed to receive response %u\n", GetLastError() );
3218 status
= 0xdeadbeef;
3219 size
= sizeof(status
);
3220 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3221 ok( ret
, "failed to query status code %u\n", GetLastError() );
3222 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3224 WinHttpCloseHandle( req
);
3226 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3227 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3229 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3230 ok( ret
, "failed to send request %u\n", GetLastError() );
3232 ret
= WinHttpReceiveResponse( req
, NULL
);
3233 ok( ret
, "failed to receive response %u\n", GetLastError() );
3235 status
= 0xdeadbeef;
3236 size
= sizeof(status
);
3237 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3238 ok( ret
, "failed to query status code %u\n", GetLastError() );
3239 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3241 WinHttpCloseHandle( req
);
3242 WinHttpCloseHandle( con
);
3244 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3245 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3247 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3248 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3250 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3251 ok( ret
, "failed to send request %u\n", GetLastError() );
3253 ret
= WinHttpReceiveResponse( req
, NULL
);
3254 ok( ret
, "failed to receive response %u\n", GetLastError() );
3256 status
= 0xdeadbeef;
3257 size
= sizeof(status
);
3258 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3259 ok( ret
, "failed to query status code %u\n", GetLastError() );
3260 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3262 WinHttpCloseHandle( req
);
3264 req
= WinHttpOpenRequest( con
, NULL
, cookie3W
, NULL
, NULL
, NULL
, 0 );
3265 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3267 ret
= WinHttpSendRequest( req
, cookieheaderW
, ~0u, NULL
, 0, 0, 0 );
3268 ok( ret
, "failed to send request %u\n", GetLastError() );
3270 ret
= WinHttpReceiveResponse( req
, NULL
);
3271 ok( ret
, "failed to receive response %u\n", GetLastError() );
3273 status
= 0xdeadbeef;
3274 size
= sizeof(status
);
3275 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3276 ok( ret
, "failed to query status code %u\n", GetLastError() );
3277 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
), "request failed unexpectedly %u\n", status
);
3279 WinHttpCloseHandle( req
);
3280 WinHttpCloseHandle( con
);
3281 WinHttpCloseHandle( ses
);
3283 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3284 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3286 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3287 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3289 req
= WinHttpOpenRequest( con
, NULL
, cookie2W
, NULL
, NULL
, NULL
, 0 );
3290 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3292 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3293 ok( ret
, "failed to send request %u\n", GetLastError() );
3295 ret
= WinHttpReceiveResponse( req
, NULL
);
3296 ok( ret
, "failed to receive response %u\n", GetLastError() );
3298 status
= 0xdeadbeef;
3299 size
= sizeof(status
);
3300 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3301 ok( ret
, "failed to query status code %u\n", GetLastError() );
3302 ok( status
== HTTP_STATUS_BAD_REQUEST
, "request failed unexpectedly %u\n", status
);
3304 WinHttpCloseHandle( req
);
3305 WinHttpCloseHandle( con
);
3306 WinHttpCloseHandle( ses
);
3308 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3309 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3311 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3312 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3314 req
= WinHttpOpenRequest( con
, NULL
, cookie4W
, NULL
, NULL
, NULL
, 0 );
3315 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3317 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3318 ok( ret
, "failed to send request %u\n", GetLastError() );
3320 ret
= WinHttpReceiveResponse( req
, NULL
);
3321 ok( ret
, "failed to receive response %u\n", GetLastError() );
3323 status
= 0xdeadbeef;
3324 size
= sizeof(status
);
3325 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3326 ok( ret
, "failed to query status code %u\n", GetLastError() );
3327 ok( status
== HTTP_STATUS_OK
, "request failed unexpectedly %u\n", status
);
3328 WinHttpCloseHandle( req
);
3330 req
= WinHttpOpenRequest( con
, NULL
, cookie5W
, NULL
, NULL
, NULL
, 0 );
3331 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3333 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3334 ok( ret
, "failed to send request %u\n", GetLastError() );
3336 ret
= WinHttpReceiveResponse( req
, NULL
);
3337 ok( ret
, "failed to receive response %u\n", GetLastError() );
3339 status
= 0xdeadbeef;
3340 size
= sizeof(status
);
3341 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3342 ok( ret
, "failed to query status code %u\n", GetLastError() );
3343 ok( status
== HTTP_STATUS_OK
|| broken(status
== HTTP_STATUS_BAD_REQUEST
) /* < win7 */,
3344 "request failed unexpectedly %u\n", status
);
3346 WinHttpCloseHandle( req
);
3347 WinHttpCloseHandle( con
);
3348 WinHttpCloseHandle( ses
);
3351 static void do_request( HINTERNET con
, const WCHAR
*obj
, DWORD flags
)
3357 req
= WinHttpOpenRequest( con
, NULL
, obj
, NULL
, NULL
, NULL
, flags
);
3358 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3360 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3361 ok( ret
, "failed to send request %u\n", GetLastError() );
3363 ret
= WinHttpReceiveResponse( req
, NULL
);
3364 ok( ret
, "failed to receive response %u\n", GetLastError() );
3366 status
= 0xdeadbeef;
3367 size
= sizeof(status
);
3368 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
3369 ok( ret
, "failed to query status code %u\n", GetLastError() );
3370 ok( status
== HTTP_STATUS_OK
, "request %s with flags %08x failed %u\n", wine_dbgstr_w(obj
), flags
, status
);
3371 WinHttpCloseHandle( req
);
3374 static void test_request_path_escapes( int port
)
3376 static const WCHAR objW
[] =
3377 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','o','n','e','?',0x1f,0x7f,' ','!','"','#',
3378 '$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`',
3379 '{','|','}','~','\r','\n',0};
3380 static const WCHAR obj2W
[] =
3381 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','t','w','o','?',0x1f,0x7f,' ','!','"','#',
3382 '$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`',
3383 '{','|','}','~','\r','\n',0};
3384 static const WCHAR obj3W
[] =
3385 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','t','h','r','e','e','?',0x1f,0x7f,' ','!',
3386 '"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^',
3387 '_','`','{','|','}','~','\r','\n',0};
3388 static const WCHAR obj4W
[] =
3389 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','f','o','u','r','?',0x1f,0x7f,' ','!','"',
3390 '#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_',
3391 '`','{','|','}','~','\r','\n',0};
3394 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3395 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3397 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3398 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3400 do_request( con
, objW
, 0 );
3401 do_request( con
, obj2W
, WINHTTP_FLAG_ESCAPE_PERCENT
);
3402 do_request( con
, obj3W
, WINHTTP_FLAG_ESCAPE_DISABLE
);
3403 do_request( con
, obj4W
, WINHTTP_FLAG_ESCAPE_DISABLE_QUERY
);
3405 WinHttpCloseHandle( con
);
3406 WinHttpCloseHandle( ses
);
3409 static void test_connection_info( int port
)
3411 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
3412 HINTERNET ses
, con
, req
;
3413 WINHTTP_CONNECTION_INFO info
;
3417 ses
= WinHttpOpen( test_useragent
, WINHTTP_ACCESS_TYPE_NO_PROXY
, NULL
, NULL
, 0 );
3418 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
3420 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
3421 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
3423 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
3424 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
3426 size
= sizeof(info
);
3427 SetLastError( 0xdeadbeef );
3428 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3429 error
= GetLastError();
3430 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
3432 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
3435 ok( !ret
, "unexpected success\n" );
3436 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
3438 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3439 ok( ret
, "failed to send request %u\n", GetLastError() );
3442 SetLastError( 0xdeadbeef );
3443 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3444 error
= GetLastError();
3445 ok( !ret
, "unexpected success\n" );
3446 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
3448 size
= sizeof(info
);
3449 memset( &info
, 0, sizeof(info
) );
3450 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3451 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3452 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3454 ret
= WinHttpReceiveResponse( req
, NULL
);
3455 ok( ret
, "failed to receive response %u\n", GetLastError() );
3457 size
= sizeof(info
);
3458 memset( &info
, 0, sizeof(info
) );
3459 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
3460 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
3461 ok( info
.cbSize
== sizeof(info
) || info
.cbSize
== sizeof(info
) - sizeof(info
.cbSize
) /* Win7 */, "wrong size %u\n", info
.cbSize
);
3463 WinHttpCloseHandle( req
);
3464 WinHttpCloseHandle( con
);
3465 WinHttpCloseHandle( ses
);
3468 static void test_credentials(void)
3470 static WCHAR userW
[] = {'u','s','e','r',0};
3471 static WCHAR passW
[] = {'p','a','s','s',0};
3472 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
3473 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
3474 HINTERNET ses
, con
, req
;
3479 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
3480 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
3482 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
3483 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
3485 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3486 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3488 size
= ARRAY_SIZE(buffer
);
3489 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3490 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3491 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3492 ok(!size
, "expected 0, got %u\n", size
);
3494 size
= ARRAY_SIZE(buffer
);
3495 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3496 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3497 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3498 ok(!size
, "expected 0, got %u\n", size
);
3500 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
3501 ok(ret
, "failed to set username %u\n", GetLastError());
3503 size
= ARRAY_SIZE(buffer
);
3504 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
3505 ok(ret
, "failed to query proxy username %u\n", GetLastError());
3506 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3507 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3509 size
= ARRAY_SIZE(buffer
);
3510 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3511 ok(ret
, "failed to query username %u\n", GetLastError());
3512 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3513 ok(!size
, "expected 0, got %u\n", size
);
3515 size
= ARRAY_SIZE(buffer
);
3516 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3517 ok(ret
, "failed to query password %u\n", GetLastError());
3518 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3519 ok(!size
, "expected 0, got %u\n", size
);
3521 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
3522 ok(ret
, "failed to set proxy password %u\n", GetLastError());
3524 size
= ARRAY_SIZE(buffer
);
3525 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
3526 ok(ret
, "failed to query proxy password %u\n", GetLastError());
3527 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3528 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3530 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
3531 ok(ret
, "failed to set username %u\n", GetLastError());
3533 size
= ARRAY_SIZE(buffer
);
3534 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3535 ok(ret
, "failed to query username %u\n", GetLastError());
3536 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3537 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3539 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
3540 ok(ret
, "failed to set password %u\n", GetLastError());
3542 size
= ARRAY_SIZE(buffer
);
3543 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3544 ok(ret
, "failed to query password %u\n", GetLastError());
3545 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
3546 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
3548 WinHttpCloseHandle(req
);
3550 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
3551 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
3553 SetLastError(0xdeadbeef);
3554 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
3555 error
= GetLastError();
3556 ok(!ret
, "expected failure\n");
3557 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3559 SetLastError(0xdeadbeef);
3560 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
3561 error
= GetLastError();
3562 ok(!ret
, "expected failure\n");
3563 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
3565 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
3566 ok(ret
, "failed to set credentials %u\n", GetLastError());
3568 size
= ARRAY_SIZE(buffer
);
3569 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
3570 ok(ret
, "failed to query username %u\n", GetLastError());
3572 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3573 ok(!size
, "expected 0, got %u\n", size
);
3576 size
= ARRAY_SIZE(buffer
);
3577 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
3578 ok(ret
, "failed to query password %u\n", GetLastError());
3580 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
3581 ok(!size
, "expected 0, got %u\n", size
);
3584 WinHttpCloseHandle(req
);
3585 WinHttpCloseHandle(con
);
3586 WinHttpCloseHandle(ses
);
3589 static void test_IWinHttpRequest(int port
)
3591 static const WCHAR data_start
[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3592 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
3593 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
3594 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3595 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3596 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3597 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3598 static const WCHAR method1W
[] = {'G','E','T',0};
3599 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
3600 static const WCHAR method3W
[] = {'P','O','S','T',0};
3601 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3602 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
3603 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
3604 static const WCHAR dateW
[] = {'D','a','t','e',0};
3605 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
3606 static const WCHAR utf8W
[] = {'u','t','f','-','8',0};
3607 static const WCHAR unauthW
[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3609 IWinHttpRequest
*req
;
3610 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
3611 BSTR date
, today
, connection
, value
= NULL
;
3612 VARIANT async
, empty
, timeout
, body
, body2
, proxy_server
, bypass_list
, data
, cp
;
3613 VARIANT_BOOL succeeded
;
3615 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
3617 IStream
*stream
, *stream2
;
3623 GetSystemTime( &st
);
3624 WinHttpTimeFromSystemTime( &st
, todayW
);
3626 CoInitialize( NULL
);
3627 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3628 ok( hr
== S_OK
, "got %08x\n", hr
);
3630 V_VT( &empty
) = VT_ERROR
;
3631 V_ERROR( &empty
) = 0xdeadbeef;
3633 V_VT( &async
) = VT_BOOL
;
3634 V_BOOL( &async
) = VARIANT_FALSE
;
3636 method
= SysAllocString( method3W
);
3637 url
= SysAllocString( url3W
);
3638 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3639 ok( hr
== S_OK
, "got %08x\n", hr
);
3640 SysFreeString( method
);
3641 SysFreeString( url
);
3643 V_VT( &data
) = VT_BSTR
;
3644 V_BSTR( &data
) = SysAllocString( test_dataW
);
3645 hr
= IWinHttpRequest_Send( req
, data
);
3646 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
3648 SysFreeString( V_BSTR( &data
) );
3650 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
3651 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3653 method
= SysAllocString( method1W
);
3654 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
3655 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3657 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
3658 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3660 url
= SysAllocString( url1W
);
3661 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
3662 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3664 hr
= IWinHttpRequest_Abort( req
);
3665 ok( hr
== S_OK
, "got %08x\n", hr
);
3667 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
3668 ok( hr
== S_OK
, "got %08x\n", hr
);
3670 hr
= IWinHttpRequest_Abort( req
);
3671 ok( hr
== S_OK
, "got %08x\n", hr
);
3673 IWinHttpRequest_Release( req
);
3675 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3676 ok( hr
== S_OK
, "got %08x\n", hr
);
3678 SysFreeString( url
);
3679 url
= SysAllocString( url2W
);
3680 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3681 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3683 SysFreeString( method
);
3684 method
= SysAllocString( method2W
);
3685 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3686 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
3688 SysFreeString( method
);
3689 method
= SysAllocString( method1W
);
3690 SysFreeString( url
);
3691 url
= SysAllocString( url1W
);
3692 V_VT( &async
) = VT_ERROR
;
3693 V_ERROR( &async
) = DISP_E_PARAMNOTFOUND
;
3694 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3695 ok( hr
== S_OK
, "got %08x\n", hr
);
3697 V_VT( &cp
) = VT_ERROR
;
3698 V_ERROR( &cp
) = 0xdeadbeef;
3699 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3700 ok( hr
== S_OK
, "got %08x\n", hr
);
3701 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3702 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3704 V_VT( &cp
) = VT_UI4
;
3705 V_UI4( &cp
) = CP_ACP
;
3706 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3707 ok( hr
== S_OK
, "got %08x\n", hr
);
3709 V_VT( &cp
) = VT_ERROR
;
3710 V_ERROR( &cp
) = 0xdeadbeef;
3711 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3712 ok( hr
== S_OK
, "got %08x\n", hr
);
3713 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3714 ok( V_I4( &cp
) == CP_ACP
, "got %u\n", V_I4( &cp
) );
3716 value
= SysAllocString( utf8W
);
3717 V_VT( &cp
) = VT_BSTR
;
3718 V_BSTR( &cp
) = value
;
3719 hr
= IWinHttpRequest_put_Option( req
, WinHttpRequestOption_URLCodePage
, cp
);
3720 ok( hr
== S_OK
, "got %08x\n", hr
);
3721 SysFreeString( value
);
3723 V_VT( &cp
) = VT_ERROR
;
3724 V_ERROR( &cp
) = 0xdeadbeef;
3725 hr
= IWinHttpRequest_get_Option( req
, WinHttpRequestOption_URLCodePage
, &cp
);
3726 ok( hr
== S_OK
, "got %08x\n", hr
);
3727 ok( V_VT( &cp
) == VT_I4
, "got %08x\n", V_VT( &cp
) );
3728 ok( V_I4( &cp
) == CP_UTF8
, "got %u\n", V_I4( &cp
) );
3730 hr
= IWinHttpRequest_Abort( req
);
3731 ok( hr
== S_OK
, "got %08x\n", hr
);
3733 hr
= IWinHttpRequest_Send( req
, empty
);
3734 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3736 hr
= IWinHttpRequest_Abort( req
);
3737 ok( hr
== S_OK
, "got %08x\n", hr
);
3739 IWinHttpRequest_Release( req
);
3741 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
3742 ok( hr
== S_OK
, "got %08x\n", hr
);
3744 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3745 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3747 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3748 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3750 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3751 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3753 hr
= IWinHttpRequest_get_Status( req
, &status
);
3754 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3756 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3757 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3759 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3760 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3762 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3763 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3765 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3766 ok( hr
== S_OK
, "got %08x\n", hr
);
3768 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3769 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3771 VariantInit( &proxy_server
);
3772 V_VT( &proxy_server
) = VT_ERROR
;
3773 VariantInit( &bypass_list
);
3774 V_VT( &bypass_list
) = VT_ERROR
;
3775 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3776 ok( hr
== S_OK
, "got %08x\n", hr
);
3778 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3779 ok( hr
== S_OK
, "got %08x\n", hr
);
3781 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3782 ok( hr
== S_OK
, "got %08x\n", hr
);
3784 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3785 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3787 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3788 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3790 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3791 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3793 connection
= SysAllocString( connectionW
);
3794 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3795 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3797 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3798 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3800 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
3801 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3803 date
= SysAllocString( dateW
);
3804 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3805 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3807 today
= SysAllocString( todayW
);
3808 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3809 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
3811 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
3812 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3814 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3815 ok( hr
== S_OK
, "got %08x\n", hr
);
3817 SysFreeString( method
);
3818 method
= SysAllocString( method1W
);
3819 SysFreeString( url
);
3820 url
= SysAllocString( url1W
);
3821 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
3822 ok( hr
== S_OK
, "got %08x\n", hr
);
3824 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3825 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3827 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3828 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3830 hr
= IWinHttpRequest_get_Status( req
, &status
);
3831 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3833 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3834 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3836 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3837 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3839 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
3840 ok( hr
== S_OK
, "got %08x\n", hr
);
3842 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
3843 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3845 username
= SysAllocString( usernameW
);
3846 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
3847 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3849 password
= SysAllocString( passwordW
);
3850 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
3851 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3853 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
3854 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3856 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3857 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3859 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3860 ok( hr
== S_OK
, "got %08x\n", hr
);
3862 V_VT( &proxy_server
) = VT_BSTR
;
3863 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
3864 V_VT( &bypass_list
) = VT_BSTR
;
3865 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
3866 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3867 ok( hr
== S_OK
, "got %08x\n", hr
);
3869 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
3870 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3872 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3873 ok( hr
== S_OK
, "got %08x\n", hr
);
3875 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3876 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3878 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3879 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
3881 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3882 ok( hr
== S_OK
, "got %08x\n", hr
);
3884 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
3885 ok( hr
== S_OK
, "got %08x\n", hr
);
3887 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3888 ok( hr
== S_OK
, "got %08x\n", hr
);
3890 hr
= IWinHttpRequest_Send( req
, empty
);
3891 ok( hr
== S_OK
, "got %08x\n", hr
);
3893 hr
= IWinHttpRequest_Send( req
, empty
);
3894 ok( hr
== S_OK
, "got %08x\n", hr
);
3896 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3897 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3899 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3900 ok( hr
== S_OK
, "got %08x\n", hr
);
3901 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
3902 SysFreeString( response
);
3904 hr
= IWinHttpRequest_get_Status( req
, NULL
);
3905 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3908 hr
= IWinHttpRequest_get_Status( req
, &status
);
3909 ok( hr
== S_OK
, "got %08x\n", hr
);
3910 trace("Status=%d\n", status
);
3912 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
3913 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3915 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3916 ok( hr
== S_OK
, "got %08x\n", hr
);
3917 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
3918 SysFreeString( status_text
);
3920 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3921 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3923 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3924 ok( hr
== S_OK
, "got %08x\n", hr
);
3926 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3927 ok( hr
== S_OK
, "got %08x\n", hr
);
3929 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3930 ok( hr
== S_OK
, "got %08x\n", hr
);
3932 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
3933 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3935 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
3936 ok( hr
== S_OK
, "got %08x\n", hr
);
3937 SysFreeString( headers
);
3939 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
3940 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3942 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
3943 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3945 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
3946 ok( hr
== S_OK
, "got %08x\n", hr
);
3947 SysFreeString( value
);
3949 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
3950 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
3952 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
3953 ok( hr
== S_OK
, "got %08x\n", hr
);
3955 VariantInit( &timeout
);
3956 V_VT( &timeout
) = VT_I4
;
3957 V_I4( &timeout
) = 10;
3958 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
3959 ok( hr
== S_OK
, "got %08x\n", hr
);
3961 hr
= IWinHttpRequest_get_Status( req
, &status
);
3962 ok( hr
== S_OK
, "got %08x\n", hr
);
3964 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
3965 ok( hr
== S_OK
, "got %08x\n", hr
);
3966 SysFreeString( status_text
);
3968 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
3969 ok( hr
== S_OK
, "got %08x\n", hr
);
3971 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
3972 ok( hr
== S_OK
, "got %08x\n", hr
);
3974 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
3975 ok( hr
== S_OK
, "got %08x\n", hr
);
3977 hr
= IWinHttpRequest_Send( req
, empty
);
3978 ok( hr
== S_OK
, "got %08x\n", hr
);
3980 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
3981 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3983 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
3984 ok( hr
== S_OK
, "got %08x\n", hr
);
3985 SysFreeString( response
);
3987 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
3988 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
3990 VariantInit( &body
);
3991 V_VT( &body
) = VT_ERROR
;
3992 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
3993 ok( hr
== S_OK
, "got %08x\n", hr
);
3994 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
3996 hr
= VariantClear( &body
);
3997 ok( hr
== S_OK
, "got %08x\n", hr
);
3999 VariantInit( &body
);
4000 V_VT( &body
) = VT_ERROR
;
4001 hr
= IWinHttpRequest_get_ResponseStream( req
, &body
);
4002 ok( hr
== S_OK
, "got %08x\n", hr
);
4003 ok( V_VT( &body
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body
) );
4005 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body
), &IID_IStream
, (void **)&stream
);
4006 ok( hr
== S_OK
, "got %08x\n", hr
);
4007 ok( V_UNKNOWN( &body
) == (IUnknown
*)stream
, "got different interface pointer\n" );
4011 hr
= IStream_Read( stream
, buf
, 128, &count
);
4012 ok( hr
== S_OK
, "got %08x\n", hr
);
4013 ok( count
!= 0xdeadbeef, "count not set\n" );
4014 ok( buf
[0], "no data\n" );
4016 VariantInit( &body2
);
4017 V_VT( &body2
) = VT_ERROR
;
4018 hr
= IWinHttpRequest_get_ResponseStream( req
, &body2
);
4019 ok( hr
== S_OK
, "got %08x\n", hr
);
4020 ok( V_VT( &body2
) == VT_UNKNOWN
, "got %08x\n", V_VT( &body2
) );
4021 ok( V_UNKNOWN( &body
) != V_UNKNOWN( &body2
), "got same interface pointer\n" );
4023 hr
= IUnknown_QueryInterface( V_UNKNOWN( &body2
), &IID_IStream
, (void **)&stream2
);
4024 ok( hr
== S_OK
, "got %08x\n", hr
);
4025 ok( V_UNKNOWN( &body2
) == (IUnknown
*)stream2
, "got different interface pointer\n" );
4026 IStream_Release( stream2
);
4028 hr
= VariantClear( &body
);
4029 ok( hr
== S_OK
, "got %08x\n", hr
);
4031 hr
= VariantClear( &body2
);
4032 ok( hr
== S_OK
, "got %08x\n", hr
);
4034 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
4035 ok( hr
== S_OK
, "got %08x\n", hr
);
4037 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
4038 ok( hr
== S_OK
, "got %08x\n", hr
);
4040 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
4041 ok( hr
== S_OK
, "got %08x\n", hr
);
4042 SysFreeString( headers
);
4044 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
4045 ok( hr
== S_OK
, "got %08x\n", hr
);
4046 SysFreeString( value
);
4048 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
4049 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
4051 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
4052 ok( hr
== S_OK
, "got %08x\n", hr
);
4054 hr
= IWinHttpRequest_Send( req
, empty
);
4055 ok( hr
== S_OK
, "got %08x\n", hr
);
4057 hr
= IWinHttpRequest_Abort( req
);
4058 ok( hr
== S_OK
, "got %08x\n", hr
);
4060 hr
= IWinHttpRequest_Abort( req
);
4061 ok( hr
== S_OK
, "got %08x\n", hr
);
4063 IWinHttpRequest_Release( req
);
4066 hr
= IStream_Seek( stream
, pos
, STREAM_SEEK_SET
, NULL
);
4067 ok( hr
== S_OK
, "got %08x\n", hr
);
4071 hr
= IStream_Read( stream
, buf
, 128, &count
);
4072 ok( hr
== S_OK
, "got %08x\n", hr
);
4073 ok( count
!= 0xdeadbeef, "count not set\n" );
4074 ok( buf
[0], "no data\n" );
4075 IStream_Release( stream
);
4077 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
4078 ok( hr
== S_OK
, "got %08x\n", hr
);
4080 V_VT( &async
) = VT_I4
;
4082 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
4083 ok( hr
== S_OK
, "got %08x\n", hr
);
4085 hr
= IWinHttpRequest_Send( req
, empty
);
4086 ok( hr
== S_OK
, "got %08x\n", hr
);
4088 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
4089 ok( hr
== S_OK
, "got %08x\n", hr
);
4091 IWinHttpRequest_Release( req
);
4093 SysFreeString( method
);
4094 SysFreeString( url
);
4095 SysFreeString( username
);
4096 SysFreeString( password
);
4097 SysFreeString( connection
);
4098 SysFreeString( date
);
4099 SysFreeString( today
);
4100 VariantClear( &proxy_server
);
4101 VariantClear( &bypass_list
);
4103 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
4104 ok( hr
== S_OK
, "got %08x\n", hr
);
4106 url
= SysAllocString( test_winehq_https
);
4107 method
= SysAllocString( method3W
);
4108 V_VT( &async
) = VT_BOOL
;
4109 V_BOOL( &async
) = VARIANT_FALSE
;
4110 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
4111 ok( hr
== S_OK
, "got %08x\n", hr
);
4112 SysFreeString( method
);
4113 SysFreeString( url
);
4115 hr
= IWinHttpRequest_Send( req
, empty
);
4116 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)), "got %08x\n", hr
);
4119 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
4120 ok( hr
== S_OK
, "got %08x\n", hr
);
4121 ok( !memcmp(response
, data_start
, sizeof(data_start
)), "got %s\n", wine_dbgstr_wn(response
, 32) );
4122 SysFreeString( response
);
4125 IWinHttpRequest_Release( req
);
4127 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
4128 ok( hr
== S_OK
, "got %08x\n", hr
);
4130 sprintf( buf
, "http://localhost:%d/auth", port
);
4131 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, bufW
, ARRAY_SIZE( bufW
));
4132 url
= SysAllocString( bufW
);
4133 method
= SysAllocString( method3W
);
4134 V_VT( &async
) = VT_BOOL
;
4135 V_BOOL( &async
) = VARIANT_FALSE
;
4136 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
4137 ok( hr
== S_OK
, "got %08x\n", hr
);
4138 SysFreeString( method
);
4139 SysFreeString( url
);
4141 hr
= IWinHttpRequest_get_Status( req
, &status
);
4142 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
4144 V_VT( &data
) = VT_BSTR
;
4145 V_BSTR( &data
) = SysAllocString( test_dataW
);
4146 hr
= IWinHttpRequest_Send( req
, data
);
4147 ok( hr
== S_OK
, "got %08x\n", hr
);
4148 SysFreeString( V_BSTR( &data
) );
4150 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
4151 ok( hr
== S_OK
, "got %08x\n", hr
);
4152 ok( !memcmp( response
, unauthW
, sizeof(unauthW
) ), "got %s\n", wine_dbgstr_w(response
) );
4153 SysFreeString( response
);
4155 status
= 0xdeadbeef;
4156 hr
= IWinHttpRequest_get_Status( req
, &status
);
4157 ok( hr
== S_OK
, "got %08x\n", hr
);
4158 ok( status
== HTTP_STATUS_DENIED
, "got %d\n", status
);
4160 IWinHttpRequest_Release( req
);
4165 static void request_get_property(IWinHttpRequest
*request
, int property
, VARIANT
*ret
)
4171 memset(¶ms
, 0, sizeof(params
));
4172 params
.cNamedArgs
= 0;
4173 params
.rgdispidNamedArgs
= NULL
;
4175 params
.rgvarg
= &arg
;
4178 V_I4(&arg
) = property
;
4180 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4181 DISPATCH_PROPERTYGET
, ¶ms
, ret
, NULL
, NULL
);
4182 ok(hr
== S_OK
, "error %#x\n", hr
);
4185 static void test_IWinHttpRequest_Invoke(void)
4187 static const WCHAR utf8W
[] = {'U','T','F','-','8',0};
4188 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};
4189 WCHAR openW
[] = {'O','p','e','n',0};
4190 WCHAR optionW
[] = {'O','p','t','i','o','n',0};
4191 OLECHAR
*open
= openW
, *option
= optionW
;
4194 IWinHttpRequest
*request
;
4195 IDispatch
*dispatch
;
4198 VARIANT arg
[3], ret
;
4205 hr
= CLSIDFromProgID(regid
, &clsid
);
4206 ok(hr
== S_OK
, "CLSIDFromProgID error %#x\n", hr
);
4207 bret
= IsEqualIID(&clsid
, &CLSID_WinHttpRequest
);
4208 ok(bret
|| broken(!bret
) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid
));
4210 hr
= CoCreateInstance(&CLSID_WinHttpRequest
, 0, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&request
);
4211 ok(hr
== S_OK
, "error %#x\n", hr
);
4213 hr
= IWinHttpRequest_QueryInterface(request
, &IID_IDispatch
, (void **)&dispatch
);
4214 ok(hr
== S_OK
, "error %#x\n", hr
);
4215 IDispatch_Release(dispatch
);
4217 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &open
, 1, 0x0409, &id
);
4218 ok(hr
== S_OK
, "error %#x\n", hr
);
4219 ok(id
== DISPID_HTTPREQUEST_OPEN
, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id
);
4221 hr
= IWinHttpRequest_GetIDsOfNames(request
, &IID_NULL
, &option
, 1, 0x0409, &id
);
4222 ok(hr
== S_OK
, "error %#x\n", hr
);
4223 ok(id
== DISPID_HTTPREQUEST_OPTION
, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id
);
4225 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4226 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4227 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4229 memset(¶ms
, 0, sizeof(params
));
4231 params
.cNamedArgs
= 0;
4232 params
.rgvarg
= arg
;
4233 V_VT(&arg
[0]) = VT_I4
;
4234 V_I4(&arg
[0]) = 1252;
4235 V_VT(&arg
[1]) = VT_R8
;
4236 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4238 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4239 DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
4240 ok(hr
== S_OK
, "error %#x\n", hr
);
4242 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4243 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4244 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4246 memset(¶ms
, 0, sizeof(params
));
4248 params
.cNamedArgs
= 0;
4249 params
.rgvarg
= arg
;
4250 V_VT(&arg
[0]) = VT_I4
;
4251 V_I4(&arg
[0]) = 1252;
4252 V_VT(&arg
[1]) = VT_R8
;
4253 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4255 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4256 DISPATCH_METHOD
| DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
4257 ok(hr
== S_OK
, "error %#x\n", hr
);
4259 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4260 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4261 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4263 memset(¶ms
, 0, sizeof(params
));
4265 params
.cNamedArgs
= 0;
4266 params
.rgvarg
= arg
;
4267 V_VT(&arg
[0]) = VT_I4
;
4268 V_I4(&arg
[0]) = 1252;
4269 V_VT(&arg
[1]) = VT_R8
;
4270 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4272 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0,
4273 DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, &err
);
4274 ok(hr
== S_OK
, "error %#x\n", hr
);
4276 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4277 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4278 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4280 memset(¶ms
, 0, sizeof(params
));
4282 params
.cNamedArgs
= 0;
4283 params
.rgvarg
= arg
;
4284 V_VT(&arg
[0]) = VT_BSTR
;
4285 utf8
= SysAllocString(utf8W
);
4286 V_BSTR(&arg
[0]) = utf8
;
4287 V_VT(&arg
[1]) = VT_R8
;
4288 V_R8(&arg
[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4289 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, NULL
, NULL
, &err
);
4290 ok(hr
== S_OK
, "error %#x\n", hr
);
4292 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4293 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4294 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4297 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, &err
);
4298 ok(hr
== S_OK
, "error %#x\n", hr
);
4300 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4301 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4302 ok(V_I4(&ret
) == 1252, "expected 1252, got %d\n", V_I4(&ret
));
4305 hr
= IWinHttpRequest_Invoke(request
, id
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4306 ok(hr
== S_OK
, "error %#x\n", hr
);
4308 request_get_property(request
, WinHttpRequestOption_URLCodePage
, &ret
);
4309 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4310 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4312 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
4313 ok(hr
== S_OK
, "error %#x\n", hr
);
4315 hr
= IWinHttpRequest_Invoke(request
, 255, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, NULL
, NULL
, NULL
);
4316 ok(hr
== DISP_E_MEMBERNOTFOUND
, "error %#x\n", hr
);
4319 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4320 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
4323 if (0) /* crashes */
4324 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, &ret
, NULL
, &err
);
4327 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4328 ok(hr
== DISP_E_TYPEMISMATCH
, "error %#x\n", hr
);
4330 VariantInit(&arg
[2]);
4332 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, ¶ms
, &ret
, NULL
, &err
);
4334 ok(hr
== S_OK
, "error %#x\n", hr
);
4336 VariantInit(&arg
[0]);
4337 VariantInit(&arg
[1]);
4338 VariantInit(&arg
[2]);
4341 V_VT(&arg
[0]) = VT_I4
;
4342 V_I4(&arg
[0]) = WinHttpRequestOption_URLCodePage
;
4343 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4344 ok(hr
== S_OK
, "error %#x\n", hr
);
4346 V_VT(&ret
) = 0xdead;
4347 V_I4(&ret
) = 0xbeef;
4348 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, &ret
, NULL
, NULL
);
4349 ok(hr
== S_OK
, "error %#x\n", hr
);
4350 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4351 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4353 V_VT(&ret
) = 0xdead;
4354 V_I4(&ret
) = 0xbeef;
4355 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
4356 ok(hr
== S_OK
, "error %#x\n", hr
);
4357 ok(V_VT(&ret
) == VT_I4
, "expected VT_I4, got %d\n", V_VT(&ret
));
4358 ok(V_I4(&ret
) == CP_UTF8
, "expected CP_UTF8, got %d\n", V_I4(&ret
));
4360 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4361 ok(hr
== S_OK
, "error %#x\n", hr
);
4363 V_VT(&ret
) = 0xdead;
4364 V_I4(&ret
) = 0xbeef;
4365 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, &ret
, NULL
, NULL
);
4366 ok(hr
== S_OK
, "error %#x\n", hr
);
4367 ok(V_VT(&ret
) == VT_EMPTY
, "expected VT_EMPTY, got %d\n", V_VT(&ret
));
4368 ok(V_I4(&ret
) == 0xbeef || V_I4(&ret
) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret
));
4370 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, 0, ¶ms
, NULL
, NULL
, NULL
);
4371 ok(hr
== S_OK
, "error %#x\n", hr
);
4373 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_IUnknown
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4374 ok(hr
== DISP_E_UNKNOWNINTERFACE
, "error %#x\n", hr
);
4377 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4379 ok(hr
== S_OK
, "error %#x\n", hr
);
4382 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_OPTION
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, ¶ms
, NULL
, NULL
, NULL
);
4383 ok(hr
== DISP_E_PARAMNOTFOUND
, "error %#x\n", hr
);
4385 SysFreeString(utf8
);
4388 V_VT(&arg
[0]) = VT_I4
;
4389 V_I4(&arg
[0]) = AutoLogonPolicy_Never
;
4391 hr
= IWinHttpRequest_Invoke(request
, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY
, &IID_NULL
, 0,
4392 DISPATCH_METHOD
, ¶ms
, &ret
, NULL
, NULL
);
4393 ok(hr
== S_OK
, "error %#x\n", hr
);
4395 IWinHttpRequest_Release(request
);
4400 static void test_WinHttpDetectAutoProxyConfigUrl(void)
4406 if (0) /* crashes on some win2k systems */
4408 SetLastError(0xdeadbeef);
4409 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
4410 error
= GetLastError();
4411 ok( !ret
, "expected failure\n" );
4412 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4415 SetLastError(0xdeadbeef);
4416 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
4417 error
= GetLastError();
4418 ok( !ret
, "expected failure\n" );
4419 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4421 if (0) /* crashes on some win2k systems */
4423 SetLastError(0xdeadbeef);
4424 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
4425 error
= GetLastError();
4426 ok( !ret
, "expected failure\n" );
4427 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4429 url
= (WCHAR
*)0xdeadbeef;
4430 SetLastError(0xdeadbeef);
4431 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
4432 error
= GetLastError();
4435 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4436 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4440 trace("%s\n", wine_dbgstr_w(url
));
4444 url
= (WCHAR
*)0xdeadbeef;
4445 SetLastError(0xdeadbeef);
4446 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
4447 error
= GetLastError();
4450 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
4451 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
4455 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4456 trace("%s\n", wine_dbgstr_w(url
));
4461 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
4465 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
4467 memset( &cfg
, 0, sizeof(cfg
) );
4469 SetLastError(0xdeadbeef);
4470 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
4471 error
= GetLastError();
4472 ok( !ret
, "expected failure\n" );
4473 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4475 SetLastError(0xdeadbeef);
4476 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
4477 error
= GetLastError();
4478 ok( ret
, "expected success\n" );
4479 ok( error
== ERROR_SUCCESS
|| broken(error
== ERROR_NO_TOKEN
) /* < win7 */, "got %u\n", error
);
4481 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
4482 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
4483 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
4484 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
4485 GlobalFree( cfg
.lpszAutoConfigUrl
);
4486 GlobalFree( cfg
.lpszProxy
);
4487 GlobalFree( cfg
.lpszProxyBypass
);
4490 static void test_WinHttpGetProxyForUrl(void)
4492 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4493 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4494 static const WCHAR emptyW
[] = {0};
4498 WINHTTP_AUTOPROXY_OPTIONS options
;
4499 WINHTTP_PROXY_INFO info
;
4501 memset( &options
, 0, sizeof(options
) );
4503 SetLastError(0xdeadbeef);
4504 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
4505 error
= GetLastError();
4506 ok( !ret
, "expected failure\n" );
4507 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
4509 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4510 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
4512 SetLastError(0xdeadbeef);
4513 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
4514 error
= GetLastError();
4515 ok( !ret
, "expected failure\n" );
4516 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4518 SetLastError(0xdeadbeef);
4519 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
4520 error
= GetLastError();
4521 ok( !ret
, "expected failure\n" );
4522 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4524 SetLastError(0xdeadbeef);
4525 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
4526 error
= GetLastError();
4527 ok( !ret
, "expected failure\n" );
4528 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4530 SetLastError(0xdeadbeef);
4531 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4532 error
= GetLastError();
4533 ok( !ret
, "expected failure\n" );
4534 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4536 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4537 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4539 SetLastError(0xdeadbeef);
4540 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
4541 error
= GetLastError();
4542 ok( !ret
, "expected failure\n" );
4543 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4545 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4546 options
.dwAutoDetectFlags
= 0;
4548 SetLastError(0xdeadbeef);
4549 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4550 error
= GetLastError();
4551 ok( !ret
, "expected failure\n" );
4552 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4554 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
4555 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4557 SetLastError(0xdeadbeef);
4558 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4559 error
= GetLastError();
4560 ok( !ret
, "expected failure\n" );
4561 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
4563 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
4564 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
4566 memset( &info
, 0, sizeof(info
) );
4567 SetLastError(0xdeadbeef);
4568 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4569 error
= GetLastError();
4572 ok( error
== ERROR_SUCCESS
, "got %u\n", error
);
4573 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4574 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4575 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4576 GlobalFree( info
.lpszProxy
);
4577 GlobalFree( info
.lpszProxyBypass
);
4580 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
4581 options
.dwAutoDetectFlags
= 0;
4582 options
.lpszAutoConfigUrl
= wpadW
;
4584 memset( &info
, 0, sizeof(info
) );
4585 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
4588 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
4589 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
4590 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
4591 GlobalFree( info
.lpszProxy
);
4592 GlobalFree( info
.lpszProxyBypass
);
4594 WinHttpCloseHandle( session
);
4597 static void test_chunked_read(void)
4599 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
4600 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
4603 HINTERNET ses
, con
= NULL
, req
= NULL
;
4606 trace( "starting chunked read test\n" );
4608 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
4609 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
4610 if (!ses
) goto done
;
4612 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
4613 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
4614 if (!con
) goto done
;
4616 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
4617 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4618 if (!req
) goto done
;
4620 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
4621 err
= GetLastError();
4622 if (!ret
&& (err
== ERROR_WINHTTP_CANNOT_CONNECT
|| err
== ERROR_WINHTTP_TIMEOUT
))
4624 skip("connection failed, skipping\n");
4627 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4628 if (!ret
) goto done
;
4630 ret
= WinHttpReceiveResponse( req
, NULL
);
4631 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4632 if (!ret
) goto done
;
4635 len
= sizeof(header
);
4636 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
4637 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4638 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
4639 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
4642 len
= sizeof(header
);
4643 SetLastError( 0xdeadbeef );
4644 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
4645 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
4646 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
4648 trace( "entering query loop\n" );
4652 ret
= WinHttpQueryDataAvailable( req
, &len
);
4653 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4654 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4655 trace( "got %u available\n", len
);
4659 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
4661 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
4663 buf
[bytes_read
] = 0;
4664 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
4665 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
4666 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
4668 HeapFree( GetProcessHeap(), 0, buf
);
4669 if (!bytes_read
) break;
4676 if (req
) WinHttpCloseHandle( req
);
4677 if (con
) WinHttpCloseHandle( con
);
4678 if (ses
) WinHttpCloseHandle( ses
);
4681 START_TEST (winhttp
)
4683 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
4684 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
4685 struct server_info si
;
4691 test_WinHttpTimeFromSystemTime();
4692 test_WinHttpTimeToSystemTime();
4693 test_WinHttpAddHeaders();
4694 test_secure_connection();
4695 test_request_parameter_defaults();
4697 test_set_default_proxy_config();
4698 test_empty_headers_param();
4700 test_resolve_timeout();
4702 test_IWinHttpRequest_Invoke();
4703 test_WinHttpDetectAutoProxyConfigUrl();
4704 test_WinHttpGetIEProxyConfigForCurrentUser();
4705 test_WinHttpGetProxyForUrl();
4706 test_chunked_read();
4708 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
4711 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
4712 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
4714 ret
= WaitForSingleObject(si
.event
, 10000);
4715 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
4716 if (ret
!= WAIT_OBJECT_0
)
4718 CloseHandle(thread
);
4722 test_IWinHttpRequest(si
.port
);
4723 test_connection_info(si
.port
);
4724 test_basic_request(si
.port
, NULL
, basicW
);
4725 test_no_headers(si
.port
);
4726 test_no_content(si
.port
);
4727 test_head_request(si
.port
);
4728 test_not_modified(si
.port
);
4729 test_basic_authentication(si
.port
);
4730 test_multi_authentication(si
.port
);
4731 test_large_data_authentication(si
.port
);
4732 test_bad_header(si
.port
);
4733 test_multiple_reads(si
.port
);
4734 test_cookies(si
.port
);
4735 test_request_path_escapes(si
.port
);
4737 /* send the basic request again to shutdown the server thread */
4738 test_basic_request(si
.port
, NULL
, quitW
);
4740 WaitForSingleObject(thread
, 3000);
4741 CloseHandle(thread
);