ReactOS  0.4.14-dev-606-g14ebc0b
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 
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 
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));
51  return ret;
52 }
53 
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 
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 
84 static 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 
261 done:
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 
270 static 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 
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();
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 
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;
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);
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);
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 
556 static void test_WinHttpAddHeaders(void)
557 {
558  HINTERNET session, request, connection;
559  BOOL ret, reverse;
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 
629  request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
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 
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;
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 
1062  ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
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 
1216 cleanup:
1217  WinHttpCloseHandle(req);
1218  WinHttpCloseHandle(con);
1219  WinHttpCloseHandle(ses);
1220 }
1221 
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();
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 
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 
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
1355  set_proxy( KEY_WRITE, buf, len, type );
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 */
1409  info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
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);
1425  if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
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);
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 
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);
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 
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;
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 
2137  ret = WinHttpReceiveResponse( req, NULL );
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 
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 
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 
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 
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));
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 
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 
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 
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 
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 
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"), "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);
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 
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 
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 
2907  ok(ret, "expected success\n");
2908 
2910  ok(ret, "expected success\n");
2911 
2912  size = sizeof(status);
2914  &status, &size, NULL);
2915  ok(ret, "expected success\n");
2916  ok(status == HTTP_STATUS_DENIED, "got %d\n", status);
2917 
2919  ok(ret, "expected success\n");
2920 
2922  ok(ret, "expected success %d\n", GetLastError());
2923 
2925  ok(ret, "expected success\n");
2926 
2927  size = sizeof(status);
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 
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 
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();
2959  }
2960  else
2961  {
2962  SetLastError(0xdeadbeef);
2964  error = GetLastError();
2965  ok(!ret, "expected failure\n");
2967  }
2968 
2969  WinHttpCloseHandle(req);
2970  WinHttpCloseHandle(con);
2971  WinHttpCloseHandle(ses);
2972 }
2973 
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 
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);
2994  todo_wine {
2995  ok(!ret, "expected error\n");
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 
3006  ok(ret, "expected success\n");
3007 
3008  status = 0xdeadbeef;
3009  size = sizeof(status);
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;
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;
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;
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);
3049  ok(!ret, "expected error\n");
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 
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 
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 
3080  ok(ret, "failed to receive response %u\n", GetLastError());
3081 
3082  status = 0xdeadbeef;
3083  size = sizeof(status);
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);
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;
3098  ok(ret, "failed to query data available %u\n",