ReactOS 0.4.15-dev-5664-g3bf4ef6
winhttp.c
Go to the documentation of this file.
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
38DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
39
40static const WCHAR test_useragent[] =
41 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
42static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
43static 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};
44static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
45
46static 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));
51 return ret;
52}
53
54static 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
62static BOOL proxy_active(void)
63{
64 WINHTTP_PROXY_INFO proxy_info;
65 BOOL active = FALSE;
66
67 SetLastError(0xdeadbeef);
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
84static void test_WinHttpQueryOption(void)
85{
86 BOOL ret;
87 HINTERNET session, request, connection;
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);
96 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
98 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
99
100 size = 0xdeadbeef;
101 SetLastError(0xdeadbeef);
103 ok(!ret, "should fail to query option\n");
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);
112 ok(!ret, "should fail to query option\n");
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);
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);
126 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
127
128 SetLastError(0xdeadbeef);
130 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
132 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
133
135 SetLastError(0xdeadbeef);
137 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
139 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
140
142 SetLastError(0xdeadbeef);
144 ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
146 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
147
149 SetLastError(0xdeadbeef);
151 ok(ret, "failed to set redirect policy %u\n", GetLastError());
152
153 feature = 0xdeadbeef;
154 size = sizeof(feature);
155 SetLastError(0xdeadbeef);
157 ok(ret, "failed to query option %u\n", GetLastError());
159 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
160
162 SetLastError(0xdeadbeef);
164 ok(!ret, "should fail to set disable feature for a session\n");
166 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
167
168 SetLastError(0xdeadbeef);
170 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
171
173 SetLastError(0xdeadbeef);
175 ok(!ret, "should fail to set disable feature for a connection\n");
177 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
178
179 SetLastError(0xdeadbeef);
183 {
184 skip("Network unreachable, skipping the test\n");
185 goto done;
186 }
187
188 feature = 0xdeadbeef;
189 size = sizeof(feature);
190 SetLastError(0xdeadbeef);
192 ok(!ret, "should fail to query disable feature for a request\n");
194 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
195
196 feature = 0;
197 size = sizeof(feature);
198 SetLastError(0xdeadbeef);
200 ok(ret, "failed to set feature %u\n", GetLastError());
201
202 feature = 0xffffffff;
203 size = sizeof(feature);
204 SetLastError(0xdeadbeef);
206 ok(ret, "failed to set feature %u\n", GetLastError());
207
209 size = sizeof(feature);
210 SetLastError(0xdeadbeef);
212 ok(ret, "failed to set feature %u\n", GetLastError());
213
214 size = 0;
215 SetLastError(0xdeadbeef);
217 ok(!ret, "should fail to query disable feature for a request\n");
219 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
220
221 feature = 0xdeadbeef;
222 size = sizeof(feature);
223 SetLastError(0xdeadbeef);
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
230 SetLastError(0xdeadbeef);
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);
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);
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);
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);
255 ok(ret, "failed to set WINHTTP_OPTION_CONNECT_RETRIES %u\n", GetLastError());
256
257 SetLastError(0xdeadbeef);
259 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
260
261done:
262 SetLastError(0xdeadbeef);
263 ret = WinHttpCloseHandle(connection);
264 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
265 SetLastError(0xdeadbeef);
267 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
268}
269
270static void test_WinHttpOpenRequest (void)
271{
272 BOOL ret;
273 HINTERNET session, request, connection;
274 DWORD err;
275
276 SetLastError(0xdeadbeef);
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);
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);
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);
300 err = GetLastError();
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);
311 err = GetLastError();
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);
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);
330 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
331
332}
333
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();
353 {
354 skip("connection failed, skipping\n");
355 goto done;
356 }
357 ok(ret, "failed to send request %u\n", GetLastError());
358
359 done:
363}
364
365static 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;
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
388 ok(session != NULL, "WinHttpOpen failed to open session.\n");
389
391 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
392
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);
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;
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 */
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();
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);
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);
456 "Expected ERROR_SUCCESS got %u.\n", GetLastError());
457 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
458
459 SetLastError(0xdeadbeef);
462
463 SetLastError(0xdeadbeef);
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:
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);
480 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
481}
482
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);
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
515{
516 BOOL ret;
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);
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
556static void test_WinHttpAddHeaders(void)
557{
558 HINTERNET session, request, connection;
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
624 ok(session != NULL, "WinHttpOpen failed to open session.\n");
625
627 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
628
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);
641 test_header_name, buffer, &len, &index);
642 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
643 SetLastError(0xdeadbeef);
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);
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
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));
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);
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);
692 test_header_name, NULL, &len, &index);
693 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
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);
703 test_header_name, NULL, &len, &index);
704 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
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));
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);
732 test_header_name, NULL, &len, &index);
733 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
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));
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 */
756 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
757
758 index = 0;
759 len = sizeof(buffer);
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);
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
774 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
775
776 index = 0;
777 len = sizeof(buffer);
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);
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 */
794 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
795
796 index = 0;
797 len = sizeof(buffer);
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);
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);
813 test_header_name, buffer, &len, &index);
814 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
815
816 /* coalesce flag */
818 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
819
820 index = 0;
821 len = sizeof(buffer);
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);
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);
838 test_header_name, buffer, &len, &index);
839 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
840
841 /* coalesce with comma flag */
843 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
844
845 index = 0;
846 len = sizeof(buffer);
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);
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);
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 */
870 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
871
872 index = 0;
873 len = sizeof(buffer);
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);
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);
891 test_header_name, buffer, &len, &index);
892 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
893
894 /* add and replace flags */
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);
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);
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);
915 test_header_name, buffer, &len, &index);
916 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
917
919 ok(!ret, "WinHttpAddRequestHeaders failed\n");
920
922 ok(ret, "WinHttpAddRequestHeaders failed\n");
923
924 index = 0;
925 memset(buffer, 0xff, sizeof(buffer));
926 len = sizeof(buffer);
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
933 ok(!ret, "WinHttpAddRequestHeaders failed\n");
934
936 ok(!ret, "WinHttpAddRequestHeaders failed\n");
937
939 ok(!ret, "WinHttpAddRequestHeaders failed\n");
940
942 ok(ret, "WinHttpAddRequestHeaders failed\n");
943
944 index = 0;
945 buffer[0] = 0;
946 len = sizeof(buffer);
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,
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,
961 ok(ret, "failed to add header: %u\n", GetLastError());
962
963 index = 0;
964 len = sizeof(buffer);
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);
975 test_header_name2, buffer, &len, &index);
976 ok(!ret, "unexpected success\n");
977
978 SetLastError(0xdeadbeef);
980 err = GetLastError();
981 ok(!ret, "unexpected success\n");
982 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
983
985 ok(ret, "got %u\n", GetLastError());
986
987 index = 0;
988 len = sizeof(buffer);
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
996 ok(ret, "got %u\n", GetLastError());
997
998 index = 0;
999 len = sizeof(buffer);
1000 SetLastError(0xdeadbeef);
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);
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
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);
1024 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
1025
1026}
1027
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);
1045#undef X
1046}
1047
1048static 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;
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
1063 ok(ret, "failed to set redirect policy %u\n", GetLastError());
1064
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
1078 err = GetLastError();
1079 ok(!ret, "unexpected success\n");
1081 "setting client cert context returned %u\n", err);
1082
1083 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1084 err = GetLastError();
1086 {
1087 skip("Connection failed, skipping.\n");
1088 goto cleanup;
1089 }
1090 ok(ret, "failed to send request %u\n", GetLastError());
1091
1093 ok(ret, "failed to receive response %u\n", GetLastError());
1094
1095 status = 0xdeadbeef;
1096 size = sizeof(status);
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
1104 ok(req != NULL, "failed to open a request %u\n", GetLastError());
1105
1106 flags = 0xdeadbeef;
1107 size = sizeof(flags);
1109 ok(ret, "failed to query security flags %u\n", GetLastError());
1110 ok(!flags, "got %08x\n", flags);
1111
1114 ok(ret, "failed to set security flags %u\n", GetLastError());
1115
1118 ok(!ret, "success\n");
1119
1122 ok(!ret, "success\n");
1123
1127 ok(ret, "failed to set security flags %u\n", GetLastError());
1128
1129 flags = 0;
1131 ok(ret, "failed to set security flags %u\n", GetLastError());
1132
1134 err = GetLastError();
1135 ok(ret || broken(!ret && err == ERROR_INVALID_PARAMETER) /* winxp */, "failed to set client cert context %u\n", err);
1136
1138
1139 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1140 err = GetLastError();
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);
1151 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1153
1154 size = sizeof(bitness);
1156 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
1157
1158 size = sizeof(info);
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
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);
1190 ok(ret, "failed unexpectedly %u\n", GetLastError());
1191 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1192
1193 size = 0;
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);
1213 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1215
1216cleanup:
1217 WinHttpCloseHandle(req);
1218 WinHttpCloseHandle(con);
1219 WinHttpCloseHandle(ses);
1220}
1221
1223{
1224 static const WCHAR empty[] = {0};
1225 HINTERNET ses, con, req;
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();
1242 {
1243 skip("connection failed, skipping\n");
1244 goto done;
1245 }
1246 ok(ret, "failed to send request %u\n", GetLastError());
1247
1249 ok(ret, "failed to receive response %u\n", GetLastError());
1250
1251 status = 0xdeadbeef;
1252 size = sizeof(status);
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();
1265 {
1266 skip("connection failed, skipping\n");
1267 goto done;
1268 }
1269 ok(ret, "failed to send request %u\n", GetLastError());
1270
1272 ok(ret, "failed to receive response %u\n", GetLastError());
1273
1274 size = 0;
1275 SetLastError(0xdeadbeef);
1277 error = GetLastError();
1278 ok(!ret, "succeeded unexpectedly\n");
1279 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
1280
1283 ok(ret, "failed unexpectedly %u\n", GetLastError());
1284 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
1286
1287 status = 0xdeadbeef;
1288 size = sizeof(status);
1290 ok(ret, "failed unexpectedly %u\n", GetLastError());
1291 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1292
1293done:
1294 WinHttpCloseHandle(req);
1295 WinHttpCloseHandle(con);
1296 WinHttpCloseHandle(ses);
1297}
1298
1299static 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 };
1306static const WCHAR WinHttpSettings[] = {
1307 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1308
1310{
1311 LONG l;
1312 HKEY key;
1313 DWORD ret = 0;
1314
1316 if (!l)
1317 {
1318 DWORD size = 0;
1319
1321 if (!l)
1322 {
1323 if (size <= len)
1325 &size );
1326 if (!l)
1327 ret = size;
1328 }
1329 RegCloseKey( key );
1330 }
1331 return ret;
1332}
1333
1335{
1336 HKEY hkey;
1338 {
1339 if (len) RegSetValueExW( hkey, WinHttpSettings, 0, type, buf, len );
1340 else RegDeleteValueW( hkey, WinHttpSettings );
1341 RegCloseKey( hkey );
1342 }
1343}
1344
1346{
1347 BOOL wow64;
1349 if (sizeof(void *) > sizeof(int) || wow64)
1350 {
1353 }
1354 else
1356}
1357
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;
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 */
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);
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);
1406 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1407
1408 /* at a minimum, the proxy server must be set */
1410 info.lpszProxy = info.lpszProxyBypass = NULL;
1411 SetLastError(0xdeadbeef);
1414 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1415 info.lpszProxyBypass = normalString;
1416 SetLastError(0xdeadbeef);
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);
1426 skip("couldn't set default proxy configuration: access denied\n");
1427 else
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);
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
1446static 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);
1458 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1459
1460 SetLastError(0xdeadbeef);
1461 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1463 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1464
1465 SetLastError(0xdeadbeef);
1466 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1468 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1469
1470 SetLastError(0xdeadbeef);
1471 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
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);
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);
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);
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);
1514 ok(ret, "%u\n", GetLastError());
1515 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1516
1517 SetLastError(0xdeadbeef);
1518 value = 0;
1520 ok(ret, "%u\n", GetLastError());
1521
1522 SetLastError(0xdeadbeef);
1523 value = 0xdeadbeef;
1524 size = sizeof(DWORD);
1526 ok(ret, "%u\n", GetLastError());
1527 ok(value == 0, "Expected 0, got %u\n", value);
1528
1529 SetLastError(0xdeadbeef);
1530 value = 0;
1532 ok(ret, "%u\n", GetLastError());
1533
1534 SetLastError(0xdeadbeef);
1535 value = 0xdeadbeef;
1536 size = sizeof(DWORD);
1538 ok(ret, "%u\n", GetLastError());
1539 ok(value == 0, "Expected 0, got %u\n", value);
1540
1541 SetLastError(0xdeadbeef);
1542 value = 0;
1544 ok(ret, "%u\n", GetLastError());
1545
1546 SetLastError(0xdeadbeef);
1547 value = 0xdeadbeef;
1548 size = sizeof(DWORD);
1550 ok(ret, "%u\n", GetLastError());
1551 ok(value == 0, "Expected 0, got %u\n", value);
1552
1553 SetLastError(0xdeadbeef);
1554 value = 0;
1556 ok(ret, "%u\n", GetLastError());
1557
1558 SetLastError(0xdeadbeef);
1559 value = 0xdeadbeef;
1560 size = sizeof(DWORD);
1562 ok(ret, "%u\n", GetLastError());
1563 ok(value == 0, "Expected 0, got %u\n", value);
1564
1565 SetLastError(0xdeadbeef);
1566 value = 0xbeefdead;
1568 ok(ret, "%u\n", GetLastError());
1569
1570 SetLastError(0xdeadbeef);
1571 value = 0xdeadbeef;
1572 size = sizeof(DWORD);
1574 ok(ret, "%u\n", GetLastError());
1575 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1576
1577 SetLastError(0xdeadbeef);
1578 value = 0xbeefdead;
1580 ok(ret, "%u\n", GetLastError());
1581
1582 SetLastError(0xdeadbeef);
1583 value = 0xdeadbeef;
1584 size = sizeof(DWORD);
1586 ok(ret, "%u\n", GetLastError());
1587 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1588
1589 SetLastError(0xdeadbeef);
1590 value = 0xbeefdead;
1592 ok(ret, "%u\n", GetLastError());
1593
1594 SetLastError(0xdeadbeef);
1595 value = 0xdeadbeef;
1596 size = sizeof(DWORD);
1598 ok(ret, "%u\n", GetLastError());
1599 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1600
1601 SetLastError(0xdeadbeef);
1602 value = 0xbeefdead;
1604 ok(ret, "%u\n", GetLastError());
1605
1606 SetLastError(0xdeadbeef);
1607 value = 0xdeadbeef;
1608 size = sizeof(DWORD);
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);
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);
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);
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);
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);
1648 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1649
1650 SetLastError(0xdeadbeef);
1651 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1653 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1654
1655 SetLastError(0xdeadbeef);
1656 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1658 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1659
1660 SetLastError(0xdeadbeef);
1661 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1663 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1664
1665 SetLastError(0xdeadbeef);
1666 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1668 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1669
1670 SetLastError(0xdeadbeef);
1671 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1673 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1674
1675 SetLastError(0xdeadbeef);
1676 value = 0;
1679 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1680
1681 SetLastError(0xdeadbeef);
1682 value = 0;
1685 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1686
1687 SetLastError(0xdeadbeef);
1688 value = 0;
1691 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1692
1693 SetLastError(0xdeadbeef);
1694 value = 0;
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;
1703 ok(ret, "%u\n", GetLastError());
1704
1705 SetLastError(0xdeadbeef);
1706 value = 0xdeadbeef;
1707 size = sizeof(DWORD);
1709 ok(ret, "%u\n", GetLastError());
1710 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1711
1712 SetLastError(0xdeadbeef);
1713 value = 0xdead;
1715 ok(ret, "%u\n", GetLastError());
1716
1717 SetLastError(0xdeadbeef);
1718 value = 0xdeadbeef;
1719 size = sizeof(DWORD);
1721 ok(ret, "%u\n", GetLastError());
1722 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1723
1724 SetLastError(0xdeadbeef);
1725 value = 0xdead;
1727 ok(ret, "%u\n", GetLastError());
1728
1729 SetLastError(0xdeadbeef);
1730 value = 0xdeadbeef;
1731 size = sizeof(DWORD);
1733 ok(ret, "%u\n", GetLastError());
1734 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1735
1736 SetLastError(0xdeadbeef);
1737 value = 0xdead;
1739 ok(ret, "%u\n", GetLastError());
1740
1741 SetLastError(0xdeadbeef);
1742 value = 0xdeadbeef;
1743 size = sizeof(DWORD);
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);
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);
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);
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);
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);
1783 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1784
1785 SetLastError(0xdeadbeef);
1786 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1788 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1789
1790 SetLastError(0xdeadbeef);
1791 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1793 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1794
1795 SetLastError(0xdeadbeef);
1796 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
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);
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);
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);
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);
1837 ok(ret, "%u\n", GetLastError());
1838 ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1839
1840 SetLastError(0xdeadbeef);
1841 value = 0;
1843 ok(ret, "%u\n", GetLastError());
1844
1845 SetLastError(0xdeadbeef);
1846 value = 0xdeadbeef;
1847 size = sizeof(DWORD);
1849 ok(ret, "%u\n", GetLastError());
1850 ok(value == 0, "Expected 0, got %u\n", value);
1851
1852 SetLastError(0xdeadbeef);
1853 value = 0;
1855 ok(ret, "%u\n", GetLastError());
1856
1857 SetLastError(0xdeadbeef);
1858 value = 0xdeadbeef;
1859 size = sizeof(DWORD);
1861 ok(ret, "%u\n", GetLastError());
1862 ok(value == 0, "Expected 0, got %u\n", value);
1863
1864 SetLastError(0xdeadbeef);
1865 value = 0;
1867 ok(ret, "%u\n", GetLastError());
1868
1869 SetLastError(0xdeadbeef);
1870 value = 0xdeadbeef;
1871 size = sizeof(DWORD);
1873 ok(ret, "%u\n", GetLastError());
1874 ok(value == 0, "Expected 0, got %u\n", value);
1875
1876 SetLastError(0xdeadbeef);
1877 value = 0;
1879 ok(ret, "%u\n", GetLastError());
1880
1881 SetLastError(0xdeadbeef);
1882 value = 0xdeadbeef;
1883 size = sizeof(DWORD);
1885 ok(ret, "%u\n", GetLastError());
1886 ok(value == 0, "Expected 0, got %u\n", value);
1887
1888 SetLastError(0xdeadbeef);
1889 value = 0xbeefdead;
1891 ok(ret, "%u\n", GetLastError());
1892
1893 SetLastError(0xdeadbeef);
1894 value = 0xdeadbeef;
1895 size = sizeof(DWORD);
1897 ok(ret, "%u\n", GetLastError());
1898 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1899
1900 SetLastError(0xdeadbeef);
1901 value = 0xbeefdead;
1903 ok(ret, "%u\n", GetLastError());
1904
1905 SetLastError(0xdeadbeef);
1906 value = 0xdeadbeef;
1907 size = sizeof(DWORD);
1909 ok(ret, "%u\n", GetLastError());
1910 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1911
1912 SetLastError(0xdeadbeef);
1913 value = 0xbeefdead;
1915 ok(ret, "%u\n", GetLastError());
1916
1917 SetLastError(0xdeadbeef);
1918 value = 0xdeadbeef;
1919 size = sizeof(DWORD);
1921 ok(ret, "%u\n", GetLastError());
1922 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1923
1924 SetLastError(0xdeadbeef);
1925 value = 0xbeefdead;
1927 ok(ret, "%u\n", GetLastError());
1928
1929 SetLastError(0xdeadbeef);
1930 value = 0xdeadbeef;
1931 size = sizeof(DWORD);
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;
1942 ok(ret, "%u\n", GetLastError());
1943
1944 SetLastError(0xdeadbeef);
1945 value = 0xdeadbeef;
1946 size = sizeof(DWORD);
1948 ok(ret, "%u\n", GetLastError());
1949 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1950
1951 SetLastError(0xdeadbeef);
1952 value = 0xbeefdead;
1954 ok(ret, "%u\n", GetLastError());
1955
1956 SetLastError(0xdeadbeef);
1957 value = 0xdeadbeef;
1958 size = sizeof(DWORD);
1960 ok(ret, "%u\n", GetLastError());
1961 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1962
1963 SetLastError(0xdeadbeef);
1964 value = 0xbeefdead;
1966 ok(ret, "%u\n", GetLastError());
1967
1968 SetLastError(0xdeadbeef);
1969 value = 0xdeadbeef;
1970 size = sizeof(DWORD);
1972 ok(ret, "%u\n", GetLastError());
1973 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1974
1975 SetLastError(0xdeadbeef);
1976 value = 0xbeefdead;
1978 ok(ret, "%u\n", GetLastError());
1979
1980 SetLastError(0xdeadbeef);
1981 value = 0xdeadbeef;
1982 size = sizeof(DWORD);
1984 ok(ret, "%u\n", GetLastError());
1985 ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1986
1987 SetLastError(0xdeadbeef);
1988 value = 0xbeef;
1990 ok(ret, "%u\n", GetLastError());
1991
1992 SetLastError(0xdeadbeef);
1993 value = 0xdeadbeef;
1994 size = sizeof(DWORD);
1996 ok(ret, "%u\n", GetLastError());
1997 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1998
1999 SetLastError(0xdeadbeef);
2000 value = 0xbeef;
2002 ok(ret, "%u\n", GetLastError());
2003
2004 SetLastError(0xdeadbeef);
2005 value = 0xdeadbeef;
2006 size = sizeof(DWORD);
2008 ok(ret, "%u\n", GetLastError());
2009 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
2010
2011 SetLastError(0xdeadbeef);
2012 value = 0xbeef;
2014 ok(ret, "%u\n", GetLastError());
2015
2016 SetLastError(0xdeadbeef);
2017 value = 0xdeadbeef;
2018 size = sizeof(DWORD);
2020 ok(ret, "%u\n", GetLastError());
2021 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
2022
2023 SetLastError(0xdeadbeef);
2024 value = 0xbeef;
2026 ok(ret, "%u\n", GetLastError());
2027
2028 SetLastError(0xdeadbeef);
2029 value = 0xdeadbeef;
2030 size = sizeof(DWORD);
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);
2040 ok(ret, "%u\n", GetLastError());
2041 ok(value == ~0u, "got %u\n", value);
2042
2043 SetLastError(0xdeadbeef);
2044 value = 30000;
2046 ok(ret, "%u\n", GetLastError());
2047
2048 SetLastError(0xdeadbeef);
2049 value = 0xdeadbeef;
2050 size = sizeof(value);
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);
2059 ok(ret, "%u\n", GetLastError());
2060 ok(value == ~0u, "got %u\n", value);
2061
2062 SetLastError(0xdeadbeef);
2063 value = 30000;
2065 ok(!ret, "expected failure\n");
2067
2068 SetLastError(0xdeadbeef);
2069 value = 0xdeadbeef;
2070 size = sizeof(value);
2072 ok(ret, "%u\n", GetLastError());
2073 ok(value == ~0u, "got %u\n", value);
2074
2075 SetLastError(0xdeadbeef);
2076 value = 48878;
2078 ok(ret, "%u\n", GetLastError());
2079
2080 SetLastError(0xdeadbeef);
2081 value = 0xdeadbeef;
2082 size = sizeof(value);
2084 ok(ret, "%u\n", GetLastError());
2085 todo_wine ok(value == 48879, "got %u\n", value);
2086
2087 SetLastError(0xdeadbeef);
2088 value = 48880;
2090 ok(ret, "%u\n", GetLastError());
2091
2092 SetLastError(0xdeadbeef);
2093 value = 0xdeadbeef;
2094 size = sizeof(value);
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
2104static 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;
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 }
2135 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
2136
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;
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);
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
2176static 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
2182static const char okmsg[] =
2183"HTTP/1.1 200 OK\r\n"
2184"Server: winetest\r\n"
2185"\r\n";
2186
2187static const char notokmsg[] =
2188"HTTP/1.1 400 Bad Request\r\n"
2189"\r\n";
2190
2191static 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
2197static 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
2202static const char nocontentmsg[] =
2203"HTTP/1.1 204 No Content\r\n"
2204"Server: winetest\r\n"
2205"\r\n";
2206
2207static const char notmodified[] =
2208"HTTP/1.1 304 Not Modified\r\n"
2209"\r\n";
2210
2211static 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
2220static 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
2228static const char headmsg[] =
2229"HTTP/1.1 200 OK\r\n"
2230"Content-Length: 100\r\n"
2231"\r\n";
2232
2233static 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
2243static 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
2252static 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
2259static const char unauthorized[] = "Unauthorized";
2260static const char hello_world[] = "Hello World";
2261static const char auth_unseen[] = "Auth Unseen";
2262
2263struct server_info
2264{
2265 HANDLE event;
2266 int port;
2267};
2268
2269#define BIG_BUFFER_LEN 0x2250
2270
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
2463static 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
2474 ok(ses != NULL, "failed to open session %u\n", GetLastError());
2475
2476 SetLastError(0xdeadbeef);
2477 ret = WinHttpSetOption(ses, 0, buffer, sizeof(buffer));
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));
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));
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
2510 ok(ret, "failed to receive response %u\n", GetLastError());
2511
2512 status = 0xdeadbeef;
2513 size = sizeof(status);
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));
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));
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
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
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);
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);
2584 error = GetLastError();
2585 ok(!ret, "expected failure\n");
2587
2588 supported = 0xdeadbeef;
2589 SetLastError(0xdeadbeef);
2590 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2591 error = GetLastError();
2592 ok(!ret, "expected failure\n");
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");
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
2629 ok(ret, "failed to receive response %u\n", GetLastError());
2630
2631 status = 0xdeadbeef;
2632 size = sizeof(status);
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);
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
2664 ok(ret, "failed to set credentials %u\n", GetLastError());
2665
2667 ok(ret, "failed to set credentials %u\n", GetLastError());
2668
2669 SetLastError(0xdeadbeef);
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);
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);
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);
2689 error = GetLastError();
2690 ok(!ret, "expected failure\n");
2691 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2692
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
2700 ok(ret, "failed to receive response %u\n", GetLastError());
2701
2702 status = 0xdeadbeef;
2703 size = sizeof(status);
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 */
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
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
2739 ok(ret, "failed to receive response %u\n", GetLastError());
2740
2741 status = 0xdeadbeef;
2742 size = sizeof(status);
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
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
2773 ok(ret, "failed to set credentials %u\n", GetLastError());
2774
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
2785 ok(ret, "failed to receive response %u\n", GetLastError());
2786
2787 status = 0xdeadbeef;
2788 size = sizeof(status);
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
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
2807 ok(ret, "failed to set username %u\n", GetLastError());
2808
2810 ok(ret, "failed to set password %u\n", GetLastError());
2811
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
2819 ok(ret, "failed to receive response %u\n", GetLastError());
2820
2821 status = 0xdeadbeef;
2822 size = sizeof(status);
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
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
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
2853 WINHTTP_NO_REQUEST_DATA,0, 0, 0 );
2854 ok(ret, "expected success\n");
2855
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"),