1 /*
2 * WinHTTP - tests
3 *
4 * Copyright 2008 Google (Zac Brown)
5 * Copyright 2015 Dmitry Timoshkov
6 *
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.
11 *
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.
16 *
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
20 */
21
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 <stdio.h>
31 #include <initguid.h>
32 #include <httprequest.h>
33 #include <httprequestid.h>
34
35 #include "wine/test.h"
36 #include "wine/heap.h"
37
38 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
39
40 static const WCHAR test_useragent[] =
41 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
42 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
43 static const WCHAR test_winehq_https[] = {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','4','4','3',0};
44 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
45
a2w(const char * str)46 static WCHAR *a2w(const char *str)
47 {
48 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
49 WCHAR *ret = heap_alloc(len * sizeof(WCHAR));
50 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
51 return ret;
52 }
53
strcmp_wa(const WCHAR * str1,const char * stra)54 static int strcmp_wa(const WCHAR *str1, const char *stra)
55 {
56 WCHAR *str2 = a2w(stra);
57 int r = lstrcmpW(str1, str2);
58 heap_free(str2);
59 return r;
60 }
61
proxy_active(void)62 static BOOL proxy_active(void)
63 {
64 WINHTTP_PROXY_INFO proxy_info;
65 BOOL active = FALSE;
66
67 SetLastError(0xdeadbeef);
68 if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
69 {
70 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
71 "got %u\n", GetLastError());
72 active = (proxy_info.lpszProxy != NULL);
73 if (active)
74 GlobalFree(proxy_info.lpszProxy);
75 if (proxy_info.lpszProxyBypass != NULL)
76 GlobalFree(proxy_info.lpszProxyBypass);
77 }
78 else
79 active = FALSE;
80
81 return active;
82 }
83
test_WinHttpQueryOption(void)84 static void test_WinHttpQueryOption(void)
85 {
86 BOOL ret;
87 HINTERNET session, request, connection;
88 DWORD feature, size;
89
90 SetLastError(0xdeadbeef);
91 session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
92 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
93
94 SetLastError(0xdeadbeef);
95 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
96 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
97 ok(GetLastError() == ERROR_INVALID_PARAMETER,
98 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
99
100 size = 0xdeadbeef;
101 SetLastError(0xdeadbeef);
102 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
103 ok(!ret, "should fail to query option\n");
104 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
105 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
106 ok(size == 4, "expected 4, got %u\n", size);
107
108 feature = 0xdeadbeef;
109 size = sizeof(feature) - 1;
110 SetLastError(0xdeadbeef);
111 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
112 ok(!ret, "should fail to query option\n");
113 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
114 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
115 ok(size == 4, "expected 4, got %u\n", size);
116
117 feature = 0xdeadbeef;
118 size = sizeof(feature) + 1;
119 SetLastError(0xdeadbeef);
120 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
121 ok(ret, "failed to query option %u\n", GetLastError());
122 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
123 "got %u\n", GetLastError());
124 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
125 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
126 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
127
128 SetLastError(0xdeadbeef);
129 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
130 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
131 ok(GetLastError() == ERROR_INVALID_PARAMETER,
132 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
133
134 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
135 SetLastError(0xdeadbeef);
136 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
137 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
138 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
139 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
140
141 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
142 SetLastError(0xdeadbeef);
143 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
144 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
145 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
146 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
147
148 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
149 SetLastError(0xdeadbeef);
150 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
151 ok(ret, "failed to set redirect policy %u\n", GetLastError());
152
153 feature = 0xdeadbeef;
154 size = sizeof(feature);
155 SetLastError(0xdeadbeef);
156 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
157 ok(ret, "failed to query option %u\n", GetLastError());
158 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
159 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
160
161 feature = WINHTTP_DISABLE_COOKIES;
162 SetLastError(0xdeadbeef);
163 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
164 ok(!ret, "should fail to set disable feature for a session\n");
165 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
166 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
167
168 SetLastError(0xdeadbeef);
169 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
170 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
171
172 feature = WINHTTP_DISABLE_COOKIES;
173 SetLastError(0xdeadbeef);
174 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
175 ok(!ret, "should fail to set disable feature for a connection\n");
176 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
177 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
178
179 SetLastError(0xdeadbeef);
180 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
181 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
182 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
183 {
184 skip("Network unreachable, skipping the test\n");
185 goto done;
186 }
187
188 feature = 0xdeadbeef;
189 size = sizeof(feature);
190 SetLastError(0xdeadbeef);
191 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
192 ok(!ret, "should fail to query disable feature for a request\n");
193 ok(GetLastError() == ERROR_INVALID_PARAMETER,
194 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
195
196 feature = 0;
197 size = sizeof(feature);
198 SetLastError(0xdeadbeef);
199 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
200 ok(ret, "failed to set feature %u\n", GetLastError());
201
202 feature = 0xffffffff;
203 size = sizeof(feature);
204 SetLastError(0xdeadbeef);
205 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
206 ok(ret, "failed to set feature %u\n", GetLastError());
207
208 feature = WINHTTP_DISABLE_COOKIES;
209 size = sizeof(feature);
210 SetLastError(0xdeadbeef);
211 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
212 ok(ret, "failed to set feature %u\n", GetLastError());
213
214 size = 0;
215 SetLastError(0xdeadbeef);
216 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
217 ok(!ret, "should fail to query disable feature for a request\n");
218 ok(GetLastError() == ERROR_INVALID_PARAMETER,
219 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
220
221 feature = 0xdeadbeef;
222 size = sizeof(feature);
223 SetLastError(0xdeadbeef);
224 ret = WinHttpQueryOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, &size);
225 ok(!ret, "should fail to query enabled features for a request\n");
226 ok(feature == 0xdeadbeef, "expect feature 0xdeadbeef, got %u\n", feature);
227 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
228
229 feature = WINHTTP_ENABLE_SSL_REVOCATION;
230 SetLastError(0xdeadbeef);
231 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, 0, sizeof(feature));
232 ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
233 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
234
235 SetLastError(0xdeadbeef);
236 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, 0);
237 ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
238 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
239
240 SetLastError(0xdeadbeef);
241 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, sizeof(feature));
242 ok(ret, "failed to set feature\n");
243 ok(GetLastError() == NO_ERROR || broken(GetLastError() == 0xdeadbeef), /* Doesn't set error code on Vista or older */
244 "expected NO_ERROR, got %u\n", GetLastError());
245
246 feature = 0xdeadbeef;
247 SetLastError(0xdeadbeef);
248 ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, sizeof(feature));
249 ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n");
250 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
251
252 feature = 6;
253 size = sizeof(feature);
254 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONNECT_RETRIES, &feature, sizeof(feature));
255 ok(ret, "failed to set WINHTTP_OPTION_CONNECT_RETRIES %u\n", GetLastError());
256
257 SetLastError(0xdeadbeef);
258 ret = WinHttpCloseHandle(request);
259 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
260
261 done:
262 SetLastError(0xdeadbeef);
263 ret = WinHttpCloseHandle(connection);
264 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
265 SetLastError(0xdeadbeef);
266 ret = WinHttpCloseHandle(session);
267 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
268 }
269
test_WinHttpOpenRequest(void)270 static void test_WinHttpOpenRequest (void)
271 {
272 BOOL ret;
273 HINTERNET session, request, connection;
274 DWORD err;
275
276 SetLastError(0xdeadbeef);
277 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
278 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
279 err = GetLastError();
280 ok(session != NULL, "WinHttpOpen failed to open session.\n");
281 ok(err == ERROR_SUCCESS, "got %u\n", err);
282
283 /* Test with a bad server name */
284 SetLastError(0xdeadbeef);
285 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
286 err = GetLastError();
287 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
288 ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err);
289
290 /* Test with a valid server name */
291 SetLastError(0xdeadbeef);
292 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
293 err = GetLastError();
294 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err);
295 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err);
296
297 SetLastError(0xdeadbeef);
298 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
299 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
300 err = GetLastError();
301 if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED)
302 {
303 skip("Network unreachable, skipping.\n");
304 goto done;
305 }
306 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err);
307 ok(err == ERROR_SUCCESS, "got %u\n", err);
308
309 SetLastError(0xdeadbeef);
310 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
311 err = GetLastError();
312 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
313 {
314 skip("Connection failed, skipping.\n");
315 goto done;
316 }
317 ok(ret, "WinHttpSendRequest failed: %u\n", err);
318 ok(err == ERROR_SUCCESS, "got %u\n", err);
319
320 SetLastError(0xdeadbeef);
321 ret = WinHttpCloseHandle(request);
322 err = GetLastError();
323 ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err);
324 ok(err == ERROR_SUCCESS, "got %u\n", err);
325
326 done:
327 ret = WinHttpCloseHandle(connection);
328 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
329 ret = WinHttpCloseHandle(session);
330 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
331
332 }
333
test_empty_headers_param(void)334 static void test_empty_headers_param(void)
335 {
336 static const WCHAR empty[] = {0};
337 HINTERNET ses, con, req;
338 DWORD err;
339 BOOL ret;
340
341 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
342 ok(ses != NULL, "failed to open session %u\n", GetLastError());
343
344 con = WinHttpConnect(ses, test_winehq, 80, 0);
345 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
346
347 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
348 ok(req != NULL, "failed to open a request %u\n", GetLastError());
349
350 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
351 err = GetLastError();
352 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
353 {
354 skip("connection failed, skipping\n");
355 goto done;
356 }
357 ok(ret, "failed to send request %u\n", GetLastError());
358
359 done:
360 WinHttpCloseHandle(req);
361 WinHttpCloseHandle(con);
362 WinHttpCloseHandle(ses);
363 }
364
test_WinHttpSendRequest(void)365 static void test_WinHttpSendRequest (void)
366 {
367 static const WCHAR content_type[] =
368 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
369 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
370 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
371 static const WCHAR postW[] = {'P','O','S','T',0};
372 static CHAR post_data[] = "mode=Test";
373 static const char test_post[] = "mode => Test\0\n";
374 HINTERNET session, request, connection;
375 DWORD header_len, optional_len, total_len, bytes_rw, size, err, disable, len;
376 DWORD_PTR context;
377 BOOL ret;
378 CHAR buffer[256];
379 WCHAR method[8];
380 int i;
381
382 header_len = -1L;
383 total_len = optional_len = sizeof(post_data);
384 memset(buffer, 0xff, sizeof(buffer));
385
386 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
387 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
388 ok(session != NULL, "WinHttpOpen failed to open session.\n");
389
390 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
391 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
392
393 request = WinHttpOpenRequest(connection, postW, test_file, NULL, WINHTTP_NO_REFERER,
394 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
395 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
396 {
397 skip("Network unreachable, skipping.\n");
398 goto done;
399 }
400 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
401 if (!request) goto done;
402
403 method[0] = 0;
404 len = sizeof(method);
405 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_REQUEST_METHOD, NULL, method, &len, NULL);
406 ok(ret, "got %u\n", GetLastError());
407 ok(len == lstrlenW(postW) * sizeof(WCHAR), "got %u\n", len);
408 ok(!lstrcmpW(method, postW), "got %s\n", wine_dbgstr_w(method));
409
410 context = 0xdeadbeef;
411 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
412 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
413
414 /* writing more data than promised by the content-length header causes an error when the connection
415 is resued, so disable keep-alive */
416 disable = WINHTTP_DISABLE_KEEP_ALIVE;
417 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable));
418 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
419
420 context++;
421 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
422 err = GetLastError();
423 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
424 {
425 skip("connection failed, skipping\n");
426 goto done;
427 }
428 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
429
430 context = 0;
431 size = sizeof(context);
432 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
433 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
434 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
435
436 for (i = 3; post_data[i]; i++)
437 {
438 bytes_rw = -1;
439 SetLastError(0xdeadbeef);
440 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
441 if (ret)
442 {
443 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
444 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
445 }
446 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
447 {
448 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
449 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
450 }
451 }
452
453 SetLastError(0xdeadbeef);
454 ret = WinHttpReceiveResponse(request, NULL);
455 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */,
456 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
457 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
458
459 SetLastError(0xdeadbeef);
460 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_ORIG_URI, NULL, NULL, &len, NULL);
461 ok(!ret && GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", GetLastError());
462
463 SetLastError(0xdeadbeef);
464 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_MAX + 1, NULL, NULL, &len, NULL);
465 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
466
467 bytes_rw = -1;
468 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
469 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
470
471 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw);
472 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
473
474 done:
475 ret = WinHttpCloseHandle(request);
476 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
477 ret = WinHttpCloseHandle(connection);
478 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
479 ret = WinHttpCloseHandle(session);
480 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
481 }
482
test_WinHttpTimeFromSystemTime(void)483 static void test_WinHttpTimeFromSystemTime(void)
484 {
485 BOOL ret;
486 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
487 static const WCHAR expected_string[] =
488 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
489 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
490 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
491 DWORD err;
492
493 SetLastError(0xdeadbeef);
494 ret = WinHttpTimeFromSystemTime(&time, NULL);
495 err = GetLastError();
496 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
497 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
498
499 SetLastError(0xdeadbeef);
500 ret = WinHttpTimeFromSystemTime(NULL, time_string);
501 err = GetLastError();
502 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
503 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
504
505 SetLastError(0xdeadbeef);
506 ret = WinHttpTimeFromSystemTime(&time, time_string);
507 err = GetLastError();
508 ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err);
509 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
510 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
511 "Time string returned did not match expected time string.\n");
512 }
513
test_WinHttpTimeToSystemTime(void)514 static void test_WinHttpTimeToSystemTime(void)
515 {
516 BOOL ret;
517 SYSTEMTIME time;
518 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
519 static const WCHAR time_string1[] =
520 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
521 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
522 static const WCHAR time_string2[] =
523 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
524 '1','0',' ','0','5',' ','5','2','\n',0};
525 DWORD err;
526
527 SetLastError(0xdeadbeef);
528 ret = WinHttpTimeToSystemTime(time_string1, NULL);
529 err = GetLastError();
530 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
531 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
532
533 SetLastError(0xdeadbeef);
534 ret = WinHttpTimeToSystemTime(NULL, &time);
535 err = GetLastError();
536 ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
537 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
538
539 SetLastError(0xdeadbeef);
540 ret = WinHttpTimeToSystemTime(time_string1, &time);
541 err = GetLastError();
542 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
543 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
544 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
545 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
546
547 SetLastError(0xdeadbeef);
548 ret = WinHttpTimeToSystemTime(time_string2, &time);
549 err = GetLastError();
550 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
551 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
552 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
553 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
554 }
555
test_WinHttpAddHeaders(void)556 static void test_WinHttpAddHeaders(void)
557 {
558 HINTERNET session, request, connection;
559 BOOL ret, reverse;
560 WCHAR buffer[MAX_PATH];
561 WCHAR check_buffer[MAX_PATH];
562 DWORD err, index, len, oldlen;
563
564 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
565 static const WCHAR test_verb[] = {'P','O','S','T',0};
566 static const WCHAR test_header_begin[] =
567 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
568 static const WCHAR full_path_test_header_begin[] =
569 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
570 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
571 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
572 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
573 static const WCHAR test_header_name2[] = {'n','a','m','e',0};
574 static const WCHAR test_header_name3[] = {'a',0};
575 static const WCHAR test_header_range[] = {'R','a','n','g','e',0};
576 static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
577 static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
578
579 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
580 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
581 static const WCHAR test_flag_coalesce_comma[] =
582 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
583 static const WCHAR test_flag_coalesce_comma_reverse[] =
584 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
585 static const WCHAR test_flag_coalesce_semicolon[] =
586 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
587 static const WCHAR test_flag_coalesce_semicolon_reverse[] =
588 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
589
590 static const WCHAR field[] = {'f','i','e','l','d',0};
591 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
592 static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
593 static const WCHAR empty[] = {0};
594
595 static const WCHAR test_headers[][14] =
596 {
597 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
598 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
599 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
600 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
601 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
602 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
603 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
604 {0},
605 {':',0},
606 {'a',':',0},
607 {':','b',0},
608 {'c','d',0},
609 {' ','e',' ',':','f',0},
610 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
611 {'n','a','m','e',':',' ','v','a','l','u','e',0},
612 {'n','a','m','e',':',0}
613 };
614 static const WCHAR test_indices[][6] =
615 {
616 {'t','e','s','t','1',0},
617 {'t','e','s','t','2',0},
618 {'t','e','s','t','3',0},
619 {'t','e','s','t','4',0}
620 };
621
622 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
623 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
624 ok(session != NULL, "WinHttpOpen failed to open session.\n");
625
626 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
627 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
628
629 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
630 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
631 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
632 {
633 skip("Network unreachable, skipping.\n");
634 goto done;
635 }
636 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
637
638 index = 0;
639 len = sizeof(buffer);
640 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
641 test_header_name, buffer, &len, &index);
642 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
643 SetLastError(0xdeadbeef);
644 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
645 err = GetLastError();
646 ok(ret, "WinHttpAddRequestHeaders failed to add new header, got %d with error %u.\n", ret, err);
647 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
648
649 index = 0;
650 len = sizeof(buffer);
651 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
652 test_header_name, buffer, &len, &index);
653 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
654 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
655 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
656 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
657
658 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
659 test_header_name, buffer, &len, &index);
660 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
661
662 /* Try to fetch the header info with a buffer that's big enough to fit the
663 * string but not the NULL terminator.
664 */
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 test_header_name, 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 %d\n", len);
675
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 test_header_name, NULL, &len, &index);
682 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
683 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
684 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
685 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
686
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 test_header_name, NULL, &len, &index);
693 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
694 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
695 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
696 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
697 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
698
699 index = 0;
700 len = 0;
701 SetLastError(0xdeadbeef);
702 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
703 test_header_name, 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 %u\n", GetLastError());
707 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
708 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
709
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 test_header_name, 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)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
720 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
721 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
722 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
723 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
724 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
725 "WinHttpQueryHeaders returned invalid end of header string.\n");
726 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
727
728 index = 0;
729 len = 0;
730 SetLastError(0xdeadbeef);
731 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
732 test_header_name, NULL, &len, &index);
733 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
734 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
735 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
736 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
737 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
738
739 oldlen = len;
740 index = 0;
741 len = sizeof(buffer);
742 memset(buffer, 0xff, sizeof(buffer));
743 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
744 test_header_name, buffer, &len, &index);
745 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
746 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
747 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
748 "no double NULL terminator\n");
749 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
750 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
751 "invalid beginning of header string.\n");
752 ok(index == 0, "header index was incremented\n");
753
754 /* tests for more indices */
755 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
756 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
757
758 index = 0;
759 len = sizeof(buffer);
760 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
761 test_header_name, buffer, &len, &index);
762 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
763 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
764 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
765
766 len = sizeof(buffer);
767 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
768 test_header_name, buffer, &len, &index);
769 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
770 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
771 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
772
773 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
774 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
775
776 index = 0;
777 len = sizeof(buffer);
778 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
779 test_header_name, buffer, &len, &index);
780 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
781 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
782 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
783 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
784
785 len = sizeof(buffer);
786 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
787 test_header_name, buffer, &len, &index);
788 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
789 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
790 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
791
792 /* add if new flag */
793 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
794 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
795
796 index = 0;
797 len = sizeof(buffer);
798 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
799 test_header_name, buffer, &len, &index);
800 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
801 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
802 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
803
804 len = sizeof(buffer);
805 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
806 test_header_name, buffer, &len, &index);
807 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
808 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
809 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
810
811 len = sizeof(buffer);
812 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
813 test_header_name, buffer, &len, &index);
814 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
815
816 /* coalesce flag */
817 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
818 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
819
820 index = 0;
821 len = sizeof(buffer);
822 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
823 test_header_name, buffer, &len, &index);
824 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
825 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
826 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
827 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
828
829 len = sizeof(buffer);
830 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
831 test_header_name, buffer, &len, &index);
832 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
833 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
834 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
835
836 len = sizeof(buffer);
837 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
838 test_header_name, buffer, &len, &index);
839 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
840
841 /* coalesce with comma flag */
842 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
843 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
844
845 index = 0;
846 len = sizeof(buffer);
847 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
848 test_header_name, buffer, &len, &index);
849 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
850 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
851 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
852 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
853 "WinHttpQueryHeaders returned incorrect string.\n");
854
855 len = sizeof(buffer);
856 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
857 test_header_name, buffer, &len, &index);
858 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
859 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
860 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
861
862 len = sizeof(buffer);
863 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
864 test_header_name, buffer, &len, &index);
865 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
866
867
868 /* coalesce with semicolon flag */
869 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
870 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
871
872 index = 0;
873 len = sizeof(buffer);
874 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
875 test_header_name, buffer, &len, &index);
876 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
877 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
878 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
879 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
880 "WinHttpQueryHeaders returned incorrect string.\n");
881
882 len = sizeof(buffer);
883 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
884 test_header_name, buffer, &len, &index);
885 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
886 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
887 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
888
889 len = sizeof(buffer);
890 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
891 test_header_name, buffer, &len, &index);
892 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
893
894 /* add and replace flags */
895 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
896 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
897
898 index = 0;
899 len = sizeof(buffer);
900 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
901 test_header_name, buffer, &len, &index);
902 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
903 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
904 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
905
906 len = sizeof(buffer);
907 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
908 test_header_name, buffer, &len, &index);
909 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
910 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
911 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
912
913 len = sizeof(buffer);
914 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
915 test_header_name, buffer, &len, &index);
916 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
917
918 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
919 ok(!ret, "WinHttpAddRequestHeaders failed\n");
920
921 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
922 ok(ret, "WinHttpAddRequestHeaders failed\n");
923
924 index = 0;
925 memset(buffer, 0xff, sizeof(buffer));
926 len = sizeof(buffer);
927 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
928 test_header_name3, buffer, &len, &index);
929 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
930 ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n");
931
932 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
933 ok(!ret, "WinHttpAddRequestHeaders failed\n");
934
935 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
936 ok(!ret, "WinHttpAddRequestHeaders failed\n");
937
938 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
939 ok(!ret, "WinHttpAddRequestHeaders failed\n");
940
941 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
942 ok(ret, "WinHttpAddRequestHeaders failed\n");
943
944 index = 0;
945 buffer[0] = 0;
946 len = sizeof(buffer);
947 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
948 field, buffer, &len, &index);
949 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
950 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
951
952 SetLastError(0xdeadbeef);
953 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, 0,
954 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
955 err = GetLastError();
956 ok(!ret, "unexpected success\n");
957 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
958
959 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, ~0u,
960 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
961 ok(ret, "failed to add header: %u\n", GetLastError());
962
963 index = 0;
964 len = sizeof(buffer);
965 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
966 test_header_range, buffer, &len, &index);
967 ok(ret, "failed to get range header %u\n", GetLastError());
968 ok(!memcmp(buffer, test_header_bytes, sizeof(test_header_bytes)), "incorrect string returned\n");
969 ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len);
970 ok(index == 1, "wrong index %u\n", index);
971
972 index = 0;
973 len = sizeof(buffer);
974 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
975 test_header_name2, buffer, &len, &index);
976 ok(!ret, "unexpected success\n");
977
978 SetLastError(0xdeadbeef);
979 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
980 err = GetLastError();
981 ok(!ret, "unexpected success\n");
982 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
983
984 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
985 ok(ret, "got %u\n", GetLastError());
986
987 index = 0;
988 len = sizeof(buffer);
989 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
990 test_header_name2, buffer, &len, &index);
991 ok(ret, "got %u\n", GetLastError());
992 ok(index == 1, "wrong index %u\n", index);
993 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
994
995 ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE);
996 ok(ret, "got %u\n", GetLastError());
997
998 index = 0;
999 len = sizeof(buffer);
1000 SetLastError(0xdeadbeef);
1001 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
1002 test_header_name2, buffer, &len, &index);
1003 err = GetLastError();
1004 ok(!ret, "unexpected success\n");
1005 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
1006
1007 ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0);
1008 ok(ret, "got %u\n", GetLastError());
1009
1010 index = 0;
1011 len = sizeof(buffer);
1012 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
1013 test_header_name2, buffer, &len, &index);
1014 ok(ret, "got %u\n", GetLastError());
1015 ok(index == 1, "wrong index %u\n", index);
1016 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
1017
1018 ret = WinHttpCloseHandle(request);
1019 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
1020 done:
1021 ret = WinHttpCloseHandle(connection);
1022 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
1023 ret = WinHttpCloseHandle(session);
1024 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
1025
1026 }
1027
cert_error(HINTERNET handle,DWORD_PTR ctx,DWORD status,LPVOID buf,DWORD len)1028 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len)
1029 {
1030 DWORD flags = *(DWORD *)buf;
1031
1032 if (!flags)
1033 {
1034 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
1035 return;
1036 }
1037 #define X(x) if (flags & x) trace("%s\n", #x);
1038 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)
1039 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)
1040 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)
1041 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)
1042 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)
1043 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)
1044 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE)
1045 #undef X
1046 }
1047
test_secure_connection(void)1048 static void test_secure_connection(void)
1049 {
1050 static const char data_start[] = "<!DOCTYPE html PUBLIC";
1051 HINTERNET ses, con, req;
1052 DWORD size, status, policy, bitness, read_size, err, available_size, protocols, flags;
1053 BOOL ret;
1054 CERT_CONTEXT *cert;
1055 WINHTTP_CERTIFICATE_INFO info;
1056 char buffer[32];
1057
1058 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1059 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1060
1061 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
1062 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
1063 ok(ret, "failed to set redirect policy %u\n", GetLastError());
1064
1065 protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
1066 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols));
1067 err = GetLastError();
1068 ok(ret || err == ERROR_INVALID_PARAMETER /* < win7 */, "failed to set protocols %u\n", err);
1069
1070 con = WinHttpConnect(ses, test_winehq, 443, 0);
1071 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1072
1073 /* try without setting WINHTTP_FLAG_SECURE */
1074 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1075 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1076
1077 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
1078 err = GetLastError();
1079 ok(!ret, "unexpected success\n");
1080 ok(err == ERROR_WINHTTP_INCORRECT_HANDLE_STATE || broken(err == ERROR_INVALID_PARAMETER) /* winxp */,
1081 "setting client cert context returned %u\n", err);
1082
1083 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1084 err = GetLastError();
1085 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
1086 {
1087 skip("Connection failed, skipping.\n");
1088 goto cleanup;
1089 }
1090 ok(ret, "failed to send request %u\n", GetLastError());
1091
1092 ret = WinHttpReceiveResponse(req, NULL);
1093 ok(ret, "failed to receive response %u\n", GetLastError());
1094
1095 status = 0xdeadbeef;
1096 size = sizeof(status);
1097 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1098 ok(ret, "header query failed %u\n", GetLastError());
1099 ok(status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status);
1100
1101 WinHttpCloseHandle(req);
1102
1103 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
1104 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1105
1106 flags = 0xdeadbeef;
1107 size = sizeof(flags);
1108 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, &size);
1109 ok(ret, "failed to query security flags %u\n", GetLastError());
1110 ok(!flags, "got %08x\n", flags);
1111
1112 flags = SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
1113 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1114 ok(ret, "failed to set security flags %u\n", GetLastError());
1115
1116 flags = SECURITY_FLAG_SECURE;
1117 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1118 ok(!ret, "success\n");
1119
1120 flags = SECURITY_FLAG_STRENGTH_STRONG;
1121 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1122 ok(!ret, "success\n");
1123
1124 flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
1125 SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
1126 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1127 ok(ret, "failed to set security flags %u\n", GetLastError());
1128
1129 flags = 0;
1130 ret = WinHttpSetOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
1131 ok(ret, "failed to set security flags %u\n", GetLastError());
1132
1133 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
1134 err = GetLastError();
1135 ok(ret || broken(!ret && err == ERROR_INVALID_PARAMETER) /* winxp */, "failed to set client cert context %u\n", err);
1136
1137 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0);
1138
1139 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1140 err = GetLastError();
1141 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT ||
1142 err == ERROR_WINHTTP_TIMEOUT || err == SEC_E_ILLEGAL_MESSAGE))
1143 {
1144 skip("secure connection failed, skipping remaining secure tests\n");
1145 goto cleanup;
1146 }
1147 ok(ret, "failed to send request %u\n", GetLastError());
1148
1149 size = sizeof(cert);
1150 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
1151 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1152 if (ret) CertFreeCertificateContext(cert);
1153
1154 size = sizeof(bitness);
1155 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
1156 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
1157
1158 size = sizeof(info);
1159 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
1160 ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
1161
1162 if (ret)
1163 {
1164 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
1165 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
1166 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
1167 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
1168 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
1169 trace("dwKeySize %u\n", info.dwKeySize);
1170 LocalFree( info.lpszSubjectInfo );
1171 LocalFree( info.lpszIssuerInfo );
1172 }
1173
1174 ret = WinHttpReceiveResponse(req, NULL);
1175 if (!ret && GetLastError() == ERROR_WINHTTP_CONNECTION_ERROR)
1176 {
1177 skip("connection error, skipping remaining secure tests\n");
1178 goto cleanup;
1179 }
1180 ok(ret, "failed to receive response %u\n", GetLastError());
1181
1182 available_size = 0;
1183 ret = WinHttpQueryDataAvailable(req, &available_size);
1184 ok(ret, "failed to query available data %u\n", GetLastError());
1185 ok(available_size > 2014, "available_size = %u\n", available_size);
1186
1187 status = 0xdeadbeef;
1188 size = sizeof(status);
1189 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1190 ok(ret, "failed unexpectedly %u\n", GetLastError());
1191 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1192
1193 size = 0;
1194 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
1195 ok(!ret, "succeeded unexpectedly\n");
1196
1197 read_size = 0;
1198 for (;;)
1199 {
1200 size = 0;
1201 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
1202 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
1203 if (!size) break;
1204 read_size += size;
1205
1206 if (read_size <= 32)
1207 ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer);
1208 }
1209 ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size);
1210
1211 size = sizeof(cert);
1212 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size);
1213 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1214 if (ret) CertFreeCertificateContext(cert);
1215
1216 cleanup:
1217 WinHttpCloseHandle(req);
1218 WinHttpCloseHandle(con);
1219 WinHttpCloseHandle(ses);
1220 }
1221
test_request_parameter_defaults(void)1222 static void test_request_parameter_defaults(void)
1223 {
1224 static const WCHAR empty[] = {0};
1225 HINTERNET ses, con, req;
1226 DWORD size, status, error;
1227 WCHAR *version;
1228 BOOL ret;
1229
1230 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1231 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1232
1233 con = WinHttpConnect(ses, test_winehq, 0, 0);
1234 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1235
1236 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1237 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1238
1239 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1240 error = GetLastError();
1241 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1242 {
1243 skip("connection failed, skipping\n");
1244 goto done;
1245 }
1246 ok(ret, "failed to send request %u\n", GetLastError());
1247
1248 ret = WinHttpReceiveResponse(req, NULL);
1249 ok(ret, "failed to receive response %u\n", GetLastError());
1250
1251 status = 0xdeadbeef;
1252 size = sizeof(status);
1253 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1254 ok(ret, "failed unexpectedly %u\n", GetLastError());
1255 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1256
1257 WinHttpCloseHandle(req);
1258
1259 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
1260 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1261
1262 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1263 error = GetLastError();
1264 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT))
1265 {
1266 skip("connection failed, skipping\n");
1267 goto done;
1268 }
1269 ok(ret, "failed to send request %u\n", GetLastError());
1270
1271 ret = WinHttpReceiveResponse(req, NULL);
1272 ok(ret, "failed to receive response %u\n", GetLastError());
1273
1274 size = 0;
1275 SetLastError(0xdeadbeef);
1276 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
1277 error = GetLastError();
1278 ok(!ret, "succeeded unexpectedly\n");
1279 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
1280
1281 version = HeapAlloc(GetProcessHeap(), 0, size);
1282 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
1283 ok(ret, "failed unexpectedly %u\n", GetLastError());
1284 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
1285 HeapFree(GetProcessHeap(), 0, version);
1286
1287 status = 0xdeadbeef;
1288 size = sizeof(status);
1289 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1290 ok(ret, "failed unexpectedly %u\n", GetLastError());
1291 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1292
1293 done:
1294 WinHttpCloseHandle(req);
1295 WinHttpCloseHandle(con);
1296 WinHttpCloseHandle(ses);
1297 }
1298
1299 static const WCHAR Connections[] = {
1300 'S','o','f','t','w','a','r','e','\\',
1301 'M','i','c','r','o','s','o','f','t','\\',
1302 'W','i','n','d','o','w','s','\\',
1303 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1304 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1305 'C','o','n','n','e','c','t','i','o','n','s',0 };
1306 static const WCHAR WinHttpSettings[] = {
1307 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1308
get_default_proxy_reg_value(BYTE * buf,DWORD len,DWORD * type)1309 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
1310 {
1311 LONG l;
1312 HKEY key;
1313 DWORD ret = 0;
1314
1315 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
1316 if (!l)
1317 {
1318 DWORD size = 0;
1319
1320 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
1321 if (!l)
1322 {
1323 if (size <= len)
1324 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
1325 &size );
1326 if (!l)
1327 ret = size;
1328 }
1329 RegCloseKey( key );
1330 }
1331 return ret;
1332 }
1333
set_proxy(REGSAM access,BYTE * buf,DWORD len,DWORD type)1334 static void set_proxy( REGSAM access, BYTE *buf, DWORD len, DWORD type )
1335 {
1336 HKEY hkey;
1337 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0, access, NULL, &hkey, NULL ))
1338 {
1339 if (len) RegSetValueExW( hkey, WinHttpSettings, 0, type, buf, len );
1340 else RegDeleteValueW( hkey, WinHttpSettings );
1341 RegCloseKey( hkey );
1342 }
1343 }
1344
set_default_proxy_reg_value(BYTE * buf,DWORD len,DWORD type)1345 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
1346 {
1347 BOOL wow64;
1348 IsWow64Process( GetCurrentProcess(), &wow64 );
1349 if (sizeof(void *) > sizeof(int) || wow64)
1350 {
1351 set_proxy( KEY_WRITE|KEY_WOW64_64KEY, buf, len, type );
1352 set_proxy( KEY_WRITE|KEY_WOW64_32KEY, buf, len, type );
1353 }
1354 else
1355 set_proxy( KEY_WRITE, buf, len, type );
1356 }
1357
test_set_default_proxy_config(void)1358 static void test_set_default_proxy_config(void)
1359 {
1360 static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1361 static WCHAR normalString[] = { 'f','o','o',0 };
1362 DWORD type, len;
1363 BYTE *saved_proxy_settings = NULL;
1364 WINHTTP_PROXY_INFO info;
1365 BOOL ret;
1366
1367 /* FIXME: it would be simpler to read the current settings using
1368 * WinHttpGetDefaultProxyConfiguration and save them using
1369 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1370 *
1371 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1372 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1373 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1374 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1375 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1376 * the lpszProxy and lpszProxyBypass values are ignored.
1377 * Thus, if a proxy is set with proxycfg, then calling
1378 * WinHttpGetDefaultProxyConfiguration followed by
1379 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1380 * getting deleted from the registry.
1381 *
1382 * Instead I read the current registry value and restore it directly.
1383 */
1384 len = get_default_proxy_reg_value( NULL, 0, &type );
1385 if (len)
1386 {
1387 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1388 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1389 }
1390
1391 if (0)
1392 {
1393 /* Crashes on Vista and higher */
1394 SetLastError(0xdeadbeef);
1395 ret = WinHttpSetDefaultProxyConfiguration(NULL);
1396 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1397 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1398 }
1399
1400 /* test with invalid access type */
1401 info.dwAccessType = 0xdeadbeef;
1402 info.lpszProxy = info.lpszProxyBypass = NULL;
1403 SetLastError(0xdeadbeef);
1404 ret = WinHttpSetDefaultProxyConfiguration(&info);
1405 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1406 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1407
1408 /* at a minimum, the proxy server must be set */
1409 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1410 info.lpszProxy = info.lpszProxyBypass = NULL;
1411 SetLastError(0xdeadbeef);
1412 ret = WinHttpSetDefaultProxyConfiguration(&info);
1413 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1414 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1415 info.lpszProxyBypass = normalString;
1416 SetLastError(0xdeadbeef);
1417 ret = WinHttpSetDefaultProxyConfiguration(&info);
1418 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1419 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1420
1421 /* the proxy server can't have wide characters */
1422 info.lpszProxy = wideString;
1423 SetLastError(0xdeadbeef);
1424 ret = WinHttpSetDefaultProxyConfiguration(&info);
1425 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1426 skip("couldn't set default proxy configuration: access denied\n");
1427 else
1428 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1429 broken(ret), /* Earlier winhttp versions on W2K/XP */
1430 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1431
1432 info.lpszProxy = normalString;
1433 SetLastError(0xdeadbeef);
1434 ret = WinHttpSetDefaultProxyConfiguration(&info);
1435 if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1436 skip("couldn't set default proxy configuration: access denied\n");
1437 else
1438 {
1439 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1440 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1441 "got %u\n", GetLastError());
1442 }
1443 set_default_proxy_reg_value( saved_proxy_settings, len, type );
1444 }
1445
test_timeouts(void)1446 static void test_timeouts(void)
1447 {
1448 BOOL ret;
1449 DWORD value, size;
1450 HINTERNET ses, req, con;
1451
1452 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1453 ok(ses != NULL, "failed to open session %u\n", GetLastError());
1454
1455 SetLastError(0xdeadbeef);
1456 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1457 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1458 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1459
1460 SetLastError(0xdeadbeef);
1461 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1462 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1463 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1464
1465 SetLastError(0xdeadbeef);
1466 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1467 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1468 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1469
1470 SetLastError(0xdeadbeef);
1471 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1472 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1473 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1474
1475 SetLastError(0xdeadbeef);
1476 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1477 ok(ret, "%u\n", GetLastError());
1478 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1479 "expected ERROR_SUCCESS, got %u\n", GetLastError());
1480
1481 SetLastError(0xdeadbeef);
1482 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1483 ok(ret, "%u\n", GetLastError());
1484
1485 SetLastError(0xdeadbeef);
1486 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1487 ok(ret, "%u\n", GetLastError());
1488
1489 SetLastError(0xdeadbeef);
1490 value = 0xdeadbeef;
1491 size = sizeof(DWORD);
1492 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1493 ok(ret, "%u\n", GetLastError());
1494 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1495
1496 SetLastError(0xdeadbeef);
1497 value = 0xdeadbeef;
1498 size = sizeof(DWORD);
1499 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1500 ok(ret, "%u\n", GetLastError());
1501 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1502
1503 SetLastError(0xdeadbeef);
1504 value = 0xdeadbeef;
1505 size = sizeof(DWORD);
1506 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1507 ok(ret, "%u\n", GetLastError());
1508 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1509
1510 SetLastError(0xdeadbeef);
1511 value = 0xdeadbeef;
1512 size = sizeof(DWORD);
1513 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1514 ok(ret, "%u\n", GetLastError());
1515 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1516
1517 SetLastError(0xdeadbeef);
1518 value = 0;
1519 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1520 ok(ret, "%u\n", GetLastError());
1521
1522 SetLastError(0xdeadbeef);
1523 value = 0xdeadbeef;
1524 size = sizeof(DWORD);
1525 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1526 ok(ret, "%u\n", GetLastError());
1527 ok(value == 0, "Expected 0, got %u\n", value);
1528
1529 SetLastError(0xdeadbeef);
1530 value = 0;
1531 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1532 ok(ret, "%u\n", GetLastError());
1533
1534 SetLastError(0xdeadbeef);
1535 value = 0xdeadbeef;
1536 size = sizeof(DWORD);
1537 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1538 ok(ret, "%u\n", GetLastError());
1539 ok(value == 0, "Expected 0, got %u\n", value);
1540
1541 SetLastError(0xdeadbeef);
1542 value = 0;
1543 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1544 ok(ret, "%u\n", GetLastError());
1545
1546 SetLastError(0xdeadbeef);
1547 value = 0xdeadbeef;
1548 size = sizeof(DWORD);
1549 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1550 ok(ret, "%u\n", GetLastError());
1551 ok(value == 0, "Expected 0, got %u\n", value);
1552
1553 SetLastError(0xdeadbeef);
1554 value = 0;
1555 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1556 ok(ret, "%u\n", GetLastError());
1557
1558 SetLastError(0xdeadbeef);
1559 value = 0xdeadbeef;
1560 size = sizeof(DWORD);
1561 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1562 ok(ret, "%u\n", GetLastError());
1563 ok(value == 0, "Expected 0, got %u\n", value);
1564
1565 SetLastError(0xdeadbeef);
1566 value = 0xbeefdead;
1567 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1568 ok(ret, "%u\n", GetLastError());
1569
1570 SetLastError(0xdeadbeef);
1571 value = 0xdeadbeef;
1572 size = sizeof(DWORD);
1573 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1574 ok(ret, "%u\n", GetLastError());
1575 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1576
1577 SetLastError(0xdeadbeef);
1578 value = 0xbeefdead;
1579 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1580 ok(ret, "%u\n", GetLastError());
1581
1582 SetLastError(0xdeadbeef);
1583 value = 0xdeadbeef;
1584 size = sizeof(DWORD);
1585 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1586 ok(ret, "%u\n", GetLastError());
1587 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1588
1589 SetLastError(0xdeadbeef);
1590 value = 0xbeefdead;
1591 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1592 ok(ret, "%u\n", GetLastError());
1593
1594 SetLastError(0xdeadbeef);
1595 value = 0xdeadbeef;
1596 size = sizeof(DWORD);
1597 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1598 ok(ret, "%u\n", GetLastError());
1599 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1600
1601 SetLastError(0xdeadbeef);
1602 value = 0xbeefdead;
1603 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1604 ok(ret, "%u\n", GetLastError());
1605
1606 SetLastError(0xdeadbeef);
1607 value = 0xdeadbeef;
1608 size = sizeof(DWORD);
1609 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1610 ok(ret, "%u\n", GetLastError());
1611 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1612
1613 con = WinHttpConnect(ses, test_winehq, 0, 0);
1614 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1615
1616 /* Timeout values should match the last one set for session */
1617 SetLastError(0xdeadbeef);
1618 value = 0xdeadbeef;
1619 size = sizeof(DWORD);
1620 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1621 ok(ret, "%u\n", GetLastError());
1622 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1623
1624 SetLastError(0xdeadbeef);
1625 value = 0xdeadbeef;
1626 size = sizeof(DWORD);
1627 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1628 ok(ret, "%u\n", GetLastError());
1629 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1630
1631 SetLastError(0xdeadbeef);
1632 value = 0xdeadbeef;
1633 size = sizeof(DWORD);
1634 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1635 ok(ret, "%u\n", GetLastError());
1636 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1637
1638 SetLastError(0xdeadbeef);
1639 value = 0xdeadbeef;
1640 size = sizeof(DWORD);
1641 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1642 ok(ret, "%u\n", GetLastError());
1643 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1644
1645 SetLastError(0xdeadbeef);
1646 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1647 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1648 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1649
1650 SetLastError(0xdeadbeef);
1651 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1652 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1653 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1654
1655 SetLastError(0xdeadbeef);
1656 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1657 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1658 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1659
1660 SetLastError(0xdeadbeef);
1661 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1662 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1663 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1664
1665 SetLastError(0xdeadbeef);
1666 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1667 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1668 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1669
1670 SetLastError(0xdeadbeef);
1671 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1672 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1673 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1674
1675 SetLastError(0xdeadbeef);
1676 value = 0;
1677 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1678 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1679 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1680
1681 SetLastError(0xdeadbeef);
1682 value = 0;
1683 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1684 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1685 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1686
1687 SetLastError(0xdeadbeef);
1688 value = 0;
1689 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1690 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1691 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1692
1693 SetLastError(0xdeadbeef);
1694 value = 0;
1695 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1696 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1697 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1698
1699 /* Changing timeout values for session should affect the values for connection */
1700 SetLastError(0xdeadbeef);
1701 value = 0xdead;
1702 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1703 ok(ret, "%u\n", GetLastError());
1704
1705 SetLastError(0xdeadbeef);
1706 value = 0xdeadbeef;
1707 size = sizeof(DWORD);
1708 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1709 ok(ret, "%u\n", GetLastError());
1710 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1711
1712 SetLastError(0xdeadbeef);
1713 value = 0xdead;
1714 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1715 ok(ret, "%u\n", GetLastError());
1716
1717 SetLastError(0xdeadbeef);
1718 value = 0xdeadbeef;
1719 size = sizeof(DWORD);
1720 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1721 ok(ret, "%u\n", GetLastError());
1722 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1723
1724 SetLastError(0xdeadbeef);
1725 value = 0xdead;
1726 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1727 ok(ret, "%u\n", GetLastError());
1728
1729 SetLastError(0xdeadbeef);
1730 value = 0xdeadbeef;
1731 size = sizeof(DWORD);
1732 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1733 ok(ret, "%u\n", GetLastError());
1734 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1735
1736 SetLastError(0xdeadbeef);
1737 value = 0xdead;
1738 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1739 ok(ret, "%u\n", GetLastError());
1740
1741 SetLastError(0xdeadbeef);
1742 value = 0xdeadbeef;
1743 size = sizeof(DWORD);
1744 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1745 ok(ret, "%u\n", GetLastError());
1746 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1747
1748 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1749 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1750
1751 /* Timeout values should match the last one set for session */
1752 SetLastError(0xdeadbeef);
1753 value = 0xdeadbeef;
1754 size = sizeof(DWORD);
1755 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1756 ok(ret, "%u\n", GetLastError());
1757 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1758
1759 SetLastError(0xdeadbeef);
1760 value = 0xdeadbeef;
1761 size = sizeof(DWORD);
1762 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1763 ok(ret, "%u\n", GetLastError());
1764 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1765
1766 SetLastError(0xdeadbeef);
1767 value = 0xdeadbeef;
1768 size = sizeof(DWORD);
1769 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1770 ok(ret, "%u\n", GetLastError());
1771 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1772
1773 SetLastError(0xdeadbeef);
1774 value = 0xdeadbeef;
1775 size = sizeof(DWORD);
1776 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1777 ok(ret, "%u\n", GetLastError());
1778 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1779
1780 SetLastError(0xdeadbeef);
1781 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1782 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1783 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1784
1785 SetLastError(0xdeadbeef);
1786 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1787 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1788 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1789
1790 SetLastError(0xdeadbeef);
1791 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1792 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1793 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1794
1795 SetLastError(0xdeadbeef);
1796 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1797 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1798 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1799
1800 SetLastError(0xdeadbeef);
1801 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1802 ok(ret, "%u\n", GetLastError());
1803
1804 SetLastError(0xdeadbeef);
1805 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1806 ok(ret, "%u\n", GetLastError());
1807
1808 SetLastError(0xdeadbeef);
1809 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1810 ok(ret, "%u\n", GetLastError());
1811
1812 SetLastError(0xdeadbeef);
1813 value = 0xdeadbeef;
1814 size = sizeof(DWORD);
1815 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1816 ok(ret, "%u\n", GetLastError());
1817 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1818
1819 SetLastError(0xdeadbeef);
1820 value = 0xdeadbeef;
1821 size = sizeof(DWORD);
1822 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1823 ok(ret, "%u\n", GetLastError());
1824 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1825
1826 SetLastError(0xdeadbeef);
1827 value = 0xdeadbeef;
1828 size = sizeof(DWORD);
1829 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1830 ok(ret, "%u\n", GetLastError());
1831 ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1832
1833 SetLastError(0xdeadbeef);
1834 value = 0xdeadbeef;
1835 size = sizeof(DWORD);
1836 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1837 ok(ret, "%u\n", GetLastError());
1838 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1839
1840 SetLastError(0xdeadbeef);
1841 value = 0;
1842 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1843 ok(ret, "%u\n", GetLastError());
1844
1845 SetLastError(0xdeadbeef);
1846 value = 0xdeadbeef;
1847 size = sizeof(DWORD);
1848 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1849 ok(ret, "%u\n", GetLastError());
1850 ok(value == 0, "Expected 0, got %u\n", value);
1851
1852 SetLastError(0xdeadbeef);
1853 value = 0;
1854 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1855 ok(ret, "%u\n", GetLastError());
1856
1857 SetLastError(0xdeadbeef);
1858 value = 0xdeadbeef;
1859 size = sizeof(DWORD);
1860 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1861 ok(ret, "%u\n", GetLastError());
1862 ok(value == 0, "Expected 0, got %u\n", value);
1863
1864 SetLastError(0xdeadbeef);
1865 value = 0;
1866 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1867 ok(ret, "%u\n", GetLastError());
1868
1869 SetLastError(0xdeadbeef);
1870 value = 0xdeadbeef;
1871 size = sizeof(DWORD);
1872 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1873 ok(ret, "%u\n", GetLastError());
1874 ok(value == 0, "Expected 0, got %u\n", value);
1875
1876 SetLastError(0xdeadbeef);
1877 value = 0;
1878 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1879 ok(ret, "%u\n", GetLastError());
1880
1881 SetLastError(0xdeadbeef);
1882 value = 0xdeadbeef;
1883 size = sizeof(DWORD);
1884 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1885 ok(ret, "%u\n", GetLastError());
1886 ok(value == 0, "Expected 0, got %u\n", value);
1887
1888 SetLastError(0xdeadbeef);
1889 value = 0xbeefdead;
1890 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1891 ok(ret, "%u\n", GetLastError());
1892
1893 SetLastError(0xdeadbeef);
1894 value = 0xdeadbeef;
1895 size = sizeof(DWORD);
1896 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1897 ok(ret, "%u\n", GetLastError());
1898 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1899
1900 SetLastError(0xdeadbeef);
1901 value = 0xbeefdead;
1902 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1903 ok(ret, "%u\n", GetLastError());
1904
1905 SetLastError(0xdeadbeef);
1906 value = 0xdeadbeef;
1907 size = sizeof(DWORD);
1908 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1909 ok(ret, "%u\n", GetLastError());
1910 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1911
1912 SetLastError(0xdeadbeef);
1913 value = 0xbeefdead;
1914 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1915 ok(ret, "%u\n", GetLastError());
1916
1917 SetLastError(0xdeadbeef);
1918 value = 0xdeadbeef;
1919 size = sizeof(DWORD);
1920 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1921 ok(ret, "%u\n", GetLastError());
1922 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1923
1924 SetLastError(0xdeadbeef);
1925 value = 0xbeefdead;
1926 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1927 ok(ret, "%u\n", GetLastError());
1928
1929 SetLastError(0xdeadbeef);
1930 value = 0xdeadbeef;
1931 size = sizeof(DWORD);
1932 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1933 ok(ret, "%u\n", GetLastError());
1934 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1935
1936 /* Changing timeout values for session should not affect the values for a request,
1937 * neither should the other way around.
1938 */
1939 SetLastError(0xdeadbeef);
1940 value = 0xbeefdead;
1941 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1942 ok(ret, "%u\n", GetLastError());
1943
1944 SetLastError(0xdeadbeef);
1945 value = 0xdeadbeef;
1946 size = sizeof(DWORD);
1947 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1948 ok(ret, "%u\n", GetLastError());
1949 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1950
1951 SetLastError(0xdeadbeef);
1952 value = 0xbeefdead;
1953 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1954 ok(ret, "%u\n", GetLastError());
1955
1956 SetLastError(0xdeadbeef);
1957 value = 0xdeadbeef;
1958 size = sizeof(DWORD);
1959 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1960 ok(ret, "%u\n", GetLastError());
1961 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1962
1963 SetLastError(0xdeadbeef);
1964 value = 0xbeefdead;
1965 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1966 ok(ret, "%u\n", GetLastError());
1967
1968 SetLastError(0xdeadbeef);
1969 value = 0xdeadbeef;
1970 size = sizeof(DWORD);
1971 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1972 ok(ret, "%u\n", GetLastError());
1973 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1974
1975 SetLastError(0xdeadbeef);
1976 value = 0xbeefdead;
1977 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1978 ok(ret, "%u\n", GetLastError());
1979
1980 SetLastError(0xdeadbeef);
1981 value = 0xdeadbeef;
1982 size = sizeof(DWORD);
1983 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1984 ok(ret, "%u\n", GetLastError());
1985 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1986
1987 SetLastError(0xdeadbeef);
1988 value = 0xbeef;
1989 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1990 ok(ret, "%u\n", GetLastError());
1991
1992 SetLastError(0xdeadbeef);
1993 value = 0xdeadbeef;
1994 size = sizeof(DWORD);
1995 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1996 ok(ret, "%u\n", GetLastError());
1997 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1998
1999 SetLastError(0xdeadbeef);
2000 value = 0xbeef;
2001 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
2002 ok(ret, "%u\n", GetLastError());
2003
2004 SetLastError(0xdeadbeef);
2005 value = 0xdeadbeef;
2006 size = sizeof(DWORD);
2007 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
2008 ok(ret, "%u\n", GetLastError());
2009 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
2010
2011 SetLastError(0xdeadbeef);
2012 value = 0xbeef;
2013 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
2014 ok(ret, "%u\n", GetLastError());
2015
2016 SetLastError(0xdeadbeef);
2017 value = 0xdeadbeef;
2018 size = sizeof(DWORD);
2019 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
2020 ok(ret, "%u\n", GetLastError());
2021 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
2022
2023 SetLastError(0xdeadbeef);
2024 value = 0xbeef;
2025 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
2026 ok(ret, "%u\n", GetLastError());
2027
2028 SetLastError(0xdeadbeef);
2029 value = 0xdeadbeef;
2030 size = sizeof(DWORD);
2031 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
2032 ok(ret, "%u\n", GetLastError());
2033 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
2034
2035 /* response timeout */
2036 SetLastError(0xdeadbeef);
2037 value = 0xdeadbeef;
2038 size = sizeof(value);
2039 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2040 ok(ret, "%u\n", GetLastError());
2041 ok(value == ~0u, "got %u\n", value);
2042
2043 SetLastError(0xdeadbeef);
2044 value = 30000;
2045 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2046 ok(ret, "%u\n", GetLastError());
2047
2048 SetLastError(0xdeadbeef);
2049 value = 0xdeadbeef;
2050 size = sizeof(value);
2051 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2052 ok(ret, "%u\n", GetLastError());
2053 todo_wine ok(value == 0xbeefdead, "got %u\n", value);
2054
2055 SetLastError(0xdeadbeef);
2056 value = 0xdeadbeef;
2057 size = sizeof(value);
2058 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2059 ok(ret, "%u\n", GetLastError());
2060 ok(value == ~0u, "got %u\n", value);
2061
2062 SetLastError(0xdeadbeef);
2063 value = 30000;
2064 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2065 ok(!ret, "expected failure\n");
2066 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %u\n", GetLastError());
2067
2068 SetLastError(0xdeadbeef);
2069 value = 0xdeadbeef;
2070 size = sizeof(value);
2071 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2072 ok(ret, "%u\n", GetLastError());
2073 ok(value == ~0u, "got %u\n", value);
2074
2075 SetLastError(0xdeadbeef);
2076 value = 48878;
2077 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2078 ok(ret, "%u\n", GetLastError());
2079
2080 SetLastError(0xdeadbeef);
2081 value = 0xdeadbeef;
2082 size = sizeof(value);
2083 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2084 ok(ret, "%u\n", GetLastError());
2085 todo_wine ok(value == 48879, "got %u\n", value);
2086
2087 SetLastError(0xdeadbeef);
2088 value = 48880;
2089 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value));
2090 ok(ret, "%u\n", GetLastError());
2091
2092 SetLastError(0xdeadbeef);
2093 value = 0xdeadbeef;
2094 size = sizeof(value);
2095 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size);
2096 ok(ret, "%u\n", GetLastError());
2097 ok(value == 48880, "got %u\n", value);
2098
2099 WinHttpCloseHandle(req);
2100 WinHttpCloseHandle(con);
2101 WinHttpCloseHandle(ses);
2102 }
2103
test_resolve_timeout(void)2104 static void test_resolve_timeout(void)
2105 {
2106 static const WCHAR nxdomain[] =
2107 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
2108 HINTERNET ses, con, req;
2109 DWORD timeout;
2110 BOOL ret;
2111
2112 if (! proxy_active())
2113 {
2114 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2115 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2116
2117 timeout = 10000;
2118 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
2119 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
2120
2121 con = WinHttpConnect(ses, nxdomain, 0, 0);
2122 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2123
2124 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2125 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2126
2127 SetLastError(0xdeadbeef);
2128 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2129 if (ret)
2130 {
2131 skip("nxdomain returned success. Broken ISP redirects?\n");
2132 goto done;
2133 }
2134 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
2135 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
2136
2137 ret = WinHttpReceiveResponse( req, NULL );
2138 ok( !ret && (GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE ||
2139 GetLastError() == ERROR_WINHTTP_OPERATION_CANCELLED /* < win7 */),
2140 "got %u\n", GetLastError() );
2141
2142 WinHttpCloseHandle(req);
2143 WinHttpCloseHandle(con);
2144 WinHttpCloseHandle(ses);
2145 }
2146 else
2147 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
2148
2149 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
2150 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2151
2152 timeout = 10000;
2153 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
2154 ok(ret, "failed to set resolve timeout %u\n", GetLastError());
2155
2156 con = WinHttpConnect(ses, test_winehq, 0, 0);
2157 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2158
2159 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2160 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2161
2162 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2163 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
2164 {
2165 skip("connection failed, skipping\n");
2166 goto done;
2167 }
2168 ok(ret, "failed to send request\n");
2169
2170 done:
2171 WinHttpCloseHandle(req);
2172 WinHttpCloseHandle(con);
2173 WinHttpCloseHandle(ses);
2174 }
2175
2176 static const char page1[] =
2177 "<HTML>\r\n"
2178 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
2179 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2180 "</HTML>\r\n\r\n";
2181
2182 static const char okmsg[] =
2183 "HTTP/1.1 200 OK\r\n"
2184 "Server: winetest\r\n"
2185 "\r\n";
2186
2187 static const char notokmsg[] =
2188 "HTTP/1.1 400 Bad Request\r\n"
2189 "\r\n";
2190
2191 static const char cookiemsg[] =
2192 "HTTP/1.1 200 OK\r\n"
2193 "Set-Cookie: name = value \r\n"
2194 "Set-Cookie: NAME = value \r\n"
2195 "\r\n";
2196
2197 static const char cookiemsg2[] =
2198 "HTTP/1.1 200 OK\r\n"
2199 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2200 "\r\n";
2201
2202 static const char nocontentmsg[] =
2203 "HTTP/1.1 204 No Content\r\n"
2204 "Server: winetest\r\n"
2205 "\r\n";
2206
2207 static const char notmodified[] =
2208 "HTTP/1.1 304 Not Modified\r\n"
2209 "\r\n";
2210
2211 static const char noauthmsg[] =
2212 "HTTP/1.1 401 Unauthorized\r\n"
2213 "Server: winetest\r\n"
2214 "Connection: close\r\n"
2215 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2216 "Content-Length: 12\r\n"
2217 "Content-Type: text/plain\r\n"
2218 "\r\n";
2219
2220 static const char okauthmsg[] =
2221 "HTTP/1.1 200 OK\r\n"
2222 "Server: winetest\r\n"
2223 "Connection: close\r\n"
2224 "Content-Length: 11\r\n"
2225 "Content-Type: text/plain\r\n"
2226 "\r\n";
2227
2228 static const char headmsg[] =
2229 "HTTP/1.1 200 OK\r\n"
2230 "Content-Length: 100\r\n"
2231 "\r\n";
2232
2233 static const char multiauth[] =
2234 "HTTP/1.1 401 Unauthorized\r\n"
2235 "Server: winetest\r\n"
2236 "WWW-Authenticate: Bearer\r\n"
2237 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2238 "WWW-Authenticate: NTLM\r\n"
2239 "Content-Length: 10\r\n"
2240 "Content-Type: text/plain\r\n"
2241 "\r\n";
2242
2243 static const char largeauth[] =
2244 "HTTP/1.1 401 Unauthorized\r\n"
2245 "Server: winetest\r\n"
2246 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2247 "WWW-Authenticate: NTLM\r\n"
2248 "Content-Length: 10240\r\n"
2249 "Content-Type: text/plain\r\n"
2250 "\r\n";
2251
2252 static const char passportauth[] =
2253 "HTTP/1.1 302 Found\r\n"
2254 "Content-Length: 0\r\n"
2255 "Location: /\r\n"
2256 "WWW-Authenticate: Passport1.4\r\n"
2257 "\r\n";
2258
2259 static const char unauthorized[] = "Unauthorized";
2260 static const char hello_world[] = "Hello World";
2261 static const char auth_unseen[] = "Auth Unseen";
2262
2263 struct server_info
2264 {
2265 HANDLE event;
2266 int port;
2267 };
2268
2269 #define BIG_BUFFER_LEN 0x2250
2270
server_thread(LPVOID param)2271 static DWORD CALLBACK server_thread(LPVOID param)
2272 {
2273 struct server_info *si = param;
2274 int r, c = -1, i, on;
2275 SOCKET s;
2276 struct sockaddr_in sa;
2277 char buffer[0x100];
2278 WSADATA wsaData;
2279 int last_request = 0;
2280
2281 WSAStartup(MAKEWORD(1,1), &wsaData);
2282
2283 s = socket(AF_INET, SOCK_STREAM, 0);
2284 if (s == INVALID_SOCKET)
2285 return 1;
2286
2287 on = 1;
2288 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2289
2290 memset(&sa, 0, sizeof sa);
2291 sa.sin_family = AF_INET;
2292 sa.sin_port = htons(si->port);
2293 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2294
2295 r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
2296 if (r < 0)
2297 return 1;
2298
2299 listen(s, 0);
2300 SetEvent(si->event);
2301 do
2302 {
2303 if (c == -1) c = accept(s, NULL, NULL);
2304
2305 memset(buffer, 0, sizeof buffer);
2306 for(i = 0; i < sizeof buffer - 1; i++)
2307 {
2308 r = recv(c, &buffer[i], 1, 0);
2309 if (r != 1)
2310 break;
2311 if (i < 4) continue;
2312 if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
2313 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
2314 break;
2315 }
2316 if (strstr(buffer, "GET /basic"))
2317 {
2318 send(c, okmsg, sizeof okmsg - 1, 0);
2319 send(c, page1, sizeof page1 - 1, 0);
2320 }
2321 if (strstr(buffer, "/auth_with_creds"))
2322 {
2323 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2324 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2325 send(c, hello_world, sizeof hello_world - 1, 0);
2326 else
2327 send(c, auth_unseen, sizeof auth_unseen - 1, 0);
2328 continue;
2329 }
2330 if (strstr(buffer, "/auth"))
2331 {
2332 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2333 {
2334 send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2335 send(c, hello_world, sizeof hello_world - 1, 0);
2336 }
2337 else
2338 {
2339 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
2340 send(c, unauthorized, sizeof unauthorized - 1, 0);
2341 }
2342 continue;
2343 }
2344 if (strstr(buffer, "/big"))
2345 {
2346 char msg[BIG_BUFFER_LEN];
2347 memset(msg, 'm', sizeof(msg));
2348 send(c, okmsg, sizeof(okmsg) - 1, 0);
2349 send(c, msg, sizeof(msg), 0);
2350 }
2351 if (strstr(buffer, "/no_headers"))
2352 {
2353 send(c, page1, sizeof page1 - 1, 0);
2354 }
2355 if (strstr(buffer, "GET /no_content"))
2356 {
2357 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
2358 continue;
2359 }
2360 if (strstr(buffer, "GET /not_modified"))
2361 {
2362 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0);
2363 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2364 continue;
2365 }
2366 if (strstr(buffer, "HEAD /head"))
2367 {
2368 send(c, headmsg, sizeof headmsg - 1, 0);
2369 continue;
2370 }
2371 if (strstr(buffer, "GET /multiauth"))
2372 {
2373 send(c, multiauth, sizeof multiauth - 1, 0);
2374 }
2375 if (strstr(buffer, "GET /largeauth"))
2376 {
2377 if (strstr(buffer, "Authorization: NTLM"))
2378 send(c, okmsg, sizeof(okmsg) - 1, 0);
2379 else
2380 {
2381 send(c, largeauth, sizeof largeauth - 1, 0);
2382 #ifdef __REACTOS__
2383 memset(buffer, 'A', sizeof(buffer));
2384 for (i = 0; i < (10240 / sizeof(buffer)); i++) send(c, buffer, sizeof(buffer), 0);
2385 #else
2386 for (i = 0; i < 10240; i++) send(c, "A", 1, 0);
2387 #endif
2388 continue;
2389 }
2390 }
2391 if (strstr(buffer, "GET /cookie5"))
2392 {
2393 if (strstr(buffer, "Cookie: name2=value\r\n"))
2394 send(c, okmsg, sizeof(okmsg) - 1, 0);
2395 else
2396 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2397 }
2398 if (strstr(buffer, "GET /cookie4"))
2399 {
2400 send(c, cookiemsg2, sizeof(cookiemsg2) - 1, 0);
2401 }
2402 if (strstr(buffer, "GET /cookie3"))
2403 {
2404 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2405 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL))
2406 send(c, okmsg, sizeof(okmsg) - 1, 0);
2407 else
2408 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2409 }
2410 if (strstr(buffer, "GET /cookie2"))
2411 {
2412 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") ||
2413 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL))
2414 send(c, okmsg, sizeof(okmsg) - 1, 0);
2415 else
2416 send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2417 }
2418 else if (strstr(buffer, "GET /cookie"))
2419 {
2420 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
2421 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2422 }
2423 else if (strstr(buffer, "GET /escape"))
2424 {
2425 static const char res[] = "%0D%0A%1F%7F%3C%20%one?%1F%7F%20!%22%23$%&'()*+,-./:;%3C=%3E?@%5B%5C%5D"
2426 "%5E_%60%7B%7C%7D~%0D%0A ";
2427 static const char res2[] = "%0D%0A%1F%7F%3C%20%25two?%1F%7F%20!%22%23$%25&'()*+,-./:;%3C=%3E?@%5B%5C%5D"
2428 "%5E_%60%7B%7C%7D~%0D%0A ";
2429 static const char res3[] = "\x1f\x7f<%20%three?\x1f\x7f%20!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
2430 static const char res4[] = "%0D%0A%1F%7F%3C%20%four?\x1f\x7f%20!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
2431 static const char res5[] = "&text=one%C2%80%7F~";
2432 static const char res6[] = "&text=two%C2%80\x7f~";
2433 static const char res7[] = "&text=%E5%90%9B%E3%81%AE%E5%90%8D%E3%81%AF";
2434
2435 if (strstr(buffer + 11, res) || strstr(buffer + 11, res2) || strstr(buffer + 11, res3) ||
2436 strstr(buffer + 11, res4) || strstr(buffer + 11, res5) || strstr(buffer + 11, res6) ||
2437 strstr(buffer + 11, res7))
2438 {
2439 send(c, okmsg, sizeof(okmsg) - 1, 0);
2440 }
2441 else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2442 }
2443 else if (strstr(buffer, "GET /passport"))
2444 {
2445 send(c, passportauth, sizeof(passportauth) - 1, 0);
2446 }
2447 if (strstr(buffer, "GET /quit"))
2448 {
2449 send(c, okmsg, sizeof okmsg - 1, 0);
2450 send(c, page1, sizeof page1 - 1, 0);
2451 last_request = 1;
2452 }
2453 shutdown(c, 2);
2454 closesocket(c);
2455 c = -1;
2456
2457 } while (!last_request);
2458
2459 closesocket(s);
2460 return 0;
2461 }
2462
test_basic_request(int port,const WCHAR * verb,const WCHAR * path)2463 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
2464 {
2465 static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0};
2466 static const WCHAR test_header_end_raw[] = {0,0};
2467 HINTERNET ses, con, req;
2468 char buffer[0x100];
2469 WCHAR buffer2[0x100];
2470 DWORD count, status, size, error, supported, first, target;
2471 BOOL ret;
2472
2473 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2474 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2475
2476 SetLastError(0xdeadbeef);
2477 ret = WinHttpSetOption(ses, 0, buffer, sizeof(buffer));
2478 ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError());
2479
2480 SetLastError(0xdeadbeef);
2481 ret = WinHttpQueryOption(ses, 0, buffer, &size);
2482 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
2483
2484 con = WinHttpConnect(ses, localhostW, port, 0);
2485 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2486
2487 SetLastError(0xdeadbeef);
2488 ret = WinHttpSetOption(con, 0, buffer, sizeof(buffer));
2489 todo_wine ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError());
2490
2491 SetLastError(0xdeadbeef);
2492 ret = WinHttpQueryOption(con, 0, buffer, &size);
2493 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
2494
2495 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
2496 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2497
2498 SetLastError(0xdeadbeef);
2499 ret = WinHttpSetOption(req, 0, buffer, sizeof(buffer));
2500 ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError());
2501
2502 SetLastError(0xdeadbeef);
2503 ret = WinHttpQueryOption(req, 0, buffer, &size);
2504 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
2505
2506 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2507 ok(ret, "failed to send request %u\n", GetLastError());
2508
2509 ret = WinHttpReceiveResponse(req, NULL);
2510 ok(ret, "failed to receive response %u\n", GetLastError());
2511
2512 status = 0xdeadbeef;
2513 size = sizeof(status);
2514 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2515 ok(ret, "failed to query status code %u\n", GetLastError());
2516 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2517
2518 supported = first = target = 0xdeadbeef;
2519 SetLastError(0xdeadbeef);
2520 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2521 error = GetLastError();
2522 ok(!ret, "unexpected success\n");
2523 ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2524 ok(supported == 0xdeadbeef, "got %x\n", supported);
2525 ok(first == 0xdeadbeef, "got %x\n", first);
2526 ok(target == 0xdeadbeef, "got %x\n", target);
2527
2528 size = sizeof(buffer2);
2529 memset(buffer2, 0, sizeof(buffer2));
2530 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL);
2531 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2532 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)),
2533 "WinHttpQueryHeaders returned invalid end of header string\n");
2534
2535 size = sizeof(buffer2);
2536 memset(buffer2, 0, sizeof(buffer2));
2537 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL);
2538 ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2539 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)),
2540 "WinHttpQueryHeaders returned invalid end of header string\n");
2541 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n");
2542
2543 count = 0;
2544 memset(buffer, 0, sizeof(buffer));
2545 ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
2546 ok(ret, "failed to read data %u\n", GetLastError());
2547 ok(count == sizeof page1 - 1, "count was wrong\n");
2548 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2549
2550 WinHttpCloseHandle(req);
2551 WinHttpCloseHandle(con);
2552 WinHttpCloseHandle(ses);
2553 }
2554
test_basic_authentication(int port)2555 static void test_basic_authentication(int port)
2556 {
2557 static const WCHAR authW[] = {'/','a','u','t','h',0};
2558 static const WCHAR auth_with_credsW[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0};
2559 static WCHAR userW[] = {'u','s','e','r',0};
2560 static WCHAR passW[] = {'p','w','d',0};
2561 static WCHAR pass2W[] = {'p','w','d','2',0};
2562 HINTERNET ses, con, req;
2563 DWORD status, size, error, supported, first, target;
2564 char buffer[32];
2565 BOOL ret;
2566
2567 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2568 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2569
2570 con = WinHttpConnect(ses, localhostW, port, 0);
2571 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2572
2573 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2574 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2575
2576 SetLastError(0xdeadbeef);
2577 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL);
2578 error = GetLastError();
2579 ok(!ret, "expected failure\n");
2580 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2581
2582 SetLastError(0xdeadbeef);
2583 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL);
2584 error = GetLastError();
2585 ok(!ret, "expected failure\n");
2586 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2587
2588 supported = 0xdeadbeef;
2589 SetLastError(0xdeadbeef);
2590 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2591 error = GetLastError();
2592 ok(!ret, "expected failure\n");
2593 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2594 ok(supported == 0xdeadbeef, "got %x\n", supported);
2595
2596 supported = first = 0xdeadbeef;
2597 SetLastError(0xdeadbeef);
2598 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
2599 error = GetLastError();
2600 ok(!ret, "expected failure\n");
2601 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error);
2602 ok(supported == 0xdeadbeef, "got %x\n", supported);
2603 ok(first == 0xdeadbeef, "got %x\n", first);
2604
2605 supported = first = target = 0xdeadbeef;
2606 SetLastError(0xdeadbeef);
2607 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2608 error = GetLastError();
2609 ok(!ret, "expected failure\n");
2610 ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2611 ok(supported == 0xdeadbeef, "got %x\n", supported);
2612 ok(first == 0xdeadbeef, "got %x\n", first);
2613 ok(target == 0xdeadbeef, "got %x\n", target);
2614
2615 supported = first = target = 0xdeadbeef;
2616 SetLastError(0xdeadbeef);
2617 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2618 error = GetLastError();
2619 ok(!ret, "expected failure\n");
2620 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2621 ok(supported == 0xdeadbeef, "got %x\n", supported);
2622 ok(first == 0xdeadbeef, "got %x\n", first);
2623 ok(target == 0xdeadbeef, "got %x\n", target);
2624
2625 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2626 ok(ret, "failed to send request %u\n", GetLastError());
2627
2628 ret = WinHttpReceiveResponse(req, NULL);
2629 ok(ret, "failed to receive response %u\n", GetLastError());
2630
2631 status = 0xdeadbeef;
2632 size = sizeof(status);
2633 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2634 ok(ret, "failed to query status code %u\n", GetLastError());
2635 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status);
2636
2637 size = 0;
2638 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2639 error = GetLastError();
2640 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2641 if (ret)
2642 {
2643 ok(size == 12, "expected 12, got %u\n", size);
2644 ok(!memcmp(buffer, unauthorized, 12), "got %s\n", buffer);
2645 }
2646
2647 supported = first = target = 0xdeadbeef;
2648 SetLastError(0xdeadbeef);
2649 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2650 error = GetLastError();
2651 ok(ret, "failed to query authentication schemes %u\n", error);
2652 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2653 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2654 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2655 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2656
2657 SetLastError(0xdeadbeef);
2658 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL);
2659 error = GetLastError();
2660 ok(ret, "failed to set credentials %u\n", error);
2661 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2662
2663 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL);
2664 ok(ret, "failed to set credentials %u\n", GetLastError());
2665
2666 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL);
2667 ok(ret, "failed to set credentials %u\n", GetLastError());
2668
2669 SetLastError(0xdeadbeef);
2670 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL);
2671 error = GetLastError();
2672 ok(!ret, "expected failure\n");
2673 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2674
2675 SetLastError(0xdeadbeef);
2676 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL);
2677 error = GetLastError();
2678 ok(!ret, "expected failure\n");
2679 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2680
2681 SetLastError(0xdeadbeef);
2682 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2683 error = GetLastError();
2684 ok(!ret, "expected failure\n");
2685 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2686
2687 SetLastError(0xdeadbeef);
2688 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2689 error = GetLastError();
2690 ok(!ret, "expected failure\n");
2691 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2692
2693 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2694 ok(ret, "failed to set credentials %u\n", GetLastError());
2695
2696 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2697 ok(ret, "failed to send request %u\n", GetLastError());
2698
2699 ret = WinHttpReceiveResponse(req, NULL);
2700 ok(ret, "failed to receive response %u\n", GetLastError());
2701
2702 status = 0xdeadbeef;
2703 size = sizeof(status);
2704 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2705 ok(ret, "failed to query status code %u\n", GetLastError());
2706 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2707
2708 size = 0;
2709 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2710 error = GetLastError();
2711 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2712 if (ret)
2713 {
2714 ok(size == 11, "expected 11, got %u\n", size);
2715 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2716 }
2717
2718 WinHttpCloseHandle(req);
2719 WinHttpCloseHandle(con);
2720 WinHttpCloseHandle(ses);
2721
2722 /* now set the credentials first to show that they get sent with the first request */
2723 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2724 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2725
2726 con = WinHttpConnect(ses, localhostW, port, 0);
2727 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2728
2729 req = WinHttpOpenRequest(con, NULL, auth_with_credsW, NULL, NULL, NULL, 0);
2730 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2731
2732 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2733 ok(ret, "failed to set credentials %u\n", GetLastError());
2734
2735 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2736 ok(ret, "failed to send request %u\n", GetLastError());
2737
2738 ret = WinHttpReceiveResponse(req, NULL);
2739 ok(ret, "failed to receive response %u\n", GetLastError());
2740
2741 status = 0xdeadbeef;
2742 size = sizeof(status);
2743 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2744 ok(ret, "failed to query status code %u\n", GetLastError());
2745 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2746
2747 size = 0;
2748 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2749 error = GetLastError();
2750 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2751 if (ret)
2752 {
2753 ok(size == 11, "expected 11, got %u\n", size);
2754 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2755 }
2756
2757 WinHttpCloseHandle(req);
2758 WinHttpCloseHandle(con);
2759 WinHttpCloseHandle(ses);
2760
2761 /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2762
2763 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2764 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2765
2766 con = WinHttpConnect(ses, localhostW, port, 0);
2767 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2768
2769 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2770 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2771
2772 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2773 ok(ret, "failed to set credentials %u\n", GetLastError());
2774
2775 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2776 ok(ret, "failed to set username %u\n", GetLastError());
2777
2778 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W));
2779 ok(ret, "failed to set password %u\n", GetLastError());
2780
2781 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2782 ok(ret, "failed to send request %u\n", GetLastError());
2783
2784 ret = WinHttpReceiveResponse(req, NULL);
2785 ok(ret, "failed to receive response %u\n", GetLastError());
2786
2787 status = 0xdeadbeef;
2788 size = sizeof(status);
2789 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2790 ok(ret, "failed to query status code %u\n", GetLastError());
2791 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2792
2793 WinHttpCloseHandle(req);
2794 WinHttpCloseHandle(con);
2795 WinHttpCloseHandle(ses);
2796
2797 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2798 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2799
2800 con = WinHttpConnect(ses, localhostW, port, 0);
2801 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2802
2803 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2804 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2805
2806 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2807 ok(ret, "failed to set username %u\n", GetLastError());
2808
2809 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2810 ok(ret, "failed to set password %u\n", GetLastError());
2811
2812 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, NULL);
2813 ok(ret, "failed to set credentials %u\n", GetLastError());
2814
2815 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2816 ok(ret, "failed to send request %u\n", GetLastError());
2817
2818 ret = WinHttpReceiveResponse(req, NULL);
2819 ok(ret, "failed to receive response %u\n", GetLastError());
2820
2821 status = 0xdeadbeef;
2822 size = sizeof(status);
2823 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
2824 ok(ret, "failed to query status code %u\n", GetLastError());
2825 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status);
2826
2827 WinHttpCloseHandle(req);
2828 WinHttpCloseHandle(con);
2829 WinHttpCloseHandle(ses);
2830 }
2831
test_multi_authentication(int port)2832 static void test_multi_authentication(int port)
2833 {
2834 static const WCHAR multiauthW[] = {'/','m','u','l','t','i','a','u','t','h',0};
2835 static const WCHAR www_authenticateW[] =
2836 {'W','W','W','-','A','u','t','h','e','n','t','i','c','a','t','e',0};
2837 static const WCHAR getW[] = {'G','E','T',0};
2838 HINTERNET ses, con, req;
2839 DWORD supported, first, target, size, index;
2840 WCHAR buf[512];
2841 BOOL ret;
2842
2843 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2844 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2845
2846 con = WinHttpConnect(ses, localhostW, port, 0);
2847 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2848
2849 req = WinHttpOpenRequest(con, getW, multiauthW, NULL, NULL, NULL, 0);
2850 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2851
2852 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
2853 WINHTTP_NO_REQUEST_DATA,0, 0, 0 );
2854 ok(ret, "expected success\n");
2855
2856 ret = WinHttpReceiveResponse(req, NULL);
2857 ok(ret, "expected success\n");
2858
2859 supported = first = target = 0xdeadbeef;
2860 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2861 ok(ret, "expected success\n");
2862 ok(supported == (WINHTTP_AUTH_SCHEME_BASIC | WINHTTP_AUTH_SCHEME_NTLM), "got %x\n", supported);
2863 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2864 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2865
2866 index = 0;
2867 size = sizeof(buf);
2868 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CUSTOM, www_authenticateW, buf, &size, &index);
2869 ok(ret, "expected success\n");
2870 ok(!strcmp_wa(buf, "Bearer"), "buf = %s\n", wine_dbgstr_w(buf));
2871 ok(size == lstrlenW(buf) * sizeof(WCHAR), "size = %u\n", size);
2872 ok(index == 1, "index = %u\n", index);
2873
2874 index = 0;
2875 size = 0xdeadbeef;
2876 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CUSTOM, www_authenticateW, NULL, &size, &index);
2877 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2878 "WinHttpQueryHeaders returned %x(%u)\n", ret, GetLastError());
2879 ok(size == (lstrlenW(buf) + 1) * sizeof(WCHAR), "size = %u\n", size);
2880 ok(index == 0, "index = %u\n", index);
2881
2882 WinHttpCloseHandle(req);
2883 WinHttpCloseHandle(con);
2884 WinHttpCloseHandle(ses);
2885 }
2886
test_large_data_authentication(int port)2887 static void test_large_data_authentication(int port)
2888 {
2889 static const WCHAR largeauthW[] = {'/','l','a','r','g','e','a','u','t','h',0};
2890 static const WCHAR getW[] = {'G','E','T',0};
2891 static WCHAR userW[] = {'u','s','e','r',0};
2892 static WCHAR passW[] = {'p','w','d',0};
2893 HINTERNET ses, con, req;
2894 DWORD status, size;
2895 BOOL ret;
2896
2897 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2898 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2899
2900 con = WinHttpConnect(ses, localhostW, port, 0);
2901 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2902
2903 req = WinHttpOpenRequest(con, getW, largeauthW, NULL, NULL, NULL, 0);
2904 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2905
2906 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
2907 ok(ret, "expected success\n");
2908
2909 ret = WinHttpReceiveResponse(req, NULL);
2910 ok(ret, "expected success\n");
2911
2912 size = sizeof(status);
2913 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL,
2914 &status, &size, NULL);
2915 ok(ret, "expected success\n");
2916 ok(status == HTTP_STATUS_DENIED, "got %d\n", status);
2917
2918 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, userW, passW, NULL);
2919 ok(ret, "expected success\n");
2920
2921 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
2922 ok(ret, "expected success %d\n", GetLastError());
2923
2924 ret = WinHttpReceiveResponse(req, NULL);
2925 ok(ret, "expected success\n");
2926
2927 size = sizeof(status);
2928 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL,
2929 &status, &size, NULL);
2930 ok(ret, "expected success\n");
2931 ok(status == HTTP_STATUS_OK, "got %d\n", status);
2932
2933 WinHttpCloseHandle(req);
2934 WinHttpCloseHandle(con);
2935 WinHttpCloseHandle(ses);
2936 }
2937
test_no_headers(int port)2938 static void test_no_headers(int port)
2939 {
2940 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2941 HINTERNET ses, con, req;
2942 DWORD error;
2943 BOOL ret;
2944
2945 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2946 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2947
2948 con = WinHttpConnect(ses, localhostW, port, 0);
2949 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2950
2951 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2952 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2953
2954 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2955 if (!ret)
2956 {
2957 error = GetLastError();
2958 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2959 }
2960 else
2961 {
2962 SetLastError(0xdeadbeef);
2963 ret = WinHttpReceiveResponse(req, NULL);
2964 error = GetLastError();
2965 ok(!ret, "expected failure\n");
2966 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
2967 }
2968
2969 WinHttpCloseHandle(req);
2970 WinHttpCloseHandle(con);
2971 WinHttpCloseHandle(ses);
2972 }
2973
test_no_content(int port)2974 static void test_no_content(int port)
2975 {
2976 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2977 HINTERNET ses, con, req;
2978 char buf[128];
2979 DWORD size, len = sizeof(buf), bytes_read, status;
2980 BOOL ret;
2981
2982 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
2983 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2984
2985 con = WinHttpConnect(ses, localhostW, port, 0);
2986 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2987
2988 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0);
2989 ok(req != NULL, "failed to open a request %u\n", GetLastError());
2990
2991 size = 12345;
2992 SetLastError(0xdeadbeef);
2993 ret = WinHttpQueryDataAvailable(req, &size);
2994 todo_wine {
2995 ok(!ret, "expected error\n");
2996 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE,
2997 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2998 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
2999 "expected 12345, got %u\n", size);
3000 }
3001
3002 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3003 ok(ret, "expected success\n");
3004
3005 ret = WinHttpReceiveResponse(req, NULL);
3006 ok(ret, "expected success\n");
3007
3008 status = 0xdeadbeef;
3009 size = sizeof(status);
3010 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
3011 NULL, &status, &size, NULL);
3012 ok(ret, "expected success\n");
3013 ok(status == HTTP_STATUS_NO_CONTENT, "expected status 204, got %d\n", status);
3014
3015 SetLastError(0xdeadbeef);
3016 size = sizeof(status);
3017 status = 12345;
3018 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
3019 NULL, &status, &size, 0);
3020 ok(!ret, "expected no content-length header\n");
3021 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError());
3022 ok(status == 12345, "expected 0, got %d\n", status);
3023
3024 SetLastError(0xdeadbeef);
3025 size = 12345;
3026 ret = WinHttpQueryDataAvailable(req, &size);
3027 ok(ret, "expected success\n");
3028 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
3029 "wrong error %u\n", GetLastError());
3030 ok(!size, "expected 0, got %u\n", size);
3031
3032 SetLastError(0xdeadbeef);
3033 ret = WinHttpReadData(req, buf, len, &bytes_read);
3034 ok(ret, "expected success\n");
3035 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
3036 "wrong error %u\n", GetLastError());
3037 ok(!bytes_read, "expected 0, got %u\n", bytes_read);
3038
3039 size = 12345;
3040 ret = WinHttpQueryDataAvailable(req, &size);
3041 ok(ret, "expected success\n");
3042 ok(size == 0, "expected 0, got %d\n", size);
3043
3044 WinHttpCloseHandle(req);
3045
3046 size = 12345;
3047 SetLastError(0xdeadbeef);
3048 ret = WinHttpQueryDataAvailable(req, &size);
3049 ok(!ret, "expected error\n");
3050 ok(GetLastError() == ERROR_INVALID_HANDLE,
3051 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
3052 ok(size == 12345, "expected 12345, got %u\n", size);
3053
3054 WinHttpCloseHandle(con);
3055 WinHttpCloseHandle(ses);
3056 }
3057
test_head_request(int port)3058 static void test_head_request(int port)
3059 {
3060 static const WCHAR verbW[] = {'H','E','A','D',0};
3061 static const WCHAR headW[] = {'/','h','e','a','d',0};
3062 HINTERNET ses, con, req;
3063 char buf[128];
3064 DWORD size, len, count, status;
3065 BOOL ret;
3066
3067 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3068 ok(ses != NULL, "failed to open session %u\n", GetLastError());
3069
3070 con = WinHttpConnect(ses, localhostW, port, 0);
3071 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
3072
3073 req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0);
3074 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3075
3076 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3077 ok(ret, "failed to send request %u\n", GetLastError());
3078
3079 ret = WinHttpReceiveResponse(req, NULL);
3080 ok(ret, "failed to receive response %u\n", GetLastError());
3081
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, "failed to get status code %u\n", GetLastError());
3087 ok(status == HTTP_STATUS_OK, "got %u\n", status);
3088
3089 len = 0xdeadbeef;
3090 size = sizeof(len);
3091 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
3092 NULL, &len, &size, 0);
3093 ok(ret, "failed to get content-length header %u\n", GetLastError());
3094 ok(len == HTTP_STATUS_CONTINUE, "got %u\n", len);
3095
3096 count = 0xdeadbeef;
3097 ret = WinHttpQueryDataAvailable(req, &count);
3098 ok(ret, "failed to query data available %u\n", GetLastError());
3099 ok(!count, "got %u\n", count);
3100
3101 len = sizeof(buf);
3102 count = 0xdeadbeef;
3103 ret = WinHttpReadData(req, buf, len, &count);
3104 ok(ret, "failed to read data %u\n", GetLastError());
3105 ok(!count, "got %u\n", count);
3106
3107 count = 0xdeadbeef;
3108 ret = WinHttpQueryDataAvailable(req, &count);
3109 ok(ret, "failed to query data available %u\n", GetLastError());
3110 ok(!count, "got %u\n", count);
3111
3112 WinHttpCloseHandle(req);
3113 WinHttpCloseHandle(con);
3114 WinHttpCloseHandle(ses);
3115 }
3116
test_not_modified(int port)3117 static void test_not_modified(int port)
3118 {
3119 static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
3120 static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
3121 static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
3122 BOOL ret;
3123 HINTERNET session, request, connection;
3124 DWORD index, len, status, size, start = GetTickCount();
3125 SYSTEMTIME st;
3126 WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32];
3127
3128 memcpy(today, ifmodifiedW, sizeof(ifmodifiedW));
3129 GetSystemTime(&st);
3130 WinHttpTimeFromSystemTime(&st, &today[ARRAY_SIZE(ifmodifiedW)]);
3131
3132 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY,
3133 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
3134 ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError());
3135
3136 connection = WinHttpConnect(session, localhostW, port, 0);
3137 ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError());
3138
3139 request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER,
3140 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
3141 ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError());
3142
3143 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0);
3144 ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError());
3145
3146 ret = WinHttpReceiveResponse(request, NULL);
3147 ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError());
3148
3149 index = 0;
3150 len = sizeof(buffer);
3151 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3152 ifmodified2W, buffer, &len, &index);
3153 ok(ret, "failed to get header %u\n", GetLastError());
3154
3155 status = 0xdeadbeef;
3156 size = sizeof(status);
3157 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER,
3158 NULL, &status, &size, NULL);
3159 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
3160 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status);
3161
3162 size = 0xdeadbeef;
3163 ret = WinHttpQueryDataAvailable(request, &size);
3164 ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
3165 ok(!size, "got %u\n", size);
3166
3167 WinHttpCloseHandle(request);
3168 WinHttpCloseHandle(connection);
3169 WinHttpCloseHandle(session);
3170 start = GetTickCount() - start;
3171 ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start);
3172 }
3173
test_bad_header(int port)3174 static void test_bad_header( int port )
3175 {
3176 static const WCHAR bad_headerW[] =
3177 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
3178 't','e','x','t','/','h','t','m','l','\n','\r',0};
3179 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
3180 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
3181 WCHAR buffer[32];
3182 HINTERNET ses, con, req;
3183 DWORD index, len;
3184 BOOL ret;
3185
3186 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3187 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3188
3189 con = WinHttpConnect( ses, localhostW, port, 0 );
3190 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3191
3192 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
3193 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3194
3195 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
3196 ok( ret, "failed to add header %u\n", GetLastError() );
3197
3198 index = 0;
3199 buffer[0] = 0;
3200 len = sizeof(buffer);
3201 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
3202 content_typeW, buffer, &len, &index );
3203 ok( ret, "failed to query headers %u\n", GetLastError() );
3204 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
3205 ok( index == 1, "index = %u\n", index );
3206
3207 WinHttpCloseHandle( req );
3208 WinHttpCloseHandle( con );
3209 WinHttpCloseHandle( ses );
3210 }
3211
test_multiple_reads(int port)3212 static void test_multiple_reads(int port)
3213 {
3214 static const WCHAR bigW[] = {'b','i','g',0};
3215 HINTERNET ses, con, req;
3216 DWORD total_len = 0;
3217 BOOL ret;
3218
3219 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
3220 ok(ses != NULL, "failed to open session %u\n", GetLastError());
3221
3222 con = WinHttpConnect(ses, localhostW, port, 0);
3223 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
3224
3225 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
3226 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3227
3228 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3229 ok(ret, "failed to send request %u\n", GetLastError());
3230
3231 trace("waiting for response\n");
3232 ret = WinHttpReceiveResponse(req, NULL);
3233 ok(ret == TRUE, "expected success\n");
3234
3235 trace("finished waiting for response\n");
3236
3237 for (;;)
3238 {
3239 DWORD len = 0xdeadbeef;
3240 ret = WinHttpQueryDataAvailable( req, &len );
3241 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3242 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3243 if (len)
3244 {
3245 DWORD bytes_read;
3246 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
3247
3248 ret = WinHttpReadData( req, buf, len, &bytes_read );
3249 ok(ret, "WinHttpReadData failed: %u.\n", GetLastError());
3250 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
3251
3252 HeapFree( GetProcessHeap(), 0, buf );
3253 if (!bytes_read) break;
3254 total_len += bytes_read;
3255 trace("read bytes %u, total_len: %u\n", bytes_read, total_len);
3256 }
3257 if (!len) break;
3258 }
3259 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
3260
3261 WinHttpCloseHandle(req);
3262 WinHttpCloseHandle(con);
3263 WinHttpCloseHandle(ses);
3264 }
3265
test_cookies(int port)3266 static void test_cookies( int port )
3267 {
3268 static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0};
3269 static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0};
3270 static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0};
3271 static const WCHAR cookie4W[] = {'/','c','o','o','k','i','e','4',0};
3272 static const WCHAR cookie5W[] = {'/','c','o','o','k','i','e','5',0};
3273 static const WCHAR cookieheaderW[] =
3274 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
3275 HINTERNET ses, con, req;
3276 DWORD status, size;
3277 BOOL ret;
3278
3279 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3280 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3281
3282 con = WinHttpConnect( ses, localhostW, port, 0 );
3283 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3284
3285 req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 );
3286 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3287
3288 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3289 ok( ret, "failed to send request %u\n", GetLastError() );
3290
3291 ret = WinHttpReceiveResponse( req, NULL );
3292 ok( ret, "failed to receive response %u\n", GetLastError() );
3293
3294 status = 0xdeadbeef;
3295 size = sizeof(status);
3296 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3297 ok( ret, "failed to query status code %u\n", GetLastError() );
3298 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3299
3300 WinHttpCloseHandle( req );
3301
3302 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
3303 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3304
3305 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3306 ok( ret, "failed to send request %u\n", GetLastError() );
3307
3308 ret = WinHttpReceiveResponse( req, NULL );
3309 ok( ret, "failed to receive response %u\n", GetLastError() );
3310
3311 status = 0xdeadbeef;
3312 size = sizeof(status);
3313 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3314 ok( ret, "failed to query status code %u\n", GetLastError() );
3315 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3316
3317 WinHttpCloseHandle( req );
3318 WinHttpCloseHandle( con );
3319
3320 con = WinHttpConnect( ses, localhostW, port, 0 );
3321 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3322
3323 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
3324 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3325
3326 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3327 ok( ret, "failed to send request %u\n", GetLastError() );
3328
3329 ret = WinHttpReceiveResponse( req, NULL );
3330 ok( ret, "failed to receive response %u\n", GetLastError() );
3331
3332 status = 0xdeadbeef;
3333 size = sizeof(status);
3334 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3335 ok( ret, "failed to query status code %u\n", GetLastError() );
3336 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3337
3338 WinHttpCloseHandle( req );
3339
3340 req = WinHttpOpenRequest( con, NULL, cookie3W, NULL, NULL, NULL, 0 );
3341 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3342
3343 ret = WinHttpSendRequest( req, cookieheaderW, ~0u, NULL, 0, 0, 0 );
3344 ok( ret, "failed to send request %u\n", GetLastError() );
3345
3346 ret = WinHttpReceiveResponse( req, NULL );
3347 ok( ret, "failed to receive response %u\n", GetLastError() );
3348
3349 status = 0xdeadbeef;
3350 size = sizeof(status);
3351 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3352 ok( ret, "failed to query status code %u\n", GetLastError() );
3353 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST), "request failed unexpectedly %u\n", status );
3354
3355 WinHttpCloseHandle( req );
3356 WinHttpCloseHandle( con );
3357 WinHttpCloseHandle( ses );
3358
3359 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3360 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3361
3362 con = WinHttpConnect( ses, localhostW, port, 0 );
3363 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3364
3365 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
3366 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3367
3368 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3369 ok( ret, "failed to send request %u\n", GetLastError() );
3370
3371 ret = WinHttpReceiveResponse( req, NULL );
3372 ok( ret, "failed to receive response %u\n", GetLastError() );
3373
3374 status = 0xdeadbeef;
3375 size = sizeof(status);
3376 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3377 ok( ret, "failed to query status code %u\n", GetLastError() );
3378 ok( status == HTTP_STATUS_BAD_REQUEST, "request failed unexpectedly %u\n", status );
3379
3380 WinHttpCloseHandle( req );
3381 WinHttpCloseHandle( con );
3382 WinHttpCloseHandle( ses );
3383
3384 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3385 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3386
3387 con = WinHttpConnect( ses, localhostW, port, 0 );
3388 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3389
3390 req = WinHttpOpenRequest( con, NULL, cookie4W, NULL, NULL, NULL, 0 );
3391 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3392
3393 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3394 ok( ret, "failed to send request %u\n", GetLastError() );
3395
3396 ret = WinHttpReceiveResponse( req, NULL );
3397 ok( ret, "failed to receive response %u\n", GetLastError() );
3398
3399 status = 0xdeadbeef;
3400 size = sizeof(status);
3401 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3402 ok( ret, "failed to query status code %u\n", GetLastError() );
3403 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3404 WinHttpCloseHandle( req );
3405
3406 req = WinHttpOpenRequest( con, NULL, cookie5W, NULL, NULL, NULL, 0 );
3407 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3408
3409 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3410 ok( ret, "failed to send request %u\n", GetLastError() );
3411
3412 ret = WinHttpReceiveResponse( req, NULL );
3413 ok( ret, "failed to receive response %u\n", GetLastError() );
3414
3415 status = 0xdeadbeef;
3416 size = sizeof(status);
3417 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3418 ok( ret, "failed to query status code %u\n", GetLastError() );
3419 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST) /* < win7 */,
3420 "request failed unexpectedly %u\n", status );
3421
3422 WinHttpCloseHandle( req );
3423 WinHttpCloseHandle( con );
3424 WinHttpCloseHandle( ses );
3425 }
3426
do_request(HINTERNET con,const WCHAR * obj,DWORD flags)3427 static void do_request( HINTERNET con, const WCHAR *obj, DWORD flags )
3428 {
3429 HINTERNET req;
3430 DWORD status, size;
3431 BOOL ret;
3432
3433 req = WinHttpOpenRequest( con, NULL, obj, NULL, NULL, NULL, flags );
3434 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3435
3436 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3437 ok( ret, "failed to send request %u\n", GetLastError() );
3438
3439 ret = WinHttpReceiveResponse( req, NULL );
3440 ok( ret, "failed to receive response %u\n", GetLastError() );
3441
3442 status = 0xdeadbeef;
3443 size = sizeof(status);
3444 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3445 ok( ret, "failed to query status code %u\n", GetLastError() );
3446 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST) /* < win7 */,
3447 "request %s with flags %08x failed %u\n", wine_dbgstr_w(obj), flags, status );
3448 WinHttpCloseHandle( req );
3449 }
3450
test_request_path_escapes(int port)3451 static void test_request_path_escapes( int port )
3452 {
3453 static const WCHAR objW[] =
3454 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','o','n','e','?',0x1f,0x7f,' ','!','"','#',
3455 '$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`',
3456 '{','|','}','~','\r','\n',0};
3457 static const WCHAR obj2W[] =
3458 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','t','w','o','?',0x1f,0x7f,' ','!','"','#',
3459 '$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_','`',
3460 '{','|','}','~','\r','\n',0};
3461 static const WCHAR obj3W[] =
3462 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','t','h','r','e','e','?',0x1f,0x7f,' ','!',
3463 '"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^',
3464 '_','`','{','|','}','~','\r','\n',0};
3465 static const WCHAR obj4W[] =
3466 {'/','e','s','c','a','p','e','\r','\n',0x1f,0x7f,'<',' ','%','f','o','u','r','?',0x1f,0x7f,' ','!','"',
3467 '#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\\',']','^','_',
3468 '`','{','|','}','~','\r','\n',0};
3469 static const WCHAR obj5W[] =
3470 {'/','e','s','c','a','p','e','&','t','e','x','t','=','o','n','e',0x80,0x7f,0x7e,0};
3471 static const WCHAR obj6W[] =
3472 {'/','e','s','c','a','p','e','&','t','e','x','t','=','t','w','o',0x80,0x7f,0x7e,0};
3473 static const WCHAR obj7W[] =
3474 {'/','e','s','c','a','p','e','&','t','e','x','t','=',0x541b,0x306e,0x540d,0x306f,0};
3475 HINTERNET ses, con;
3476
3477 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3478 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3479
3480 con = WinHttpConnect( ses, localhostW, port, 0 );
3481 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3482
3483 do_request( con, objW, 0 );
3484 do_request( con, obj2W, WINHTTP_FLAG_ESCAPE_PERCENT );
3485 do_request( con, obj3W, WINHTTP_FLAG_ESCAPE_DISABLE );
3486 do_request( con, obj4W, WINHTTP_FLAG_ESCAPE_DISABLE_QUERY );
3487 do_request( con, obj5W, 0 );
3488 do_request( con, obj6W, WINHTTP_FLAG_ESCAPE_DISABLE );
3489 do_request( con, obj7W, WINHTTP_FLAG_ESCAPE_DISABLE );
3490
3491 WinHttpCloseHandle( con );
3492 WinHttpCloseHandle( ses );
3493 }
3494
test_connection_info(int port)3495 static void test_connection_info( int port )
3496 {
3497 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
3498 HINTERNET ses, con, req;
3499 WINHTTP_CONNECTION_INFO info;
3500 DWORD size, error;
3501 BOOL ret;
3502
3503 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 );
3504 ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3505
3506 con = WinHttpConnect( ses, localhostW, port, 0 );
3507 ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3508
3509 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 );
3510 ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3511
3512 size = sizeof(info);
3513 SetLastError( 0xdeadbeef );
3514 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
3515 error = GetLastError();
3516 if (!ret && error == ERROR_INVALID_PARAMETER)
3517 {
3518 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
3519 return;
3520 }
3521 ok( !ret, "unexpected success\n" );
3522 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error );
3523
3524 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3525 ok( ret, "failed to send request %u\n", GetLastError() );
3526
3527 size = 0;
3528 SetLastError( 0xdeadbeef );
3529 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
3530 error = GetLastError();
3531 ok( !ret, "unexpected success\n" );
3532 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error );
3533
3534 size = sizeof(info);
3535 memset( &info, 0, sizeof(info) );
3536 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
3537 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
3538 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize );
3539
3540 ret = WinHttpReceiveResponse( req, NULL );
3541 ok( ret, "failed to receive response %u\n", GetLastError() );
3542
3543 size = sizeof(info);
3544 memset( &info, 0, sizeof(info) );
3545 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size );
3546 ok( ret, "failed to retrieve connection info %u\n", GetLastError() );
3547 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize );
3548
3549 WinHttpCloseHandle( req );
3550 WinHttpCloseHandle( con );
3551 WinHttpCloseHandle( ses );
3552 }
3553
test_passport_auth(int port)3554 static void test_passport_auth( int port )
3555 {
3556 static const WCHAR passportW[] =
3557 {'/','p','a','s','s','p','o','r','t',0};
3558 static const WCHAR foundW[] =
3559 {'F','o','u','n','d',0};
3560 static const WCHAR unauthorizedW[] =
3561 {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3562 static const WCHAR headersW[] =
3563 {'H','T','T','P','/','1','.','1',' ','4','0','1',' ','F','o','u','n','d','\r','\n',
3564 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',':',' ','0','\r','\n',
3565 'L','o','c','a','t','i','o','n',':',' ','/','\r','\n',
3566 'W','W','W','-','A','u','t','h','e','n','t','i','c','a','t','e',':',' ',
3567 'P','a','s','s','p','o','r','t','1','.','4','\r','\n','\r','\n',0};
3568 HINTERNET ses, con, req;
3569 DWORD status, size, option;
3570 WCHAR buf[128];
3571 BOOL ret;
3572
3573 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
3574 ok( ses != NULL, "got %u\n", GetLastError() );
3575
3576 option = WINHTTP_ENABLE_PASSPORT_AUTH;
3577 ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH, &option, sizeof(option) );
3578 ok( ret, "got %u\n", GetLastError() );
3579
3580 con = WinHttpConnect( ses, localhostW, port, 0 );
3581 ok( con != NULL, "got %u\n", GetLastError() );
3582
3583 req = WinHttpOpenRequest( con, NULL, passportW, NULL, NULL, NULL, 0 );
3584 ok( req != NULL, "got %u\n", GetLastError() );
3585
3586 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3587 ok( ret, "got %u\n", GetLastError() );
3588
3589 ret = WinHttpReceiveResponse( req, NULL );
3590 ok( ret || broken(!ret && GetLastError() == ERROR_WINHTTP_LOGIN_FAILURE) /* winxp */, "got %u\n", GetLastError() );
3591 if (!ret && GetLastError() == ERROR_WINHTTP_LOGIN_FAILURE)
3592 {
3593 win_skip("no support for Passport redirects\n");
3594 goto cleanup;
3595 }
3596
3597 status = 0xdeadbeef;
3598 size = sizeof(status);
3599 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
3600 ok( ret, "got %u\n", GetLastError() );
3601 ok( status == HTTP_STATUS_DENIED, "got %u\n", status );
3602
3603 buf[0] = 0;
3604 size = sizeof(buf);
3605 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_TEXT, NULL, buf, &size, NULL );
3606 ok( ret, "got %u\n", GetLastError() );
3607 ok( !lstrcmpW(foundW, buf) || broken(!lstrcmpW(unauthorizedW, buf)) /* < win7 */, "got %s\n", wine_dbgstr_w(buf) );
3608
3609 buf[0] = 0;
3610 size = sizeof(buf);
3611 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buf, &size, NULL );
3612 ok( ret || broken(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) /* < win7 */, "got %u\n", GetLastError() );
3613 if (ret)
3614 {
3615 ok( size == lstrlenW(headersW) * sizeof(WCHAR), "got %u\n", size );
3616 ok( !lstrcmpW(headersW, buf), "got %s\n", wine_dbgstr_w(buf) );
3617 }
3618
3619 cleanup:
3620 WinHttpCloseHandle( req );
3621 WinHttpCloseHandle( con );
3622 WinHttpCloseHandle( ses );
3623 }
3624
test_credentials(void)3625 static void test_credentials(void)
3626 {
3627 static WCHAR userW[] = {'u','s','e','r',0};
3628 static WCHAR passW[] = {'p','a','s','s',0};
3629 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
3630 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
3631 HINTERNET ses, con, req;
3632 DWORD size, error;
3633 WCHAR buffer[32];
3634 BOOL ret;
3635
3636 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
3637 ok(ses != NULL, "failed to open session %u\n", GetLastError());
3638
3639 con = WinHttpConnect(ses, localhostW, 0, 0);
3640 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
3641
3642 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
3643 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3644
3645 size = ARRAY_SIZE(buffer);
3646 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
3647 ok(ret, "failed to query proxy username %u\n", GetLastError());
3648 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3649 ok(!size, "expected 0, got %u\n", size);
3650
3651 size = ARRAY_SIZE(buffer);
3652 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
3653 ok(ret, "failed to query proxy password %u\n", GetLastError());
3654 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3655 ok(!size, "expected 0, got %u\n", size);
3656
3657 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
3658 ok(ret, "failed to set username %u\n", GetLastError());
3659
3660 size = ARRAY_SIZE(buffer);
3661 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
3662 ok(ret, "failed to query proxy username %u\n", GetLastError());
3663 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3664 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
3665
3666 size = ARRAY_SIZE(buffer);
3667 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3668 ok(ret, "failed to query username %u\n", GetLastError());
3669 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3670 ok(!size, "expected 0, got %u\n", size);
3671
3672 size = ARRAY_SIZE(buffer);
3673 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3674 ok(ret, "failed to query password %u\n", GetLastError());
3675 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3676 ok(!size, "expected 0, got %u\n", size);
3677
3678 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
3679 ok(ret, "failed to set proxy password %u\n", GetLastError());
3680
3681 size = ARRAY_SIZE(buffer);
3682 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
3683 ok(ret, "failed to query proxy password %u\n", GetLastError());
3684 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3685 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
3686
3687 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
3688 ok(ret, "failed to set username %u\n", GetLastError());
3689
3690 size = ARRAY_SIZE(buffer);
3691 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3692 ok(ret, "failed to query username %u\n", GetLastError());
3693 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3694 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
3695
3696 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
3697 ok(ret, "failed to set password %u\n", GetLastError());
3698
3699 size = ARRAY_SIZE(buffer);
3700 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3701 ok(ret, "failed to query password %u\n", GetLastError());
3702 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
3703 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
3704
3705 WinHttpCloseHandle(req);
3706
3707 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
3708 ok(req != NULL, "failed to open a request %u\n", GetLastError());
3709
3710 SetLastError(0xdeadbeef);
3711 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
3712 error = GetLastError();
3713 ok(!ret, "expected failure\n");
3714 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3715
3716 SetLastError(0xdeadbeef);
3717 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
3718 error = GetLastError();
3719 ok(!ret, "expected failure\n");
3720 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
3721
3722 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
3723 ok(ret, "failed to set credentials %u\n", GetLastError());
3724
3725 size = ARRAY_SIZE(buffer);
3726 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
3727 ok(ret, "failed to query username %u\n", GetLastError());
3728 todo_wine {
3729 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3730 ok(!size, "expected 0, got %u\n", size);
3731 }
3732
3733 size = ARRAY_SIZE(buffer);
3734 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
3735 ok(ret, "failed to query password %u\n", GetLastError());
3736 todo_wine {
3737 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
3738 ok(!size, "expected 0, got %u\n", size);
3739 }
3740
3741 WinHttpCloseHandle(req);
3742 WinHttpCloseHandle(con);
3743 WinHttpCloseHandle(ses);
3744 }
3745
test_IWinHttpRequest(int port)3746 static void test_IWinHttpRequest(int port)
3747 {
3748 static const WCHAR data_start[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'};
3749 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
3750 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
3751 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3752 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
3753 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
3754 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
3755 static const WCHAR method1W[] = {'G','E','T',0};
3756 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
3757 static const WCHAR method3W[] = {'P','O','S','T',0};
3758 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
3759 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
3760 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
3761 static const WCHAR dateW[] = {'D','a','t','e',0};
3762 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
3763 static const WCHAR utf8W[] = {'u','t','f','-','8',0};
3764 static const WCHAR unauthW[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0};
3765 HRESULT hr;
3766 IWinHttpRequest *req;
3767 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
3768 BSTR date, today, connection, value = NULL;
3769 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp;
3770 VARIANT_BOOL succeeded;
3771 LONG status;
3772 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
3773 SYSTEMTIME st;
3774 IStream *stream, *stream2;
3775 LARGE_INTEGER pos;
3776 char buf[128];
3777 WCHAR bufW[128];
3778 DWORD count;
3779
3780 GetSystemTime( &st );
3781 WinHttpTimeFromSystemTime( &st, todayW );
3782
3783 CoInitialize( NULL );
3784 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3785 ok( hr == S_OK, "got %08x\n", hr );
3786
3787 V_VT( &empty ) = VT_ERROR;
3788 V_ERROR( &empty ) = 0xdeadbeef;
3789
3790 V_VT( &async ) = VT_BOOL;
3791 V_BOOL( &async ) = VARIANT_FALSE;
3792
3793 method = SysAllocString( method3W );
3794 url = SysAllocString( url3W );
3795 hr = IWinHttpRequest_Open( req, method, url, async );
3796 ok( hr == S_OK, "got %08x\n", hr );
3797 SysFreeString( method );
3798 SysFreeString( url );
3799
3800 V_VT( &data ) = VT_BSTR;
3801 V_BSTR( &data ) = SysAllocString( test_dataW );
3802 hr = IWinHttpRequest_Send( req, data );
3803 ok( hr == S_OK || hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE ), "got %08x\n", hr );
3804 SysFreeString( V_BSTR( &data ) );
3805 if (hr != S_OK) goto done;
3806
3807 hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
3808 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3809
3810 method = SysAllocString( method1W );
3811 hr = IWinHttpRequest_Open( req, method, NULL, empty );
3812 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3813
3814 hr = IWinHttpRequest_Open( req, method, NULL, async );
3815 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3816
3817 url = SysAllocString( url1W );
3818 hr = IWinHttpRequest_Open( req, NULL, url, empty );
3819 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3820
3821 hr = IWinHttpRequest_Abort( req );
3822 ok( hr == S_OK, "got %08x\n", hr );
3823
3824 hr = IWinHttpRequest_Open( req, method, url, empty );
3825 ok( hr == S_OK, "got %08x\n", hr );
3826
3827 hr = IWinHttpRequest_Abort( req );
3828 ok( hr == S_OK, "got %08x\n", hr );
3829
3830 IWinHttpRequest_Release( req );
3831
3832 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3833 ok( hr == S_OK, "got %08x\n", hr );
3834
3835 SysFreeString( url );
3836 url = SysAllocString( url2W );
3837 hr = IWinHttpRequest_Open( req, method, url, async );
3838 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3839
3840 SysFreeString( method );
3841 method = SysAllocString( method2W );
3842 hr = IWinHttpRequest_Open( req, method, url, async );
3843 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
3844
3845 SysFreeString( method );
3846 method = SysAllocString( method1W );
3847 SysFreeString( url );
3848 url = SysAllocString( url1W );
3849 V_VT( &async ) = VT_ERROR;
3850 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND;
3851 hr = IWinHttpRequest_Open( req, method, url, async );
3852 ok( hr == S_OK, "got %08x\n", hr );
3853
3854 V_VT( &cp ) = VT_ERROR;
3855 V_ERROR( &cp ) = 0xdeadbeef;
3856 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3857 ok( hr == S_OK, "got %08x\n", hr );
3858 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3859 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3860
3861 V_VT( &cp ) = VT_UI4;
3862 V_UI4( &cp ) = CP_ACP;
3863 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3864 ok( hr == S_OK, "got %08x\n", hr );
3865
3866 V_VT( &cp ) = VT_ERROR;
3867 V_ERROR( &cp ) = 0xdeadbeef;
3868 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3869 ok( hr == S_OK, "got %08x\n", hr );
3870 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3871 ok( V_I4( &cp ) == CP_ACP, "got %u\n", V_I4( &cp ) );
3872
3873 value = SysAllocString( utf8W );
3874 V_VT( &cp ) = VT_BSTR;
3875 V_BSTR( &cp ) = value;
3876 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp );
3877 ok( hr == S_OK, "got %08x\n", hr );
3878 SysFreeString( value );
3879
3880 V_VT( &cp ) = VT_ERROR;
3881 V_ERROR( &cp ) = 0xdeadbeef;
3882 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp );
3883 ok( hr == S_OK, "got %08x\n", hr );
3884 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) );
3885 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) );
3886
3887 hr = IWinHttpRequest_Abort( req );
3888 ok( hr == S_OK, "got %08x\n", hr );
3889
3890 hr = IWinHttpRequest_Send( req, empty );
3891 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3892
3893 hr = IWinHttpRequest_Abort( req );
3894 ok( hr == S_OK, "got %08x\n", hr );
3895
3896 IWinHttpRequest_Release( req );
3897
3898 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
3899 ok( hr == S_OK, "got %08x\n", hr );
3900
3901 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3902 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3903
3904 hr = IWinHttpRequest_get_ResponseText( req, &response );
3905 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3906
3907 hr = IWinHttpRequest_get_Status( req, NULL );
3908 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3909
3910 hr = IWinHttpRequest_get_Status( req, &status );
3911 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3912
3913 hr = IWinHttpRequest_get_StatusText( req, NULL );
3914 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3915
3916 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3917 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3918
3919 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3920 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3921
3922 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3923 ok( hr == S_OK, "got %08x\n", hr );
3924
3925 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
3926 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3927
3928 VariantInit( &proxy_server );
3929 V_VT( &proxy_server ) = VT_ERROR;
3930 VariantInit( &bypass_list );
3931 V_VT( &bypass_list ) = VT_ERROR;
3932 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3933 ok( hr == S_OK, "got %08x\n", hr );
3934
3935 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
3936 ok( hr == S_OK, "got %08x\n", hr );
3937
3938 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
3939 ok( hr == S_OK, "got %08x\n", hr );
3940
3941 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
3942 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3943
3944 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
3945 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3946
3947 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
3948 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3949
3950 connection = SysAllocString( connectionW );
3951 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
3952 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3953
3954 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
3955 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3956
3957 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
3958 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3959
3960 date = SysAllocString( dateW );
3961 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
3962 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3963
3964 today = SysAllocString( todayW );
3965 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
3966 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
3967
3968 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
3969 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3970
3971 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
3972 ok( hr == S_OK, "got %08x\n", hr );
3973
3974 SysFreeString( method );
3975 method = SysAllocString( method1W );
3976 SysFreeString( url );
3977 url = SysAllocString( url1W );
3978 hr = IWinHttpRequest_Open( req, method, url, async );
3979 ok( hr == S_OK, "got %08x\n", hr );
3980
3981 hr = IWinHttpRequest_get_ResponseText( req, NULL );
3982 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3983
3984 hr = IWinHttpRequest_get_ResponseText( req, &response );
3985 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3986
3987 hr = IWinHttpRequest_get_Status( req, &status );
3988 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3989
3990 hr = IWinHttpRequest_get_StatusText( req, &status_text );
3991 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
3992
3993 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
3994 ok( hr == E_INVALIDARG, "got %08x\n", hr );
3995
3996 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
3997 ok( hr == S_OK, "got %08x\n", hr );
3998
3999 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
4000 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4001
4002 username = SysAllocString( usernameW );
4003 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
4004 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4005
4006 password = SysAllocString( passwordW );
4007 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
4008 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4009
4010 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
4011 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4012
4013 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4014 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4015
4016 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4017 ok( hr == S_OK, "got %08x\n", hr );
4018
4019 V_VT( &proxy_server ) = VT_BSTR;
4020 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
4021 V_VT( &bypass_list ) = VT_BSTR;
4022 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
4023 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4024 ok( hr == S_OK, "got %08x\n", hr );
4025
4026 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
4027 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4028
4029 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4030 ok( hr == S_OK, "got %08x\n", hr );
4031
4032 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4033 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
4034
4035 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4036 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
4037
4038 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4039 ok( hr == S_OK, "got %08x\n", hr );
4040
4041 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
4042 ok( hr == S_OK, "got %08x\n", hr );
4043
4044 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4045 ok( hr == S_OK, "got %08x\n", hr );
4046
4047 hr = IWinHttpRequest_Send( req, empty );
4048 ok( hr == S_OK, "got %08x\n", hr );
4049
4050 hr = IWinHttpRequest_Send( req, empty );
4051 ok( hr == S_OK, "got %08x\n", hr );
4052
4053 hr = IWinHttpRequest_get_ResponseText( req, NULL );
4054 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4055
4056 hr = IWinHttpRequest_get_ResponseText( req, &response );
4057 ok( hr == S_OK, "got %08x\n", hr );
4058 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
4059 SysFreeString( response );
4060
4061 hr = IWinHttpRequest_get_Status( req, NULL );
4062 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4063
4064 status = 0;
4065 hr = IWinHttpRequest_get_Status( req, &status );
4066 ok( hr == S_OK, "got %08x\n", hr );
4067 trace("Status=%d\n", status);
4068
4069 hr = IWinHttpRequest_get_StatusText( req, NULL );
4070 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4071
4072 hr = IWinHttpRequest_get_StatusText( req, &status_text );
4073 ok( hr == S_OK, "got %08x\n", hr );
4074 trace("StatusText=%s\n", wine_dbgstr_w(status_text));
4075 SysFreeString( status_text );
4076
4077 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
4078 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4079
4080 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4081 ok( hr == S_OK, "got %08x\n", hr );
4082
4083 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4084 ok( hr == S_OK, "got %08x\n", hr );
4085
4086 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4087 ok( hr == S_OK, "got %08x\n", hr );
4088
4089 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
4090 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4091
4092 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4093 ok( hr == S_OK, "got %08x\n", hr );
4094 SysFreeString( headers );
4095
4096 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
4097 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4098
4099 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
4100 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4101
4102 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4103 ok( hr == S_OK, "got %08x\n", hr );
4104 SysFreeString( value );
4105
4106 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4107 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
4108
4109 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4110 ok( hr == S_OK, "got %08x\n", hr );
4111
4112 VariantInit( &timeout );
4113 V_VT( &timeout ) = VT_I4;
4114 V_I4( &timeout ) = 10;
4115 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
4116 ok( hr == S_OK, "got %08x\n", hr );
4117
4118 hr = IWinHttpRequest_get_Status( req, &status );
4119 ok( hr == S_OK, "got %08x\n", hr );
4120
4121 hr = IWinHttpRequest_get_StatusText( req, &status_text );
4122 ok( hr == S_OK, "got %08x\n", hr );
4123 SysFreeString( status_text );
4124
4125 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
4126 ok( hr == S_OK, "got %08x\n", hr );
4127
4128 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4129 ok( hr == S_OK, "got %08x\n", hr );
4130
4131 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4132 ok( hr == S_OK, "got %08x\n", hr );
4133
4134 hr = IWinHttpRequest_Send( req, empty );
4135 ok( hr == S_OK, "got %08x\n", hr );
4136
4137 hr = IWinHttpRequest_get_ResponseText( req, NULL );
4138 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4139
4140 hr = IWinHttpRequest_get_ResponseText( req, &response );
4141 ok( hr == S_OK, "got %08x\n", hr );
4142 SysFreeString( response );
4143
4144 hr = IWinHttpRequest_get_ResponseBody( req, NULL );
4145 ok( hr == E_INVALIDARG, "got %08x\n", hr );
4146
4147 VariantInit( &body );
4148 V_VT( &body ) = VT_ERROR;
4149 hr = IWinHttpRequest_get_ResponseBody( req, &body );
4150 ok( hr == S_OK, "got %08x\n", hr );
4151 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
4152
4153 hr = VariantClear( &body );
4154 ok( hr == S_OK, "got %08x\n", hr );
4155
4156 VariantInit( &body );
4157 V_VT( &body ) = VT_ERROR;
4158 hr = IWinHttpRequest_get_ResponseStream( req, &body );
4159 ok( hr == S_OK, "got %08x\n", hr );
4160 ok( V_VT( &body ) == VT_UNKNOWN, "got %08x\n", V_VT( &body ) );
4161
4162 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream );
4163 ok( hr == S_OK, "got %08x\n", hr );
4164 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" );
4165
4166 buf[0] = 0;
4167 count = 0xdeadbeef;
4168 hr = IStream_Read( stream, buf, 128, &count );
4169 ok( hr == S_OK, "got %08x\n", hr );
4170 ok( count != 0xdeadbeef, "count not set\n" );
4171 ok( buf[0], "no data\n" );
4172
4173 VariantInit( &body2 );
4174 V_VT( &body2 ) = VT_ERROR;
4175 hr = IWinHttpRequest_get_ResponseStream( req, &body2 );
4176 ok( hr == S_OK, "got %08x\n", hr );
4177 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %08x\n", V_VT( &body2 ) );
4178 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" );
4179
4180 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 );
4181 ok( hr == S_OK, "got %08x\n", hr );
4182 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" );
4183 IStream_Release( stream2 );
4184
4185 hr = VariantClear( &body );
4186 ok( hr == S_OK, "got %08x\n", hr );
4187
4188 hr = VariantClear( &body2 );
4189 ok( hr == S_OK, "got %08x\n", hr );
4190
4191 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
4192 ok( hr == S_OK, "got %08x\n", hr );
4193
4194 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
4195 ok( hr == S_OK, "got %08x\n", hr );
4196
4197 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
4198 ok( hr == S_OK, "got %08x\n", hr );
4199 SysFreeString( headers );
4200
4201 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
4202 ok( hr == S_OK, "got %08x\n", hr );
4203 SysFreeString( value );
4204
4205 hr = IWinHttpRequest_SetRequestHeader( req, date, today );
4206 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
4207
4208 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
4209 ok( hr == S_OK, "got %08x\n", hr );
4210
4211 hr = IWinHttpRequest_Send( req, empty );
4212 ok( hr == S_OK, "got %08x\n", hr );
4213
4214 hr = IWinHttpRequest_Abort( req );
4215 ok( hr == S_OK, "got %08x\n", hr );
4216
4217 hr = IWinHttpRequest_Abort( req );
4218 ok( hr == S_OK, "got %08x\n", hr );
4219
4220 IWinHttpRequest_Release( req );
4221
4222 pos.QuadPart = 0;
4223 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL );
4224 ok( hr == S_OK, "got %08x\n", hr );
4225
4226 buf[0] = 0;
4227 count = 0xdeadbeef;
4228 hr = IStream_Read( stream, buf, 128, &count );
4229 ok( hr == S_OK, "got %08x\n", hr );
4230 ok( count != 0xdeadbeef, "count not set\n" );
4231 ok( buf[0], "no data\n" );
4232 IStream_Release( stream );
4233
4234 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4235 ok( hr == S_OK, "got %08x\n", hr );
4236
4237 V_VT( &async ) = VT_I4;
4238 V_I4( &async ) = 1;
4239 hr = IWinHttpRequest_Open( req, method, url, async );
4240 ok( hr == S_OK, "got %08x\n", hr );
4241
4242 hr = IWinHttpRequest_Send( req, empty );
4243 ok( hr == S_OK, "got %08x\n", hr );
4244
4245 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
4246 ok( hr == S_OK, "got %08x\n", hr );
4247
4248 IWinHttpRequest_Release( req );
4249
4250 SysFreeString( method );
4251 SysFreeString( url );
4252 SysFreeString( username );
4253 SysFreeString( password );
4254 SysFreeString( connection );
4255 SysFreeString( date );
4256 SysFreeString( today );
4257 VariantClear( &proxy_server );
4258 VariantClear( &bypass_list );
4259
4260 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4261 ok( hr == S_OK, "got %08x\n", hr );
4262
4263 url = SysAllocString( test_winehq_https );
4264 method = SysAllocString( method3W );
4265 V_VT( &async ) = VT_BOOL;
4266 V_BOOL( &async ) = VARIANT_FALSE;
4267 hr = IWinHttpRequest_Open( req, method, url, async );
4268 ok( hr == S_OK, "got %08x\n", hr );
4269 SysFreeString( method );
4270 SysFreeString( url );
4271
4272 hr = IWinHttpRequest_Send( req, empty );
4273 ok( hr == S_OK || hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE ) ||
4274 hr == SEC_E_ILLEGAL_MESSAGE /* winxp */, "got %08x\n", hr );
4275 if (hr != S_OK) goto done;
4276
4277 hr = IWinHttpRequest_get_ResponseText( req, &response );
4278 ok( hr == S_OK, "got %08x\n", hr );
4279 #ifdef __REACTOS__
4280 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n",
4281 wine_dbgstr_wn(response, min(SysStringLen(response), 32)) );
4282 #else
4283 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) );
4284 #endif
4285 SysFreeString( response );
4286
4287 IWinHttpRequest_Release( req );
4288
4289 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
4290 ok( hr == S_OK, "got %08x\n", hr );
4291
4292 sprintf( buf, "http://localhost:%d/auth", port );
4293 MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, ARRAY_SIZE( bufW ));
4294 url = SysAllocString( bufW );
4295 method = SysAllocString( method3W );
4296 V_VT( &async ) = VT_BOOL;
4297 V_BOOL( &async ) = VARIANT_FALSE;
4298 hr = IWinHttpRequest_Open( req, method, url, async );
4299 ok( hr == S_OK, "got %08x\n", hr );
4300 SysFreeString( method );
4301 SysFreeString( url );
4302
4303 hr = IWinHttpRequest_get_Status( req, &status );
4304 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
4305
4306 V_VT( &data ) = VT_BSTR;
4307 V_BSTR( &data ) = SysAllocString( test_dataW );
4308 hr = IWinHttpRequest_Send( req, data );
4309 ok( hr == S_OK, "got %08x\n", hr );
4310 SysFreeString( V_BSTR( &data ) );
4311
4312 hr = IWinHttpRequest_get_ResponseText( req, &response );
4313 ok( hr == S_OK, "got %08x\n", hr );
4314 ok( !memcmp( response, unauthW, sizeof(unauthW) ), "got %s\n", wine_dbgstr_w(response) );
4315 SysFreeString( response );
4316
4317 status = 0xdeadbeef;
4318 hr = IWinHttpRequest_get_Status( req, &status );
4319 ok( hr == S_OK, "got %08x\n", hr );
4320 ok( status == HTTP_STATUS_DENIED, "got %d\n", status );
4321
4322 done:
4323 IWinHttpRequest_Release( req );
4324 CoUninitialize();
4325 }
4326
request_get_property(IWinHttpRequest * request,int property,VARIANT * ret)4327 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret)
4328 {
4329 DISPPARAMS params;
4330 VARIANT arg;
4331 HRESULT hr;
4332
4333 memset(¶ms, 0, sizeof(params));
4334 params.cNamedArgs = 0;
4335 params.rgdispidNamedArgs = NULL;
4336 params.cArgs = 1;
4337 params.rgvarg = &arg;
4338 VariantInit(&arg);
4339 V_VT(&arg) = VT_I4;
4340 V_I4(&arg) = property;
4341 VariantInit(ret);
4342 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4343 DISPATCH_PROPERTYGET, ¶ms, ret, NULL, NULL);
4344 ok(hr == S_OK, "error %#x\n", hr);
4345 }
4346
test_IWinHttpRequest_Invoke(void)4347 static void test_IWinHttpRequest_Invoke(void)
4348 {
4349 static const WCHAR utf8W[] = {'U','T','F','-','8',0};
4350 static const WCHAR regid[] = {'W','i','n','H','t','t','p','.','W','i','n','H','t','t','p','R','e','q','u','e','s','t','.','5','.','1',0};
4351 WCHAR openW[] = {'O','p','e','n',0};
4352 WCHAR optionW[] = {'O','p','t','i','o','n',0};
4353 OLECHAR *open = openW, *option = optionW;
4354 BSTR utf8;
4355 CLSID clsid;
4356 IWinHttpRequest *request;
4357 IDispatch *dispatch;
4358 DISPID id;
4359 DISPPARAMS params;
4360 VARIANT arg[3], ret;
4361 UINT err;
4362 BOOL bret;
4363 HRESULT hr;
4364
4365 CoInitialize(NULL);
4366
4367 hr = CLSIDFromProgID(regid, &clsid);
4368 ok(hr == S_OK, "CLSIDFromProgID error %#x\n", hr);
4369 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest);
4370 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid));
4371
4372 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request);
4373 ok(hr == S_OK, "error %#x\n", hr);
4374
4375 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch);
4376 ok(hr == S_OK, "error %#x\n", hr);
4377 IDispatch_Release(dispatch);
4378
4379 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id);
4380 ok(hr == S_OK, "error %#x\n", hr);
4381 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id);
4382
4383 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id);
4384 ok(hr == S_OK, "error %#x\n", hr);
4385 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id);
4386
4387 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4388 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4389 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
4390
4391 memset(¶ms, 0, sizeof(params));
4392 params.cArgs = 2;
4393 params.cNamedArgs = 0;
4394 params.rgvarg = arg;
4395 V_VT(&arg[0]) = VT_I4;
4396 V_I4(&arg[0]) = 1252;
4397 V_VT(&arg[1]) = VT_R8;
4398 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4399 VariantInit(&ret);
4400 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4401 DISPATCH_METHOD, ¶ms, NULL, NULL, &err);
4402 ok(hr == S_OK, "error %#x\n", hr);
4403
4404 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4405 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4406 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
4407
4408 memset(¶ms, 0, sizeof(params));
4409 params.cArgs = 2;
4410 params.cNamedArgs = 0;
4411 params.rgvarg = arg;
4412 V_VT(&arg[0]) = VT_I4;
4413 V_I4(&arg[0]) = 1252;
4414 V_VT(&arg[1]) = VT_R8;
4415 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4416 VariantInit(&ret);
4417 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4418 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, &err);
4419 ok(hr == S_OK, "error %#x\n", hr);
4420
4421 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4422 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4423 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
4424
4425 memset(¶ms, 0, sizeof(params));
4426 params.cArgs = 2;
4427 params.cNamedArgs = 0;
4428 params.rgvarg = arg;
4429 V_VT(&arg[0]) = VT_I4;
4430 V_I4(&arg[0]) = 1252;
4431 V_VT(&arg[1]) = VT_R8;
4432 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4433 VariantInit(&ret);
4434 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0,
4435 DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, &err);
4436 ok(hr == S_OK, "error %#x\n", hr);
4437
4438 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4439 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4440 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
4441
4442 memset(¶ms, 0, sizeof(params));
4443 params.cArgs = 2;
4444 params.cNamedArgs = 0;
4445 params.rgvarg = arg;
4446 V_VT(&arg[0]) = VT_BSTR;
4447 utf8 = SysAllocString(utf8W);
4448 V_BSTR(&arg[0]) = utf8;
4449 V_VT(&arg[1]) = VT_R8;
4450 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */
4451 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, &err);
4452 ok(hr == S_OK, "error %#x\n", hr);
4453
4454 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4455 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4456 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
4457
4458 VariantInit(&ret);
4459 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &ret, NULL, &err);
4460 ok(hr == S_OK, "error %#x\n", hr);
4461
4462 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4463 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4464 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret));
4465
4466 VariantInit(&ret);
4467 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err);
4468 ok(hr == S_OK, "error %#x\n", hr);
4469
4470 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret);
4471 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4472 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
4473
4474 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL);
4475 ok(hr == S_OK, "error %#x\n", hr);
4476
4477 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL);
4478 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#x\n", hr);
4479
4480 VariantInit(&ret);
4481 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err);
4482 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
4483
4484 VariantInit(&ret);
4485 if (0) /* crashes */
4486 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err);
4487
4488 params.cArgs = 1;
4489 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err);
4490 ok(hr == DISP_E_TYPEMISMATCH, "error %#x\n", hr);
4491
4492 VariantInit(&arg[2]);
4493 params.cArgs = 3;
4494 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err);
4495 todo_wine
4496 ok(hr == S_OK, "error %#x\n", hr);
4497
4498 VariantInit(&arg[0]);
4499 VariantInit(&arg[1]);
4500 VariantInit(&arg[2]);
4501
4502 params.cArgs = 1;
4503 V_VT(&arg[0]) = VT_I4;
4504 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage;
4505 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL);
4506 ok(hr == S_OK, "error %#x\n", hr);
4507
4508 V_VT(&ret) = 0xdead;
4509 V_I4(&ret) = 0xbeef;
4510 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, ¶ms, &ret, NULL, NULL);
4511 ok(hr == S_OK, "error %#x\n", hr);
4512 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4513 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
4514
4515 V_VT(&ret) = 0xdead;
4516 V_I4(&ret) = 0xbeef;
4517 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &ret, NULL, NULL);
4518 ok(hr == S_OK, "error %#x\n", hr);
4519 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret));
4520 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret));
4521
4522 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL);
4523 ok(hr == S_OK, "error %#x\n", hr);
4524
4525 V_VT(&ret) = 0xdead;
4526 V_I4(&ret) = 0xbeef;
4527 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, ¶ms, &ret, NULL, NULL);
4528 ok(hr == S_OK, "error %#x\n", hr);
4529 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %d\n", V_VT(&ret));
4530 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret));
4531
4532 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, ¶ms, NULL, NULL, NULL);
4533 ok(hr == S_OK, "error %#x\n", hr);
4534
4535 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL);
4536 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr);
4537
4538 params.cArgs = 2;
4539 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL);
4540 todo_wine
4541 ok(hr == S_OK, "error %#x\n", hr);
4542
4543 params.cArgs = 0;
4544 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL);
4545 ok(hr == DISP_E_PARAMNOTFOUND, "error %#x\n", hr);
4546
4547 SysFreeString(utf8);
4548
4549 params.cArgs = 1;
4550 V_VT(&arg[0]) = VT_I4;
4551 V_I4(&arg[0]) = AutoLogonPolicy_Never;
4552 VariantInit(&ret);
4553 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0,
4554 DISPATCH_METHOD, ¶ms, &ret, NULL, NULL);
4555 ok(hr == S_OK, "error %#x\n", hr);
4556
4557 IWinHttpRequest_Release(request);
4558
4559 CoUninitialize();
4560 }
4561
test_WinHttpDetectAutoProxyConfigUrl(void)4562 static void test_WinHttpDetectAutoProxyConfigUrl(void)
4563 {
4564 BOOL ret;
4565 WCHAR *url;
4566 DWORD error;
4567
4568 SetLastError(0xdeadbeef);
4569 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
4570 error = GetLastError();
4571 ok( !ret, "expected failure\n" );
4572 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4573
4574 url = NULL;
4575 SetLastError(0xdeadbeef);
4576 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
4577 error = GetLastError();
4578 ok( !ret, "expected failure\n" );
4579 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4580
4581 SetLastError(0xdeadbeef);
4582 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
4583 error = GetLastError();
4584 ok( !ret, "expected failure\n" );
4585 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4586
4587 url = (WCHAR *)0xdeadbeef;
4588 SetLastError(0xdeadbeef);
4589 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
4590 error = GetLastError();
4591 if (!ret)
4592 {
4593 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
4594 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
4595 }
4596 else
4597 {
4598 trace("%s\n", wine_dbgstr_w(url));
4599 GlobalFree( url );
4600 }
4601
4602 url = (WCHAR *)0xdeadbeef;
4603 SetLastError(0xdeadbeef);
4604 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url );
4605 error = GetLastError();
4606 if (!ret)
4607 {
4608 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
4609 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url );
4610 }
4611 else
4612 {
4613 ok( error == ERROR_SUCCESS, "got %u\n", error );
4614 trace("%s\n", wine_dbgstr_w(url));
4615 GlobalFree( url );
4616 }
4617 }
4618
test_WinHttpGetIEProxyConfigForCurrentUser(void)4619 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
4620 {
4621 BOOL ret;
4622 DWORD error;
4623 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
4624
4625 memset( &cfg, 0, sizeof(cfg) );
4626
4627 SetLastError(0xdeadbeef);
4628 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
4629 error = GetLastError();
4630 ok( !ret, "expected failure\n" );
4631 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4632
4633 SetLastError(0xdeadbeef);
4634 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
4635 error = GetLastError();
4636 ok( ret, "expected success\n" );
4637 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error );
4638
4639 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
4640 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
4641 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
4642 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
4643 GlobalFree( cfg.lpszAutoConfigUrl );
4644 GlobalFree( cfg.lpszProxy );
4645 GlobalFree( cfg.lpszProxyBypass );
4646 }
4647
test_WinHttpGetProxyForUrl(void)4648 static void test_WinHttpGetProxyForUrl(void)
4649 {
4650 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
4651 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
4652 static const WCHAR emptyW[] = {0};
4653 BOOL ret;
4654 DWORD error;
4655 HINTERNET session;
4656 WINHTTP_AUTOPROXY_OPTIONS options;
4657 WINHTTP_PROXY_INFO info;
4658
4659 memset( &options, 0, sizeof(options) );
4660
4661 SetLastError(0xdeadbeef);
4662 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
4663 error = GetLastError();
4664 ok( !ret, "expected failure\n" );
4665 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
4666
4667 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
4668 ok( session != NULL, "failed to open session %u\n", GetLastError() );
4669
4670 SetLastError(0xdeadbeef);
4671 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
4672 error = GetLastError();
4673 ok( !ret, "expected failure\n" );
4674 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4675
4676 SetLastError(0xdeadbeef);
4677 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
4678 error = GetLastError();
4679 ok( !ret, "expected failure\n" );
4680 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4681
4682 SetLastError(0xdeadbeef);
4683 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
4684 error = GetLastError();
4685 ok( !ret, "expected failure\n" );
4686 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4687
4688 SetLastError(0xdeadbeef);
4689 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4690 error = GetLastError();
4691 ok( !ret, "expected failure\n" );
4692 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4693
4694 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
4695 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
4696
4697 SetLastError(0xdeadbeef);
4698 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
4699 error = GetLastError();
4700 ok( !ret, "expected failure\n" );
4701 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4702
4703 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
4704 options.dwAutoDetectFlags = 0;
4705
4706 SetLastError(0xdeadbeef);
4707 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4708 error = GetLastError();
4709 ok( !ret, "expected failure\n" );
4710 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4711
4712 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
4713 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
4714
4715 SetLastError(0xdeadbeef);
4716 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4717 error = GetLastError();
4718 ok( !ret, "expected failure\n" );
4719 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
4720
4721 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
4722 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
4723
4724 memset( &info, 0, sizeof(info) );
4725 SetLastError(0xdeadbeef);
4726 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4727 error = GetLastError();
4728 if (ret)
4729 {
4730 ok( error == ERROR_SUCCESS, "got %u\n", error );
4731 trace("Proxy.AccessType=%u\n", info.dwAccessType);
4732 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
4733 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
4734 GlobalFree( info.lpszProxy );
4735 GlobalFree( info.lpszProxyBypass );
4736 }
4737
4738 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
4739 options.dwAutoDetectFlags = 0;
4740 options.lpszAutoConfigUrl = wpadW;
4741
4742 memset( &info, 0, sizeof(info) );
4743 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
4744 if (ret)
4745 {
4746 trace("Proxy.AccessType=%u\n", info.dwAccessType);
4747 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
4748 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
4749 GlobalFree( info.lpszProxy );
4750 GlobalFree( info.lpszProxyBypass );
4751 }
4752 WinHttpCloseHandle( session );
4753 }
4754
test_chunked_read(void)4755 static void test_chunked_read(void)
4756 {
4757 static const WCHAR verb[] = {'/','t','e','s','t','s','/','c','h','u','n','k','e','d',0};
4758 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0};
4759 WCHAR header[32];
4760 DWORD len, err;
4761 HINTERNET ses, con = NULL, req = NULL;
4762 BOOL ret;
4763
4764 trace( "starting chunked read test\n" );
4765
4766 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
4767 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() );
4768 if (!ses) goto done;
4769
4770 con = WinHttpConnect( ses, test_winehq, 0, 0 );
4771 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() );
4772 if (!con) goto done;
4773
4774 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 );
4775 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
4776 if (!req) goto done;
4777
4778 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
4779 err = GetLastError();
4780 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT))
4781 {
4782 skip("connection failed, skipping\n");
4783 goto done;
4784 }
4785 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() );
4786 if (!ret) goto done;
4787
4788 ret = WinHttpReceiveResponse( req, NULL );
4789 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
4790 if (!ret) goto done;
4791
4792 header[0] = 0;
4793 len = sizeof(header);
4794 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 );
4795 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
4796 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) );
4797 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) );
4798
4799 header[0] = 0;
4800 len = sizeof(header);
4801 SetLastError( 0xdeadbeef );
4802 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 );
4803 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) );
4804 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() );
4805
4806 trace( "entering query loop\n" );
4807 for (;;)
4808 {
4809 len = 0xdeadbeef;
4810 ret = WinHttpQueryDataAvailable( req, &len );
4811 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
4812 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
4813 trace( "got %u available\n", len );
4814 if (len)
4815 {
4816 DWORD bytes_read;
4817 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
4818
4819 ret = WinHttpReadData( req, buf, len, &bytes_read );
4820 ok(ret, "WinHttpReadData failed: %u.\n", GetLastError());
4821
4822 buf[bytes_read] = 0;
4823 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read );
4824 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
4825 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf );
4826
4827 HeapFree( GetProcessHeap(), 0, buf );
4828 if (!bytes_read) break;
4829 }
4830 if (!len) break;
4831 }
4832 trace( "done\n" );
4833
4834 done:
4835 if (req) WinHttpCloseHandle( req );
4836 if (con) WinHttpCloseHandle( con );
4837 if (ses) WinHttpCloseHandle( ses );
4838 }
4839
START_TEST(winhttp)4840 START_TEST (winhttp)
4841 {
4842 static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
4843 static const WCHAR quitW[] = {'/','q','u','i','t',0};
4844 struct server_info si;
4845 HANDLE thread;
4846 DWORD ret;
4847
4848 test_WinHttpOpenRequest();
4849 test_WinHttpSendRequest();
4850 test_WinHttpTimeFromSystemTime();
4851 test_WinHttpTimeToSystemTime();
4852 test_WinHttpAddHeaders();
4853 test_secure_connection();
4854 test_request_parameter_defaults();
4855 test_WinHttpQueryOption();
4856 test_set_default_proxy_config();
4857 test_empty_headers_param();
4858 test_timeouts();
4859 test_resolve_timeout();
4860 test_credentials();
4861 test_IWinHttpRequest_Invoke();
4862 test_WinHttpDetectAutoProxyConfigUrl();
4863 test_WinHttpGetIEProxyConfigForCurrentUser();
4864 test_WinHttpGetProxyForUrl();
4865 test_chunked_read();
4866
4867 si.event = CreateEventW(NULL, 0, 0, NULL);
4868 si.port = 7532;
4869
4870 thread = CreateThread(NULL, 0, server_thread, &si, 0, NULL);
4871 ok(thread != NULL, "failed to create thread %u\n", GetLastError());
4872
4873 ret = WaitForSingleObject(si.event, 10000);
4874 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
4875 if (ret != WAIT_OBJECT_0)
4876 {
4877 CloseHandle(thread);
4878 return;
4879 }
4880
4881 test_IWinHttpRequest(si.port);
4882 test_connection_info(si.port);
4883 test_basic_request(si.port, NULL, basicW);
4884 test_no_headers(si.port);
4885 test_no_content(si.port);
4886 test_head_request(si.port);
4887 test_not_modified(si.port);
4888 test_basic_authentication(si.port);
4889 test_multi_authentication(si.port);
4890 test_large_data_authentication(si.port);
4891 test_bad_header(si.port);
4892 #ifdef __REACTOS__
4893 if (!winetest_interactive)
4894 {
4895 skip("Skipping tests due to hang. See ROSTESTS-350\n");
4896 }
4897 else
4898 {
4899 test_multiple_reads(si.port);
4900 test_cookies(si.port);
4901 test_request_path_escapes(si.port);
4902 test_passport_auth(si.port);
4903
4904 /* send the basic request again to shutdown the server thread */
4905 test_basic_request(si.port, NULL, quitW);
4906 }
4907 #else
4908 test_multiple_reads(si.port);
4909 test_cookies(si.port);
4910 test_request_path_escapes(si.port);
4911 test_passport_auth(si.port);
4912
4913 /* send the basic request again to shutdown the server thread */
4914 test_basic_request(si.port, NULL, quitW);
4915 #endif
4916
4917 WaitForSingleObject(thread, 3000);
4918 CloseHandle(thread);
4919 }
4920