winhttp: Support WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE.
[wine.git] / dlls / winhttp / tests / winhttp.c
blob45eaf1a673a3e286dbfe38cef8fc82362ecb0025
1 /*
2 * WinHTTP - tests
4 * Copyright 2008 Google (Zac Brown)
5 * Copyright 2015 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
23 #include <stdarg.h>
24 #include <windef.h>
25 #include <winsock2.h>
26 #include <ws2tcpip.h>
27 #include <winhttp.h>
28 #include <wincrypt.h>
29 #include <winreg.h>
30 #include <initguid.h>
31 #include <httprequest.h>
32 #include <httprequestid.h>
34 #include "wine/test.h"
36 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
38 static DWORD (WINAPI *pWinHttpWebSocketClose)(HINTERNET,USHORT,void*,DWORD);
39 static HINTERNET (WINAPI *pWinHttpWebSocketCompleteUpgrade)(HINTERNET,DWORD_PTR);
40 static DWORD (WINAPI *pWinHttpWebSocketQueryCloseStatus)(HINTERNET,USHORT*,void*,DWORD,DWORD*);
41 static DWORD (WINAPI *pWinHttpWebSocketReceive)(HINTERNET,void*,DWORD,DWORD*,WINHTTP_WEB_SOCKET_BUFFER_TYPE*);
42 static DWORD (WINAPI *pWinHttpWebSocketSend)(HINTERNET,WINHTTP_WEB_SOCKET_BUFFER_TYPE,void*,DWORD);
43 static DWORD (WINAPI *pWinHttpWebSocketShutdown)(HINTERNET,USHORT,void*,DWORD);
45 static BOOL proxy_active(void)
47 WINHTTP_PROXY_INFO proxy_info;
48 BOOL active = FALSE;
50 SetLastError(0xdeadbeef);
51 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
53 ok( GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
54 "got %lu\n", GetLastError() );
55 active = (proxy_info.lpszProxy != NULL);
56 if (active)
57 GlobalFree(proxy_info.lpszProxy);
58 if (proxy_info.lpszProxyBypass != NULL)
59 GlobalFree(proxy_info.lpszProxyBypass);
61 else
62 active = FALSE;
64 return active;
67 static void test_WinHttpQueryOption(void)
69 BOOL ret;
70 HINTERNET session, request, connection;
71 DWORD feature, size;
73 SetLastError(0xdeadbeef);
74 session = WinHttpOpen(L"winetest", 0, 0, 0, 0);
75 ok( session != NULL, "WinHttpOpen failed to open session, error %lu\n", GetLastError() );
77 SetLastError(0xdeadbeef);
78 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
79 ok( !ret, "should fail to set redirect policy %lu\n", GetLastError() );
80 ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError() );
82 size = 0xdeadbeef;
83 SetLastError(0xdeadbeef);
84 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
85 ok(!ret, "should fail to query option\n");
86 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError() );
87 ok( size == 4, "expected 4, got %lu\n", size );
89 feature = 0xdeadbeef;
90 size = sizeof(feature) - 1;
91 SetLastError(0xdeadbeef);
92 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
93 ok(!ret, "should fail to query option\n");
94 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError() );
95 ok( size == 4, "expected 4, got %lu\n", size );
97 feature = 0xdeadbeef;
98 size = sizeof(feature) + 1;
99 SetLastError(0xdeadbeef);
100 ret = WinHttpQueryOption(session, WINHTTP_OPTION_WORKER_THREAD_COUNT, &feature, &size);
101 ok(ret, "failed to query option %lu\n", GetLastError());
102 ok(GetLastError() == ERROR_SUCCESS, "got %lu\n", GetLastError());
103 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %lu\n", size);
104 ok(feature == 0, "got unexpected WINHTTP_OPTION_WORKER_THREAD_COUNT %#lx\n", feature);
106 feature = 0xdeadbeef;
107 size = sizeof(feature) + 1;
108 SetLastError(0xdeadbeef);
109 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
110 ok(ret, "failed to query option %lu\n", GetLastError());
111 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
112 "got %lu\n", GetLastError());
113 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %lu\n", size);
114 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
115 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#lx\n", feature);
117 SetLastError(0xdeadbeef);
118 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
119 ok(!ret, "should fail to set redirect policy %lu\n", GetLastError());
120 ok(GetLastError() == ERROR_INVALID_PARAMETER,
121 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
123 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
124 SetLastError(0xdeadbeef);
125 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
126 ok(!ret, "should fail to set redirect policy %lu\n", GetLastError());
127 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
128 "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
130 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
131 SetLastError(0xdeadbeef);
132 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
133 ok(!ret, "should fail to set redirect policy %lu\n", GetLastError());
134 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
135 "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
137 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
138 SetLastError(0xdeadbeef);
139 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
140 ok(ret, "failed to set redirect policy %lu\n", GetLastError());
142 feature = 0xdeadbeef;
143 size = sizeof(feature);
144 SetLastError(0xdeadbeef);
145 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
146 ok(ret, "failed to query option %lu\n", GetLastError());
147 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
148 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#lx\n", feature);
150 feature = WINHTTP_DISABLE_COOKIES;
151 SetLastError(0xdeadbeef);
152 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
153 ok(!ret, "should fail to set disable feature for a session\n");
154 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
155 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %lu\n", GetLastError());
157 SetLastError(0xdeadbeef);
158 connection = WinHttpConnect(session, L"test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, 0);
159 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %lu\n", GetLastError());
161 feature = WINHTTP_DISABLE_COOKIES;
162 SetLastError(0xdeadbeef);
163 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
164 ok(!ret, "should fail to set disable feature for a connection\n");
165 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
166 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %lu\n", GetLastError());
168 SetLastError(0xdeadbeef);
169 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
170 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
171 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
173 skip("Network unreachable, skipping the test\n");
174 goto done;
177 feature = 0xdeadbeef;
178 size = sizeof(feature);
179 SetLastError(0xdeadbeef);
180 ret = WinHttpQueryOption(connection, WINHTTP_OPTION_WORKER_THREAD_COUNT, &feature, &size);
181 ok(ret, "query WINHTTP_OPTION_WORKER_THREAD_COUNT failed for a request\n");
182 ok(GetLastError() == ERROR_SUCCESS, "got unexpected error %lu\n", GetLastError());
183 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %lu\n", size);
184 ok(feature == 0, "got unexpected WINHTTP_OPTION_WORKER_THREAD_COUNT %#lx\n", feature);
186 feature = 0xdeadbeef;
187 size = sizeof(feature);
188 SetLastError(0xdeadbeef);
189 ret = WinHttpQueryOption(request, WINHTTP_OPTION_WORKER_THREAD_COUNT, &feature, &size);
190 ok(ret, "query WINHTTP_OPTION_WORKER_THREAD_COUNT failed for a request\n");
191 ok(GetLastError() == ERROR_SUCCESS, "got unexpected error %lu\n", GetLastError());
192 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %lu\n", size);
193 ok(feature == 0, "got unexpected WINHTTP_OPTION_WORKER_THREAD_COUNT %#lx\n", feature);
195 feature = 0xdeadbeef;
196 size = sizeof(feature);
197 SetLastError(0xdeadbeef);
198 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
199 ok(!ret, "should fail to query disable feature for a request\n");
200 ok(GetLastError() == ERROR_INVALID_PARAMETER,
201 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
203 feature = 0;
204 size = sizeof(feature);
205 SetLastError(0xdeadbeef);
206 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
207 ok(ret, "failed to set feature %lu\n", GetLastError());
209 feature = 0xffffffff;
210 size = sizeof(feature);
211 SetLastError(0xdeadbeef);
212 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
213 ok(ret, "failed to set feature %lu\n", GetLastError());
215 feature = WINHTTP_DISABLE_COOKIES;
216 size = sizeof(feature);
217 SetLastError(0xdeadbeef);
218 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
219 ok(ret, "failed to set feature %lu\n", GetLastError());
221 size = 0;
222 SetLastError(0xdeadbeef);
223 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
224 ok(!ret, "should fail to query disable feature for a request\n");
225 ok(GetLastError() == ERROR_INVALID_PARAMETER,
226 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
228 feature = 0xdeadbeef;
229 size = sizeof(feature);
230 SetLastError(0xdeadbeef);
231 ret = WinHttpQueryOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, &size);
232 ok(!ret, "should fail to query enabled features for a request\n");
233 ok(feature == 0xdeadbeef, "expect feature 0xdeadbeef, got %#lx\n", feature);
234 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
236 feature = WINHTTP_ENABLE_SSL_REVOCATION;
237 SetLastError(0xdeadbeef);
238 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, 0, sizeof(feature));
239 ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
240 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
242 SetLastError(0xdeadbeef);
243 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, 0);
244 ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
245 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
247 SetLastError(0xdeadbeef);
248 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, sizeof(feature));
249 ok(ret, "failed to set feature\n");
250 ok(GetLastError() == NO_ERROR || broken(GetLastError() == 0xdeadbeef), /* Doesn't set error code on Vista or older */
251 "expected NO_ERROR, got %lu\n", GetLastError());
253 feature = 0xdeadbeef;
254 SetLastError(0xdeadbeef);
255 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, sizeof(feature));
256 ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
257 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
259 feature = 6;
260 size = sizeof(feature);
261 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONNECT_RETRIES, &feature, sizeof(feature));
262 ok(ret, "failed to set WINHTTP_OPTION_CONNECT_RETRIES %lu\n", GetLastError());
264 SetLastError(0xdeadbeef);
265 ret = WinHttpCloseHandle(request);
266 ok(ret, "WinHttpCloseHandle failed on closing request: %lu\n", GetLastError());
268 done:
269 SetLastError(0xdeadbeef);
270 ret = WinHttpCloseHandle(connection);
271 ok(ret, "WinHttpCloseHandle failed on closing connection: %lu\n", GetLastError());
272 SetLastError(0xdeadbeef);
273 ret = WinHttpCloseHandle(session);
274 ok(ret, "WinHttpCloseHandle failed on closing session: %lu\n", GetLastError());
277 static void test_WinHttpOpenRequest (void)
279 BOOL ret;
280 HINTERNET session, request, connection;
281 DWORD err;
283 SetLastError(0xdeadbeef);
284 session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
285 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
286 err = GetLastError();
287 ok(session != NULL, "WinHttpOpen failed to open session.\n");
288 ok(err == ERROR_SUCCESS, "got %lu\n", err);
290 /* Test with a bad server name */
291 SetLastError(0xdeadbeef);
292 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
293 err = GetLastError();
294 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
295 ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %lu.\n", err);
297 /* Test with a valid server name */
298 SetLastError(0xdeadbeef);
299 connection = WinHttpConnect (session, L"test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, 0);
300 err = GetLastError();
301 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %lu.\n", err);
302 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %lu\n", err);
304 SetLastError(0xdeadbeef);
305 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
306 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
307 err = GetLastError();
308 if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED)
310 skip("Network unreachable, skipping.\n");
311 goto done;
313 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %lu.\n", err);
314 ok(err == ERROR_SUCCESS, "got %lu\n", err);
316 SetLastError(0xdeadbeef);
317 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
318 err = GetLastError();
319 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
321 skip("Connection failed, skipping.\n");
322 goto done;
324 ok(ret, "WinHttpSendRequest failed: %lu\n", err);
325 ok(err == ERROR_SUCCESS, "got %lu\n", err);
327 SetLastError(0xdeadbeef);
328 ret = WinHttpCloseHandle(request);
329 err = GetLastError();
330 ok(ret, "WinHttpCloseHandle failed on closing request, got %lu.\n", err);
331 ok(err == ERROR_SUCCESS, "got %lu\n", err);
333 done:
334 ret = WinHttpCloseHandle(connection);
335 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
336 ret = WinHttpCloseHandle(session);
337 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
341 static void test_empty_headers_param(void)
343 HINTERNET ses, con, req;
344 DWORD err;
345 BOOL ret;
347 ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
348 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
350 con = WinHttpConnect(ses, L"test.winehq.org", 80, 0);
351 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
353 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
354 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
356 ret = WinHttpSendRequest(req, L"", 0, NULL, 0, 0, 0);
357 err = GetLastError();
358 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
360 skip("connection failed, skipping\n");
361 goto done;
363 ok(ret, "failed to send request %lu\n", GetLastError());
365 done:
366 WinHttpCloseHandle(req);
367 WinHttpCloseHandle(con);
368 WinHttpCloseHandle(ses);
371 static void test_WinHttpSendRequest (void)
373 static const WCHAR content_type[] = L"Content-Type: application/x-www-form-urlencoded";
374 static char post_data[] = "mode=Test";
375 static const char test_post[] = "mode => Test\0\n";
376 HINTERNET session, request, connection;
377 DWORD header_len, optional_len, total_len, bytes_rw, size, err, disable, len;
378 DWORD_PTR context;
379 BOOL ret;
380 CHAR buffer[256];
381 WCHAR method[8];
382 int i;
384 header_len = -1L;
385 total_len = optional_len = sizeof(post_data);
386 memset(buffer, 0xff, sizeof(buffer));
388 session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
389 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
390 ok(session != NULL, "WinHttpOpen failed to open session.\n");
392 connection = WinHttpConnect (session, L"test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, 0);
393 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %lu\n", GetLastError());
395 request = WinHttpOpenRequest(connection, L"POST", L"tests/post.php", NULL, WINHTTP_NO_REFERER,
396 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
397 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
399 skip("Network unreachable, skipping.\n");
400 goto done;
402 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %lu\n", GetLastError());
403 if (!request) goto done;
405 method[0] = 0;
406 len = sizeof(method);
407 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_REQUEST_METHOD, NULL, method, &len, NULL);
408 ok(ret, "got %lu\n", GetLastError());
409 ok(len == lstrlenW(L"POST") * sizeof(WCHAR), "got %lu\n", len);
410 ok(!lstrcmpW(method, L"POST"), "got %s\n", wine_dbgstr_w(method));
412 context = 0xdeadbeef;
413 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
414 ok(ret, "WinHttpSetOption failed: %lu\n", GetLastError());
416 /* writing more data than promised by the content-length header causes an error when the connection
417 is reused, so disable keep-alive */
418 disable = WINHTTP_DISABLE_KEEP_ALIVE;
419 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable));
420 ok(ret, "WinHttpSetOption failed: %lu\n", GetLastError());
422 context++;
423 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
424 err = GetLastError();
425 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
427 skip("connection failed, skipping\n");
428 goto done;
430 ok(ret == TRUE, "WinHttpSendRequest failed: %lu\n", GetLastError());
432 context = 0;
433 size = sizeof(context);
434 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
435 ok(ret, "WinHttpQueryOption failed: %lu\n", GetLastError());
436 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %#Ix\n", context);
438 for (i = 3; post_data[i]; i++)
440 bytes_rw = -1;
441 SetLastError(0xdeadbeef);
442 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
443 if (ret)
445 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %lu\n", GetLastError());
446 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %lu bytes instead of 1 byte\n", bytes_rw);
448 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
450 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %lu\n", GetLastError());
451 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
455 SetLastError(0xdeadbeef);
456 ret = WinHttpReceiveResponse(request, NULL);
457 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */,
458 "Expected ERROR_SUCCESS got %lu\n", GetLastError());
459 ok(ret == TRUE, "WinHttpReceiveResponse failed: %lu\n", GetLastError());
461 SetLastError(0xdeadbeef);
462 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_ORIG_URI, NULL, NULL, &len, NULL);
463 ok(!ret && GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %lu\n", GetLastError());
465 SetLastError(0xdeadbeef);
466 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_MAX + 1, NULL, NULL, &len, NULL);
467 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
469 bytes_rw = -1;
470 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
471 ok(ret == TRUE, "WinHttpReadData failed: %lu\n", GetLastError());
473 ok(bytes_rw == sizeof(test_post) - 1, "Read %lu bytes\n", bytes_rw);
474 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
476 done:
477 ret = WinHttpCloseHandle(request);
478 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
479 ret = WinHttpCloseHandle(connection);
480 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
481 ret = WinHttpCloseHandle(session);
482 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
485 static void test_connect_error(void)
487 static const WCHAR content_type[] = L"Content-Type: application/x-www-form-urlencoded";
488 DWORD header_len, optional_len, total_len, err, t1, t2;
489 HINTERNET session, request, connection;
490 static char post_data[] = "mode=Test";
491 BOOL ret;
493 header_len = ~0u;
494 total_len = optional_len = sizeof(post_data);
496 session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
497 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
498 ok(!!session, "WinHttpOpen failed to open session.\n");
500 connection = WinHttpConnect (session, L"127.0.0.1", 12345, 0);
501 ok(!!connection, "WinHttpConnect failed to open a connection, error %lu.\n", GetLastError());
503 request = WinHttpOpenRequest(connection, L"POST", L"tests/post.php", NULL, WINHTTP_NO_REFERER,
504 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
505 ok(!!request, "WinHttpOpenrequest failed to open a request, error: %lu\n", GetLastError());
507 t1 = GetTickCount();
508 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, 0);
509 t2 = GetTickCount();
510 err = GetLastError();
511 ok(!ret, "WinHttpSendRequest() succeeded.\n");
512 ok(err == ERROR_WINHTTP_CANNOT_CONNECT, "Got unexpected err %lu.\n", err);
513 ok(t2 - t1 < 5000, "Unexpected connect failure delay %lums.\n", t2 - t1);
515 WinHttpCloseHandle(request);
516 WinHttpCloseHandle(connection);
517 WinHttpCloseHandle(session);
520 static void test_WinHttpTimeFromSystemTime(void)
522 BOOL ret;
523 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
524 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
525 DWORD err;
527 SetLastError(0xdeadbeef);
528 ret = WinHttpTimeFromSystemTime(&time, NULL);
529 err = GetLastError();
530 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
531 ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err);
533 SetLastError(0xdeadbeef);
534 ret = WinHttpTimeFromSystemTime(NULL, time_string);
535 err = GetLastError();
536 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
537 ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err);
539 SetLastError(0xdeadbeef);
540 ret = WinHttpTimeFromSystemTime(&time, time_string);
541 err = GetLastError();
542 ok(ret, "WinHttpTimeFromSystemTime failed: %lu\n", err);
543 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err);
544 ok(!memcmp(time_string, L"Mon, 28 Jul 2008 10:05:52 GMT", sizeof(L"Mon, 28 Jul 2008 10:05:52 GMT")),
545 "Time string returned did not match expected time string.\n");
548 static void test_WinHttpTimeToSystemTime(void)
550 BOOL ret;
551 SYSTEMTIME time;
552 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
553 DWORD err;
555 SetLastError(0xdeadbeef);
556 ret = WinHttpTimeToSystemTime(L"Mon, 28 Jul 2008 10:05:52 GMT\n", NULL);
557 err = GetLastError();
558 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
559 ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err);
561 SetLastError(0xdeadbeef);
562 ret = WinHttpTimeToSystemTime(NULL, &time);
563 err = GetLastError();
564 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
565 ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err);
567 SetLastError(0xdeadbeef);
568 ret = WinHttpTimeToSystemTime(L"Mon, 28 Jul 2008 10:05:52 GMT\n", &time);
569 err = GetLastError();
570 ok(ret, "WinHttpTimeToSystemTime failed: %lu\n", err);
571 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err);
572 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
573 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
575 SetLastError(0xdeadbeef);
576 ret = WinHttpTimeToSystemTime(L" mon 28 jul 2008 10 05 52\n", &time);
577 err = GetLastError();
578 ok(ret, "WinHttpTimeToSystemTime failed: %lu\n", err);
579 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err);
580 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
581 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
584 static void test_WinHttpAddHeaders(void)
586 static const WCHAR test_header_begin[] =
587 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
588 HINTERNET session, request, connection;
589 BOOL ret, reverse;
590 WCHAR buffer[MAX_PATH];
591 WCHAR check_buffer[MAX_PATH];
592 DWORD err, index, len, oldlen;
594 static const WCHAR test_headers[][14] =
596 L"Warning:test1",
597 L"Warning:test2",
598 L"Warning:test3",
599 L"Warning:test4",
600 L"Warning:test5",
601 L"Warning:test6",
602 L"Warning:test7",
603 L"",
604 L":",
605 L"a:",
606 L":b",
607 L"cd",
608 L" e :f",
609 L"field: value ",
610 L"name: value",
611 L"name:",
613 static const WCHAR test_indices[][6] =
615 L"test1",
616 L"test2",
617 L"test3",
618 L"test4",
621 session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
622 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
623 ok(session != NULL, "WinHttpOpen failed to open session.\n");
625 connection = WinHttpConnect (session, L"test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, 0);
626 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %lu\n", GetLastError());
628 request = WinHttpOpenRequest(connection, L"POST", L"/posttest.php", NULL, WINHTTP_NO_REFERER,
629 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
630 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
632 skip("Network unreachable, skipping.\n");
633 goto done;
635 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %lu\n", GetLastError());
637 index = 0;
638 len = sizeof(buffer);
639 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
640 L"Warning", buffer, &len, &index);
641 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
642 SetLastError(0xdeadbeef);
643 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
644 err = GetLastError();
645 ok(ret, "WinHttpAddRequestHeaders failed to add new header, got %d with error %lu\n", ret, err);
646 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %lu\n", err);
648 index = 0;
649 len = sizeof(buffer);
650 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
651 L"Warning", buffer, &len, &index);
652 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
653 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
654 ok(!memcmp(buffer, test_indices[0], sizeof(test_indices[0])),
655 "WinHttpQueryHeaders failed: incorrect string returned\n");
656 ok(len == 5 * sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %lu\n", len);
658 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
659 L"Warning", buffer, &len, &index);
660 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
662 /* Try to fetch the header info with a buffer that's big enough to fit the
663 * string but not the NULL terminator.
665 index = 0;
666 len = 5*sizeof(WCHAR);
667 memset(check_buffer, 0xab, sizeof(check_buffer));
668 memcpy(buffer, check_buffer, sizeof(buffer));
669 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
670 L"Warning", buffer, &len, &index);
671 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
672 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
673 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
674 ok(len == 6 * sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %lu\n", len);
676 /* Try with a NULL buffer */
677 index = 0;
678 len = sizeof(buffer);
679 SetLastError(0xdeadbeef);
680 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
681 L"Warning", NULL, &len, &index);
682 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
683 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
684 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %lu\n", len);
685 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
687 /* Try with a NULL buffer and a length that's too small */
688 index = 0;
689 len = 10;
690 SetLastError(0xdeadbeef);
691 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
692 L"Warning", NULL, &len, &index);
693 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
694 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
695 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
696 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %lu\n", len);
697 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
699 index = 0;
700 len = 0;
701 SetLastError(0xdeadbeef);
702 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
703 L"Warning", NULL, &len, &index);
704 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
705 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
706 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
707 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %lu\n", len);
708 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
710 /* valid query */
711 oldlen = len;
712 index = 0;
713 len = sizeof(buffer);
714 memset(buffer, 0xff, sizeof(buffer));
715 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
716 L"Warning", buffer, &len, &index);
717 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
718 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
719 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)],
720 "WinHttpQueryHeaders did not append NULL terminator\n");
721 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
722 ok(!memcmp(buffer, test_header_begin, sizeof(test_header_begin)), "invalid beginning of header string.\n");
723 ok(!memcmp(buffer + lstrlenW(buffer) - 4, L"\r\n\r\n", sizeof(L"\r\n\r\n")),
724 "WinHttpQueryHeaders returned invalid end of header string.\n");
725 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
727 index = 0;
728 len = 0;
729 SetLastError(0xdeadbeef);
730 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
731 L"Warning", NULL, &len, &index);
732 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
733 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
734 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
735 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %lu\n", len);
736 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
738 oldlen = len;
739 index = 0;
740 len = sizeof(buffer);
741 memset(buffer, 0xff, sizeof(buffer));
742 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
743 L"Warning", buffer, &len, &index);
744 ok(ret == TRUE, "WinHttpQueryHeaders failed %lu\n", GetLastError());
745 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
746 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
747 "no double NULL terminator\n");
748 ok(!memcmp(buffer, test_header_begin, sizeof(test_header_begin)), "invalid beginning of header string.\n");
749 ok(index == 0, "header index was incremented\n");
751 /* tests for more indices */
752 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
753 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
755 index = 0;
756 len = sizeof(buffer);
757 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
758 L"Warning", buffer, &len, &index);
759 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
760 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
761 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
763 len = sizeof(buffer);
764 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
765 L"Warning", buffer, &len, &index);
766 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
767 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
768 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
770 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
771 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
773 index = 0;
774 len = sizeof(buffer);
775 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
776 L"Warning", buffer, &len, &index);
777 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
778 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
779 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
780 ok(!memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])),
781 "WinHttpQueryHeaders returned incorrect string.\n");
783 len = sizeof(buffer);
784 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
785 L"Warning", buffer, &len, &index);
786 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
787 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
788 ok(!memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])),
789 "WinHttpQueryHeaders returned incorrect string.\n");
791 /* add if new flag */
792 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
793 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
795 index = 0;
796 len = sizeof(buffer);
797 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
798 L"Warning", buffer, &len, &index);
799 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
800 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
801 ok(!memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])),
802 "WinHttpQueryHeaders returned incorrect string.\n");
804 len = sizeof(buffer);
805 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
806 L"Warning", buffer, &len, &index);
807 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
808 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
809 ok(!memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])),
810 "WinHttpQueryHeaders returned incorrect string.\n");
812 len = sizeof(buffer);
813 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
814 L"Warning", buffer, &len, &index);
815 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
817 /* coalesce flag */
818 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
819 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
821 index = 0;
822 len = sizeof(buffer);
823 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
824 L"Warning", buffer, &len, &index);
825 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
826 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
827 ok(!memcmp(buffer, reverse ? L"test3, test4" : L"test2, test4",
828 reverse ? sizeof(L"test3, test4") : sizeof(L"test2, test4")),
829 "WinHttpQueryHeaders returned incorrect string.\n");
831 len = sizeof(buffer);
832 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
833 L"Warning", buffer, &len, &index);
834 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
835 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
836 ok(!memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])),
837 "WinHttpQueryHeaders returned incorrect string.\n");
839 len = sizeof(buffer);
840 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
841 L"Warning", buffer, &len, &index);
842 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
844 /* coalesce with comma flag */
845 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
846 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
848 index = 0;
849 len = sizeof(buffer);
850 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
851 L"Warning", buffer, &len, &index);
852 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
853 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
855 ok(!memcmp(buffer, reverse ? L"test3, test4, test5" : L"test2, test4, test5",
856 reverse ? sizeof(L"test3, test4, test5") : sizeof(L"test2, test4, test5")),
857 "WinHttpQueryHeaders returned incorrect string.\n");
859 len = sizeof(buffer);
860 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
861 L"Warning", buffer, &len, &index);
862 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
863 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
864 ok(!memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])),
865 "WinHttpQueryHeaders returned incorrect string.\n");
867 len = sizeof(buffer);
868 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
869 L"Warning", buffer, &len, &index);
870 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
873 /* coalesce with semicolon flag */
874 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
875 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
877 index = 0;
878 len = sizeof(buffer);
879 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
880 L"Warning", buffer, &len, &index);
881 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
882 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
884 ok(!memcmp(buffer, reverse ? L"test3, test4, test5; test6" : L"test2, test4, test5; test6",
885 reverse ? sizeof(L"test3, test4, test5; test6") : sizeof(L"test2, test4, test5; test6")),
886 "WinHttpQueryHeaders returned incorrect string.\n");
888 len = sizeof(buffer);
889 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
890 L"Warning", buffer, &len, &index);
891 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
892 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
893 ok(!memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])),
894 "WinHttpQueryHeaders returned incorrect string.\n");
896 len = sizeof(buffer);
897 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
898 L"Warning", buffer, &len, &index);
899 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
901 /* add and replace flags */
902 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
903 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
905 index = 0;
906 len = sizeof(buffer);
907 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
908 L"Warning", buffer, &len, &index);
909 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
910 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
911 ok(!memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])),
912 "WinHttpQueryHeaders returned incorrect string.\n");
914 len = sizeof(buffer);
915 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
916 L"Warning", buffer, &len, &index);
917 ok(ret == TRUE, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
918 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
919 ok(!memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])),
920 "WinHttpQueryHeaders returned incorrect string.\n");
922 len = sizeof(buffer);
923 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
924 L"Warning", buffer, &len, &index);
925 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
927 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
928 ok(!ret, "WinHttpAddRequestHeaders failed\n");
930 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
931 ok(ret, "WinHttpAddRequestHeaders failed\n");
933 index = 0;
934 memset(buffer, 0xff, sizeof(buffer));
935 len = sizeof(buffer);
936 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
937 L"a", buffer, &len, &index);
938 ok(ret, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
939 ok(!memcmp(buffer, L"", sizeof(L"")), "unexpected result\n");
941 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
942 ok(!ret, "WinHttpAddRequestHeaders failed\n");
944 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
945 ok(!ret, "WinHttpAddRequestHeaders failed\n");
947 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
948 ok(!ret, "WinHttpAddRequestHeaders failed\n");
950 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
951 ok(ret, "WinHttpAddRequestHeaders failed\n");
953 index = 0;
954 buffer[0] = 0;
955 len = sizeof(buffer);
956 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
957 L"field", buffer, &len, &index);
958 ok(ret, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
959 ok(!memcmp(buffer, L"value ", sizeof(L"value ")) || !memcmp(buffer, L"value", sizeof(L"value")),
960 "unexpected result\n");
962 SetLastError(0xdeadbeef);
963 ret = WinHttpAddRequestHeaders(request, L"Range: bytes=0-773\r\n", 0,
964 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
965 err = GetLastError();
966 ok(!ret, "unexpected success\n");
967 ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err);
969 ret = WinHttpAddRequestHeaders(request, L"Range: bytes=0-773\r\n", ~0u,
970 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
971 ok(ret, "failed to add header: %lu\n", GetLastError());
973 index = 0;
974 len = sizeof(buffer);
975 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
976 L"Range", buffer, &len, &index);
977 ok(ret, "failed to get range header %lu\n", GetLastError());
978 ok(!memcmp(buffer, L"bytes=0-773", sizeof(L"bytes=0-773")), "incorrect string returned\n");
979 ok(len == lstrlenW(L"bytes=0-773") * sizeof(WCHAR), "wrong length %lu\n", len);
980 ok(index == 1, "wrong index %lu\n", index);
981 index = 0;
982 len = sizeof(buffer);
983 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
984 L"name", buffer, &len, &index);
985 ok(!ret, "unexpected success\n");
987 SetLastError(0xdeadbeef);
988 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
989 err = GetLastError();
990 ok(!ret, "unexpected success\n");
991 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %lu\n", err);
993 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
994 ok(ret, "got %lu\n", GetLastError());
996 index = 0;
997 len = sizeof(buffer);
998 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
999 L"name", buffer, &len, &index);
1000 ok(ret, "got %lu\n", GetLastError());
1001 ok(index == 1, "wrong index %lu\n", index);
1002 ok(!memcmp(buffer, L"value", sizeof(L"value")), "incorrect string\n");
1004 ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
1005 ok(ret, "got %lu\n", GetLastError());
1007 index = 0;
1008 len = sizeof(buffer);
1009 SetLastError(0xdeadbeef);
1010 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
1011 L"name", buffer, &len, &index);
1012 err = GetLastError();
1013 ok(!ret, "unexpected success\n");
1014 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %lu\n", err);
1016 ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0);
1017 ok(ret, "got %lu\n", GetLastError());
1019 index = 0;
1020 len = sizeof(buffer);
1021 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
1022 L"name", buffer, &len, &index);
1023 ok(ret, "got %lu\n", GetLastError());
1024 ok(index == 1, "wrong index %lu\n", index);
1025 ok(!memcmp(buffer, L"value", sizeof(L"value")), "incorrect string\n");
1027 ret = WinHttpCloseHandle(request);
1028 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
1029 done:
1030 ret = WinHttpCloseHandle(connection);
1031 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
1032 ret = WinHttpCloseHandle(session);
1033 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
1037 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len)
1039 DWORD flags = *(DWORD *)buf;
1041 if (!flags)
1043 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
1044 return;
1046 #define X(x) if (flags & x) trace("%s\n", #x);
1047 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
1048 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
1049 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
1050 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
1051 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
1052 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
1053 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
1054 #undef X
1057 static void test_secure_connection(void)
1059 static const char data_start[] = "<!DOCTYPE html PUBLIC";
1060 HINTERNET ses, con, req;
1061 DWORD size, status, policy, bitness, read_size, err, available_size, protocols, flags;
1062 BOOL ret;
1063 CERT_CONTEXT *cert;
1064 WINHTTP_CERTIFICATE_INFO info;
1065 char buffer[32];
1067 ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
1068 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
1070 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
1071 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
1072 ok(ret, "failed to set redirect policy %lu\n", GetLastError());
1074 protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
1075 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols));
1076 err = GetLastError();
1077 ok(ret || err == ERROR_INVALID_PARAMETER /* < win7 */, "failed to set protocols %lu\n", err);
1079 con = WinHttpConnect(ses, L"test.winehq.org", 443, 0);
1080 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
1082 SetLastError( 0xdeadbeef );
1083 protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
1084 ret = WinHttpSetOption(con, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols));
1085 err = GetLastError();
1086 ok(!ret, "unexpected success\n");
1087 ok(err == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", err);
1089 /* try without setting WINHTTP_FLAG_SECURE */
1090 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1091 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
1093 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
1094 err = GetLastError();
1095 ok(!ret, "unexpected success\n");
1096 ok(err == ERROR_WINHTTP_INCORRECT_HANDLE_STATE || broken(err == ERROR_INVALID_PARAMETER) /* winxp */,
1097 "setting client cert context returned %lu\n", err);
1099 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1100 err = GetLastError();
1101 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
1103 skip("Connection failed, skipping.\n");
1104 goto cleanup;
1106 ok(ret, "failed to send request %lu\n", GetLastError());
1108 ret = WinHttpReceiveResponse(req, NULL);
1109 ok(ret, "failed to receive response %lu\n", GetLastError());
1111 status = 0xdeadbeef;
1112 size = sizeof(status);
1113 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1114 ok(ret, "header query failed %lu\n", GetLastError());
1115 ok(status == HTTP_STATUS_BAD_REQUEST, "got %lu\n", status);
1117 WinHttpCloseHandle(req);
1119 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
1120 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
1122 flags = 0xdeadbeef;
1123 size = sizeof(flags);
1124 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, &size);
1125 ok(ret, "failed to query security flags %lu\n", GetLastError());
1126 ok(!flags, "got %#lx\n", flags);
1128 flags = SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
1129 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1130 ok(ret, "failed to set security flags %lu\n", GetLastError());
1132 flags = SECURITY_FLAG_SECURE;
1133 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1134 ok(!ret, "success\n");
1136 flags = SECURITY_FLAG_STRENGTH_STRONG;
1137 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1138 ok(!ret, "success\n");
1140 flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
1141 SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
1142 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1143 ok(ret, "failed to set security flags %lu\n", GetLastError());
1145 flags = 0;
1146 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1147 ok(ret, "failed to set security flags %lu\n", GetLastError());
1149 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
1150 err = GetLastError();
1151 ok(ret || broken(!ret && err == ERROR_INVALID_PARAMETER) /* winxp */, "failed to set client cert context %lu\n", err);
1153 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
1155 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1156 err = GetLastError();
1157 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT ||
1158 err == ERROR_WINHTTP_TIMEOUT || err == SEC_E_ILLEGAL_MESSAGE))
1160 skip("secure connection failed, skipping remaining secure tests\n");
1161 goto cleanup;
1163 ok(ret, "failed to send request %lu\n", GetLastError());
1165 size = sizeof(cert);
1166 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
1167 ok(ret, "failed to retrieve certificate context %lu\n", GetLastError());
1168 if (ret) CertFreeCertificateContext(cert);
1170 size = sizeof(bitness);
1171 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
1172 ok(ret, "failed to retrieve key bitness %lu\n", GetLastError());
1174 size = sizeof(info);
1175 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
1176 ok(ret, "failed to retrieve certificate info %lu\n", GetLastError());
1178 if (ret)
1180 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
1181 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
1182 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
1183 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
1184 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
1185 trace("dwKeySize %lu\n", info.dwKeySize);
1186 LocalFree( info.lpszSubjectInfo );
1187 LocalFree( info.lpszIssuerInfo );
1190 ret = WinHttpReceiveResponse(req, NULL);
1191 if (!ret && GetLastError() == ERROR_WINHTTP_CONNECTION_ERROR)
1193 skip("connection error, skipping remaining secure tests\n");
1194 goto cleanup;
1196 ok(ret, "failed to receive response %lu\n", GetLastError());
1198 available_size = 0;
1199 ret = WinHttpQueryDataAvailable(req, &available_size);
1200 ok(ret, "failed to query available data %lu\n", GetLastError());
1201 ok(available_size > 2014, "available_size = %lu\n", available_size);
1203 status = 0xdeadbeef;
1204 size = sizeof(status);
1205 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1206 ok(ret, "failed unexpectedly %lu\n", GetLastError());
1207 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
1209 size = 0;
1210 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1211 ok(!ret, "succeeded unexpectedly\n");
1213 read_size = 0;
1214 for (;;)
1216 size = 0;
1217 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
1218 ok(ret == TRUE, "WinHttpReadData failed: %lu\n", GetLastError());
1219 if (!size) break;
1220 read_size += size;
1222 if (read_size <= 32)
1223 ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer);
1225 ok(read_size >= available_size, "read_size = %lu, available_size = %lu\n", read_size, available_size);
1227 size = sizeof(cert);
1228 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size);
1229 ok(ret, "failed to retrieve certificate context %lu\n", GetLastError());
1230 if (ret) CertFreeCertificateContext(cert);
1232 cleanup:
1233 WinHttpCloseHandle(req);
1234 WinHttpCloseHandle(con);
1235 WinHttpCloseHandle(ses);
1238 static void test_request_parameter_defaults(void)
1240 HINTERNET ses, con, req;
1241 DWORD size, status, error;
1242 WCHAR *version;
1243 BOOL ret;
1245 ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
1246 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
1248 con = WinHttpConnect(ses, L"test.winehq.org", 0, 0);
1249 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
1251 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1252 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
1254 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1255 error = GetLastError();
1256 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1258 skip("connection failed, skipping\n");
1259 goto done;
1261 ok(ret, "failed to send request %lu\n", GetLastError());
1263 ret = WinHttpReceiveResponse(req, NULL);
1264 ok(ret, "failed to receive response %lu\n", GetLastError());
1266 status = 0xdeadbeef;
1267 size = sizeof(status);
1268 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1269 ok(ret, "failed unexpectedly %lu\n", GetLastError());
1270 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
1272 WinHttpCloseHandle(req);
1274 req = WinHttpOpenRequest(con, L"", L"", L"", NULL, NULL, 0);
1275 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
1277 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1278 error = GetLastError();
1279 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1281 skip("connection failed, skipping\n");
1282 goto done;
1284 ok(ret, "failed to send request %lu\n", GetLastError());
1286 ret = WinHttpReceiveResponse(req, NULL);
1287 ok(ret, "failed to receive response %lu\n", GetLastError());
1289 size = 0;
1290 SetLastError(0xdeadbeef);
1291 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
1292 error = GetLastError();
1293 ok(!ret, "succeeded unexpectedly\n");
1294 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", error);
1296 version = HeapAlloc(GetProcessHeap(), 0, size);
1297 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
1298 ok(ret, "failed unexpectedly %lu\n", GetLastError());
1299 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %lu\n", size);
1300 HeapFree(GetProcessHeap(), 0, version);
1302 status = 0xdeadbeef;
1303 size = sizeof(status);
1304 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1305 ok(ret, "failed unexpectedly %lu\n", GetLastError());
1306 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
1308 done:
1309 WinHttpCloseHandle(req);
1310 WinHttpCloseHandle(con);
1311 WinHttpCloseHandle(ses);
1314 static const WCHAR Connections[] = {
1315 'S','o','f','t','w','a','r','e','\\',
1316 'M','i','c','r','o','s','o','f','t','\\',
1317 'W','i','n','d','o','w','s','\\',
1318 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1319 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1320 'C','o','n','n','e','c','t','i','o','n','s',0 };
1321 static const WCHAR WinHttpSettings[] = {
1322 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1324 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
1326 LONG l;
1327 HKEY key;
1328 DWORD ret = 0;
1330 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
1331 if (!l)
1333 DWORD size = 0;
1335 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
1336 if (!l)
1338 if (size <= len)
1339 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1340 &size );
1341 if (!l)
1342 ret = size;
1344 RegCloseKey( key );
1346 return ret;
1349 static void set_proxy( REGSAM access, BYTE *buf, DWORD len, DWORD type )
1351 HKEY hkey;
1352 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0, access, NULL, &hkey, NULL ))
1354 if (len) RegSetValueExW( hkey, WinHttpSettings, 0, type, buf, len );
1355 else RegDeleteValueW( hkey, WinHttpSettings );
1356 RegCloseKey( hkey );
1360 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1362 BOOL wow64;
1363 IsWow64Process( GetCurrentProcess(), &wow64 );
1364 if (sizeof(void *) > sizeof(int) || wow64)
1366 set_proxy( KEY_WRITE|KEY_WOW64_64KEY, buf, len, type );
1367 set_proxy( KEY_WRITE|KEY_WOW64_32KEY, buf, len, type );
1369 else
1370 set_proxy( KEY_WRITE, buf, len, type );
1373 static void test_set_default_proxy_config(void)
1375 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1376 static WCHAR normalString[] = { 'f','o','o',0 };
1377 DWORD type, len;
1378 BYTE *saved_proxy_settings = NULL;
1379 WINHTTP_PROXY_INFO info;
1380 BOOL ret;
1382 /* FIXME: it would be simpler to read the current settings using
1383 * WinHttpGetDefaultProxyConfiguration and save them using
1384 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1386 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1387 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1388 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1389 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1390 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1391 * the lpszProxy and lpszProxyBypass values are ignored.
1392 * Thus, if a proxy is set with proxycfg, then calling
1393 * WinHttpGetDefaultProxyConfiguration followed by
1394 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1395 * getting deleted from the registry.
1397 * Instead I read the current registry value and restore it directly.
1399 len = get_default_proxy_reg_value( NULL, 0, &type );
1400 if (len)
1402 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1403 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1406 if (0)
1408 /* Crashes on Vista and higher */
1409 SetLastError(0xdeadbeef);
1410 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1411 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1412 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1415 /* test with invalid access type */
1416 info.dwAccessType = 0xdeadbeef;
1417 info.lpszProxy = info.lpszProxyBypass = NULL;
1418 SetLastError(0xdeadbeef);
1419 ret = WinHttpSetDefaultProxyConfiguration(&info);
1420 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1421 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1423 /* at a minimum, the proxy server must be set */
1424 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1425 info.lpszProxy = info.lpszProxyBypass = NULL;
1426 SetLastError(0xdeadbeef);
1427 ret = WinHttpSetDefaultProxyConfiguration(&info);
1428 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1429 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1430 info.lpszProxyBypass = normalString;
1431 SetLastError(0xdeadbeef);
1432 ret = WinHttpSetDefaultProxyConfiguration(&info);
1433 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1434 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1436 /* the proxy server can't have wide characters */
1437 info.lpszProxy = wideString;
1438 SetLastError(0xdeadbeef);
1439 ret = WinHttpSetDefaultProxyConfiguration(&info);
1440 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1441 skip("couldn't set default proxy configuration: access denied\n");
1442 else
1443 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1444 broken(ret), /* Earlier winhttp versions on W2K/XP */
1445 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1447 info.lpszProxy = normalString;
1448 SetLastError(0xdeadbeef);
1449 ret = WinHttpSetDefaultProxyConfiguration(&info);
1450 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1451 skip("couldn't set default proxy configuration: access denied\n");
1452 else
1454 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %lu\n", GetLastError());
1455 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1456 "got %lu\n", GetLastError());
1458 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1461 static void test_timeouts(void)
1463 BOOL ret;
1464 DWORD value, size;
1465 HINTERNET ses, req, con;
1467 ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
1468 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
1470 SetLastError(0xdeadbeef);
1471 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1472 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1473 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1475 SetLastError(0xdeadbeef);
1476 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1477 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1478 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1480 SetLastError(0xdeadbeef);
1481 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1482 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1483 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1485 SetLastError(0xdeadbeef);
1486 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1487 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1488 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1490 SetLastError(0xdeadbeef);
1491 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1492 ok(ret, "%lu\n", GetLastError());
1493 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1494 "expected ERROR_SUCCESS, got %lu\n", GetLastError());
1496 SetLastError(0xdeadbeef);
1497 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1498 ok(ret, "%lu\n", GetLastError());
1500 SetLastError(0xdeadbeef);
1501 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1502 ok(ret, "%lu\n", GetLastError());
1504 SetLastError(0xdeadbeef);
1505 value = 0xdeadbeef;
1506 size = sizeof(DWORD);
1507 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1508 ok(ret, "%lu\n", GetLastError());
1509 ok(value == 0x0123, "Expected 0x0123, got %lu\n", value);
1511 SetLastError(0xdeadbeef);
1512 value = 0xdeadbeef;
1513 size = sizeof(DWORD);
1514 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1515 ok(ret, "%lu\n", GetLastError());
1516 ok(value == 0x4567, "Expected 0x4567, got %lu\n", value);
1518 SetLastError(0xdeadbeef);
1519 value = 0xdeadbeef;
1520 size = sizeof(DWORD);
1521 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1522 ok(ret, "%lu\n", GetLastError());
1523 ok(value == 0x89ab, "Expected 0x89ab, got %lu\n", value);
1525 SetLastError(0xdeadbeef);
1526 value = 0xdeadbeef;
1527 size = sizeof(DWORD);
1528 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1529 ok(ret, "%lu\n", GetLastError());
1530 ok(value == 0xcdef, "Expected 0xcdef, got %lu\n", value);
1532 SetLastError(0xdeadbeef);
1533 value = 0;
1534 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1535 ok(ret, "%lu\n", GetLastError());
1537 SetLastError(0xdeadbeef);
1538 value = 0xdeadbeef;
1539 size = sizeof(DWORD);
1540 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1541 ok(ret, "%lu\n", GetLastError());
1542 ok(value == 0, "Expected 0, got %lu\n", value);
1544 SetLastError(0xdeadbeef);
1545 value = 0;
1546 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1547 ok(ret, "%lu\n", GetLastError());
1549 SetLastError(0xdeadbeef);
1550 value = 0xdeadbeef;
1551 size = sizeof(DWORD);
1552 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1553 ok(ret, "%lu\n", GetLastError());
1554 ok(value == 0, "Expected 0, got %lu\n", value);
1556 SetLastError(0xdeadbeef);
1557 value = 0;
1558 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1559 ok(ret, "%lu\n", GetLastError());
1561 SetLastError(0xdeadbeef);
1562 value = 0xdeadbeef;
1563 size = sizeof(DWORD);
1564 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1565 ok(ret, "%lu\n", GetLastError());
1566 ok(value == 0, "Expected 0, got %lu\n", value);
1568 SetLastError(0xdeadbeef);
1569 value = 0;
1570 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1571 ok(ret, "%lu\n", GetLastError());
1573 SetLastError(0xdeadbeef);
1574 value = 0xdeadbeef;
1575 size = sizeof(DWORD);
1576 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1577 ok(ret, "%lu\n", GetLastError());
1578 ok(value == 0, "Expected 0, got %lu\n", value);
1580 SetLastError(0xdeadbeef);
1581 value = 0xbeefdead;
1582 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1583 ok(ret, "%lu\n", GetLastError());
1585 SetLastError(0xdeadbeef);
1586 value = 0xdeadbeef;
1587 size = sizeof(DWORD);
1588 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1589 ok(ret, "%lu\n", GetLastError());
1590 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1592 SetLastError(0xdeadbeef);
1593 value = 0xbeefdead;
1594 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1595 ok(ret, "%lu\n", GetLastError());
1597 SetLastError(0xdeadbeef);
1598 value = 0xdeadbeef;
1599 size = sizeof(DWORD);
1600 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1601 ok(ret, "%lu\n", GetLastError());
1602 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1604 SetLastError(0xdeadbeef);
1605 value = 0xbeefdead;
1606 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1607 ok(ret, "%lu\n", GetLastError());
1609 SetLastError(0xdeadbeef);
1610 value = 0xdeadbeef;
1611 size = sizeof(DWORD);
1612 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1613 ok(ret, "%lu\n", GetLastError());
1614 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1616 SetLastError(0xdeadbeef);
1617 value = 0xbeefdead;
1618 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1619 ok(ret, "%lu\n", GetLastError());
1621 SetLastError(0xdeadbeef);
1622 value = 0xdeadbeef;
1623 size = sizeof(DWORD);
1624 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1625 ok(ret, "%lu\n", GetLastError());
1626 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1628 con = WinHttpConnect(ses, L"test.winehq.org", 0, 0);
1629 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
1631 /* Timeout values should match the last one set for session */
1632 SetLastError(0xdeadbeef);
1633 value = 0xdeadbeef;
1634 size = sizeof(DWORD);
1635 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1636 ok(ret, "%lu\n", GetLastError());
1637 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1639 SetLastError(0xdeadbeef);
1640 value = 0xdeadbeef;
1641 size = sizeof(DWORD);
1642 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1643 ok(ret, "%lu\n", GetLastError());
1644 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1646 SetLastError(0xdeadbeef);
1647 value = 0xdeadbeef;
1648 size = sizeof(DWORD);
1649 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1650 ok(ret, "%lu\n", GetLastError());
1651 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1653 SetLastError(0xdeadbeef);
1654 value = 0xdeadbeef;
1655 size = sizeof(DWORD);
1656 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1657 ok(ret, "%lu\n", GetLastError());
1658 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1660 SetLastError(0xdeadbeef);
1661 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1662 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1663 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1665 SetLastError(0xdeadbeef);
1666 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1667 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1668 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1670 SetLastError(0xdeadbeef);
1671 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1672 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1673 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1675 SetLastError(0xdeadbeef);
1676 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1677 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1678 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1680 SetLastError(0xdeadbeef);
1681 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1682 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1683 "expected ERROR_WINHTTP_INVALID_TYPE, got %lu\n", GetLastError());
1685 SetLastError(0xdeadbeef);
1686 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1687 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1688 "expected ERROR_WINHTTP_INVALID_TYPE, got %lu\n", GetLastError());
1690 SetLastError(0xdeadbeef);
1691 value = 0;
1692 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1693 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1694 "expected ERROR_WINHTTP_INVALID_TYPE, got %lu\n", GetLastError());
1696 SetLastError(0xdeadbeef);
1697 value = 0;
1698 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1699 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1700 "expected ERROR_WINHTTP_INVALID_TYPE, got %lu\n", GetLastError());
1702 SetLastError(0xdeadbeef);
1703 value = 0;
1704 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1705 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1706 "expected ERROR_WINHTTP_INVALID_TYPE, got %lu\n", GetLastError());
1708 SetLastError(0xdeadbeef);
1709 value = 0;
1710 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1711 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1712 "expected ERROR_WINHTTP_INVALID_TYPE, got %lu\n", GetLastError());
1714 /* Changing timeout values for session should affect the values for connection */
1715 SetLastError(0xdeadbeef);
1716 value = 0xdead;
1717 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1718 ok(ret, "%lu\n", GetLastError());
1720 SetLastError(0xdeadbeef);
1721 value = 0xdeadbeef;
1722 size = sizeof(DWORD);
1723 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1724 ok(ret, "%lu\n", GetLastError());
1725 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1727 SetLastError(0xdeadbeef);
1728 value = 0xdead;
1729 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1730 ok(ret, "%lu\n", GetLastError());
1732 SetLastError(0xdeadbeef);
1733 value = 0xdeadbeef;
1734 size = sizeof(DWORD);
1735 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1736 ok(ret, "%lu\n", GetLastError());
1737 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1739 SetLastError(0xdeadbeef);
1740 value = 0xdead;
1741 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1742 ok(ret, "%lu\n", GetLastError());
1744 SetLastError(0xdeadbeef);
1745 value = 0xdeadbeef;
1746 size = sizeof(DWORD);
1747 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1748 ok(ret, "%lu\n", GetLastError());
1749 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1751 SetLastError(0xdeadbeef);
1752 value = 0xdead;
1753 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1754 ok(ret, "%lu\n", GetLastError());
1756 SetLastError(0xdeadbeef);
1757 value = 0xdeadbeef;
1758 size = sizeof(DWORD);
1759 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1760 ok(ret, "%lu\n", GetLastError());
1761 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1763 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1764 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
1766 /* Timeout values should match the last one set for session */
1767 SetLastError(0xdeadbeef);
1768 value = 0xdeadbeef;
1769 size = sizeof(DWORD);
1770 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1771 ok(ret, "%lu\n", GetLastError());
1772 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1774 SetLastError(0xdeadbeef);
1775 value = 0xdeadbeef;
1776 size = sizeof(DWORD);
1777 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1778 ok(ret, "%lu\n", GetLastError());
1779 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1781 SetLastError(0xdeadbeef);
1782 value = 0xdeadbeef;
1783 size = sizeof(DWORD);
1784 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1785 ok(ret, "%lu\n", GetLastError());
1786 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1788 SetLastError(0xdeadbeef);
1789 value = 0xdeadbeef;
1790 size = sizeof(DWORD);
1791 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1792 ok(ret, "%lu\n", GetLastError());
1793 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1795 SetLastError(0xdeadbeef);
1796 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1797 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1798 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1800 SetLastError(0xdeadbeef);
1801 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1802 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1803 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1805 SetLastError(0xdeadbeef);
1806 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1807 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1808 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1810 SetLastError(0xdeadbeef);
1811 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1812 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1813 "expected ERROR_INVALID_PARAMETER, got %lu\n", GetLastError());
1815 SetLastError(0xdeadbeef);
1816 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1817 ok(ret, "%lu\n", GetLastError());
1819 SetLastError(0xdeadbeef);
1820 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1821 ok(ret, "%lu\n", GetLastError());
1823 SetLastError(0xdeadbeef);
1824 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1825 ok(ret, "%lu\n", GetLastError());
1827 SetLastError(0xdeadbeef);
1828 value = 0xdeadbeef;
1829 size = sizeof(DWORD);
1830 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1831 ok(ret, "%lu\n", GetLastError());
1832 ok(value == 0xcdef, "Expected 0xcdef, got %lu\n", value);
1834 SetLastError(0xdeadbeef);
1835 value = 0xdeadbeef;
1836 size = sizeof(DWORD);
1837 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1838 ok(ret, "%lu\n", GetLastError());
1839 ok(value == 0x89ab, "Expected 0x89ab, got %lu\n", value);
1841 SetLastError(0xdeadbeef);
1842 value = 0xdeadbeef;
1843 size = sizeof(DWORD);
1844 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1845 ok(ret, "%lu\n", GetLastError());
1846 ok(value == 0x4567, "Expected 0x4567, got %lu\n", value);
1848 SetLastError(0xdeadbeef);
1849 value = 0xdeadbeef;
1850 size = sizeof(DWORD);
1851 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1852 ok(ret, "%lu\n", GetLastError());
1853 ok(value == 0x0123, "Expected 0x0123, got %lu\n", value);
1855 SetLastError(0xdeadbeef);
1856 value = 0;
1857 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1858 ok(ret, "%lu\n", GetLastError());
1860 SetLastError(0xdeadbeef);
1861 value = 0xdeadbeef;
1862 size = sizeof(DWORD);
1863 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1864 ok(ret, "%lu\n", GetLastError());
1865 ok(value == 0, "Expected 0, got %lu\n", value);
1867 SetLastError(0xdeadbeef);
1868 value = 0;
1869 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1870 ok(ret, "%lu\n", GetLastError());
1872 SetLastError(0xdeadbeef);
1873 value = 0xdeadbeef;
1874 size = sizeof(DWORD);
1875 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1876 ok(ret, "%lu\n", GetLastError());
1877 ok(value == 0, "Expected 0, got %lu\n", value);
1879 SetLastError(0xdeadbeef);
1880 value = 0;
1881 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1882 ok(ret, "%lu\n", GetLastError());
1884 SetLastError(0xdeadbeef);
1885 value = 0xdeadbeef;
1886 size = sizeof(DWORD);
1887 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1888 ok(ret, "%lu\n", GetLastError());
1889 ok(value == 0, "Expected 0, got %lu\n", value);
1891 SetLastError(0xdeadbeef);
1892 value = 0;
1893 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1894 ok(ret, "%lu\n", GetLastError());
1896 SetLastError(0xdeadbeef);
1897 value = 0xdeadbeef;
1898 size = sizeof(DWORD);
1899 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1900 ok(ret, "%lu\n", GetLastError());
1901 ok(value == 0, "Expected 0, got %lu\n", value);
1903 SetLastError(0xdeadbeef);
1904 value = 0xbeefdead;
1905 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1906 ok(ret, "%lu\n", GetLastError());
1908 SetLastError(0xdeadbeef);
1909 value = 0xdeadbeef;
1910 size = sizeof(DWORD);
1911 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1912 ok(ret, "%lu\n", GetLastError());
1913 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1915 SetLastError(0xdeadbeef);
1916 value = 0xbeefdead;
1917 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1918 ok(ret, "%lu\n", GetLastError());
1920 SetLastError(0xdeadbeef);
1921 value = 0xdeadbeef;
1922 size = sizeof(DWORD);
1923 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1924 ok(ret, "%lu\n", GetLastError());
1925 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1927 SetLastError(0xdeadbeef);
1928 value = 0xbeefdead;
1929 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1930 ok(ret, "%lu\n", GetLastError());
1932 SetLastError(0xdeadbeef);
1933 value = 0xdeadbeef;
1934 size = sizeof(DWORD);
1935 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1936 ok(ret, "%lu\n", GetLastError());
1937 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1939 SetLastError(0xdeadbeef);
1940 value = 0xbeefdead;
1941 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1942 ok(ret, "%lu\n", GetLastError());
1944 SetLastError(0xdeadbeef);
1945 value = 0xdeadbeef;
1946 size = sizeof(DWORD);
1947 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1948 ok(ret, "%lu\n", GetLastError());
1949 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
1951 /* Changing timeout values for session should not affect the values for a request,
1952 * neither should the other way around.
1954 SetLastError(0xdeadbeef);
1955 value = 0xbeefdead;
1956 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1957 ok(ret, "%lu\n", GetLastError());
1959 SetLastError(0xdeadbeef);
1960 value = 0xdeadbeef;
1961 size = sizeof(DWORD);
1962 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1963 ok(ret, "%lu\n", GetLastError());
1964 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1966 SetLastError(0xdeadbeef);
1967 value = 0xbeefdead;
1968 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1969 ok(ret, "%lu\n", GetLastError());
1971 SetLastError(0xdeadbeef);
1972 value = 0xdeadbeef;
1973 size = sizeof(DWORD);
1974 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1975 ok(ret, "%lu\n", GetLastError());
1976 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1978 SetLastError(0xdeadbeef);
1979 value = 0xbeefdead;
1980 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1981 ok(ret, "%lu\n", GetLastError());
1983 SetLastError(0xdeadbeef);
1984 value = 0xdeadbeef;
1985 size = sizeof(DWORD);
1986 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1987 ok(ret, "%lu\n", GetLastError());
1988 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
1990 SetLastError(0xdeadbeef);
1991 value = 0xbeefdead;
1992 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1993 ok(ret, "%lu\n", GetLastError());
1995 SetLastError(0xdeadbeef);
1996 value = 0xdeadbeef;
1997 size = sizeof(DWORD);
1998 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1999 ok(ret, "%lu\n", GetLastError());
2000 ok(value == 0xdead, "Expected 0xdead, got %lu\n", value);
2002 SetLastError(0xdeadbeef);
2003 value = 0xbeef;
2004 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
2005 ok(ret, "%lu\n", GetLastError());
2007 SetLastError(0xdeadbeef);
2008 value = 0xdeadbeef;
2009 size = sizeof(DWORD);
2010 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
2011 ok(ret, "%lu\n", GetLastError());
2012 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
2014 SetLastError(0xdeadbeef);
2015 value = 0xbeef;
2016 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
2017 ok(ret, "%lu\n", GetLastError());
2019 SetLastError(0xdeadbeef);
2020 value = 0xdeadbeef;
2021 size = sizeof(DWORD);
2022 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
2023 ok(ret, "%lu\n", GetLastError());
2024 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
2026 SetLastError(0xdeadbeef);
2027 value = 0xbeef;
2028 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
2029 ok(ret, "%lu\n", GetLastError());
2031 SetLastError(0xdeadbeef);
2032 value = 0xdeadbeef;
2033 size = sizeof(DWORD);
2034 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
2035 ok(ret, "%lu\n", GetLastError());
2036 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
2038 SetLastError(0xdeadbeef);
2039 value = 0xbeef;
2040 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
2041 ok(ret, "%lu\n", GetLastError());
2043 SetLastError(0xdeadbeef);
2044 value = 0xdeadbeef;
2045 size = sizeof(DWORD);
2046 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
2047 ok(ret, "%lu\n", GetLastError());
2048 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %lu\n", value);
2050 /* response timeout */
2051 SetLastError(0xdeadbeef);
2052 value = 0xdeadbeef;
2053 size = sizeof(value);
2054 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2055 ok(ret, "%lu\n", GetLastError());
2056 ok(value == ~0u, "got %lu\n", value);
2058 SetLastError(0xdeadbeef);
2059 value = 30000;
2060 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2061 ok(ret, "%lu\n", GetLastError());
2063 SetLastError(0xdeadbeef);
2064 value = 0xdeadbeef;
2065 size = sizeof(value);
2066 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2067 ok(ret, "%lu\n", GetLastError());
2068 todo_wine ok(value == 0xbeefdead, "got %lu\n", value);
2070 SetLastError(0xdeadbeef);
2071 value = 0xdeadbeef;
2072 size = sizeof(value);
2073 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2074 ok(ret, "%lu\n", GetLastError());
2075 ok(value == ~0u, "got %lu\n", value);
2077 SetLastError(0xdeadbeef);
2078 value = 30000;
2079 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2080 ok(!ret, "expected failure\n");
2081 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", GetLastError());
2083 SetLastError(0xdeadbeef);
2084 value = 0xdeadbeef;
2085 size = sizeof(value);
2086 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2087 ok(ret, "%lu\n", GetLastError());
2088 ok(value == ~0u, "got %lu\n", value);
2090 SetLastError(0xdeadbeef);
2091 value = 48878;
2092 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2093 ok(ret, "%lu\n", GetLastError());
2095 SetLastError(0xdeadbeef);
2096 value = 0xdeadbeef;
2097 size = sizeof(value);
2098 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2099 ok(ret, "%lu\n", GetLastError());
2100 todo_wine ok(value == 48879, "got %lu\n", value);
2102 SetLastError(0xdeadbeef);
2103 value = 48880;
2104 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2105 ok(ret, "%lu\n", GetLastError());
2107 SetLastError(0xdeadbeef);
2108 value = 0xdeadbeef;
2109 size = sizeof(value);
2110 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2111 ok(ret, "%lu\n", GetLastError());
2112 ok(value == 48880, "got %lu\n", value);
2114 WinHttpCloseHandle(req);
2115 WinHttpCloseHandle(con);
2116 WinHttpCloseHandle(ses);
2119 static void test_resolve_timeout(void)
2121 HINTERNET ses, con, req;
2122 DWORD timeout;
2123 BOOL ret;
2125 if (! proxy_active())
2127 ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
2128 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2130 timeout = 10000;
2131 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
2132 ok(ret, "failed to set resolve timeout %lu\n", GetLastError());
2134 con = WinHttpConnect(ses, L"nxdomain.winehq.org", 0, 0);
2135 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2137 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2138 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2140 SetLastError(0xdeadbeef);
2141 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2142 if (ret)
2144 skip("nxdomain returned success. Broken ISP redirects?\n");
2145 goto done;
2147 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
2148 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %lu\n", GetLastError());
2150 ret = WinHttpReceiveResponse( req, NULL );
2151 ok( !ret && (GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE ||
2152 GetLastError() == ERROR_WINHTTP_OPERATION_CANCELLED /* < win7 */),
2153 "got %lu\n", GetLastError() );
2155 WinHttpCloseHandle(req);
2156 WinHttpCloseHandle(con);
2157 WinHttpCloseHandle(ses);
2159 else
2160 skip("Skipping host resolution tests, host resolution performed by proxy\n");
2162 ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
2163 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2165 timeout = 10000;
2166 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
2167 ok(ret, "failed to set resolve timeout %lu\n", GetLastError());
2169 con = WinHttpConnect(ses, L"test.winehq.org", 0, 0);
2170 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2172 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2173 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2175 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2176 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
2178 skip("connection failed, skipping\n");
2179 goto done;
2181 ok(ret, "failed to send request\n");
2183 done:
2184 WinHttpCloseHandle(req);
2185 WinHttpCloseHandle(con);
2186 WinHttpCloseHandle(ses);
2189 static const char page1[] =
2190 "<HTML>\r\n"
2191 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
2192 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2193 "</HTML>\r\n\r\n";
2195 static const char okmsg[] =
2196 "HTTP/1.1 200 OK\r\n"
2197 "Server: winetest\r\n"
2198 "\r\n";
2200 static const char notokmsg[] =
2201 "HTTP/1.1 400 Bad Request\r\n"
2202 "\r\n";
2204 static const char cookiemsg[] =
2205 "HTTP/1.1 200 OK\r\n"
2206 "Set-Cookie: name = value \r\n"
2207 "Set-Cookie: NAME = value \r\n"
2208 "\r\n";
2210 static const char cookiemsg2[] =
2211 "HTTP/1.1 200 OK\r\n"
2212 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2213 "\r\n";
2215 static const char nocontentmsg[] =
2216 "HTTP/1.1 204 No Content\r\n"
2217 "Server: winetest\r\n"
2218 "\r\n";
2220 static const char notmodified[] =
2221 "HTTP/1.1 304 Not Modified\r\n"
2222 "\r\n";
2224 static const char noauthmsg[] =
2225 "HTTP/1.1 401 Unauthorized\r\n"
2226 "Server: winetest\r\n"
2227 "Connection: close\r\n"
2228 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2229 "Content-Length: 12\r\n"
2230 "Content-Type: text/plain\r\n"
2231 "\r\n";
2233 static const char okauthmsg[] =
2234 "HTTP/1.1 200 OK\r\n"
2235 "Server: winetest\r\n"
2236 "Connection: close\r\n"
2237 "Content-Length: 11\r\n"
2238 "Content-Type: text/plain\r\n"
2239 "\r\n";
2241 static const char headmsg[] =
2242 "HTTP/1.1 200 OK\r\n"
2243 "Content-Length: 100\r\n"
2244 "\r\n";
2246 static const char multiauth[] =
2247 "HTTP/1.1 401 Unauthorized\r\n"
2248 "Server: winetest\r\n"
2249 "WWW-Authenticate: Bearer\r\n"
2250 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2251 "WWW-Authenticate: NTLM\r\n"
2252 "Content-Length: 10\r\n"
2253 "Content-Type: text/plain\r\n"
2254 "\r\n";
2256 static const char largeauth[] =
2257 "HTTP/1.1 401 Unauthorized\r\n"
2258 "Server: winetest\r\n"
2259 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2260 "WWW-Authenticate: NTLM\r\n"
2261 "Content-Length: 10240\r\n"
2262 "Content-Type: text/plain\r\n"
2263 "\r\n";
2265 static const char passportauth[] =
2266 "HTTP/1.1 302 Found\r\n"
2267 "Content-Length: 0\r\n"
2268 "Location: /\r\n"
2269 "WWW-Authenticate: Passport1.4\r\n"
2270 "\r\n";
2272 static const char switchprotocols[] =
2273 "HTTP/1.1 101 Switching Protocols\r\n"
2274 "Server: winetest\r\n"
2275 "Upgrade: websocket\r\n"
2276 "Connection: Upgrade\r\n";
2278 static const char redirectmsg[] =
2279 "HTTP/1.1 307 Temporary Redirect\r\n"
2280 "Content-Length: 0\r\n"
2281 "Location: /temporary\r\n"
2282 "Connection: close\r\n\r\n";
2284 static const char unauthorized[] = "Unauthorized";
2285 static const char hello_world[] = "Hello World";
2286 static const char auth_unseen[] = "Auth Unseen";
2288 struct server_info
2290 HANDLE event;
2291 int port;
2294 #define BIG_BUFFER_LEN 0x2250
2296 static void create_websocket_accept(const char *key, char *buf, unsigned int buflen)
2298 HCRYPTPROV provider;
2299 HCRYPTHASH hash;
2300 BYTE sha1[20];
2301 char data[128];
2302 DWORD len;
2304 strcpy(data, key);
2305 strcat(data, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
2307 CryptAcquireContextW(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2308 CryptCreateHash(provider, CALG_SHA1, 0, 0, &hash);
2309 CryptHashData(hash, (BYTE *)data, strlen(data), 0);
2311 len = sizeof(sha1);
2312 CryptGetHashParam(hash, HP_HASHVAL, sha1, &len, 0);
2313 CryptDestroyHash(hash);
2314 CryptReleaseContext(provider, 0);
2316 buf[0] = 0;
2317 len = buflen;
2318 CryptBinaryToStringA( (BYTE *)sha1, sizeof(sha1), CRYPT_STRING_BASE64, buf, &len);
2321 static DWORD CALLBACK server_thread(LPVOID param)
2323 struct server_info *si = param;
2324 int r, c = -1, i, on;
2325 SOCKET s;
2326 struct sockaddr_in sa;
2327 char buffer[0x100];
2328 WSADATA wsaData;
2329 int last_request = 0;
2331 WSAStartup(MAKEWORD(1,1), &wsaData);
2333 s = socket(AF_INET, SOCK_STREAM, 0);
2334 if (s == INVALID_SOCKET)
2335 return 1;
2337 on = 1;
2338 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2340 memset(&sa, 0, sizeof sa);
2341 sa.sin_family = AF_INET;
2342 sa.sin_port = htons(si->port);
2343 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2345 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
2346 if (r < 0)
2347 return 1;
2349 listen(s, 0);
2350 SetEvent(si->event);
2353 if (c == -1) c = accept(s, NULL, NULL);
2355 memset(buffer, 0, sizeof buffer);
2356 for(i = 0; i < sizeof buffer - 1; i++)
2358 r = recv(c, &buffer[i], 1, 0);
2359 if (r != 1)
2360 break;
2361 if (i < 4) continue;
2362 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
2363 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
2364 break;
2366 if (strstr(buffer, "GET /basic"))
2368 send(c, okmsg, sizeof okmsg - 1, 0);
2369 send(c, page1, sizeof page1 - 1, 0);
2371 if (strstr(buffer, "/auth_with_creds"))
2373 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2374 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2375 send(c, hello_world, sizeof hello_world - 1, 0);
2376 else
2377 send(c, auth_unseen, sizeof auth_unseen - 1, 0);
2378 continue;
2380 if (strstr(buffer, "/auth"))
2382 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2384 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2385 send(c, hello_world, sizeof hello_world - 1, 0);
2387 else
2389 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
2390 send(c, unauthorized, sizeof unauthorized - 1, 0);
2392 continue;
2394 if (strstr(buffer, "/big"))
2396 char msg[BIG_BUFFER_LEN];
2397 memset(msg, 'm', sizeof(msg));
2398 send(c, okmsg, sizeof(okmsg) - 1, 0);
2399 send(c, msg, sizeof(msg), 0);
2401 if (strstr(buffer, "/no_headers"))
2403 send(c, page1, sizeof page1 - 1, 0);
2405 if (strstr(buffer, "GET /no_content"))
2407 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
2408 continue;
2410 if (strstr(buffer, "GET /not_modified"))
2412 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0);
2413 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2414 continue;
2416 if (strstr(buffer, "HEAD /head"))
2418 send(c, headmsg, sizeof headmsg - 1, 0);
2419 continue;
2421 if (strstr(buffer, "GET /multiauth"))
2423 send(c, multiauth, sizeof multiauth - 1, 0);
2425 if (strstr(buffer, "GET /largeauth"))
2427 if (strstr(buffer, "Authorization: NTLM"))
2428 send(c, okmsg, sizeof(okmsg) - 1, 0);
2429 else
2431 send(c, largeauth, sizeof largeauth - 1, 0);
2432 for (i = 0; i < 10240; i++) send(c, "A", 1, 0);
2433 continue;
2436 if (strstr(buffer, "GET /cookie5"))
2438 if (strstr(buffer, "Cookie: name2=value\r\n"))
2439 send(c, okmsg, sizeof(okmsg) - 1, 0);
2440 else
2441 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2443 if (strstr(buffer, "GET /cookie4"))
2445 send(c, cookiemsg2, sizeof(cookiemsg2) - 1, 0);
2447 if (strstr(buffer, "GET /cookie3"))
2449 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2450 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL))
2451 send(c, okmsg, sizeof(okmsg) - 1, 0);
2452 else
2453 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2455 if (strstr(buffer, "GET /cookie2"))
2457 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") ||
2458 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL))
2459 send(c, okmsg, sizeof(okmsg) - 1, 0);
2460 else
2461 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2463 else if (strstr(buffer, "GET /cookie"))
2465 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
2466 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2468 else if (strstr(buffer, "GET /escape"))
2470 static const char res[] = "%0D%0A%1F%7F%3C%20%one?%1F%7F%20!%22%23$%&'()*+,-./:;%3C=%3E?@%5B%5C%5D"
2471 "%5E_%60%7B%7C%7D~%0D%0A ";
2472 static const char res2[] = "%0D%0A%1F%7F%3C%20%25two?%1F%7F%20!%22%23$%25&'()*+,-./:;%3C=%3E?@%5B%5C%5D"
2473 "%5E_%60%7B%7C%7D~%0D%0A ";
2474 static const char res3[] = "\x1f\x7f<%20%three?\x1f\x7f%20!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
2475 static const char res4[] = "%0D%0A%1F%7F%3C%20%four?\x1f\x7f%20!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
2476 static const char res5[] = "&text=one%C2%80%7F~";
2477 static const char res6[] = "&text=two%C2%80\x7f~";
2478 static const char res7[] = "&text=%E5%90%9B%E3%81%AE%E5%90%8D%E3%81%AF";
2480 if (strstr(buffer + 11, res) || strstr(buffer + 11, res2) || strstr(buffer + 11, res3) ||
2481 strstr(buffer + 11, res4) || strstr(buffer + 11, res5) || strstr(buffer + 11, res6) ||
2482 strstr(buffer + 11, res7))
2484 send(c, okmsg, sizeof(okmsg) - 1, 0);
2486 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2488 else if (strstr(buffer, "GET /passport"))
2490 send(c, passportauth, sizeof(passportauth) - 1, 0);
2492 else if (strstr(buffer, "GET /websocket"))
2494 char headers[256], key[32], accept[64];
2495 const char *pos = strstr(buffer, "Sec-WebSocket-Key: ");
2496 if (pos && strstr(buffer, "Connection: Upgrade\r\n") &&
2497 (strstr(buffer, "Upgrade: websocket\r\n") || strstr(buffer, "Upgrade: Websocket\r\n")) &&
2498 strstr(buffer, "Host: ") && strstr(buffer, "Sec-WebSocket-Version: 13\r\n"))
2500 memcpy(headers, switchprotocols, sizeof(switchprotocols));
2501 memcpy(key, pos + 19, 24);
2502 key[24] = 0;
2504 create_websocket_accept(key, accept, sizeof(accept));
2506 strcat(headers, "Sec-WebSocket-Accept: ");
2507 strcat(headers, accept);
2508 strcat(headers, "\r\n\r\n");
2510 send(c, headers, strlen(headers), 0);
2511 continue;
2513 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2515 else if (strstr(buffer, "POST /redirect"))
2517 send(c, redirectmsg, sizeof redirectmsg - 1, 0);
2519 else if (strstr(buffer, "POST /temporary"))
2521 char buf[32];
2522 recv(c, buf, sizeof(buf), 0);
2523 send(c, okmsg, sizeof okmsg - 1, 0);
2524 send(c, page1, sizeof page1 - 1, 0);
2526 if (strstr(buffer, "GET /quit"))
2528 send(c, okmsg, sizeof okmsg - 1, 0);
2529 send(c, page1, sizeof page1 - 1, 0);
2530 last_request = 1;
2532 if (strstr(buffer, "POST /bad_headers"))
2534 ok(!!strstr(buffer, "Content-Type: text/html\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2535 ok(!!strstr(buffer, "Test1: Value1\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2536 ok(!!strstr(buffer, "Test2: Value2\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2537 ok(!!strstr(buffer, "Test3: Value3\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2538 ok(!!strstr(buffer, "Test4: Value4\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2539 ok(!!strstr(buffer, "Test5: Value5\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2540 ok(!!strstr(buffer, "Test6: Value6\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2541 ok(!!strstr(buffer, "Cookie: 111\r\n"), "Header missing from request %s.\n", debugstr_a(buffer));
2542 send(c, okmsg, sizeof(okmsg) - 1, 0);
2544 shutdown(c, 2);
2545 closesocket(c);
2546 c = -1;
2548 } while (!last_request);
2550 closesocket(s);
2551 return 0;
2554 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
2556 HINTERNET ses, con, req;
2557 char buffer[0x100];
2558 WCHAR buffer2[0x100];
2559 DWORD count, status, size, error, supported, first, target;
2560 BOOL ret;
2562 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2563 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2565 SetLastError(0xdeadbeef);
2566 ret = WinHttpSetOption(ses, 0, buffer, sizeof(buffer));
2567 ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %lu\n", GetLastError());
2569 SetLastError(0xdeadbeef);
2570 ret = WinHttpQueryOption(ses, 0, buffer, &size);
2571 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
2573 con = WinHttpConnect(ses, L"localhost", port, 0);
2574 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2576 SetLastError(0xdeadbeef);
2577 ret = WinHttpSetOption(con, 0, buffer, sizeof(buffer));
2578 todo_wine ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %lu\n", GetLastError());
2580 SetLastError(0xdeadbeef);
2581 ret = WinHttpQueryOption(con, 0, buffer, &size);
2582 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
2584 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
2585 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2587 SetLastError(0xdeadbeef);
2588 ret = WinHttpSetOption(req, 0, buffer, sizeof(buffer));
2589 ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %lu\n", GetLastError());
2591 SetLastError(0xdeadbeef);
2592 ret = WinHttpQueryOption(req, 0, buffer, &size);
2593 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
2595 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2596 ok(ret, "failed to send request %lu\n", GetLastError());
2598 ret = WinHttpReceiveResponse(req, NULL);
2599 ok(ret, "failed to receive response %lu\n", GetLastError());
2601 status = 0xdeadbeef;
2602 size = sizeof(status);
2603 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2604 ok(ret, "failed to query status code %lu\n", GetLastError());
2605 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
2607 supported = first = target = 0xdeadbeef;
2608 SetLastError(0xdeadbeef);
2609 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2610 error = GetLastError();
2611 ok(!ret, "unexpected success\n");
2612 ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %lu\n", error);
2613 ok(supported == 0xdeadbeef, "got %lu\n", supported);
2614 ok(first == 0xdeadbeef, "got %lu\n", first);
2615 ok(target == 0xdeadbeef, "got %lu\n", target);
2617 size = sizeof(buffer2);
2618 memset(buffer2, 0, sizeof(buffer2));
2619 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL);
2620 ok(ret, "failed to query for raw headers: %lu\n", GetLastError());
2621 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, L"\r\n\r\n", sizeof(L"\r\n\r\n")),
2622 "WinHttpQueryHeaders returned invalid end of header string\n");
2624 size = sizeof(buffer2);
2625 memset(buffer2, 0, sizeof(buffer2));
2626 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL);
2627 ok(ret, "failed to query for raw headers: %lu\n", GetLastError());
2628 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, L"", sizeof(L"")),
2629 "WinHttpQueryHeaders returned invalid end of header string\n");
2630 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n");
2632 count = 0;
2633 memset(buffer, 0, sizeof(buffer));
2634 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
2635 ok(ret, "failed to read data %lu\n", GetLastError());
2636 ok(count == sizeof page1 - 1, "count was wrong\n");
2637 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2639 WinHttpCloseHandle(req);
2640 WinHttpCloseHandle(con);
2641 WinHttpCloseHandle(ses);
2644 static void test_basic_authentication(int port)
2646 HINTERNET ses, con, req;
2647 DWORD status, size, error, supported, first, target;
2648 char buffer[32];
2649 BOOL ret;
2651 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2652 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2654 con = WinHttpConnect(ses, L"localhost", port, 0);
2655 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2657 req = WinHttpOpenRequest(con, NULL, L"/auth", NULL, NULL, NULL, 0);
2658 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2660 SetLastError(0xdeadbeef);
2661 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
2662 error = GetLastError();
2663 ok(!ret, "expected failure\n");
2664 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %lu\n", error);
2666 SetLastError(0xdeadbeef);
2667 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
2668 error = GetLastError();
2669 ok(!ret, "expected failure\n");
2670 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %lu\n", error);
2672 supported = 0xdeadbeef;
2673 SetLastError(0xdeadbeef);
2674 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2675 error = GetLastError();
2676 ok(!ret, "expected failure\n");
2677 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %lu\n", error);
2678 ok(supported == 0xdeadbeef, "got %lu\n", supported);
2680 supported = first = 0xdeadbeef;
2681 SetLastError(0xdeadbeef);
2682 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
2683 error = GetLastError();
2684 ok(!ret, "expected failure\n");
2685 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %lu\n", error);
2686 ok(supported == 0xdeadbeef, "got %lu\n", supported);
2687 ok(first == 0xdeadbeef, "got %lu\n", first);
2689 supported = first = target = 0xdeadbeef;
2690 SetLastError(0xdeadbeef);
2691 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2692 error = GetLastError();
2693 ok(!ret, "expected failure\n");
2694 ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %lu\n", error);
2695 ok(supported == 0xdeadbeef, "got %lu\n", supported);
2696 ok(first == 0xdeadbeef, "got %lu\n", first);
2697 ok(target == 0xdeadbeef, "got %lu\n", target);
2699 supported = first = target = 0xdeadbeef;
2700 SetLastError(0xdeadbeef);
2701 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2702 error = GetLastError();
2703 ok(!ret, "expected failure\n");
2704 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %lu\n", error);
2705 ok(supported == 0xdeadbeef, "got %lu\n", supported);
2706 ok(first == 0xdeadbeef, "got %lu\n", first);
2707 ok(target == 0xdeadbeef, "got %lu\n", target);
2709 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2710 ok(ret, "failed to send request %lu\n", GetLastError());
2712 ret = WinHttpReceiveResponse(req, NULL);
2713 ok(ret, "failed to receive response %lu\n", GetLastError());
2715 status = 0xdeadbeef;
2716 size = sizeof(status);
2717 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2718 ok(ret, "failed to query status code %lu\n", GetLastError());
2719 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %lu\n", status);
2721 size = 0;
2722 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2723 error = GetLastError();
2724 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %lu\n", GetLastError());
2725 if (ret)
2727 ok(size == 12, "expected 12, got %lu\n", size);
2728 ok(!memcmp(buffer, unauthorized, 12), "got %s\n", buffer);
2731 supported = first = target = 0xdeadbeef;
2732 SetLastError(0xdeadbeef);
2733 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2734 error = GetLastError();
2735 ok(ret, "failed to query authentication schemes %lu\n", error);
2736 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %lu\n", error);
2737 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %lu\n", supported);
2738 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %lu\n", first);
2739 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %lu\n", target);
2741 SetLastError(0xdeadbeef);
2742 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2743 error = GetLastError();
2744 ok(ret, "failed to set credentials %lu\n", error);
2745 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %lu\n", error);
2747 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2748 ok(ret, "failed to set credentials %lu\n", GetLastError());
2750 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2751 ok(ret, "failed to set credentials %lu\n", GetLastError());
2753 SetLastError(0xdeadbeef);
2754 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2755 error = GetLastError();
2756 ok(!ret, "expected failure\n");
2757 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
2759 SetLastError(0xdeadbeef);
2760 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2761 error = GetLastError();
2762 ok(!ret, "expected failure\n");
2763 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
2765 SetLastError(0xdeadbeef);
2766 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, L"user", NULL, NULL);
2767 error = GetLastError();
2768 ok(!ret, "expected failure\n");
2769 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
2771 SetLastError(0xdeadbeef);
2772 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, L"pwd", NULL);
2773 error = GetLastError();
2774 ok(!ret, "expected failure\n");
2775 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
2777 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, L"user", L"pwd", NULL);
2778 ok(ret, "failed to set credentials %lu\n", GetLastError());
2780 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2781 ok(ret, "failed to send request %lu\n", GetLastError());
2783 ret = WinHttpReceiveResponse(req, NULL);
2784 ok(ret, "failed to receive response %lu\n", GetLastError());
2786 status = 0xdeadbeef;
2787 size = sizeof(status);
2788 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2789 ok(ret, "failed to query status code %lu\n", GetLastError());
2790 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
2792 size = 0;
2793 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2794 error = GetLastError();
2795 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %lu\n", GetLastError());
2796 if (ret)
2798 ok(size == 11, "expected 11, got %lu\n", size);
2799 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2802 WinHttpCloseHandle(req);
2803 WinHttpCloseHandle(con);
2804 WinHttpCloseHandle(ses);
2806 /* now set the credentials first to show that they get sent with the first request */
2807 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2808 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2810 con = WinHttpConnect(ses, L"localhost", port, 0);
2811 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2813 req = WinHttpOpenRequest(con, NULL, L"/auth_with_creds", NULL, NULL, NULL, 0);
2814 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2816 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, L"user", L"pwd", NULL);
2817 ok(ret, "failed to set credentials %lu\n", GetLastError());
2819 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2820 ok(ret, "failed to send request %lu\n", GetLastError());
2822 ret = WinHttpReceiveResponse(req, NULL);
2823 ok(ret, "failed to receive response %lu\n", GetLastError());
2825 status = 0xdeadbeef;
2826 size = sizeof(status);
2827 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2828 ok(ret, "failed to query status code %lu\n", GetLastError());
2829 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
2831 size = 0;
2832 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2833 error = GetLastError();
2834 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %lu\n", GetLastError());
2835 if (ret)
2837 ok(size == 11, "expected 11, got %lu\n", size);
2838 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2841 WinHttpCloseHandle(req);
2842 WinHttpCloseHandle(con);
2843 WinHttpCloseHandle(ses);
2845 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2847 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2848 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2850 con = WinHttpConnect(ses, L"localhost", port, 0);
2851 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2853 req = WinHttpOpenRequest(con, NULL, L"/auth", NULL, NULL, NULL, 0);
2854 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2856 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, L"user", L"pwd", NULL);
2857 ok(ret, "failed to set credentials %lu\n", GetLastError());
2859 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, (void *)L"user", lstrlenW(L"user"));
2860 ok(ret, "failed to set username %lu\n", GetLastError());
2862 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, (void *)L"pwd2", lstrlenW(L"pwd2"));
2863 ok(ret, "failed to set password %lu\n", GetLastError());
2865 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2866 ok(ret, "failed to send request %lu\n", GetLastError());
2868 ret = WinHttpReceiveResponse(req, NULL);
2869 ok(ret, "failed to receive response %lu\n", GetLastError());
2871 status = 0xdeadbeef;
2872 size = sizeof(status);
2873 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2874 ok(ret, "failed to query status code %lu\n", GetLastError());
2875 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status);
2877 WinHttpCloseHandle(req);
2878 WinHttpCloseHandle(con);
2879 WinHttpCloseHandle(ses);
2881 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2882 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2884 con = WinHttpConnect(ses, L"localhost", port, 0);
2885 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2887 req = WinHttpOpenRequest(con, NULL, L"/auth", NULL, NULL, NULL, 0);
2888 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2890 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, (void *)L"user", lstrlenW(L"user"));
2891 ok(ret, "failed to set username %lu\n", GetLastError());
2893 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, (void *)L"pwd", lstrlenW(L"pwd"));
2894 ok(ret, "failed to set password %lu\n", GetLastError());
2896 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, L"user", L"pwd2", NULL);
2897 ok(ret, "failed to set credentials %lu\n", GetLastError());
2899 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2900 ok(ret, "failed to send request %lu\n", GetLastError());
2902 ret = WinHttpReceiveResponse(req, NULL);
2903 ok(ret, "failed to receive response %lu\n", GetLastError());
2905 status = 0xdeadbeef;
2906 size = sizeof(status);
2907 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2908 ok(ret, "failed to query status code %lu\n", GetLastError());
2909 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %lu\n", status);
2911 WinHttpCloseHandle(req);
2912 WinHttpCloseHandle(con);
2913 WinHttpCloseHandle(ses);
2916 static void test_multi_authentication(int port)
2918 HINTERNET ses, con, req;
2919 DWORD supported, first, target, size, index;
2920 WCHAR buf[512];
2921 BOOL ret;
2923 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2924 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2926 con = WinHttpConnect(ses, L"localhost", port, 0);
2927 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2929 req = WinHttpOpenRequest(con, L"GET", L"/multiauth", NULL, NULL, NULL, 0);
2930 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2932 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
2933 WINHTTP_NO_REQUEST_DATA,0, 0, 0 );
2934 ok(ret, "expected success\n");
2936 ret = WinHttpReceiveResponse(req, NULL);
2937 ok(ret, "expected success\n");
2939 supported = first = target = 0xdeadbeef;
2940 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2941 ok(ret, "expected success\n");
2942 ok(supported == (WINHTTP_AUTH_SCHEME_BASIC | WINHTTP_AUTH_SCHEME_NTLM), "got %#lx\n", supported);
2943 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %#lx\n", target);
2944 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %#lx\n", first);
2946 index = 0;
2947 size = sizeof(buf);
2948 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CUSTOM, L"WWW-Authenticate", buf, &size, &index);
2949 ok(ret, "expected success\n");
2950 ok(!lstrcmpW(buf, L"Bearer"), "buf = %s\n", wine_dbgstr_w(buf));
2951 ok(size == lstrlenW(buf) * sizeof(WCHAR), "size = %lu\n", size);
2952 ok(index == 1, "index = %lu\n", index);
2954 index = 0;
2955 size = 0xdeadbeef;
2956 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CUSTOM, L"WWW-Authenticate", NULL, &size, &index);
2957 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2958 "WinHttpQueryHeaders returned %d(%lu)\n", ret, GetLastError());
2959 ok(size == (lstrlenW(buf) + 1) * sizeof(WCHAR), "size = %lu\n", size);
2960 ok(index == 0, "index = %lu\n", index);
2962 WinHttpCloseHandle(req);
2963 WinHttpCloseHandle(con);
2964 WinHttpCloseHandle(ses);
2967 static void test_large_data_authentication(int port)
2969 HINTERNET ses, con, req;
2970 DWORD status, size;
2971 BOOL ret;
2973 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2974 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
2976 con = WinHttpConnect(ses, L"localhost", port, 0);
2977 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
2979 req = WinHttpOpenRequest(con, L"GET", L"/largeauth", NULL, NULL, NULL, 0);
2980 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
2982 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
2983 ok(ret, "expected success\n");
2985 ret = WinHttpReceiveResponse(req, NULL);
2986 ok(ret, "expected success\n");
2988 size = sizeof(status);
2989 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL,
2990 &status, &size, NULL);
2991 ok(ret, "expected success\n");
2992 ok(status == HTTP_STATUS_DENIED, "got %lu\n", status);
2994 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, L"user", L"pwd", NULL);
2995 ok(ret, "expected success\n");
2997 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
2998 ok(ret, "expected success %lu\n", GetLastError());
3000 ret = WinHttpReceiveResponse(req, NULL);
3001 ok(ret, "expected success\n");
3003 size = sizeof(status);
3004 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL,
3005 &status, &size, NULL);
3006 ok(ret, "expected success\n");
3007 ok(status == HTTP_STATUS_OK, "got %lu\n", status);
3009 WinHttpCloseHandle(req);
3010 WinHttpCloseHandle(con);
3011 WinHttpCloseHandle(ses);
3014 static void test_no_headers(int port)
3016 HINTERNET ses, con, req;
3017 DWORD error;
3018 BOOL ret;
3020 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3021 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
3023 con = WinHttpConnect(ses, L"localhost", port, 0);
3024 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
3026 req = WinHttpOpenRequest(con, NULL, L"/no_headers", NULL, NULL, NULL, 0);
3027 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
3029 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3030 if (!ret)
3032 error = GetLastError();
3033 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %lu\n", error);
3035 else
3037 SetLastError(0xdeadbeef);
3038 ret = WinHttpReceiveResponse(req, NULL);
3039 error = GetLastError();
3040 ok(!ret, "expected failure\n");
3041 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %lu\n", error);
3044 WinHttpCloseHandle(req);
3045 WinHttpCloseHandle(con);
3046 WinHttpCloseHandle(ses);
3049 static void test_no_content(int port)
3051 HINTERNET ses, con, req;
3052 char buf[128];
3053 DWORD size, len = sizeof(buf), bytes_read, status;
3054 BOOL ret;
3056 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3057 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
3059 con = WinHttpConnect(ses, L"localhost", port, 0);
3060 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
3062 req = WinHttpOpenRequest(con, NULL, L"/no_content", NULL, NULL, NULL, 0);
3063 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
3065 size = 12345;
3066 SetLastError(0xdeadbeef);
3067 ret = WinHttpQueryDataAvailable(req, &size);
3068 todo_wine {
3069 ok(!ret, "expected error\n");
3070 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE,
3071 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got %lu\n", GetLastError());
3072 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
3073 "expected 12345, got %lu\n", size);
3076 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3077 ok(ret, "expected success\n");
3079 ret = WinHttpReceiveResponse(req, NULL);
3080 ok(ret, "expected success\n");
3082 status = 0xdeadbeef;
3083 size = sizeof(status);
3084 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
3085 NULL, &status, &size, NULL);
3086 ok(ret, "expected success\n");
3087 ok(status == HTTP_STATUS_NO_CONTENT, "expected status 204, got %lu\n", status);
3089 SetLastError(0xdeadbeef);
3090 size = sizeof(status);
3091 status = 12345;
3092 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
3093 NULL, &status, &size, 0);
3094 ok(!ret, "expected no content-length header\n");
3095 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %lu\n", GetLastError());
3096 ok(status == 12345, "expected 0, got %lu\n", status);
3098 SetLastError(0xdeadbeef);
3099 size = 12345;
3100 ret = WinHttpQueryDataAvailable(req, &size);
3101 ok(ret, "expected success\n");
3102 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
3103 "wrong error %lu\n", GetLastError());
3104 ok(!size, "expected 0, got %lu\n", size);
3106 SetLastError(0xdeadbeef);
3107 ret = WinHttpReadData(req, buf, len, &bytes_read);
3108 ok(ret, "expected success\n");
3109 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
3110 "wrong error %lu\n", GetLastError());
3111 ok(!bytes_read, "expected 0, got %lu\n", bytes_read);
3113 size = 12345;
3114 ret = WinHttpQueryDataAvailable(req, &size);
3115 ok(ret, "expected success\n");
3116 ok(size == 0, "expected 0, got %lu\n", size);
3118 WinHttpCloseHandle(req);
3120 size = 12345;
3121 SetLastError(0xdeadbeef);
3122 ret = WinHttpQueryDataAvailable(req, &size);
3123 ok(!ret, "expected error\n");
3124 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %#lx\n", GetLastError());
3125 ok(size == 12345, "expected 12345, got %lu\n", size);
3127 WinHttpCloseHandle(con);
3128 WinHttpCloseHandle(ses);
3131 static void test_head_request(int port)
3133 HINTERNET ses, con, req;
3134 char buf[128];
3135 DWORD size, len, count, status;
3136 BOOL ret;
3138 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3139 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
3141 con = WinHttpConnect(ses, L"localhost", port, 0);
3142 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
3144 req = WinHttpOpenRequest(con, L"HEAD", L"/head", NULL, NULL, NULL, 0);
3145 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
3147 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3148 ok(ret, "failed to send request %lu\n", GetLastError());
3150 ret = WinHttpReceiveResponse(req, NULL);
3151 ok(ret, "failed to receive response %lu\n", GetLastError());
3153 status = 0xdeadbeef;
3154 size = sizeof(status);
3155 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
3156 NULL, &status, &size, NULL);
3157 ok(ret, "failed to get status code %lu\n", GetLastError());
3158 ok(status == HTTP_STATUS_OK, "got %lu\n", status);
3160 len = 0xdeadbeef;
3161 size = sizeof(len);
3162 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
3163 NULL, &len, &size, 0);
3164 ok(ret, "failed to get content-length header %lu\n", GetLastError());
3165 ok(len == HTTP_STATUS_CONTINUE, "got %lu\n", len);
3167 count = 0xdeadbeef;
3168 ret = WinHttpQueryDataAvailable(req, &count);
3169 ok(ret, "failed to query data available %lu\n", GetLastError());
3170 ok(!count, "got %lu\n", count);
3172 len = sizeof(buf);
3173 count = 0xdeadbeef;
3174 ret = WinHttpReadData(req, buf, len, &count);
3175 ok(ret, "failed to read data %lu\n", GetLastError());
3176 ok(!count, "got %lu\n", count);
3178 count = 0xdeadbeef;
3179 ret = WinHttpQueryDataAvailable(req, &count);
3180 ok(ret, "failed to query data available %lu\n", GetLastError());
3181 ok(!count, "got %lu\n", count);
3183 WinHttpCloseHandle(req);
3184 WinHttpCloseHandle(con);
3185 WinHttpCloseHandle(ses);
3188 static void test_redirect(int port)
3190 HINTERNET ses, con, req;
3191 char buf[128];
3192 DWORD size, len, count, status;
3193 BOOL ret;
3195 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3196 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
3198 con = WinHttpConnect(ses, L"localhost", port, 0);
3199 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
3201 req = WinHttpOpenRequest(con, L"POST", L"/redirect", NULL, NULL, NULL, 0);
3202 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
3204 ret = WinHttpSendRequest(req, NULL, 0, (void *)"data", sizeof("data"), sizeof("data"), 0);
3205 ok(ret, "failed to send request %lu\n", GetLastError());
3207 ret = WinHttpReceiveResponse(req, NULL);
3208 ok(ret, "failed to receive response %lu\n", GetLastError());
3210 status = 0xdeadbeef;
3211 size = sizeof(status);
3212 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
3213 NULL, &status, &size, NULL);
3214 ok(ret, "failed to get status code %lu\n", GetLastError());
3215 ok(status == HTTP_STATUS_OK, "got %lu\n", status);
3217 count = 0;
3218 ret = WinHttpQueryDataAvailable(req, &count);
3219 ok(ret, "failed to query data available %lu\n", GetLastError());
3220 ok(count == 128, "got %lu\n", count);
3222 len = sizeof(buf);
3223 count = 0;
3224 ret = WinHttpReadData(req, buf, len, &count);
3225 ok(ret, "failed to read data %lu\n", GetLastError());
3226 ok(count == 128, "got %lu\n", count);
3228 WinHttpCloseHandle(req);
3229 WinHttpCloseHandle(con);
3230 WinHttpCloseHandle(ses);
3233 static void test_websocket(int port)
3235 HINTERNET session, connection, request, socket, socket2;
3236 DWORD size, len, count, status, index, error, value;
3237 DWORD_PTR ctx;
3238 WINHTTP_WEB_SOCKET_BUFFER_TYPE type;
3239 BOOL broken_buffer_sizes = FALSE;
3240 WCHAR header[32];
3241 char buf[128], *large_buf;
3242 USHORT close_status;
3243 BOOL ret;
3245 if (!pWinHttpWebSocketCompleteUpgrade)
3247 win_skip("WinHttpWebSocketCompleteUpgrade not supported\n");
3248 return;
3251 session = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
3252 ok(session != NULL, "got %lu\n", GetLastError());
3254 connection = WinHttpConnect(session, L"localhost", port, 0);
3255 ok(connection != NULL, "got %lu\n", GetLastError());
3257 request = WinHttpOpenRequest(connection, L"GET", L"/websocket", NULL, NULL, NULL, 0);
3258 ok(request != NULL, "got %lu\n", GetLastError());
3260 ret = WinHttpSetOption(request, WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET, NULL, 0);
3261 ok(ret, "got %lu\n", GetLastError());
3263 size = sizeof(header);
3264 SetLastError(0xdeadbeef);
3265 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL);
3266 error = GetLastError();
3267 ok(!ret, "success\n");
3268 todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
3270 size = sizeof(header);
3271 SetLastError(0xdeadbeef);
3272 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONNECTION, NULL, &header, &size, NULL);
3273 error = GetLastError();
3274 ok(!ret, "success\n");
3275 todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
3277 index = 0;
3278 size = sizeof(buf);
3279 SetLastError(0xdeadbeef);
3280 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3281 L"Sec-WebSocket-Key", buf, &size, &index);
3282 error = GetLastError();
3283 ok(!ret, "success\n");
3284 ok(error == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %lu\n", error);
3286 index = 0;
3287 size = sizeof(buf);
3288 SetLastError(0xdeadbeef);
3289 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3290 L"Sec-WebSocket-Version", buf, &size, &index);
3291 error = GetLastError();
3292 ok(!ret, "success\n");
3293 ok(error == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %lu\n", error);
3295 ret = WinHttpSendRequest(request, NULL, 0, NULL, 0, 0, 0);
3296 ok(ret, "got %lu\n", GetLastError());
3298 size = sizeof(header);
3299 SetLastError(0xdeadbeef);
3300 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL);
3301 error = GetLastError();
3302 ok(!ret, "success\n");
3303 todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
3305 size = sizeof(header);
3306 SetLastError(0xdeadbeef);
3307 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONNECTION, NULL, &header, &size, NULL);
3308 error = GetLastError();
3309 ok(!ret, "success\n");
3310 todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
3312 index = 0;
3313 buf[0] = 0;
3314 size = sizeof(buf);
3315 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3316 L"Sec-WebSocket-Key", buf, &size, &index);
3317 ok(ret, "got %lu\n", GetLastError());
3319 index = 0;
3320 buf[0] = 0;
3321 size = sizeof(buf);
3322 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3323 L"Sec-WebSocket-Version", buf, &size, &index);
3324 ok(ret, "got %lu\n", GetLastError());
3326 ret = WinHttpReceiveResponse(request, NULL);
3327 ok(ret, "got %lu\n", GetLastError());
3329 count = 0xdeadbeef;
3330 ret = WinHttpQueryDataAvailable(request, &count);
3331 ok(ret, "got %lu\n", GetLastError());
3332 ok(!count, "got %lu\n", count);
3334 header[0] = 0;
3335 size = sizeof(header);
3336 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL);
3337 ok(ret, "got %lu\n", GetLastError());
3338 ok(!wcscmp( header, L"websocket" ), "got %s\n", wine_dbgstr_w(header));
3340 header[0] = 0;
3341 size = sizeof(header);
3342 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONNECTION, NULL, &header, &size, NULL);
3343 ok(ret, "got %lu\n", GetLastError());
3344 ok(!wcscmp( header, L"Upgrade" ), "got %s\n", wine_dbgstr_w(header));
3346 status = 0xdeadbeef;
3347 size = sizeof(status);
3348 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status,
3349 &size, NULL);
3350 ok(ret, "got %lu\n", GetLastError());
3351 ok(status == HTTP_STATUS_SWITCH_PROTOCOLS, "got %lu\n", status);
3353 len = 0xdeadbeef;
3354 size = sizeof(len);
3355 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &len,
3356 &size, NULL);
3357 ok(!ret, "success\n");
3359 index = 0;
3360 size = sizeof(buf);
3361 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM, L"Sec-WebSocket-Accept", buf, &size, &index);
3362 ok(ret, "got %lu\n", GetLastError());
3364 socket = pWinHttpWebSocketCompleteUpgrade(request, 0);
3365 ok(socket != NULL, "got %lu\n", GetLastError());
3367 size = sizeof(header);
3368 ret = WinHttpQueryHeaders(socket, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL);
3369 error = GetLastError();
3370 ok(!ret, "success\n");
3371 ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", error);
3373 header[0] = 0;
3374 size = sizeof(header);
3375 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL);
3376 ok(ret, "got %lu\n", GetLastError());
3377 ok(!wcscmp( header, L"websocket" ), "got %s\n", wine_dbgstr_w(header));
3379 header[0] = 0;
3380 size = sizeof(header);
3381 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONNECTION, NULL, &header, &size, NULL);
3382 ok(ret, "got %lu\n", GetLastError());
3383 ok(!wcscmp( header, L"Upgrade" ), "got %s\n", wine_dbgstr_w(header));
3385 index = 0;
3386 size = sizeof(buf);
3387 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM, L"Sec-WebSocket-Accept", buf, &size, &index);
3388 ok(ret, "got %lu\n", GetLastError());
3390 /* sending request again generates new key */
3391 ret = WinHttpSendRequest(request, NULL, 0, NULL, 0, 0, 0);
3392 ok(ret, "got %lu\n", GetLastError());
3394 /* and creates a new websocket */
3395 socket2 = pWinHttpWebSocketCompleteUpgrade(request, 0);
3396 ok(socket2 != NULL, "got %lu\n", GetLastError());
3397 ok(socket2 != socket, "got same socket\n");
3399 WinHttpCloseHandle(connection);
3400 /* request handle is still valid */
3401 size = sizeof(ctx);
3402 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &ctx, &size);
3403 ok(ret, "got %lu\n", GetLastError());
3405 ret = WinHttpCloseHandle(socket2);
3406 ok(ret, "got %lu\n", GetLastError());
3408 ret = WinHttpCloseHandle(socket);
3409 ok(ret, "got %lu\n", GetLastError());
3411 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &ctx, &size);
3412 ok(ret, "got %lu\n", GetLastError());
3414 ret = WinHttpCloseHandle(session);
3415 ok(ret, "got %lu\n", GetLastError());
3417 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &ctx, &size);
3418 ok(ret, "got %lu\n", GetLastError());
3420 ret = WinHttpCloseHandle(request);
3421 ok(ret, "got %lu\n", GetLastError());
3423 session = WinHttpOpen(L"winetest", 0, NULL, NULL, 0);
3424 ok(session != NULL, "got %lu\n", GetLastError());
3426 connection = WinHttpConnect(session, L"ws.ifelse.io", 0, 0);
3427 ok(connection != NULL, "got %lu\n", GetLastError());
3429 size = 0xdeadbeef;
3430 ret = WinHttpQueryOption(session, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3431 ok(ret, "got %lu\n", GetLastError());
3432 ok(size == sizeof(DWORD), "got %lu.\n", size);
3433 ok(value == 32768, "got %lu.\n", value);
3435 value = 65535;
3436 ret = WinHttpSetOption(session, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, sizeof(DWORD));
3437 ok(ret, "got %lu\n", GetLastError());
3439 size = 0xdeadbeef;
3440 ret = WinHttpQueryOption(session, WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE, &value, &size);
3441 ok(ret, "got %lu\n", GetLastError());
3442 ok(size == sizeof(DWORD), "got %lu.\n", size);
3443 ok(value == 32768, "got %lu.\n", value);
3445 value = 15;
3446 ret = WinHttpSetOption(session, WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE, &value, sizeof(DWORD));
3447 ok(ret, "got %lu\n", GetLastError());
3449 request = WinHttpOpenRequest(connection, L"GET", L"/", NULL, NULL, NULL, 0);
3450 ok(request != NULL, "got %lu\n", GetLastError());
3452 size = 0xdeadbeef;
3453 ret = WinHttpQueryOption(session, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3454 ok(ret, "got %lu\n", GetLastError());
3455 ok(size == sizeof(DWORD), "got %lu.\n", size);
3456 ok(value == 65535 || broken( value == WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE ) /* Win8 */, "got %lu.\n", value);
3457 if (value == WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE)
3458 broken_buffer_sizes = TRUE;
3460 size = 0xdeadbeef;
3461 ret = WinHttpQueryOption(request, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3462 ok(ret, "got %lu\n", GetLastError());
3463 ok(size == sizeof(DWORD), "got %lu.\n", size);
3464 ok(value == 65535 || broken( value == WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE ), "got %lu.\n", value);
3466 value = 1048576;
3467 ret = WinHttpSetOption(request, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, sizeof(DWORD));
3468 ok(ret, "got %lu\n", GetLastError());
3470 size = 0xdeadbeef;
3471 ret = WinHttpQueryOption(session, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3472 ok(ret, "got %lu\n", GetLastError());
3473 ok(size == sizeof(DWORD), "got %lu.\n", size);
3474 ok(value == 65535 || broken( value == WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE ) /* Win8 */, "got %lu.\n", value);
3476 size = 0xdeadbeef;
3477 ret = WinHttpQueryOption(request, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3478 ok(ret, "got %lu\n", GetLastError());
3479 ok(size == sizeof(DWORD), "got %lu.\n", size);
3480 ok(value == 1048576, "got %lu.\n", value);
3482 size = 0xdeadbeef;
3483 ret = WinHttpQueryOption(connection, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3484 ok(!ret, "got %d\n", ret);
3485 todo_wine ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", GetLastError());
3487 size = 0xdeadbeef;
3488 ret = WinHttpQueryOption(request, WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE, &value, &size);
3489 ok(ret, "got %lu\n", GetLastError());
3490 ok(size == sizeof(DWORD), "got %lu.\n", size);
3491 ok(value == 15 || broken( value == WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE ) /* Win8 */, "got %lu.\n", value);
3493 size = sizeof(value);
3494 ret = WinHttpQueryOption(session, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, &size);
3495 ok(!ret, "got %d\n", ret);
3496 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3498 size = sizeof(value);
3499 ret = WinHttpQueryOption(request, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, &size);
3500 ok(!ret, "got %d\n", ret);
3501 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3503 value = 20000;
3504 ret = WinHttpSetOption(request, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, sizeof(DWORD));
3505 ok(!ret, "got %d\n", ret);
3506 todo_wine ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", GetLastError());
3508 ret = WinHttpSetOption(request, WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET, NULL, 0);
3509 ok(ret, "got %lu\n", GetLastError());
3511 if (!broken_buffer_sizes)
3513 /* Fails because we have a too small send buffer size set, but is different on Win8. */
3514 ret = WinHttpSendRequest(request, NULL, 0, NULL, 0, 0, 0);
3515 ok(!ret, "got %d\n", ret);
3516 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got %lu\n", GetLastError());
3519 value = 16;
3520 ret = WinHttpSetOption(request, WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE, &value, sizeof(DWORD));
3521 ok(ret, "got %lu\n", GetLastError());
3523 ret = WinHttpSendRequest(request, NULL, 0, NULL, 0, 0, 0);
3524 ok(ret, "got %lu\n", GetLastError());
3526 value = 15;
3527 ret = WinHttpSetOption(request, WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE, &value, sizeof(DWORD));
3528 ok(ret, "got %lu\n", GetLastError());
3530 ret = WinHttpReceiveResponse(request, NULL);
3531 ok(ret, "got %lu\n", GetLastError());
3533 status = 0xdeadbeef;
3534 size = sizeof(status);
3535 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status,
3536 &size, NULL);
3537 ok(ret, "got %lu\n", GetLastError());
3538 ok(status == HTTP_STATUS_SWITCH_PROTOCOLS, "got %lu\n", status);
3540 socket = pWinHttpWebSocketCompleteUpgrade(request, 0);
3541 ok(socket != NULL, "got %lu\n", GetLastError());
3543 size = sizeof(value);
3544 ret = WinHttpQueryOption(socket, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, &size);
3545 ok(!ret, "got %d\n", ret);
3546 todo_wine ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", GetLastError());
3548 value = 65535;
3549 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE, &value, sizeof(DWORD));
3550 ok(!ret, "got %d\n", ret);
3551 todo_wine ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", GetLastError());
3553 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE, &value, sizeof(DWORD));
3554 ok(!ret, "got %d\n", ret);
3555 todo_wine ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %lu\n", GetLastError());
3557 value = 20000;
3558 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, 2);
3559 ok(!ret, "got %d\n", ret);
3560 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3562 value = 20000;
3563 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, sizeof(DWORD) * 2);
3564 ok(!ret, "got %d\n", ret);
3565 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3567 SetLastError(0xdeadbeef);
3568 value = 20000;
3569 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, sizeof(DWORD));
3570 ok(ret, "got %lu\n", GetLastError());
3571 ok(!GetLastError(), "got %lu\n", GetLastError());
3573 size = sizeof(value);
3574 ret = WinHttpQueryOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, &size);
3575 ok(!ret, "got %d\n", ret);
3576 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3578 size = 0;
3579 ret = WinHttpQueryOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, NULL, &size);
3580 ok(!ret, "got %d\n", ret);
3581 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3583 value = 10000;
3584 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, sizeof(DWORD));
3585 ok(!ret, "got %d\n", ret);
3586 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3588 value = 10000;
3589 ret = WinHttpSetOption(socket, WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL, &value, 2);
3590 ok(!ret, "got %d\n", ret);
3591 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
3593 buf[0] = 0;
3594 count = 0;
3595 type = 0xdeadbeef;
3596 error = pWinHttpWebSocketReceive(socket, buf, sizeof(buf), &count, &type);
3597 ok(!error, "got %lu\n", error);
3598 ok(buf[0] == 'R', "got %c\n", buf[0]);
3599 ok(count == 26, "got %lu\n", count);
3600 ok(type == WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE, "got %u\n", type);
3602 error = pWinHttpWebSocketSend(socket, WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, NULL, 1);
3603 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3605 large_buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(buf) * 2);
3606 memcpy(large_buf, "hello", sizeof("hello"));
3607 memcpy(large_buf + sizeof(buf), "world", sizeof("world"));
3608 error = pWinHttpWebSocketSend(socket, WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, large_buf, sizeof(buf) * 2);
3609 ok(!error, "got %lu\n", error);
3610 HeapFree(GetProcessHeap(), 0, large_buf);
3612 error = pWinHttpWebSocketReceive(socket, NULL, 0, NULL, NULL);
3613 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3615 error = pWinHttpWebSocketReceive(socket, buf, 0, NULL, NULL);
3616 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3618 error = pWinHttpWebSocketReceive(socket, NULL, 1, NULL, NULL);
3619 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3621 buf[0] = 0;
3622 count = 0;
3623 type = 0xdeadbeef;
3624 error = pWinHttpWebSocketReceive(socket, buf, sizeof(buf), &count, &type);
3625 ok(!error, "got %lu\n", error);
3626 ok(buf[0] == 'h', "got %c\n", buf[0]);
3627 ok(count == sizeof(buf), "got %lu\n", count);
3628 ok(type == WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE, "got %u\n", type);
3630 buf[0] = 0;
3631 count = 0;
3632 type = 0xdeadbeef;
3633 error = pWinHttpWebSocketReceive(socket, buf, sizeof(buf), &count, &type);
3634 ok(!error, "got %lu\n", error);
3635 ok(buf[0] == 'w', "got %c\n", buf[0]);
3636 ok(count == sizeof(buf), "got %lu\n", count);
3637 ok(type == WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, "got %u\n", type);
3639 error = pWinHttpWebSocketShutdown(socket, WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS, NULL, 1);
3640 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3642 error = pWinHttpWebSocketShutdown(socket, WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS, buf, sizeof(buf));
3643 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3645 error = pWinHttpWebSocketShutdown(socket, WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS, (void *)"success",
3646 sizeof("success"));
3647 ok(!error, "got %lu\n", error);
3649 error = pWinHttpWebSocketClose(socket, WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS, NULL, 1);
3650 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3652 error = pWinHttpWebSocketClose(socket, WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS, buf, sizeof(buf));
3653 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3655 error = pWinHttpWebSocketClose(socket, WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS, (void *)"success2",
3656 sizeof("success2"));
3657 ok(!error, "got %lu\n", error);
3659 error = pWinHttpWebSocketQueryCloseStatus(socket, NULL, NULL, 0, NULL);
3660 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3662 error = pWinHttpWebSocketQueryCloseStatus(socket, &close_status, NULL, 0, NULL);
3663 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3665 error = pWinHttpWebSocketQueryCloseStatus(socket, &close_status, buf, 0, NULL);
3666 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3668 error = pWinHttpWebSocketQueryCloseStatus(socket, &close_status, buf, sizeof(buf), NULL);
3669 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3671 error = pWinHttpWebSocketQueryCloseStatus(socket, NULL, NULL, 0, &len);
3672 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3674 len = 0xdeadbeef;
3675 error = pWinHttpWebSocketQueryCloseStatus(socket, &close_status, NULL, 0, &len);
3676 ok(!error, "got %lu\n", error);
3677 ok(!len, "got %lu\n", len);
3679 error = pWinHttpWebSocketQueryCloseStatus(socket, &close_status, NULL, 1, &len);
3680 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
3682 close_status = 0xdead;
3683 len = 0xdeadbeef;
3684 memset(buf, 0, sizeof(buf));
3685 error = pWinHttpWebSocketQueryCloseStatus(socket, &close_status, buf, sizeof(buf), &len);
3686 ok(!error, "got %lu\n", error);
3687 ok(close_status == 1000, "got %d\n", close_status);
3688 ok(!len, "got %lu\n", len);
3690 WinHttpCloseHandle(socket);
3691 WinHttpCloseHandle(request);
3692 WinHttpCloseHandle(connection);
3693 WinHttpCloseHandle(session);
3696 static void test_not_modified(int port)
3698 BOOL ret;
3699 HINTERNET session, request, connection;
3700 DWORD index, len, status, size, start = GetTickCount();
3701 SYSTEMTIME st;
3702 WCHAR today[(sizeof(L"If-Modified-Since: ") + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32];
3704 memcpy(today, L"If-Modified-Since: ", sizeof(L"If-Modified-Since: "));
3705 GetSystemTime(&st);
3706 WinHttpTimeFromSystemTime(&st, &today[ARRAY_SIZE(L"If-Modified-Since: ") - 1]);
3708 session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY,
3709 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
3710 ok(session != NULL, "WinHttpOpen failed: %lu\n", GetLastError());
3712 connection = WinHttpConnect(session, L"localhost", port, 0);
3713 ok(connection != NULL, "WinHttpConnect failed: %lu\n", GetLastError());
3715 request = WinHttpOpenRequest(connection, NULL, L"/not_modified", NULL, WINHTTP_NO_REFERER,
3716 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
3717 ok(request != NULL, "WinHttpOpenrequest failed: %lu\n", GetLastError());
3719 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0);
3720 ok(ret, "WinHttpSendRequest failed: %lu\n", GetLastError());
3722 ret = WinHttpReceiveResponse(request, NULL);
3723 ok(ret, "WinHttpReceiveResponse failed: %lu\n", GetLastError());
3725 index = 0;
3726 len = sizeof(buffer);
3727 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3728 L"If-Modified-Since", buffer, &len, &index);
3729 ok(ret, "failed to get header %lu\n", GetLastError());
3731 status = 0xdeadbeef;
3732 size = sizeof(status);
3733 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
3734 NULL, &status, &size, NULL);
3735 ok(ret, "WinHttpQueryHeaders failed: %lu\n", GetLastError());
3736 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %lu\n", status);
3738 size = 0xdeadbeef;
3739 ret = WinHttpQueryDataAvailable(request, &size);
3740 ok(ret, "WinHttpQueryDataAvailable failed: %lu\n", GetLastError());
3741 ok(!size, "got %lu\n", size);
3743 WinHttpCloseHandle(request);
3744 WinHttpCloseHandle(connection);
3745 WinHttpCloseHandle(session);
3746 start = GetTickCount() - start;
3747 ok(start <= 2000, "Expected less than 2 seconds for the test, got %lu ms\n", start);
3750 static void test_bad_header( int port )
3752 WCHAR buffer[32];
3753 HINTERNET ses, con, req;
3754 DWORD index, len;
3755 unsigned int i;
3756 BOOL ret;
3758 static const WCHAR bad_headers[] =
3759 L"Content-Type: text/html\n\r"
3760 L"Test1: Value1\n"
3761 L"Test2: Value2\n\n\n"
3762 L"Test3: Value3\r\r\r"
3763 L"Test4: Value4\r\n\r\n"
3764 L"Cookie: 111";
3766 static const struct
3768 const WCHAR *header;
3769 const WCHAR *value;
3771 header_tests[] =
3773 {L"Content-Type", L"text/html"},
3774 {L"Test1", L"Value1"},
3775 {L"Test2", L"Value2"},
3776 {L"Test3", L"Value3"},
3777 {L"Test4", L"Value4"},
3778 {L"Cookie", L"111"},
3781 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3782 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
3784 con = WinHttpConnect( ses, L"localhost", port, 0 );
3785 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
3787 req = WinHttpOpenRequest( con, L"POST", L"/bad_headers", NULL, NULL, NULL, 0 );
3788 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3790 ret = WinHttpAddRequestHeaders( req, bad_headers, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
3791 ok( ret, "failed to add header %lu\n", GetLastError() );
3793 for (i = 0; i < ARRAY_SIZE(header_tests); ++i)
3795 index = 0;
3796 buffer[0] = 0;
3797 len = sizeof(buffer);
3798 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3799 header_tests[i].header, buffer, &len, &index );
3800 ok( ret, "header %s: failed to query headers %lu\n", debugstr_w(header_tests[i].header), GetLastError() );
3801 ok( !wcscmp( buffer, header_tests[i].value ), "header %s: got %s\n",
3802 debugstr_w(header_tests[i].header), debugstr_w(buffer) );
3803 ok( index == 1, "header %s: index = %lu\n", debugstr_w(header_tests[i].header), index );
3806 ret = WinHttpSendRequest( req, L"Test5: Value5\rTest6: Value6", ~0u, NULL, 0, 0, 0 );
3807 ok( ret, "failed to send request %lu\n", GetLastError() );
3809 ret = WinHttpReceiveResponse( req, NULL );
3810 ok( ret, "failed to receive response %lu\n", GetLastError() );
3812 WinHttpCloseHandle( req );
3813 WinHttpCloseHandle( con );
3814 WinHttpCloseHandle( ses );
3817 static void test_multiple_reads(int port)
3819 HINTERNET ses, con, req;
3820 DWORD total_len = 0;
3821 BOOL ret;
3823 ses = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3824 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
3826 con = WinHttpConnect(ses, L"localhost", port, 0);
3827 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
3829 req = WinHttpOpenRequest(con, NULL, L"big", NULL, NULL, NULL, 0);
3830 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
3832 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3833 ok(ret, "failed to send request %lu\n", GetLastError());
3835 ret = WinHttpReceiveResponse(req, NULL);
3836 ok(ret == TRUE, "expected success\n");
3838 for (;;)
3840 DWORD len = 0xdeadbeef;
3841 ret = WinHttpQueryDataAvailable( req, &len );
3842 ok( ret, "WinHttpQueryDataAvailable failed with error %lu\n", GetLastError() );
3843 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3844 if (len)
3846 DWORD bytes_read;
3847 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
3849 ret = WinHttpReadData( req, buf, len, &bytes_read );
3850 ok(ret, "WinHttpReadData failed: %lu\n", GetLastError());
3851 ok( len == bytes_read, "only got %lu of %lu available\n", bytes_read, len );
3853 HeapFree( GetProcessHeap(), 0, buf );
3854 if (!bytes_read) break;
3855 total_len += bytes_read;
3857 if (!len) break;
3859 ok(total_len == BIG_BUFFER_LEN, "got wrong length: %lu\n", total_len);
3861 WinHttpCloseHandle(req);
3862 WinHttpCloseHandle(con);
3863 WinHttpCloseHandle(ses);
3866 static void test_cookies( int port )
3868 HINTERNET ses, con, req;
3869 DWORD status, size;
3870 BOOL ret;
3872 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3873 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
3875 con = WinHttpConnect( ses, L"localhost", port, 0 );
3876 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
3878 req = WinHttpOpenRequest( con, NULL, L"/cookie", NULL, NULL, NULL, 0 );
3879 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3881 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3882 ok( ret, "failed to send request %lu\n", GetLastError() );
3884 ret = WinHttpReceiveResponse( req, NULL );
3885 ok( ret, "failed to receive response %lu\n", GetLastError() );
3887 status = 0xdeadbeef;
3888 size = sizeof(status);
3889 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3890 ok( ret, "failed to query status code %lu\n", GetLastError() );
3891 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status );
3893 WinHttpCloseHandle( req );
3895 req = WinHttpOpenRequest( con, NULL, L"/cookie2", NULL, NULL, NULL, 0 );
3896 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3898 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3899 ok( ret, "failed to send request %lu\n", GetLastError() );
3901 ret = WinHttpReceiveResponse( req, NULL );
3902 ok( ret, "failed to receive response %lu\n", GetLastError() );
3904 status = 0xdeadbeef;
3905 size = sizeof(status);
3906 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3907 ok( ret, "failed to query status code %lu\n", GetLastError() );
3908 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status );
3910 WinHttpCloseHandle( req );
3911 WinHttpCloseHandle( con );
3913 con = WinHttpConnect( ses, L"localhost", port, 0 );
3914 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
3916 req = WinHttpOpenRequest( con, NULL, L"/cookie2", NULL, NULL, NULL, 0 );
3917 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3919 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3920 ok( ret, "failed to send request %lu\n", GetLastError() );
3922 ret = WinHttpReceiveResponse( req, NULL );
3923 ok( ret, "failed to receive response %lu\n", GetLastError() );
3925 status = 0xdeadbeef;
3926 size = sizeof(status);
3927 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3928 ok( ret, "failed to query status code %lu\n", GetLastError() );
3929 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status );
3931 WinHttpCloseHandle( req );
3933 req = WinHttpOpenRequest( con, NULL, L"/cookie3", NULL, NULL, NULL, 0 );
3934 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3935 ret = WinHttpSendRequest( req, L"Cookie: name=value2\r\n", ~0u, NULL, 0, 0, 0 );
3936 ok( ret, "failed to send request %lu\n", GetLastError() );
3938 ret = WinHttpReceiveResponse( req, NULL );
3939 ok( ret, "failed to receive response %lu\n", GetLastError() );
3941 status = 0xdeadbeef;
3942 size = sizeof(status);
3943 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3944 ok( ret, "failed to query status code %lu\n", GetLastError() );
3945 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST), "request failed unexpectedly %lu\n", status );
3947 WinHttpCloseHandle( req );
3948 WinHttpCloseHandle( con );
3949 WinHttpCloseHandle( ses );
3951 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3952 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
3954 con = WinHttpConnect( ses, L"localhost", port, 0 );
3955 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
3957 req = WinHttpOpenRequest( con, NULL, L"/cookie2", NULL, NULL, NULL, 0 );
3958 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3960 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3961 ok( ret, "failed to send request %lu\n", GetLastError() );
3963 ret = WinHttpReceiveResponse( req, NULL );
3964 ok( ret, "failed to receive response %lu\n", GetLastError() );
3966 status = 0xdeadbeef;
3967 size = sizeof(status);
3968 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3969 ok( ret, "failed to query status code %lu\n", GetLastError() );
3970 ok( status == HTTP_STATUS_BAD_REQUEST, "request failed unexpectedly %lu\n", status );
3972 WinHttpCloseHandle( req );
3973 WinHttpCloseHandle( con );
3974 WinHttpCloseHandle( ses );
3976 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3977 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
3979 con = WinHttpConnect( ses, L"localhost", port, 0 );
3980 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
3982 req = WinHttpOpenRequest( con, NULL, L"/cookie4", NULL, NULL, NULL, 0 );
3983 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
3985 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3986 ok( ret, "failed to send request %lu\n", GetLastError() );
3988 ret = WinHttpReceiveResponse( req, NULL );
3989 ok( ret, "failed to receive response %lu\n", GetLastError() );
3991 status = 0xdeadbeef;
3992 size = sizeof(status);
3993 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3994 ok( ret, "failed to query status code %lu\n", GetLastError() );
3995 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %lu\n", status );
3996 WinHttpCloseHandle( req );
3998 req = WinHttpOpenRequest( con, NULL, L"/cookie5", NULL, NULL, NULL, 0 );
3999 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
4001 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4002 ok( ret, "failed to send request %lu\n", GetLastError() );
4004 ret = WinHttpReceiveResponse( req, NULL );
4005 ok( ret, "failed to receive response %lu\n", GetLastError() );
4007 status = 0xdeadbeef;
4008 size = sizeof(status);
4009 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
4010 ok( ret, "failed to query status code %lu\n", GetLastError() );
4011 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST) /* < win7 */,
4012 "request failed unexpectedly %lu\n", status );
4014 WinHttpCloseHandle( req );
4015 WinHttpCloseHandle( con );
4016 WinHttpCloseHandle( ses );
4019 static void do_request( HINTERNET con, const WCHAR *obj, DWORD flags )
4021 HINTERNET req;
4022 DWORD status, size;
4023 BOOL ret;
4025 req = WinHttpOpenRequest( con, NULL, obj, NULL, NULL, NULL, flags );
4026 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
4028 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4029 ok( ret, "failed to send request %lu\n", GetLastError() );
4031 ret = WinHttpReceiveResponse( req, NULL );
4032 ok( ret, "failed to receive response %lu\n", GetLastError() );
4034 status = 0xdeadbeef;
4035 size = sizeof(status);
4036 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
4037 ok( ret, "failed to query status code %lu\n", GetLastError() );
4038 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST) /* < win7 */,
4039 "request %s with flags %#lx failed %lu\n", wine_dbgstr_w(obj), flags, status );
4040 WinHttpCloseHandle( req );
4043 static void test_request_path_escapes( int port )
4045 static const WCHAR objW[] =
4046 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','o','n','e','?',0x1f,0x7f,' ','!','"','#',
4047 '$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`',
4048 '{','|','}','~','\r','\n',0};
4049 static const WCHAR obj2W[] =
4050 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','t','w','o','?',0x1f,0x7f,' ','!','"','#',
4051 '$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`',
4052 '{','|','}','~','\r','\n',0};
4053 static const WCHAR obj3W[] =
4054 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','t','h','r','e','e','?',0x1f,0x7f,' ','!',
4055 '"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^',
4056 '_','`','{','|','}','~','\r','\n',0};
4057 static const WCHAR obj4W[] =
4058 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','f','o','u','r','?',0x1f,0x7f,' ','!','"',
4059 '#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_',
4060 '`','{','|','}','~','\r','\n',0};
4061 static const WCHAR obj5W[] =
4062 {'/','e','s','c','a','p','e','&','t','e','x','t','=','o','n','e',0x80,0x7f,0x7e,0};
4063 static const WCHAR obj6W[] =
4064 {'/','e','s','c','a','p','e','&','t','e','x','t','=','t','w','o',0x80,0x7f,0x7e,0};
4065 static const WCHAR obj7W[] =
4066 {'/','e','s','c','a','p','e','&','t','e','x','t','=',0x541b,0x306e,0x540d,0x306f,0};
4067 HINTERNET ses, con;
4069 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
4070 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
4072 con = WinHttpConnect( ses, L"localhost", port, 0 );
4073 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
4075 do_request( con, objW, 0 );
4076 do_request( con, obj2W, WINHTTP_FLAG_ESCAPE_PERCENT );
4077 do_request( con, obj3W, WINHTTP_FLAG_ESCAPE_DISABLE );
4078 do_request( con, obj4W, WINHTTP_FLAG_ESCAPE_DISABLE_QUERY );
4079 do_request( con, obj5W, 0 );
4080 do_request( con, obj6W, WINHTTP_FLAG_ESCAPE_DISABLE );
4081 do_request( con, obj7W, WINHTTP_FLAG_ESCAPE_DISABLE );
4083 WinHttpCloseHandle( con );
4084 WinHttpCloseHandle( ses );
4087 static void test_connection_info( int port )
4089 HINTERNET ses, con, req;
4090 WINHTTP_CONNECTION_INFO info;
4091 DWORD size, error;
4092 BOOL ret;
4094 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
4095 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
4097 con = WinHttpConnect( ses, L"localhost", port, 0 );
4098 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
4100 req = WinHttpOpenRequest( con, NULL, L"/basic", NULL, NULL, NULL, 0 );
4101 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
4103 size = sizeof(info);
4104 SetLastError( 0xdeadbeef );
4105 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
4106 error = GetLastError();
4107 if (!ret && error == ERROR_INVALID_PARAMETER)
4109 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
4110 return;
4112 ok( !ret, "unexpected success\n" );
4113 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error );
4115 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4116 ok( ret, "failed to send request %lu\n", GetLastError() );
4118 size = 0;
4119 SetLastError( 0xdeadbeef );
4120 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
4121 error = GetLastError();
4122 ok( !ret, "unexpected success\n" );
4123 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", error );
4125 size = sizeof(info);
4126 memset( &info, 0, sizeof(info) );
4127 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
4128 ok( ret, "failed to retrieve connection info %lu\n", GetLastError() );
4129 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %lu\n", info.cbSize );
4131 ret = WinHttpReceiveResponse( req, NULL );
4132 ok( ret, "failed to receive response %lu\n", GetLastError() );
4134 size = sizeof(info);
4135 memset( &info, 0, sizeof(info) );
4136 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
4137 ok( ret, "failed to retrieve connection info %lu\n", GetLastError() );
4138 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %lu\n", info.cbSize );
4140 WinHttpCloseHandle( req );
4141 WinHttpCloseHandle( con );
4142 WinHttpCloseHandle( ses );
4145 static void test_passport_auth( int port )
4147 static const WCHAR headersW[] =
4148 L"HTTP/1.1 401 Found\r\nContent-Length: 0\r\nLocation: /\r\nWWW-Authenticate: Passport1.4\r\n\r\n";
4149 HINTERNET ses, con, req;
4150 DWORD status, size, option, err;
4151 WCHAR buf[128];
4152 BOOL ret;
4154 ses = WinHttpOpen( L"winetest", 0, NULL, NULL, 0 );
4155 ok( ses != NULL, "got %lu\n", GetLastError() );
4157 option = WINHTTP_ENABLE_PASSPORT_AUTH;
4158 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH, &option, sizeof(option) );
4159 ok( ret, "got %lu\n", GetLastError() );
4161 con = WinHttpConnect( ses, L"localhost", port, 0 );
4162 ok( con != NULL, "got %lu\n", GetLastError() );
4164 req = WinHttpOpenRequest( con, NULL, L"/passport", NULL, NULL, NULL, 0 );
4165 ok( req != NULL, "got %lu\n", GetLastError() );
4167 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4168 ok( ret, "got %lu\n", GetLastError() );
4170 ret = WinHttpReceiveResponse( req, NULL );
4171 err = GetLastError();
4172 ok( ret || broken(!ret && err == ERROR_WINHTTP_LOGIN_FAILURE) /* winxp */
4173 || broken(!ret && err == ERROR_WINHTTP_INVALID_SERVER_RESPONSE ), "got %lu\n", err );
4174 if (!ret)
4176 win_skip("no support for Passport redirects\n");
4177 goto cleanup;
4180 status = 0xdeadbeef;
4181 size = sizeof(status);
4182 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
4183 ok( ret, "got %lu\n", GetLastError() );
4184 ok( status == HTTP_STATUS_DENIED, "got %lu\n", status );
4186 buf[0] = 0;
4187 size = sizeof(buf);
4188 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_TEXT, NULL, buf, &size, NULL );
4189 ok( ret, "got %lu\n", GetLastError() );
4190 ok( !lstrcmpW(L"Found", buf) || broken(!lstrcmpW(L"Unauthorized", buf)) /* < win7 */, "got %s\n",
4191 wine_dbgstr_w(buf) );
4193 buf[0] = 0;
4194 size = sizeof(buf);
4195 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buf, &size, NULL );
4196 ok( ret || broken(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) /* < win7 */, "got %lu\n", GetLastError() );
4197 if (ret)
4199 ok( size == lstrlenW(headersW) * sizeof(WCHAR), "got %lu\n", size );
4200 ok( !lstrcmpW(headersW, buf), "got %s\n", wine_dbgstr_w(buf) );
4203 cleanup:
4204 WinHttpCloseHandle( req );
4205 WinHttpCloseHandle( con );
4206 WinHttpCloseHandle( ses );
4209 static void test_credentials(void)
4211 static WCHAR userW[] = {'u','s','e','r',0};
4212 static WCHAR passW[] = {'p','a','s','s',0};
4213 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
4214 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
4215 HINTERNET ses, con, req;
4216 DWORD size, error;
4217 WCHAR buffer[32];
4218 BOOL ret;
4220 ses = WinHttpOpen(L"winetest", 0, proxy_userW, proxy_passW, 0);
4221 ok(ses != NULL, "failed to open session %lu\n", GetLastError());
4223 con = WinHttpConnect(ses, L"localhost", 0, 0);
4224 ok(con != NULL, "failed to open a connection %lu\n", GetLastError());
4226 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
4227 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
4229 size = ARRAY_SIZE(buffer);
4230 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
4231 ok(ret, "failed to query proxy username %lu\n", GetLastError());
4232 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
4233 ok(!size, "expected 0, got %lu\n", size);
4235 size = ARRAY_SIZE(buffer);
4236 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
4237 ok(ret, "failed to query proxy password %lu\n", GetLastError());
4238 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
4239 ok(!size, "expected 0, got %lu\n", size);
4241 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
4242 ok(ret, "failed to set username %lu\n", GetLastError());
4244 size = ARRAY_SIZE(buffer);
4245 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
4246 ok(ret, "failed to query proxy username %lu\n", GetLastError());
4247 ok(!wcscmp(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
4248 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %lu\n", size);
4250 size = ARRAY_SIZE(buffer);
4251 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
4252 ok(ret, "failed to query username %lu\n", GetLastError());
4253 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
4254 ok(!size, "expected 0, got %lu\n", size);
4256 size = ARRAY_SIZE(buffer);
4257 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
4258 ok(ret, "failed to query password %lu\n", GetLastError());
4259 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
4260 ok(!size, "expected 0, got %lu\n", size);
4262 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
4263 ok(ret, "failed to set proxy password %lu\n", GetLastError());
4265 size = ARRAY_SIZE(buffer);
4266 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
4267 ok(ret, "failed to query proxy password %lu\n", GetLastError());
4268 ok(!wcscmp(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
4269 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %lu\n", size);
4271 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
4272 ok(ret, "failed to set username %lu\n", GetLastError());
4274 size = ARRAY_SIZE(buffer);
4275 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
4276 ok(ret, "failed to query username %lu\n", GetLastError());
4277 ok(!wcscmp(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
4278 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %lu\n", size);
4280 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
4281 ok(ret, "failed to set password %lu\n", GetLastError());
4283 size = ARRAY_SIZE(buffer);
4284 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
4285 ok(ret, "failed to query password %lu\n", GetLastError());
4286 ok(!wcscmp(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
4287 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %lu\n", size);
4289 WinHttpCloseHandle(req);
4291 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
4292 ok(req != NULL, "failed to open a request %lu\n", GetLastError());
4294 SetLastError(0xdeadbeef);
4295 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
4296 error = GetLastError();
4297 ok(!ret, "expected failure\n");
4298 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
4300 SetLastError(0xdeadbeef);
4301 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
4302 error = GetLastError();
4303 ok(!ret, "expected failure\n");
4304 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
4306 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
4307 ok(ret, "failed to set credentials %lu\n", GetLastError());
4309 size = ARRAY_SIZE(buffer);
4310 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
4311 ok(ret, "failed to query username %lu\n", GetLastError());
4312 todo_wine {
4313 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
4314 ok(!size, "expected 0, got %lu\n", size);
4317 size = ARRAY_SIZE(buffer);
4318 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
4319 ok(ret, "failed to query password %lu\n", GetLastError());
4320 todo_wine {
4321 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
4322 ok(!size, "expected 0, got %lu\n", size);
4325 WinHttpCloseHandle(req);
4326 WinHttpCloseHandle(con);
4327 WinHttpCloseHandle(ses);
4330 static void test_IWinHttpRequest(int port)
4332 static const WCHAR data_start[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
4333 HRESULT hr;
4334 IWinHttpRequest *req;
4335 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
4336 BSTR date, today, connection, value = NULL;
4337 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp;
4338 VARIANT_BOOL succeeded;
4339 LONG status;
4340 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
4341 SYSTEMTIME st;
4342 IStream *stream, *stream2;
4343 LARGE_INTEGER pos;
4344 char buf[128];
4345 WCHAR bufW[128];
4346 DWORD count;
4348 GetSystemTime( &st );
4349 WinHttpTimeFromSystemTime( &st, todayW );
4351 CoInitialize( NULL );
4352 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4353 ok( hr == S_OK, "got %#lx\n", hr );
4355 V_VT( &empty ) = VT_ERROR;
4356 V_ERROR( &empty ) = 0xdeadbeef;
4358 V_VT( &async ) = VT_BOOL;
4359 V_BOOL( &async ) = VARIANT_FALSE;
4361 method = SysAllocString( L"POST" );
4362 url = SysAllocString( L"http://test.winehq.org/tests/post.php" );
4363 hr = IWinHttpRequest_Open( req, method, url, async );
4364 ok( hr == S_OK, "got %#lx\n", hr );
4365 SysFreeString( method );
4366 SysFreeString( url );
4368 V_VT( &data ) = VT_BSTR;
4369 V_BSTR( &data ) = SysAllocString( L"testdata\x80" );
4370 hr = IWinHttpRequest_Send( req, data );
4371 ok( hr == S_OK || hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE ), "got %#lx\n", hr );
4372 SysFreeString( V_BSTR( &data ) );
4373 if (hr != S_OK) goto done;
4375 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
4376 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4378 method = SysAllocString( L"GET" );
4379 hr = IWinHttpRequest_Open( req, method, NULL, empty );
4380 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4382 hr = IWinHttpRequest_Open( req, method, NULL, async );
4383 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4385 url = SysAllocString( L"http://test.winehq.org" );
4386 hr = IWinHttpRequest_Open( req, NULL, url, empty );
4387 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4389 hr = IWinHttpRequest_Abort( req );
4390 ok( hr == S_OK, "got %#lx\n", hr );
4392 hr = IWinHttpRequest_Open( req, method, url, empty );
4393 ok( hr == S_OK, "got %#lx\n", hr );
4395 hr = IWinHttpRequest_Abort( req );
4396 ok( hr == S_OK, "got %#lx\n", hr );
4398 IWinHttpRequest_Release( req );
4400 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4401 ok( hr == S_OK, "got %#lx\n", hr );
4403 SysFreeString( url );
4404 url = SysAllocString( L"test.winehq.org" );
4405 hr = IWinHttpRequest_Open( req, method, url, async );
4406 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %#lx\n", hr );
4408 SysFreeString( method );
4409 method = SysAllocString( L"INVALID" );
4410 hr = IWinHttpRequest_Open( req, method, url, async );
4411 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %#lx\n", hr );
4413 SysFreeString( method );
4414 method = SysAllocString( L"GET" );
4415 SysFreeString( url );
4416 url = SysAllocString( L"http://test.winehq.org" );
4417 V_VT( &async ) = VT_ERROR;
4418 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND;
4419 hr = IWinHttpRequest_Open( req, method, url, async );
4420 ok( hr == S_OK, "got %#lx\n", hr );
4422 V_VT( &cp ) = VT_ERROR;
4423 V_ERROR( &cp ) = 0xdeadbeef;
4424 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
4425 ok( hr == S_OK, "got %#lx\n", hr );
4426 ok( V_VT( &cp ) == VT_I4, "got %#x\n", V_VT( &cp ) );
4427 ok( V_I4( &cp ) == CP_UTF8, "got %ld\n", V_I4( &cp ) );
4429 V_VT( &cp ) = VT_UI4;
4430 V_UI4( &cp ) = CP_ACP;
4431 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
4432 ok( hr == S_OK, "got %#lx\n", hr );
4434 V_VT( &cp ) = VT_ERROR;
4435 V_ERROR( &cp ) = 0xdeadbeef;
4436 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
4437 ok( hr == S_OK, "got %#lx\n", hr );
4438 ok( V_VT( &cp ) == VT_I4, "got %#x\n", V_VT( &cp ) );
4439 ok( V_I4( &cp ) == CP_ACP, "got %ld\n", V_I4( &cp ) );
4441 value = SysAllocString( L"utf-8" );
4442 V_VT( &cp ) = VT_BSTR;
4443 V_BSTR( &cp ) = value;
4444 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
4445 ok( hr == S_OK, "got %#lx\n", hr );
4446 SysFreeString( value );
4448 V_VT( &cp ) = VT_ERROR;
4449 V_ERROR( &cp ) = 0xdeadbeef;
4450 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
4451 ok( hr == S_OK, "got %#lx\n", hr );
4452 ok( V_VT( &cp ) == VT_I4, "got %#x\n", V_VT( &cp ) );
4453 ok( V_I4( &cp ) == CP_UTF8, "got %ld\n", V_I4( &cp ) );
4455 hr = IWinHttpRequest_Abort( req );
4456 ok( hr == S_OK, "got %#lx\n", hr );
4458 hr = IWinHttpRequest_Send( req, empty );
4459 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %#lx\n", hr );
4461 hr = IWinHttpRequest_Abort( req );
4462 ok( hr == S_OK, "got %#lx\n", hr );
4464 IWinHttpRequest_Release( req );
4466 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4467 ok( hr == S_OK, "got %#lx\n", hr );
4469 hr = IWinHttpRequest_get_ResponseText( req, NULL );
4470 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4472 hr = IWinHttpRequest_get_ResponseText( req, &response );
4473 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4475 hr = IWinHttpRequest_get_Status( req, NULL );
4476 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4478 hr = IWinHttpRequest_get_Status( req, &status );
4479 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4481 hr = IWinHttpRequest_get_StatusText( req, NULL );
4482 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4484 hr = IWinHttpRequest_get_StatusText( req, &status_text );
4485 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4487 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
4488 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4490 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
4491 ok( hr == S_OK, "got %#lx\n", hr );
4493 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
4494 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %#lx\n", hr );
4496 VariantInit( &proxy_server );
4497 V_VT( &proxy_server ) = VT_ERROR;
4498 VariantInit( &bypass_list );
4499 V_VT( &bypass_list ) = VT_ERROR;
4500 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4501 ok( hr == S_OK, "got %#lx\n", hr );
4503 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4504 ok( hr == S_OK, "got %#lx\n", hr );
4506 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4507 ok( hr == S_OK, "got %#lx\n", hr );
4509 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
4510 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4512 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4513 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4515 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
4516 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4518 connection = SysAllocString( L"Connection" );
4519 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
4520 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4522 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4523 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4525 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
4526 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4528 date = SysAllocString( L"Date" );
4529 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
4530 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %#lx\n", hr );
4532 today = SysAllocString( todayW );
4533 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4534 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %#lx\n", hr );
4536 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
4537 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4539 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4540 ok( hr == S_OK, "got %#lx\n", hr );
4542 SysFreeString( method );
4543 method = SysAllocString( L"GET" );
4544 SysFreeString( url );
4545 url = SysAllocString( L"http://test.winehq.org" );
4546 hr = IWinHttpRequest_Open( req, method, url, async );
4547 ok( hr == S_OK, "got %#lx\n", hr );
4549 hr = IWinHttpRequest_get_ResponseText( req, NULL );
4550 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4552 hr = IWinHttpRequest_get_ResponseText( req, &response );
4553 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4555 hr = IWinHttpRequest_get_Status( req, &status );
4556 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4558 hr = IWinHttpRequest_get_StatusText( req, &status_text );
4559 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4561 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
4562 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4564 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
4565 ok( hr == S_OK, "got %#lx\n", hr );
4567 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
4568 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4570 username = SysAllocString( L"username" );
4571 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
4572 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4574 password = SysAllocString( L"password" );
4575 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
4576 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4578 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
4579 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4581 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4582 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4584 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4585 ok( hr == S_OK, "got %#lx\n", hr );
4587 V_VT( &proxy_server ) = VT_BSTR;
4588 V_BSTR( &proxy_server ) = SysAllocString( L"proxyserver" );
4589 V_VT( &bypass_list ) = VT_BSTR;
4590 V_BSTR( &bypass_list ) = SysAllocString( L"bypasslist" );
4591 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4592 ok( hr == S_OK, "got %#lx\n", hr );
4594 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
4595 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4597 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4598 ok( hr == S_OK, "got %#lx\n", hr );
4600 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4601 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4603 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4604 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4606 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4607 ok( hr == S_OK, "got %#lx\n", hr );
4609 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
4610 ok( hr == S_OK, "got %#lx\n", hr );
4612 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4613 ok( hr == S_OK, "got %#lx\n", hr );
4615 hr = IWinHttpRequest_Send( req, empty );
4616 ok( hr == S_OK, "got %#lx\n", hr );
4618 hr = IWinHttpRequest_Send( req, empty );
4619 ok( hr == S_OK, "got %#lx\n", hr );
4621 hr = IWinHttpRequest_get_ResponseText( req, NULL );
4622 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4624 hr = IWinHttpRequest_get_ResponseText( req, &response );
4625 ok( hr == S_OK, "got %#lx\n", hr );
4626 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
4627 SysFreeString( response );
4629 hr = IWinHttpRequest_get_Status( req, NULL );
4630 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4632 status = 0;
4633 hr = IWinHttpRequest_get_Status( req, &status );
4634 ok( hr == S_OK, "got %#lx\n", hr );
4635 trace("Status = %lu\n", status);
4637 hr = IWinHttpRequest_get_StatusText( req, NULL );
4638 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4640 hr = IWinHttpRequest_get_StatusText( req, &status_text );
4641 ok( hr == S_OK, "got %#lx\n", hr );
4642 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
4643 SysFreeString( status_text );
4645 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
4646 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4648 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4649 ok( hr == S_OK, "got %#lx\n", hr );
4651 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4652 ok( hr == S_OK, "got %#lx\n", hr );
4654 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4655 ok( hr == S_OK, "got %#lx\n", hr );
4657 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
4658 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4660 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4661 ok( hr == S_OK, "got %#lx\n", hr );
4662 SysFreeString( headers );
4664 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
4665 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4667 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
4668 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4670 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4671 ok( hr == S_OK, "got %#lx\n", hr );
4672 SysFreeString( value );
4674 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4675 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %#lx\n", hr );
4677 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4678 ok( hr == S_OK, "got %#lx\n", hr );
4680 VariantInit( &timeout );
4681 V_VT( &timeout ) = VT_I4;
4682 V_I4( &timeout ) = 10;
4683 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
4684 ok( hr == S_OK, "got %#lx\n", hr );
4686 hr = IWinHttpRequest_get_Status( req, &status );
4687 ok( hr == S_OK, "got %#lx\n", hr );
4689 hr = IWinHttpRequest_get_StatusText( req, &status_text );
4690 ok( hr == S_OK, "got %#lx\n", hr );
4691 SysFreeString( status_text );
4693 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4694 ok( hr == S_OK, "got %#lx\n", hr );
4696 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4697 ok( hr == S_OK, "got %#lx\n", hr );
4699 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4700 ok( hr == S_OK, "got %#lx\n", hr );
4702 hr = IWinHttpRequest_Send( req, empty );
4703 ok( hr == S_OK, "got %#lx\n", hr );
4705 hr = IWinHttpRequest_get_ResponseText( req, NULL );
4706 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4708 hr = IWinHttpRequest_get_ResponseText( req, &response );
4709 ok( hr == S_OK, "got %#lx\n", hr );
4710 SysFreeString( response );
4712 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
4713 ok( hr == E_INVALIDARG, "got %#lx\n", hr );
4715 VariantInit( &body );
4716 V_VT( &body ) = VT_ERROR;
4717 hr = IWinHttpRequest_get_ResponseBody( req, &body );
4718 ok( hr == S_OK, "got %#lx\n", hr );
4719 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %#x\n", V_VT( &body ) );
4721 hr = VariantClear( &body );
4722 ok( hr == S_OK, "got %#lx\n", hr );
4724 VariantInit( &body );
4725 V_VT( &body ) = VT_ERROR;
4726 hr = IWinHttpRequest_get_ResponseStream( req, &body );
4727 ok( hr == S_OK, "got %#lx\n", hr );
4728 ok( V_VT( &body ) == VT_UNKNOWN, "got %#x\n", V_VT( &body ) );
4730 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream );
4731 ok( hr == S_OK, "got %#lx\n", hr );
4732 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" );
4734 buf[0] = 0;
4735 count = 0xdeadbeef;
4736 hr = IStream_Read( stream, buf, 128, &count );
4737 ok( hr == S_OK, "got %#lx\n", hr );
4738 ok( count != 0xdeadbeef, "count not set\n" );
4739 ok( buf[0], "no data\n" );
4741 VariantInit( &body2 );
4742 V_VT( &body2 ) = VT_ERROR;
4743 hr = IWinHttpRequest_get_ResponseStream( req, &body2 );
4744 ok( hr == S_OK, "got %#lx\n", hr );
4745 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %#x\n", V_VT( &body2 ) );
4746 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" );
4748 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 );
4749 ok( hr == S_OK, "got %#lx\n", hr );
4750 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" );
4751 IStream_Release( stream2 );
4753 hr = VariantClear( &body );
4754 ok( hr == S_OK, "got %#lx\n", hr );
4756 hr = VariantClear( &body2 );
4757 ok( hr == S_OK, "got %#lx\n", hr );
4759 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4760 ok( hr == S_OK, "got %#lx\n", hr );
4762 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4763 ok( hr == S_OK, "got %#lx\n", hr );
4765 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4766 ok( hr == S_OK, "got %#lx\n", hr );
4767 SysFreeString( headers );
4769 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4770 ok( hr == S_OK, "got %#lx\n", hr );
4771 SysFreeString( value );
4773 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4774 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %#lx\n", hr );
4776 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4777 ok( hr == S_OK, "got %#lx\n", hr );
4779 hr = IWinHttpRequest_Send( req, empty );
4780 ok( hr == S_OK, "got %#lx\n", hr );
4782 hr = IWinHttpRequest_Abort( req );
4783 ok( hr == S_OK, "got %#lx\n", hr );
4785 hr = IWinHttpRequest_Abort( req );
4786 ok( hr == S_OK, "got %#lx\n", hr );
4788 IWinHttpRequest_Release( req );
4790 pos.QuadPart = 0;
4791 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL );
4792 ok( hr == S_OK, "got %#lx\n", hr );
4794 buf[0] = 0;
4795 count = 0xdeadbeef;
4796 hr = IStream_Read( stream, buf, 128, &count );
4797 ok( hr == S_OK, "got %#lx\n", hr );
4798 ok( count != 0xdeadbeef, "count not set\n" );
4799 ok( buf[0], "no data\n" );
4800 IStream_Release( stream );
4802 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4803 ok( hr == S_OK, "got %#lx\n", hr );
4805 V_VT( &async ) = VT_I4;
4806 V_I4( &async ) = 1;
4807 hr = IWinHttpRequest_Open( req, method, url, async );
4808 ok( hr == S_OK, "got %#lx\n", hr );
4810 hr = IWinHttpRequest_Send( req, empty );
4811 ok( hr == S_OK, "got %#lx\n", hr );
4813 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
4814 ok( hr == S_OK, "got %#lx\n", hr );
4816 IWinHttpRequest_Release( req );
4818 SysFreeString( method );
4819 SysFreeString( url );
4820 SysFreeString( username );
4821 SysFreeString( password );
4822 SysFreeString( connection );
4823 SysFreeString( date );
4824 SysFreeString( today );
4825 VariantClear( &proxy_server );
4826 VariantClear( &bypass_list );
4828 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4829 ok( hr == S_OK, "got %#lx\n", hr );
4831 url = SysAllocString( L"https://test.winehq.org:443" );
4832 method = SysAllocString( L"POST" );
4833 V_VT( &async ) = VT_BOOL;
4834 V_BOOL( &async ) = VARIANT_FALSE;
4835 hr = IWinHttpRequest_Open( req, method, url, async );
4836 ok( hr == S_OK, "got %#lx\n", hr );
4837 SysFreeString( method );
4838 SysFreeString( url );
4840 hr = IWinHttpRequest_Send( req, empty );
4841 ok( hr == S_OK || hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE ) ||
4842 hr == SEC_E_ILLEGAL_MESSAGE /* winxp */, "got %#lx\n", hr );
4843 if (hr != S_OK) goto done;
4845 hr = IWinHttpRequest_get_ResponseText( req, &response );
4846 ok( hr == S_OK, "got %#lx\n", hr );
4847 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
4848 SysFreeString( response );
4850 IWinHttpRequest_Release( req );
4852 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4853 ok( hr == S_OK, "got %#lx\n", hr );
4855 sprintf( buf, "http://localhost:%d/auth", port );
4856 MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, ARRAY_SIZE( bufW ));
4857 url = SysAllocString( bufW );
4858 method = SysAllocString( L"POST" );
4859 V_VT( &async ) = VT_BOOL;
4860 V_BOOL( &async ) = VARIANT_FALSE;
4861 hr = IWinHttpRequest_Open( req, method, url, async );
4862 ok( hr == S_OK, "got %#lx\n", hr );
4863 SysFreeString( method );
4864 SysFreeString( url );
4866 hr = IWinHttpRequest_get_Status( req, &status );
4867 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %#lx\n", hr );
4869 V_VT( &data ) = VT_BSTR;
4870 V_BSTR( &data ) = SysAllocString( L"testdata\x80" );
4871 hr = IWinHttpRequest_Send( req, data );
4872 ok( hr == S_OK, "got %#lx\n", hr );
4873 SysFreeString( V_BSTR( &data ) );
4875 hr = IWinHttpRequest_get_ResponseText( req, &response );
4876 ok( hr == S_OK, "got %#lx\n", hr );
4877 ok( !memcmp( response, L"Unauthorized", sizeof(L"Unauthorized") ), "got %s\n", wine_dbgstr_w(response) );
4878 SysFreeString( response );
4880 status = 0xdeadbeef;
4881 hr = IWinHttpRequest_get_Status( req, &status );
4882 ok( hr == S_OK, "got %#lx\n", hr );
4883 ok( status == HTTP_STATUS_DENIED, "got %lu\n", status );
4885 done:
4886 IWinHttpRequest_Release( req );
4887 CoUninitialize();
4890 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret)
4892 DISPPARAMS params;
4893 VARIANT arg;
4894 HRESULT hr;
4896 memset(&params, 0, sizeof(params));
4897 params.cNamedArgs = 0;
4898 params.rgdispidNamedArgs = NULL;
4899 params.cArgs = 1;
4900 params.rgvarg = &arg;
4901 VariantInit(&arg);
4902 V_VT(&arg) = VT_I4;
4903 V_I4(&arg) = property;
4904 VariantInit(ret);
4905 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4906 DISPATCH_PROPERTYGET, &params, ret, NULL, NULL);
4907 ok(hr == S_OK, "error %#lx\n", hr);
4910 static void test_IWinHttpRequest_Invoke(void)
4912 WCHAR openW[] = {'O','p','e','n',0};
4913 WCHAR optionW[] = {'O','p','t','i','o','n',0};
4914 OLECHAR *open = openW, *option = optionW;
4915 BSTR utf8;
4916 CLSID clsid;
4917 IWinHttpRequest *request;
4918 IDispatch *dispatch;
4919 DISPID id;
4920 DISPPARAMS params;
4921 VARIANT arg[3], ret;
4922 UINT err;
4923 BOOL bret;
4924 HRESULT hr;
4926 CoInitialize(NULL);
4928 hr = CLSIDFromProgID(L"WinHttp.WinHttpRequest.5.1", &clsid);
4929 ok(hr == S_OK, "CLSIDFromProgID error %#lx\n", hr);
4930 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest);
4931 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid));
4933 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request);
4934 ok(hr == S_OK, "error %#lx\n", hr);
4936 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch);
4937 ok(hr == S_OK, "error %#lx\n", hr);
4938 IDispatch_Release(dispatch);
4940 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id);
4941 ok(hr == S_OK, "error %#lx\n", hr);
4942 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %lu\n", id);
4944 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id);
4945 ok(hr == S_OK, "error %#lx\n", hr);
4946 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %lu\n", id);
4948 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4949 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
4950 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %ld\n", V_I4(&ret));
4952 memset(&params, 0, sizeof(params));
4953 params.cArgs = 2;
4954 params.cNamedArgs = 0;
4955 params.rgvarg = arg;
4956 V_VT(&arg[0]) = VT_I4;
4957 V_I4(&arg[0]) = 1252;
4958 V_VT(&arg[1]) = VT_R8;
4959 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4960 VariantInit(&ret);
4961 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4962 DISPATCH_METHOD, &params, NULL, NULL, &err);
4963 ok(hr == S_OK, "error %#lx\n", hr);
4965 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4966 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
4967 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %ld\n", V_I4(&ret));
4969 memset(&params, 0, sizeof(params));
4970 params.cArgs = 2;
4971 params.cNamedArgs = 0;
4972 params.rgvarg = arg;
4973 V_VT(&arg[0]) = VT_I4;
4974 V_I4(&arg[0]) = 1252;
4975 V_VT(&arg[1]) = VT_R8;
4976 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4977 VariantInit(&ret);
4978 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4979 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
4980 ok(hr == S_OK, "error %#lx\n", hr);
4982 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4983 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
4984 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %ld\n", V_I4(&ret));
4986 memset(&params, 0, sizeof(params));
4987 params.cArgs = 2;
4988 params.cNamedArgs = 0;
4989 params.rgvarg = arg;
4990 V_VT(&arg[0]) = VT_I4;
4991 V_I4(&arg[0]) = 1252;
4992 V_VT(&arg[1]) = VT_R8;
4993 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4994 VariantInit(&ret);
4995 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4996 DISPATCH_PROPERTYPUT, &params, NULL, NULL, &err);
4997 ok(hr == S_OK, "error %#lx\n", hr);
4999 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
5000 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
5001 ok(V_I4(&ret) == 1252, "expected 1252, got %ld\n", V_I4(&ret));
5003 memset(&params, 0, sizeof(params));
5004 params.cArgs = 2;
5005 params.cNamedArgs = 0;
5006 params.rgvarg = arg;
5007 V_VT(&arg[0]) = VT_BSTR;
5008 utf8 = SysAllocString(L"UTF-8");
5009 V_BSTR(&arg[0]) = utf8;
5010 V_VT(&arg[1]) = VT_R8;
5011 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
5012 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, &err);
5013 ok(hr == S_OK, "error %#lx\n", hr);
5015 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
5016 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
5017 ok(V_I4(&ret) == 1252, "expected 1252, got %ld\n", V_I4(&ret));
5019 VariantInit(&ret);
5020 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, &err);
5021 ok(hr == S_OK, "error %#lx\n", hr);
5023 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
5024 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
5025 ok(V_I4(&ret) == 1252, "expected 1252, got %ld\n", V_I4(&ret));
5027 VariantInit(&ret);
5028 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
5029 ok(hr == S_OK, "error %#lx\n", hr);
5031 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
5032 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
5033 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %ld\n", V_I4(&ret));
5035 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
5036 ok(hr == S_OK, "error %#lx\n", hr);
5038 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
5039 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#lx\n", hr);
5041 VariantInit(&ret);
5042 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
5043 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#lx\n", hr);
5045 VariantInit(&ret);
5046 if (0) /* crashes */
5047 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err);
5049 params.cArgs = 1;
5050 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
5051 ok(hr == DISP_E_TYPEMISMATCH, "error %#lx\n", hr);
5053 VariantInit(&arg[2]);
5054 params.cArgs = 3;
5055 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &params, &ret, NULL, &err);
5056 todo_wine
5057 ok(hr == S_OK, "error %#lx\n", hr);
5059 VariantInit(&arg[0]);
5060 VariantInit(&arg[1]);
5061 VariantInit(&arg[2]);
5063 params.cArgs = 1;
5064 V_VT(&arg[0]) = VT_I4;
5065 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage;
5066 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
5067 ok(hr == S_OK, "error %#lx\n", hr);
5069 V_VT(&ret) = 0xdead;
5070 V_I4(&ret) = 0xbeef;
5071 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, &ret, NULL, NULL);
5072 ok(hr == S_OK, "error %#lx\n", hr);
5073 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
5074 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %ld\n", V_I4(&ret));
5076 V_VT(&ret) = 0xdead;
5077 V_I4(&ret) = 0xbeef;
5078 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, &params, &ret, NULL, NULL);
5079 ok(hr == S_OK, "error %#lx\n", hr);
5080 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %#x\n", V_VT(&ret));
5081 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %ld\n", V_I4(&ret));
5083 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
5084 ok(hr == S_OK, "error %#lx\n", hr);
5086 V_VT(&ret) = 0xdead;
5087 V_I4(&ret) = 0xbeef;
5088 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, &ret, NULL, NULL);
5089 ok(hr == S_OK, "error %#lx\n", hr);
5090 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %#x\n", V_VT(&ret));
5091 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %ld\n", V_I4(&ret));
5093 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, &params, NULL, NULL, NULL);
5094 ok(hr == S_OK, "error %#lx\n", hr);
5096 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
5097 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#lx\n", hr);
5099 params.cArgs = 2;
5100 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
5101 todo_wine
5102 ok(hr == S_OK, "error %#lx\n", hr);
5104 params.cArgs = 0;
5105 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, &params, NULL, NULL, NULL);
5106 ok(hr == DISP_E_PARAMNOTFOUND, "error %#lx\n", hr);
5108 SysFreeString(utf8);
5110 params.cArgs = 1;
5111 V_VT(&arg[0]) = VT_I4;
5112 V_I4(&arg[0]) = AutoLogonPolicy_Never;
5113 VariantInit(&ret);
5114 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0,
5115 DISPATCH_METHOD, &params, &ret, NULL, NULL);
5116 ok(hr == S_OK, "error %#lx\n", hr);
5118 IWinHttpRequest_Release(request);
5120 CoUninitialize();
5123 static void test_WinHttpDetectAutoProxyConfigUrl(void)
5125 BOOL ret;
5126 WCHAR *url;
5127 DWORD error;
5129 SetLastError(0xdeadbeef);
5130 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
5131 error = GetLastError();
5132 ok( !ret, "expected failure\n" );
5133 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5135 url = NULL;
5136 SetLastError(0xdeadbeef);
5137 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
5138 error = GetLastError();
5139 ok( !ret, "expected failure\n" );
5140 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5142 SetLastError(0xdeadbeef);
5143 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
5144 error = GetLastError();
5145 ok( !ret, "expected failure\n" );
5146 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5148 url = (WCHAR *)0xdeadbeef;
5149 SetLastError(0xdeadbeef);
5150 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
5151 error = GetLastError();
5152 if (!ret)
5154 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %lu\n", error );
5155 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
5157 else
5159 trace("%s\n", wine_dbgstr_w(url));
5160 GlobalFree( url );
5163 url = (WCHAR *)0xdeadbeef;
5164 SetLastError(0xdeadbeef);
5165 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
5166 error = GetLastError();
5167 if (!ret)
5169 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %lu\n", error );
5170 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
5172 else
5174 ok( error == ERROR_SUCCESS, "got %lu\n", error );
5175 trace("%s\n", wine_dbgstr_w(url));
5176 GlobalFree( url );
5180 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
5182 BOOL ret;
5183 DWORD error;
5184 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
5186 memset( &cfg, 0, sizeof(cfg) );
5188 SetLastError(0xdeadbeef);
5189 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
5190 error = GetLastError();
5191 ok( !ret, "expected failure\n" );
5192 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5194 SetLastError(0xdeadbeef);
5195 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
5196 error = GetLastError();
5197 ok( ret, "expected success\n" );
5198 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %lu\n", error );
5200 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
5201 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
5202 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
5203 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
5204 GlobalFree( cfg.lpszAutoConfigUrl );
5205 GlobalFree( cfg.lpszProxy );
5206 GlobalFree( cfg.lpszProxyBypass );
5209 static void test_WinHttpGetProxyForUrl(void)
5211 BOOL ret;
5212 DWORD error;
5213 HINTERNET session;
5214 WINHTTP_AUTOPROXY_OPTIONS options;
5215 WINHTTP_PROXY_INFO info;
5217 memset( &options, 0, sizeof(options) );
5219 SetLastError(0xdeadbeef);
5220 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
5221 error = GetLastError();
5222 ok( !ret, "expected failure\n" );
5223 ok( error == ERROR_INVALID_HANDLE, "got %lu\n", error );
5225 session = WinHttpOpen( L"winetest", 0, NULL, NULL, 0 );
5226 ok( session != NULL, "failed to open session %lu\n", GetLastError() );
5228 SetLastError(0xdeadbeef);
5229 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
5230 error = GetLastError();
5231 ok( !ret, "expected failure\n" );
5232 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5234 SetLastError(0xdeadbeef);
5235 ret = WinHttpGetProxyForUrl( session, L"", NULL, NULL );
5236 error = GetLastError();
5237 ok( !ret, "expected failure\n" );
5238 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5240 SetLastError(0xdeadbeef);
5241 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", NULL, NULL );
5242 error = GetLastError();
5243 ok( !ret, "expected failure\n" );
5244 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5246 SetLastError(0xdeadbeef);
5247 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", &options, &info );
5248 error = GetLastError();
5249 ok( !ret, "expected failure\n" );
5250 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5252 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
5253 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
5255 SetLastError(0xdeadbeef);
5256 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", &options, NULL );
5257 error = GetLastError();
5258 ok( !ret, "expected failure\n" );
5259 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5261 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
5262 options.dwAutoDetectFlags = 0;
5264 SetLastError(0xdeadbeef);
5265 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", &options, &info );
5266 error = GetLastError();
5267 ok( !ret, "expected failure\n" );
5268 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5270 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
5271 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
5273 SetLastError(0xdeadbeef);
5274 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", &options, &info );
5275 error = GetLastError();
5276 ok( !ret, "expected failure\n" );
5277 ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error );
5279 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
5280 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
5282 memset( &info, 0, sizeof(info) );
5283 SetLastError(0xdeadbeef);
5284 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", &options, &info );
5285 error = GetLastError();
5286 if (ret)
5288 ok( error == ERROR_SUCCESS, "got %lu\n", error );
5289 trace("Proxy.AccessType=%lu\n", info.dwAccessType);
5290 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
5291 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
5292 GlobalFree( info.lpszProxy );
5293 GlobalFree( info.lpszProxyBypass );
5295 ret = WinHttpGetProxyForUrl( session, L"http:", &options, &info );
5296 ok( !ret, "expected failure\n" );
5299 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
5300 options.dwAutoDetectFlags = 0;
5301 options.lpszAutoConfigUrl = L"http://wpad/wpad.dat";
5303 memset( &info, 0, sizeof(info) );
5304 ret = WinHttpGetProxyForUrl( session, L"http://winehq.org", &options, &info );
5305 if (ret)
5307 trace("Proxy.AccessType=%lu\n", info.dwAccessType);
5308 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
5309 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
5310 GlobalFree( info.lpszProxy );
5311 GlobalFree( info.lpszProxyBypass );
5314 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
5315 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A;
5317 ret = WinHttpGetProxyForUrl( session, L"http:", &options, &info );
5318 ok( !ret, "expected failure\n" );
5320 WinHttpCloseHandle( session );
5323 static void test_chunked_read(void)
5325 WCHAR header[32];
5326 DWORD len, err;
5327 HINTERNET ses, con = NULL, req = NULL;
5328 BOOL ret;
5330 trace( "starting chunked read test\n" );
5332 ses = WinHttpOpen( L"winetest", 0, NULL, NULL, 0 );
5333 ok( ses != NULL, "WinHttpOpen failed with error %lu\n", GetLastError() );
5334 if (!ses) goto done;
5336 con = WinHttpConnect( ses, L"test.winehq.org", 0, 0 );
5337 ok( con != NULL, "WinHttpConnect failed with error %lu\n", GetLastError() );
5338 if (!con) goto done;
5340 req = WinHttpOpenRequest( con, NULL, L"/tests/chunked", NULL, NULL, NULL, 0 );
5341 ok( req != NULL, "WinHttpOpenRequest failed with error %lu\n", GetLastError() );
5342 if (!req) goto done;
5344 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
5345 err = GetLastError();
5346 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
5348 skip("connection failed, skipping\n");
5349 goto done;
5351 ok( ret, "WinHttpSendRequest failed with error %lu\n", GetLastError() );
5352 if (!ret) goto done;
5354 ret = WinHttpReceiveResponse( req, NULL );
5355 ok( ret, "WinHttpReceiveResponse failed with error %lu\n", GetLastError() );
5356 if (!ret) goto done;
5358 header[0] = 0;
5359 len = sizeof(header);
5360 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
5361 ok( ret, "failed to get TRANSFER_ENCODING header with error %lu\n", GetLastError() );
5362 ok( !lstrcmpW( header, L"chunked" ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
5363 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
5365 header[0] = 0;
5366 len = sizeof(header);
5367 SetLastError( 0xdeadbeef );
5368 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
5369 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
5370 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %lu\n", GetLastError() );
5372 trace( "entering query loop\n" );
5373 for (;;)
5375 len = 0xdeadbeef;
5376 ret = WinHttpQueryDataAvailable( req, &len );
5377 ok( ret, "WinHttpQueryDataAvailable failed with error %lu\n", GetLastError() );
5378 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
5379 trace( "got %lu available\n", len );
5380 if (len)
5382 DWORD bytes_read;
5383 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
5385 ret = WinHttpReadData( req, buf, len, &bytes_read );
5386 ok(ret, "WinHttpReadData failed: %lu\n", GetLastError());
5388 buf[bytes_read] = 0;
5389 trace( "WinHttpReadData -> %d %lu\n", ret, bytes_read );
5390 ok( len == bytes_read, "only got %lu of %lu available\n", bytes_read, len );
5391 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
5393 HeapFree( GetProcessHeap(), 0, buf );
5394 if (!bytes_read) break;
5396 if (!len) break;
5398 trace( "done\n" );
5400 done:
5401 if (req) WinHttpCloseHandle( req );
5402 if (con) WinHttpCloseHandle( con );
5403 if (ses) WinHttpCloseHandle( ses );
5406 static void test_max_http_automatic_redirects (void)
5408 HINTERNET session, request, connection;
5409 DWORD max_redirects, err;
5410 BOOL ret;
5412 session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
5413 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
5414 ok(session != NULL, "WinHttpOpen failed to open session.\n");
5416 connection = WinHttpConnect (session, L"test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, 0);
5417 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %lu\n", GetLastError());
5419 /* Test with 2 redirects (page will try to redirect 3 times) */
5420 request = WinHttpOpenRequest(connection, L"GET", L"tests/redirecttest.php?max=3", NULL, WINHTTP_NO_REFERER,
5421 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
5422 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
5424 skip("Network unreachable, skipping.\n");
5425 goto done;
5427 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %lu\n", GetLastError());
5428 if (!request) goto done;
5430 max_redirects = 2;
5431 ret = WinHttpSetOption(request, WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS, &max_redirects, sizeof(max_redirects));
5432 ok(ret, "WinHttpSetOption failed: %lu\n", GetLastError());
5434 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
5435 err = GetLastError();
5436 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
5438 skip("connection failed, skipping\n");
5439 goto done;
5441 ok(ret == TRUE, "WinHttpSendRequest failed: %lu\n", GetLastError());
5443 SetLastError(0xdeadbeef);
5444 ret = WinHttpReceiveResponse(request, NULL);
5445 ok(!ret, "WinHttpReceiveResponse succeeded, expected failure\n");
5446 ok(GetLastError() == ERROR_WINHTTP_REDIRECT_FAILED, "Expected ERROR_WINHTTP_REDIRECT_FAILED, got %lu\n", GetLastError());
5448 done:
5449 ret = WinHttpCloseHandle(request);
5450 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
5451 ret = WinHttpCloseHandle(connection);
5452 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
5453 ret = WinHttpCloseHandle(session);
5454 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
5457 static const BYTE pfxdata[] =
5459 0x30, 0x82, 0x0b, 0x1d, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0a, 0xe3, 0x06,
5460 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
5461 0x0a, 0xd4, 0x04, 0x82, 0x0a, 0xd0, 0x30, 0x82, 0x0a, 0xcc, 0x30, 0x82,
5462 0x05, 0x07, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
5463 0x06, 0xa0, 0x82, 0x04, 0xf8, 0x30, 0x82, 0x04, 0xf4, 0x02, 0x01, 0x00,
5464 0x30, 0x82, 0x04, 0xed, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
5465 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5466 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xac, 0x3e, 0x35,
5467 0xa8, 0xed, 0x0d, 0x50, 0x07, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x04,
5468 0xc0, 0x5a, 0x62, 0x55, 0x25, 0xf6, 0x2c, 0xf1, 0x78, 0x6c, 0x63, 0x96,
5469 0x8a, 0xea, 0x04, 0x64, 0xb3, 0x99, 0x3b, 0x80, 0x50, 0x05, 0x37, 0x55,
5470 0xa3, 0x5e, 0x9f, 0x35, 0xc3, 0x3c, 0xdc, 0xf6, 0xc4, 0xc1, 0x39, 0xa2,
5471 0xd7, 0x50, 0xad, 0xf9, 0x29, 0x3c, 0x51, 0xea, 0x15, 0x20, 0x25, 0xd3,
5472 0x4d, 0x69, 0xdf, 0x10, 0xd8, 0x9d, 0x60, 0x78, 0x8a, 0x70, 0x44, 0x7f,
5473 0x01, 0x4f, 0x4a, 0xfa, 0xab, 0xfd, 0x46, 0x48, 0x96, 0x2b, 0x69, 0xfc,
5474 0x11, 0xf8, 0x3f, 0xd3, 0x79, 0x09, 0x75, 0x81, 0x47, 0xdf, 0xce, 0xfe,
5475 0x07, 0x2f, 0x0a, 0xd8, 0xac, 0x87, 0x14, 0x1f, 0x7b, 0x95, 0x70, 0xee,
5476 0x7e, 0x52, 0x90, 0x11, 0xd6, 0x69, 0xf4, 0xd5, 0x38, 0x85, 0xc9, 0xc1,
5477 0x07, 0x01, 0xe8, 0xbb, 0xfb, 0xe2, 0x08, 0xa8, 0xfa, 0xbf, 0xf0, 0x92,
5478 0x63, 0x1d, 0xbb, 0x2b, 0x45, 0x6f, 0xce, 0x97, 0x01, 0xd7, 0x95, 0xf0,
5479 0x9c, 0x9a, 0x6b, 0x73, 0x01, 0xbf, 0xf9, 0x3d, 0xc8, 0x2b, 0x86, 0x7a,
5480 0xd5, 0x65, 0x84, 0xd7, 0xff, 0xb2, 0xf9, 0x20, 0x52, 0x35, 0xc5, 0x60,
5481 0x33, 0x70, 0x1d, 0x2f, 0x26, 0x09, 0x1c, 0x22, 0x17, 0xd8, 0x08, 0x4e,
5482 0x69, 0x20, 0xe2, 0x71, 0xe4, 0x07, 0xb1, 0x48, 0x5f, 0x20, 0x08, 0x7a,
5483 0xbf, 0x65, 0x53, 0x23, 0x07, 0xf9, 0x6c, 0xde, 0x3e, 0x29, 0xbf, 0x6b,
5484 0xef, 0xbb, 0x6a, 0x5f, 0x79, 0xa1, 0x72, 0xa1, 0x10, 0x24, 0x80, 0xb4,
5485 0x44, 0xb8, 0xc9, 0xfc, 0xa3, 0x36, 0x7e, 0x23, 0x37, 0x58, 0xc6, 0x1e,
5486 0xe8, 0x42, 0x4d, 0xb5, 0xf5, 0x58, 0x93, 0x21, 0x38, 0xa2, 0xc4, 0xa9,
5487 0x01, 0x96, 0xf9, 0x61, 0xac, 0x55, 0xb3, 0x3d, 0xe4, 0x54, 0x8b, 0x6c,
5488 0xc3, 0x83, 0xff, 0x50, 0x87, 0x94, 0xe8, 0x35, 0x3c, 0x26, 0x0d, 0x20,
5489 0x8a, 0x25, 0x0e, 0xb6, 0x67, 0x78, 0x29, 0xc7, 0xbf, 0x76, 0x8e, 0x62,
5490 0x62, 0xc4, 0x50, 0xd6, 0xc5, 0x3c, 0xb4, 0x7a, 0x35, 0xbe, 0x53, 0x52,
5491 0xc4, 0xe4, 0x10, 0xb3, 0xe0, 0x73, 0xb0, 0xd1, 0xc1, 0x5a, 0x4f, 0x4e,
5492 0x64, 0x0d, 0x92, 0x51, 0x2d, 0x4d, 0xec, 0xb0, 0xc6, 0x40, 0x1b, 0x03,
5493 0x89, 0x7f, 0xc2, 0x2c, 0xe3, 0x2c, 0xbd, 0x8c, 0x9c, 0xd9, 0xe0, 0x08,
5494 0x59, 0xd3, 0xaf, 0x48, 0x56, 0x89, 0x60, 0x85, 0x76, 0xe0, 0xd8, 0x7c,
5495 0xcf, 0x02, 0x8f, 0xfd, 0xb2, 0x8f, 0x2b, 0x61, 0xcf, 0x28, 0x56, 0x8b,
5496 0x6b, 0x03, 0x2b, 0x2f, 0x83, 0x31, 0xa0, 0x1c, 0xd1, 0x6c, 0x87, 0x49,
5497 0xc4, 0x77, 0x55, 0x1f, 0x61, 0x45, 0x58, 0x88, 0x9f, 0x01, 0xc3, 0x63,
5498 0x62, 0x30, 0x35, 0xdf, 0x61, 0x74, 0x55, 0x63, 0x3f, 0xae, 0x41, 0xc1,
5499 0xb8, 0xf0, 0x9f, 0xab, 0x25, 0xad, 0x41, 0x5c, 0x1f, 0x00, 0x0d, 0xef,
5500 0xf0, 0xcf, 0xaf, 0x41, 0x23, 0xca, 0x8c, 0x38, 0xea, 0x5a, 0xe4, 0x8b,
5501 0xb4, 0x89, 0xd0, 0x76, 0x7f, 0x2b, 0x77, 0x8f, 0xe4, 0x44, 0xd5, 0x37,
5502 0xac, 0xc2, 0x09, 0x7e, 0x7e, 0x7e, 0x02, 0x5c, 0x27, 0x01, 0xcb, 0x4d,
5503 0xea, 0xb3, 0x97, 0x36, 0x35, 0xd2, 0x05, 0x3c, 0x4e, 0xb8, 0x04, 0x5c,
5504 0xb8, 0x95, 0x3f, 0xc6, 0xbf, 0xd4, 0x20, 0x01, 0xfb, 0xed, 0x37, 0x5a,
5505 0xad, 0x4c, 0x61, 0x93, 0xfe, 0x95, 0x7c, 0x34, 0x11, 0x15, 0x9d, 0x00,
5506 0x0b, 0x99, 0x69, 0xcb, 0x7e, 0xb9, 0x53, 0x46, 0x57, 0x39, 0x3f, 0x59,
5507 0x4b, 0x30, 0x8d, 0xfb, 0x84, 0x66, 0x2d, 0x06, 0xc9, 0x88, 0xa6, 0x18,
5508 0xd7, 0x36, 0xc6, 0xf6, 0xf7, 0x47, 0x85, 0x38, 0xc8, 0x3d, 0x37, 0xea,
5509 0x57, 0x4c, 0xb0, 0x7c, 0x95, 0x29, 0x84, 0xab, 0xbb, 0x19, 0x86, 0xc2,
5510 0xc5, 0x99, 0x01, 0x38, 0x6b, 0xf1, 0xd3, 0x1d, 0xa8, 0x02, 0xf9, 0x6f,
5511 0xaa, 0xf1, 0x57, 0xd0, 0x88, 0x68, 0x62, 0x5f, 0x9f, 0x7a, 0x63, 0xba,
5512 0x3a, 0xc9, 0x95, 0x11, 0x3c, 0xf9, 0xa1, 0xc1, 0x35, 0xfe, 0xd5, 0x12,
5513 0x49, 0x88, 0x0d, 0x5c, 0xe2, 0xd1, 0x15, 0x18, 0xfb, 0xd5, 0x7f, 0x19,
5514 0x3f, 0xaf, 0xa0, 0xcb, 0x31, 0x20, 0x9e, 0x03, 0x93, 0xa4, 0x66, 0xbd,
5515 0x83, 0xe8, 0x60, 0x34, 0x55, 0x0d, 0x97, 0x10, 0x23, 0x24, 0x7a, 0x45,
5516 0x36, 0xb4, 0xc4, 0xee, 0x60, 0x6f, 0xd8, 0x46, 0xc5, 0xac, 0x2b, 0xa9,
5517 0x18, 0x74, 0x83, 0x1e, 0xdf, 0x7c, 0x1a, 0x5a, 0xe8, 0x5f, 0x8b, 0x4f,
5518 0x9f, 0x40, 0x3e, 0x5e, 0xfb, 0xd3, 0x68, 0xac, 0x34, 0x62, 0x30, 0x23,
5519 0xb6, 0xbc, 0xdf, 0xbc, 0xc7, 0x25, 0xd2, 0x1b, 0x57, 0x33, 0xfb, 0x78,
5520 0x22, 0x21, 0x1e, 0x3a, 0xf6, 0x44, 0x18, 0x7e, 0x12, 0x36, 0x47, 0x58,
5521 0xd0, 0x59, 0x26, 0x98, 0x98, 0x95, 0xf4, 0xd1, 0xaa, 0x45, 0xaa, 0xe7,
5522 0xd1, 0xe6, 0x2d, 0x78, 0xf0, 0x8b, 0x1c, 0xfd, 0xf8, 0x50, 0x60, 0xa2,
5523 0x1e, 0x7f, 0xe3, 0x31, 0x77, 0x31, 0x58, 0x99, 0x0f, 0xda, 0x0e, 0xa3,
5524 0xc6, 0x7a, 0x30, 0x45, 0x55, 0x11, 0x91, 0x77, 0x41, 0x79, 0xd3, 0x56,
5525 0xb2, 0x07, 0x00, 0x61, 0xab, 0xec, 0x27, 0xc7, 0x9f, 0xfa, 0x89, 0x08,
5526 0xc2, 0x87, 0xcf, 0xe9, 0xdc, 0x9e, 0x29, 0x22, 0xfb, 0x23, 0x7f, 0x9d,
5527 0x89, 0xd5, 0x6e, 0x75, 0x20, 0xd8, 0x00, 0x5b, 0xc4, 0x94, 0xbb, 0xc5,
5528 0xb2, 0xba, 0x77, 0x2b, 0xf6, 0x3c, 0x88, 0xb0, 0x4c, 0x38, 0x46, 0x55,
5529 0xee, 0x8b, 0x03, 0x15, 0xbc, 0x0a, 0x1d, 0x47, 0x87, 0x44, 0xaf, 0xb1,
5530 0x2a, 0xa7, 0x4d, 0x08, 0xdf, 0x3b, 0x2d, 0x70, 0xa1, 0x67, 0x31, 0x76,
5531 0x6e, 0x6f, 0x40, 0x3b, 0x3b, 0xe8, 0xf9, 0xdf, 0x90, 0xa4, 0xce, 0x7f,
5532 0xb8, 0x2d, 0x69, 0xcb, 0x1c, 0x1e, 0x94, 0xcd, 0xb1, 0xd8, 0x43, 0x22,
5533 0xb8, 0x4f, 0x98, 0x92, 0x74, 0xb3, 0xde, 0xeb, 0x7a, 0xcb, 0xfa, 0xd0,
5534 0x36, 0xe4, 0x5d, 0xfa, 0xd3, 0xce, 0xf9, 0xba, 0x3e, 0x0f, 0x6c, 0xc3,
5535 0x5b, 0xb3, 0x81, 0x84, 0x6e, 0x5d, 0xc1, 0x21, 0x89, 0xec, 0x67, 0x9a,
5536 0xfd, 0x55, 0x20, 0xb0, 0x71, 0x53, 0xae, 0xf8, 0xa4, 0x8d, 0xd5, 0xe5,
5537 0x2d, 0x3a, 0xce, 0x89, 0x55, 0x8c, 0x4f, 0x3b, 0x37, 0x95, 0x4e, 0x15,
5538 0xbe, 0xe7, 0xd1, 0x7a, 0x36, 0x82, 0x45, 0x69, 0x7c, 0x27, 0x4f, 0xb9,
5539 0x4b, 0x7d, 0xcd, 0x59, 0xc8, 0xf4, 0x8b, 0x0f, 0x4f, 0x75, 0x23, 0xd3,
5540 0xd0, 0xc7, 0x10, 0x79, 0xc0, 0xf1, 0xac, 0x14, 0xf7, 0x0d, 0xc8, 0x5e,
5541 0xfc, 0xff, 0x1a, 0x2b, 0x10, 0x88, 0x7e, 0x7e, 0x2f, 0xfa, 0x7b, 0x9f,
5542 0x47, 0x23, 0x34, 0xfc, 0xf5, 0xde, 0xd9, 0xa3, 0x05, 0x99, 0x2a, 0x96,
5543 0x83, 0x3d, 0xa4, 0x7f, 0x6a, 0x66, 0x9b, 0xe7, 0xf1, 0x00, 0x4e, 0x9a,
5544 0xfc, 0x68, 0xd2, 0x74, 0x17, 0xba, 0xc9, 0xc8, 0x20, 0x39, 0xa1, 0xa8,
5545 0x85, 0xc6, 0x10, 0x2b, 0xab, 0x97, 0x34, 0x2d, 0x49, 0x68, 0x57, 0xb0,
5546 0x43, 0xee, 0x25, 0xbb, 0x35, 0x1b, 0x03, 0x99, 0xa3, 0x21, 0x68, 0x66,
5547 0x86, 0x3f, 0xc6, 0xfc, 0x49, 0xf0, 0xba, 0x5f, 0x00, 0xc6, 0xe3, 0x1c,
5548 0xb2, 0x9f, 0x16, 0x7f, 0xc7, 0x40, 0x4a, 0x9a, 0x39, 0xc1, 0x95, 0x69,
5549 0xa2, 0x87, 0xba, 0x58, 0xc6, 0xf2, 0xd6, 0x66, 0xa6, 0x4c, 0x6d, 0x29,
5550 0x9c, 0xa8, 0x6e, 0xa9, 0xd2, 0xe4, 0x54, 0x17, 0x89, 0xe2, 0x43, 0xf0,
5551 0xe1, 0x8b, 0x57, 0x84, 0x6c, 0x87, 0x63, 0x17, 0xbb, 0xf6, 0x33, 0x1b,
5552 0xe4, 0x34, 0x6a, 0x80, 0x70, 0x7b, 0x1b, 0xfd, 0xf8, 0x79, 0x28, 0xc8,
5553 0x3c, 0x8e, 0xa4, 0xd5, 0xb8, 0x96, 0x54, 0xd4, 0xec, 0x72, 0xe5, 0x40,
5554 0x8f, 0x56, 0xde, 0x82, 0x15, 0x72, 0x4d, 0xd8, 0x0c, 0x07, 0xea, 0xe6,
5555 0x44, 0xcd, 0x94, 0x73, 0x5c, 0x04, 0xe8, 0x8e, 0xb7, 0xc7, 0xc9, 0x29,
5556 0xdc, 0x04, 0xef, 0x7c, 0x31, 0x9b, 0x50, 0xbc, 0xea, 0x71, 0x1f, 0x28,
5557 0x22, 0xb6, 0x04, 0x53, 0x2e, 0x71, 0xc4, 0xf6, 0xbb, 0x88, 0x51, 0xee,
5558 0x3e, 0x76, 0x65, 0xb4, 0x4b, 0x1b, 0xa3, 0xec, 0x7b, 0xa7, 0x9d, 0x31,
5559 0x5d, 0xb8, 0x9f, 0xab, 0x6b, 0x54, 0x7d, 0xbd, 0xc1, 0x2c, 0x55, 0xb0,
5560 0x23, 0x8c, 0x06, 0x60, 0x01, 0x4f, 0x60, 0x85, 0x56, 0x7f, 0xfb, 0x99,
5561 0x0c, 0xdc, 0x8c, 0x09, 0x37, 0x46, 0x5b, 0x97, 0x5d, 0xe8, 0x31, 0x00,
5562 0x1b, 0x30, 0x9b, 0x02, 0x92, 0x29, 0xb5, 0x20, 0xce, 0x4b, 0x90, 0xfb,
5563 0x91, 0x07, 0x5a, 0xd3, 0xf5, 0xa0, 0xe6, 0x8f, 0xf8, 0x73, 0xc5, 0x4b,
5564 0xbb, 0xad, 0x2a, 0xeb, 0xa8, 0xb7, 0x68, 0x34, 0x36, 0x47, 0xd5, 0x4b,
5565 0x61, 0x89, 0x53, 0xe6, 0xb6, 0xb1, 0x07, 0xe4, 0x08, 0x2e, 0xed, 0x50,
5566 0xd4, 0x1e, 0xed, 0x7f, 0xbf, 0x35, 0x68, 0x04, 0x45, 0x72, 0x86, 0x71,
5567 0x15, 0x55, 0xdf, 0xe6, 0x30, 0xc0, 0x8b, 0x8a, 0xb0, 0x6c, 0xd0, 0x35,
5568 0x57, 0x8f, 0x04, 0x37, 0xbc, 0xe1, 0xb8, 0xbf, 0x27, 0x37, 0x3d, 0xd0,
5569 0xc8, 0x46, 0x67, 0x42, 0x51, 0x30, 0x82, 0x05, 0xbd, 0x06, 0x09, 0x2a,
5570 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0xae,
5571 0x04, 0x82, 0x05, 0xaa, 0x30, 0x82, 0x05, 0xa6, 0x30, 0x82, 0x05, 0xa2,
5572 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
5573 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06,
5574 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
5575 0x0e, 0x04, 0x08, 0x9f, 0xa4, 0x72, 0x2b, 0x6b, 0x0e, 0xcb, 0x9f, 0x02,
5576 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0xe5, 0x35, 0xb9, 0x72, 0x28,
5577 0x20, 0x28, 0xad, 0xe3, 0x01, 0xd7, 0x0b, 0xe0, 0x4e, 0x36, 0xc3, 0x73,
5578 0x06, 0xd5, 0xf6, 0x75, 0x1a, 0x78, 0xb2, 0xd8, 0xf6, 0x5a, 0x85, 0x8e,
5579 0x50, 0xa3, 0x05, 0x49, 0x02, 0x2d, 0xf8, 0xa3, 0x2f, 0xe6, 0x02, 0x7a,
5580 0xd5, 0x0b, 0x1d, 0xf1, 0xd1, 0xe4, 0x16, 0xaa, 0x70, 0x2e, 0x34, 0xdb,
5581 0x56, 0xd9, 0x33, 0x94, 0x11, 0xaa, 0x60, 0xd4, 0xfa, 0x5b, 0xd1, 0xb3,
5582 0x2e, 0x86, 0x6a, 0x5a, 0x69, 0xdf, 0x11, 0x91, 0xb0, 0xca, 0x82, 0xff,
5583 0x63, 0xad, 0x6a, 0x0b, 0x90, 0xa6, 0xc7, 0x9b, 0xef, 0x9a, 0xf8, 0x96,
5584 0xec, 0xe4, 0xc4, 0xdf, 0x55, 0x4c, 0x12, 0x07, 0xab, 0x7c, 0x5c, 0x68,
5585 0x47, 0xf2, 0x92, 0xfb, 0x94, 0xab, 0xc3, 0x64, 0xd3, 0xfe, 0xb2, 0x16,
5586 0xb4, 0x78, 0x80, 0x52, 0xe9, 0x32, 0x39, 0x3b, 0x8d, 0x12, 0x91, 0x36,
5587 0xfd, 0xa1, 0x97, 0xc2, 0x0a, 0x4a, 0xf1, 0xb3, 0x8a, 0xe4, 0x01, 0xed,
5588 0x0a, 0xda, 0x2e, 0xa0, 0x38, 0xa9, 0x47, 0x3d, 0x3a, 0x64, 0x87, 0x06,
5589 0xc3, 0x83, 0x60, 0xaf, 0x84, 0xdb, 0x87, 0xff, 0x70, 0x61, 0x43, 0x7d,
5590 0x2d, 0x61, 0x9a, 0xf7, 0x0d, 0xca, 0x0c, 0x0f, 0xbe, 0x43, 0x5b, 0x99,
5591 0xe1, 0x90, 0x64, 0x1f, 0xa7, 0x1b, 0xa6, 0xa6, 0x5c, 0x13, 0x70, 0xa3,
5592 0xdb, 0xd7, 0xf0, 0xe8, 0x7a, 0xb0, 0xd1, 0x9b, 0x52, 0xa6, 0x4f, 0xd6,
5593 0xff, 0x54, 0x4d, 0xa6, 0x15, 0x05, 0x5c, 0xe9, 0x04, 0x6a, 0xc3, 0x49,
5594 0x12, 0x2f, 0x24, 0x03, 0xc3, 0x80, 0x06, 0xa6, 0x07, 0x8b, 0x96, 0xe7,
5595 0x39, 0x31, 0x6d, 0xd3, 0x1b, 0xa5, 0x45, 0x58, 0x04, 0xe7, 0x87, 0xdf,
5596 0x26, 0xfb, 0x1b, 0x9f, 0x92, 0x93, 0x32, 0x12, 0x9a, 0xc9, 0xe6, 0xcb,
5597 0x88, 0x14, 0x9f, 0x23, 0x0b, 0x52, 0xa2, 0xb8, 0x32, 0x6c, 0xa9, 0x33,
5598 0xa1, 0x17, 0xe8, 0x4a, 0xd4, 0x5c, 0x7d, 0xb3, 0xa3, 0x64, 0x86, 0x03,
5599 0x7c, 0x7c, 0x3f, 0x99, 0xdc, 0x21, 0x9f, 0x93, 0xc6, 0xb9, 0x1d, 0xe0,
5600 0x21, 0x79, 0x78, 0x35, 0xdc, 0x1e, 0x27, 0x3c, 0x73, 0x7f, 0x0f, 0xd6,
5601 0x4f, 0xde, 0xe9, 0xb4, 0xb7, 0xe3, 0xf5, 0x72, 0xce, 0x42, 0xf3, 0x91,
5602 0x5b, 0x84, 0xba, 0xbb, 0xae, 0xf0, 0x87, 0x0f, 0x50, 0xa4, 0x5e, 0x80,
5603 0x23, 0x57, 0x2b, 0xa0, 0xa3, 0xc3, 0x8a, 0x2f, 0xa8, 0x7a, 0x1a, 0x65,
5604 0x8f, 0x62, 0xf8, 0x3e, 0xe2, 0xcd, 0xbc, 0x63, 0x56, 0x8e, 0x77, 0xf3,
5605 0xf9, 0x69, 0x10, 0x57, 0xa8, 0xaf, 0x67, 0x2a, 0x9f, 0x7f, 0x7e, 0xeb,
5606 0x1d, 0x99, 0xa6, 0x67, 0xcd, 0x9e, 0x42, 0x2e, 0x5e, 0x4e, 0x61, 0x24,
5607 0xfa, 0xca, 0x2a, 0xeb, 0x62, 0x1f, 0xa3, 0x14, 0x0a, 0x06, 0x4b, 0x77,
5608 0x78, 0x77, 0x9b, 0xf1, 0x03, 0xcc, 0xb5, 0xfe, 0xfb, 0x7a, 0x77, 0xa6,
5609 0x82, 0x9f, 0xe5, 0xde, 0x9d, 0x0d, 0x4d, 0x37, 0xc6, 0x12, 0x73, 0x6d,
5610 0xea, 0xbb, 0x48, 0xf0, 0xd2, 0x81, 0xcc, 0x1a, 0x47, 0xfa, 0xa4, 0xd2,
5611 0xb2, 0x27, 0xa0, 0xfc, 0x30, 0x04, 0xdb, 0x05, 0xd3, 0x0b, 0xbc, 0x4d,
5612 0x7a, 0x99, 0xef, 0x7f, 0x26, 0x01, 0xd4, 0x07, 0x0b, 0x1e, 0x99, 0x06,
5613 0x3c, 0xde, 0x3d, 0x1c, 0x21, 0x82, 0x68, 0x46, 0x35, 0x38, 0x61, 0xea,
5614 0xd4, 0xc2, 0x65, 0x09, 0x39, 0x87, 0xb4, 0xd3, 0x5d, 0x3c, 0xa3, 0x79,
5615 0xe4, 0x01, 0x4e, 0xbf, 0x18, 0xba, 0x57, 0x3f, 0xdd, 0xea, 0x0a, 0x6b,
5616 0x99, 0xfb, 0x93, 0xfa, 0xab, 0xee, 0x08, 0xdf, 0x38, 0x23, 0xae, 0x8d,
5617 0xa8, 0x03, 0x13, 0xfe, 0x83, 0x88, 0xb0, 0xc2, 0xf9, 0x90, 0xa5, 0x1c,
5618 0x01, 0x6f, 0x71, 0x91, 0x42, 0x35, 0x81, 0x74, 0x71, 0x6c, 0xba, 0x86,
5619 0x48, 0xfe, 0x96, 0xd2, 0x88, 0x12, 0x36, 0x4e, 0xa6, 0x2f, 0xd1, 0xdb,
5620 0xfa, 0xbf, 0xdb, 0x84, 0x01, 0xfc, 0x7d, 0x7a, 0xac, 0x20, 0xae, 0xf5,
5621 0x95, 0xc9, 0xdc, 0x10, 0x5f, 0x4c, 0xae, 0x85, 0x01, 0x8b, 0xfe, 0x77,
5622 0x13, 0x01, 0xae, 0x39, 0x59, 0x7e, 0xbc, 0xfd, 0xc9, 0x42, 0xe4, 0x13,
5623 0x07, 0x3f, 0xa9, 0x74, 0xd9, 0xd5, 0xfc, 0xb9, 0x78, 0xbe, 0x97, 0xf5,
5624 0xe7, 0x36, 0x7f, 0xfa, 0x23, 0x30, 0xeb, 0xab, 0x92, 0xd3, 0xdc, 0x3f,
5625 0x7f, 0xc0, 0x77, 0x93, 0xf9, 0x88, 0xe3, 0x4e, 0x13, 0x53, 0x6d, 0x71,
5626 0x87, 0xe9, 0x24, 0x2b, 0xae, 0x26, 0xbf, 0x62, 0x51, 0x04, 0x42, 0xe1,
5627 0x13, 0x9d, 0xd8, 0x9f, 0x59, 0x87, 0x3f, 0xfc, 0x94, 0xff, 0xcf, 0x88,
5628 0x88, 0xe6, 0xeb, 0x6e, 0xc1, 0x96, 0x04, 0x27, 0xc8, 0xda, 0xfa, 0xe8,
5629 0x2e, 0xbb, 0x2c, 0x6e, 0xf4, 0xb4, 0x00, 0x7d, 0x8d, 0x3b, 0xef, 0x8b,
5630 0x18, 0xa9, 0x5f, 0x32, 0xa9, 0xf2, 0x3a, 0x7e, 0x65, 0x2d, 0x6e, 0x8d,
5631 0x75, 0x77, 0xf6, 0xa6, 0xd8, 0xf9, 0x6b, 0x51, 0xe6, 0x66, 0x52, 0x59,
5632 0x39, 0x97, 0x22, 0xda, 0xb2, 0xd6, 0x82, 0x5a, 0x6e, 0x61, 0x60, 0x16,
5633 0x48, 0x7b, 0xf1, 0xc3, 0x4d, 0x7f, 0x50, 0xfa, 0x4d, 0x58, 0x27, 0x30,
5634 0xc8, 0x96, 0xe0, 0x41, 0x4f, 0x6b, 0xeb, 0x88, 0xa2, 0x7a, 0xef, 0x8a,
5635 0x88, 0xc8, 0x50, 0x4b, 0x55, 0x66, 0xee, 0xbf, 0xc4, 0x01, 0x82, 0x4c,
5636 0xec, 0xde, 0x37, 0x64, 0xd6, 0x1e, 0xcf, 0x3e, 0x2e, 0xfe, 0x84, 0x68,
5637 0xbf, 0xa3, 0x68, 0x77, 0xa9, 0x03, 0xe4, 0xf8, 0xd7, 0xb2, 0x6e, 0xa3,
5638 0xc4, 0xc3, 0x36, 0x53, 0xf3, 0xdd, 0x7e, 0x4c, 0xf0, 0xe9, 0xb2, 0x44,
5639 0xe6, 0x60, 0x3d, 0x00, 0x9a, 0x08, 0xc3, 0x21, 0x17, 0x49, 0xda, 0x49,
5640 0xfb, 0x4c, 0x8b, 0xe9, 0x10, 0x66, 0xfe, 0xb7, 0xe0, 0xf9, 0xdd, 0xbf,
5641 0x41, 0xfe, 0x04, 0x9b, 0x7f, 0xe8, 0xd6, 0x2e, 0x4d, 0x0f, 0x7b, 0x10,
5642 0x73, 0x4c, 0xa1, 0x3e, 0x43, 0xb7, 0xcf, 0x94, 0x97, 0x7e, 0x24, 0xbb,
5643 0x87, 0xbf, 0x22, 0xb8, 0x3e, 0xeb, 0x9a, 0x3f, 0xe3, 0x86, 0xee, 0x21,
5644 0xbc, 0xf5, 0x44, 0xeb, 0x60, 0x2e, 0xe7, 0x8f, 0x89, 0xa4, 0x91, 0x61,
5645 0x28, 0x90, 0x85, 0x68, 0xe0, 0xa9, 0x62, 0x93, 0x86, 0x5a, 0x15, 0xbe,
5646 0xb2, 0x76, 0x83, 0xf2, 0x0f, 0x00, 0xc7, 0xb6, 0x57, 0xe9, 0x1f, 0x92,
5647 0x49, 0xfe, 0x50, 0x85, 0xbf, 0x39, 0x3d, 0xe4, 0x8b, 0x72, 0x2d, 0x49,
5648 0xbe, 0x05, 0x0a, 0x34, 0x56, 0x80, 0xc6, 0x1f, 0x46, 0x59, 0xc9, 0xfe,
5649 0x40, 0xfb, 0x78, 0x6d, 0x7a, 0xe5, 0x30, 0xe9, 0x81, 0x55, 0x75, 0x05,
5650 0x63, 0xd2, 0x22, 0xee, 0x2e, 0x6e, 0xb9, 0x18, 0xe5, 0x8a, 0x5a, 0x66,
5651 0xbd, 0x74, 0x30, 0xe3, 0x8b, 0x76, 0x22, 0x18, 0x1e, 0xef, 0x69, 0xe8,
5652 0x9d, 0x07, 0xa7, 0x9a, 0x87, 0x6c, 0x04, 0x4b, 0x74, 0x2b, 0xbe, 0x37,
5653 0x2f, 0x29, 0x9b, 0x60, 0x9d, 0x8b, 0x57, 0x55, 0x34, 0xca, 0x41, 0x25,
5654 0xae, 0x56, 0x92, 0x34, 0x1b, 0x9e, 0xbd, 0xfe, 0x74, 0xbd, 0x4e, 0x29,
5655 0xf0, 0x5e, 0x27, 0x94, 0xb0, 0x9e, 0x23, 0x9f, 0x4a, 0x0f, 0xa1, 0xdf,
5656 0xe7, 0xc4, 0xdb, 0xbe, 0x0f, 0x1a, 0x0b, 0x6c, 0xb0, 0xe1, 0x06, 0x7c,
5657 0x5a, 0x5b, 0x81, 0x1c, 0xb6, 0x12, 0xec, 0x6f, 0x3b, 0xbb, 0x84, 0x36,
5658 0xd5, 0x28, 0x16, 0xea, 0x51, 0xa8, 0x99, 0x24, 0x8f, 0xe7, 0xf8, 0xe9,
5659 0xce, 0xa1, 0x65, 0x96, 0x6f, 0x4e, 0x2f, 0xb7, 0x6f, 0x65, 0x39, 0xad,
5660 0xfd, 0x2e, 0xa0, 0x37, 0x32, 0x2f, 0xf3, 0x95, 0xa1, 0x3a, 0xa1, 0x9d,
5661 0x2c, 0x9e, 0xa1, 0x4b, 0x7e, 0xc9, 0x7e, 0x86, 0xaa, 0x16, 0x00, 0x82,
5662 0x1d, 0x36, 0xbf, 0x98, 0x0a, 0x82, 0x5b, 0xcc, 0xc4, 0x6a, 0xad, 0xa0,
5663 0x1f, 0x47, 0x98, 0xde, 0x8d, 0x68, 0x38, 0x3f, 0x33, 0xe2, 0x08, 0x3b,
5664 0x2a, 0x65, 0xd9, 0x2f, 0x53, 0x68, 0xb8, 0x78, 0xd0, 0x1d, 0xbb, 0x2a,
5665 0x73, 0x19, 0xba, 0x58, 0xea, 0xf1, 0x0a, 0xaa, 0xa6, 0xbe, 0x27, 0xd6,
5666 0x00, 0x6b, 0x4e, 0x43, 0x8e, 0x5b, 0x19, 0xc1, 0x37, 0x0f, 0xfb, 0x81,
5667 0x72, 0x10, 0xb6, 0x20, 0x32, 0xcd, 0xa2, 0x7c, 0x90, 0xd4, 0xf5, 0xcf,
5668 0x1c, 0xcb, 0x14, 0x24, 0x7a, 0x4d, 0xf5, 0xd5, 0xd9, 0xce, 0x6a, 0x64,
5669 0xc9, 0xd3, 0xa7, 0x36, 0x6f, 0x1d, 0xf1, 0xe9, 0x71, 0x6c, 0x3d, 0x02,
5670 0xa4, 0x62, 0xb1, 0x82, 0x5c, 0x13, 0x4b, 0x6b, 0x68, 0xe2, 0x31, 0xef,
5671 0xe4, 0x46, 0xfd, 0xe5, 0xa8, 0x29, 0xe9, 0x1e, 0xad, 0xff, 0x33, 0xdb,
5672 0x0b, 0xc0, 0x92, 0xb1, 0xef, 0xeb, 0xb3, 0x6f, 0x96, 0x7b, 0xdf, 0xcd,
5673 0x07, 0x19, 0x86, 0x60, 0x98, 0xcf, 0x95, 0xfe, 0x98, 0xdd, 0x29, 0xa6,
5674 0x35, 0x7b, 0x46, 0x13, 0x03, 0xa8, 0xd9, 0x7c, 0xb3, 0xdf, 0x9f, 0x14,
5675 0xb7, 0x34, 0x5a, 0xc4, 0x12, 0x81, 0xc5, 0x98, 0x25, 0x8d, 0x3e, 0xe3,
5676 0xd8, 0x2d, 0xe4, 0x54, 0xab, 0xb0, 0x13, 0xfd, 0xd1, 0x3f, 0x3b, 0xbf,
5677 0xa9, 0x45, 0x28, 0x8a, 0x2f, 0x9c, 0x1e, 0x2d, 0xe5, 0xab, 0x13, 0x95,
5678 0x97, 0xc3, 0x34, 0x37, 0x8d, 0x93, 0x66, 0x31, 0x81, 0xa0, 0x30, 0x23,
5679 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31,
5680 0x16, 0x04, 0x14, 0xa5, 0x23, 0x9b, 0x7e, 0xe6, 0x45, 0x71, 0xbf, 0x48,
5681 0xc6, 0x27, 0x3c, 0x96, 0x87, 0x63, 0xbd, 0x1f, 0xde, 0x72, 0x12, 0x30,
5682 0x79, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01,
5683 0x31, 0x6c, 0x1e, 0x6a, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72,
5684 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20,
5685 0x00, 0x45, 0x00, 0x6e, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
5686 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41,
5687 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x41,
5688 0x00, 0x45, 0x00, 0x53, 0x00, 0x20, 0x00, 0x43, 0x00, 0x72, 0x00, 0x79,
5689 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61,
5690 0x00, 0x70, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x50,
5691 0x00, 0x72, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65,
5692 0x00, 0x72, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
5693 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x93, 0xa8, 0xb2, 0x7e, 0xb7,
5694 0xab, 0xf1, 0x1c, 0x3c, 0x36, 0x58, 0xdc, 0x67, 0x6d, 0x42, 0xa6, 0xfc,
5695 0x53, 0x01, 0xe6, 0x04, 0x08, 0x77, 0x57, 0x22, 0xa1, 0x7d, 0xb9, 0xa2,
5696 0x69, 0x02, 0x02, 0x08, 0x00
5699 static void test_client_cert_authentication(void)
5701 HINTERNET ses, req, con;
5702 DWORD protocols;
5703 BOOL ret;
5704 CRYPT_DATA_BLOB pfx;
5705 HCERTSTORE store;
5706 const CERT_CONTEXT *cert;
5708 ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
5709 ok( ses != NULL, "failed to open session %lu\n", GetLastError() );
5711 protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1;
5712 ret = WinHttpSetOption( ses, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols) );
5713 if (!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* vista */
5715 win_skip( "can't set secure protocols\n" );
5716 WinHttpCloseHandle( ses );
5717 return;
5719 ok( ret, "failed to set protocols %lu\n", GetLastError() );
5721 con = WinHttpConnect( ses, L"test.winehq.org", 443, 0 );
5722 ok( con != NULL, "failed to open a connection %lu\n", GetLastError() );
5724 req = WinHttpOpenRequest( con, NULL, L"/tests/clientcert/", NULL, NULL, NULL, WINHTTP_FLAG_SECURE );
5725 ok( req != NULL, "failed to open a request %lu\n", GetLastError() );
5727 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
5728 ok( ret, "failed to send request %lu\n", GetLastError() );
5730 SetLastError( 0xdeadbeef );
5731 ret = WinHttpReceiveResponse( req, NULL );
5732 ok( !ret, "unexpected success\n" );
5733 ok( GetLastError() == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED, "got %lu\n", GetLastError() );
5735 pfx.pbData = (BYTE *)pfxdata;
5736 pfx.cbData = sizeof(pfxdata);
5737 store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY );
5738 ok( store != NULL, "got %lu\n", GetLastError() );
5740 cert = CertFindCertificateInStore( store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
5741 ok( cert != NULL, "got %lu\n", GetLastError() );
5743 ret = WinHttpSetOption( req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, (void *)cert, sizeof(*cert) );
5744 ok( ret, "failed to set client cert %lu\n", GetLastError() );
5746 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
5747 ok( ret, "failed to send request %lu\n", GetLastError() );
5749 SetLastError( 0xdeadbeef );
5750 ret = WinHttpReceiveResponse( req, NULL );
5751 todo_wine {
5752 ok( !ret, "unexpected success\n" );
5753 ok( GetLastError() == SEC_E_CERT_EXPIRED, "got %lu\n", GetLastError() );
5756 CertFreeCertificateContext( cert );
5757 CertCloseStore( store, 0 );
5758 WinHttpCloseHandle( req );
5759 WinHttpCloseHandle( con );
5760 WinHttpCloseHandle( ses );
5763 START_TEST (winhttp)
5765 struct server_info si;
5766 HANDLE thread;
5767 DWORD ret;
5768 HMODULE mod = GetModuleHandleA("winhttp.dll");
5770 pWinHttpWebSocketClose = (void *)GetProcAddress(mod, "WinHttpWebSocketClose");
5771 pWinHttpWebSocketCompleteUpgrade = (void *)GetProcAddress(mod, "WinHttpWebSocketCompleteUpgrade");
5772 pWinHttpWebSocketQueryCloseStatus = (void *)GetProcAddress(mod, "WinHttpWebSocketQueryCloseStatus");
5773 pWinHttpWebSocketSend = (void *)GetProcAddress(mod, "WinHttpWebSocketSend");
5774 pWinHttpWebSocketShutdown = (void *)GetProcAddress(mod, "WinHttpWebSocketShutdown");
5775 pWinHttpWebSocketReceive = (void *)GetProcAddress(mod, "WinHttpWebSocketReceive");
5777 test_WinHttpOpenRequest();
5778 test_WinHttpSendRequest();
5779 test_connect_error();
5780 test_WinHttpTimeFromSystemTime();
5781 test_WinHttpTimeToSystemTime();
5782 test_WinHttpAddHeaders();
5783 test_secure_connection();
5784 test_client_cert_authentication();
5785 test_request_parameter_defaults();
5786 test_WinHttpQueryOption();
5787 test_set_default_proxy_config();
5788 test_empty_headers_param();
5789 test_timeouts();
5790 test_resolve_timeout();
5791 test_credentials();
5792 test_IWinHttpRequest_Invoke();
5793 test_WinHttpDetectAutoProxyConfigUrl();
5794 test_WinHttpGetIEProxyConfigForCurrentUser();
5795 test_WinHttpGetProxyForUrl();
5796 test_chunked_read();
5797 test_max_http_automatic_redirects();
5799 si.event = CreateEventW(NULL, 0, 0, NULL);
5800 si.port = 7532;
5802 thread = CreateThread(NULL, 0, server_thread, &si, 0, NULL);
5803 ok(thread != NULL, "failed to create thread %lu\n", GetLastError());
5805 ret = WaitForSingleObject(si.event, 10000);
5806 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %lu\n", GetLastError());
5807 if (ret != WAIT_OBJECT_0)
5809 CloseHandle(thread);
5810 return;
5813 test_IWinHttpRequest(si.port);
5814 test_connection_info(si.port);
5815 test_basic_request(si.port, NULL, L"/basic");
5816 test_no_headers(si.port);
5817 test_no_content(si.port);
5818 test_head_request(si.port);
5819 test_not_modified(si.port);
5820 test_basic_authentication(si.port);
5821 test_multi_authentication(si.port);
5822 test_large_data_authentication(si.port);
5823 test_bad_header(si.port);
5824 test_multiple_reads(si.port);
5825 test_cookies(si.port);
5826 test_request_path_escapes(si.port);
5827 test_passport_auth(si.port);
5828 test_websocket(si.port);
5829 test_redirect(si.port);
5831 /* send the basic request again to shutdown the server thread */
5832 test_basic_request(si.port, NULL, L"/quit");
5834 WaitForSingleObject(thread, 3000);
5835 CloseHandle(thread);