ReactOS  0.4.14-dev-49-gfb4591c
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 
37 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
38 
39 static const WCHAR test_useragent[] =
40  {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
41 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
42 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};
43 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
44 
45 static BOOL proxy_active(void)
46 {
47  WINHTTP_PROXY_INFO proxy_info;
48  BOOL active = FALSE;
49 
50  SetLastError(0xdeadbeef);
51  if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
52  {
53  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
54  "got %u\n", GetLastError());
55  active = (proxy_info.lpszProxy != NULL);
56  if (active)
57  GlobalFree(proxy_info.lpszProxy);
58  if (proxy_info.lpszProxyBypass != NULL)
59  GlobalFree(proxy_info.lpszProxyBypass);
60  }
61  else
62  active = FALSE;
63 
64  return active;
65 }
66 
67 static void test_QueryOption(void)
68 {
69  BOOL ret;
70  HINTERNET session, request, connection;
72 
73  SetLastError(0xdeadbeef);
74  session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
75  ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
76 
77  SetLastError(0xdeadbeef);
79  ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
81  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
82 
83  size = 0xdeadbeef;
84  SetLastError(0xdeadbeef);
86  ok(!ret, "should fail to query option\n");
88  "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
89  ok(size == 4, "expected 4, got %u\n", size);
90 
91  feature = 0xdeadbeef;
92  size = sizeof(feature) - 1;
93  SetLastError(0xdeadbeef);
95  ok(!ret, "should fail to query option\n");
97  "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
98  ok(size == 4, "expected 4, got %u\n", size);
99 
100  feature = 0xdeadbeef;
101  size = sizeof(feature) + 1;
102  SetLastError(0xdeadbeef);
104  ok(ret, "failed to query option %u\n", GetLastError());
105  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
106  "got %u\n", GetLastError());
107  ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
109  "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
110 
111  SetLastError(0xdeadbeef);
113  ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
115  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
116 
118  SetLastError(0xdeadbeef);
120  ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
122  "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
123 
125  SetLastError(0xdeadbeef);
127  ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
129  "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
130 
132  SetLastError(0xdeadbeef);
134  ok(ret, "failed to set redirect policy %u\n", GetLastError());
135 
136  feature = 0xdeadbeef;
137  size = sizeof(feature);
138  SetLastError(0xdeadbeef);
140  ok(ret, "failed to query option %u\n", GetLastError());
142  "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
143 
145  SetLastError(0xdeadbeef);
147  ok(!ret, "should fail to set disable feature for a session\n");
149  "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
150 
151  SetLastError(0xdeadbeef);
152  connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
153  ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
154 
156  SetLastError(0xdeadbeef);
158  ok(!ret, "should fail to set disable feature for a connection\n");
160  "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
161 
162  SetLastError(0xdeadbeef);
166  {
167  skip("Network unreachable, skipping the test\n");
168  goto done;
169  }
170 
171  feature = 0xdeadbeef;
172  size = sizeof(feature);
173  SetLastError(0xdeadbeef);
175  ok(!ret, "should fail to query disable feature for a request\n");
177  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
178 
179  feature = 0;
180  size = sizeof(feature);
181  SetLastError(0xdeadbeef);
183  ok(ret, "failed to set feature %u\n", GetLastError());
184 
185  feature = 0xffffffff;
186  size = sizeof(feature);
187  SetLastError(0xdeadbeef);
189  ok(ret, "failed to set feature %u\n", GetLastError());
190 
192  size = sizeof(feature);
193  SetLastError(0xdeadbeef);
195  ok(ret, "failed to set feature %u\n", GetLastError());
196 
197  size = 0;
198  SetLastError(0xdeadbeef);
200  ok(!ret, "should fail to query disable feature for a request\n");
202  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
203 
204  SetLastError(0xdeadbeef);
206  ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
207 
208 done:
209  SetLastError(0xdeadbeef);
210  ret = WinHttpCloseHandle(connection);
211  ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
212  SetLastError(0xdeadbeef);
213  ret = WinHttpCloseHandle(session);
214  ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
215 }
216 
217 static void test_OpenRequest (void)
218 {
219  BOOL ret;
220  HINTERNET session, request, connection;
221  DWORD err;
222 
223  SetLastError(0xdeadbeef);
226  err = GetLastError();
227  ok(session != NULL, "WinHttpOpen failed to open session.\n");
228  ok(err == ERROR_SUCCESS, "got %u\n", err);
229 
230  /* Test with a bad server name */
231  SetLastError(0xdeadbeef);
232  connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
233  err = GetLastError();
234  ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
235  ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err);
236 
237  /* Test with a valid server name */
238  SetLastError(0xdeadbeef);
239  connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
240  err = GetLastError();
241  ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err);
242  ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err);
243 
244  SetLastError(0xdeadbeef);
247  err = GetLastError();
249  {
250  skip("Network unreachable, skipping.\n");
251  goto done;
252  }
253  ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err);
254  ok(err == ERROR_SUCCESS, "got %u\n", err);
255 
256  SetLastError(0xdeadbeef);
258  err = GetLastError();
260  {
261  skip("Connection failed, skipping.\n");
262  goto done;
263  }
264  ok(ret, "WinHttpSendRequest failed: %u\n", err);
265  ok(err == ERROR_SUCCESS, "got %u\n", err);
266 
267  SetLastError(0xdeadbeef);
269  err = GetLastError();
270  ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err);
271  ok(err == ERROR_SUCCESS, "got %u\n", err);
272 
273  done:
274  ret = WinHttpCloseHandle(connection);
275  ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
276  ret = WinHttpCloseHandle(session);
277  ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
278 
279 }
280 
281 static void test_empty_headers_param(void)
282 {
283  static const WCHAR empty[] = {0};
284  HINTERNET ses, con, req;
285  DWORD err;
286  BOOL ret;
287 
288  ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
289  ok(ses != NULL, "failed to open session %u\n", GetLastError());
290 
291  con = WinHttpConnect(ses, test_winehq, 80, 0);
292  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
293 
294  req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
295  ok(req != NULL, "failed to open a request %u\n", GetLastError());
296 
297  ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
298  err = GetLastError();
300  {
301  skip("connection failed, skipping\n");
302  goto done;
303  }
304  ok(ret, "failed to send request %u\n", GetLastError());
305 
306  done:
307  WinHttpCloseHandle(req);
308  WinHttpCloseHandle(con);
309  WinHttpCloseHandle(ses);
310 }
311 
312 static void test_SendRequest (void)
313 {
314  static const WCHAR content_type[] =
315  {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
316  '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
317  static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
318  static const WCHAR test_verb[] = {'P','O','S','T',0};
319  static CHAR post_data[] = "mode=Test";
320  static const char test_post[] = "mode => Test\0\n";
321  HINTERNET session, request, connection;
322  DWORD header_len, optional_len, total_len, bytes_rw, size, err, disable;
324  BOOL ret;
325  CHAR buffer[256];
326  int i;
327 
328  header_len = -1L;
329  total_len = optional_len = sizeof(post_data);
330  memset(buffer, 0xff, sizeof(buffer));
331 
334  ok(session != NULL, "WinHttpOpen failed to open session.\n");
335 
336  connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
337  ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
338 
339  request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
342  {
343  skip("Network unreachable, skipping.\n");
344  goto done;
345  }
346  ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
347  if (!request) goto done;
348 
349  context = 0xdeadbeef;
351  ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
352 
353  /* writing more data than promised by the content-length header causes an error when the connection
354  is resued, so disable keep-alive */
357  ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
358 
359  context++;
360  ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
361  err = GetLastError();
363  {
364  skip("connection failed, skipping\n");
365  goto done;
366  }
367  ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
368 
369  context = 0;
370  size = sizeof(context);
372  ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
373  ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
374 
375  for (i = 3; post_data[i]; i++)
376  {
377  bytes_rw = -1;
378  SetLastError(0xdeadbeef);
379  ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
380  if (ret)
381  {
382  ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError());
383  ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
384  }
385  else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
386  {
387  ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
388  ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
389  }
390  }
391 
392  SetLastError(0xdeadbeef);
394  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */,
395  "Expected ERROR_SUCCESS got %u.\n", GetLastError());
396  ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
397 
398  bytes_rw = -1;
399  ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
400  ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
401 
402  ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw);
403  ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n");
404 
405  done:
407  ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
408  ret = WinHttpCloseHandle(connection);
409  ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
410  ret = WinHttpCloseHandle(session);
411  ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
412 }
413 
415 {
416  BOOL ret;
417  static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
418  static const WCHAR expected_string[] =
419  {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
420  '1','0',':','0','5',':','5','2',' ','G','M','T',0};
421  WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
422  DWORD err;
423 
424  SetLastError(0xdeadbeef);
426  err = GetLastError();
427  ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
428  ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
429 
430  SetLastError(0xdeadbeef);
431  ret = WinHttpTimeFromSystemTime(NULL, time_string);
432  err = GetLastError();
433  ok(!ret, "WinHttpTimeFromSystemTime succeeded\n");
434  ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
435 
436  SetLastError(0xdeadbeef);
437  ret = WinHttpTimeFromSystemTime(&time, time_string);
438  err = GetLastError();
439  ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err);
440  ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
441  ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
442  "Time string returned did not match expected time string.\n");
443 }
444 
446 {
447  BOOL ret;
449  static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
450  static const WCHAR time_string1[] =
451  {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
452  + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
453  static const WCHAR time_string2[] =
454  {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
455  '1','0',' ','0','5',' ','5','2','\n',0};
456  DWORD err;
457 
458  SetLastError(0xdeadbeef);
459  ret = WinHttpTimeToSystemTime(time_string1, NULL);
460  err = GetLastError();
461  ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
462  ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
463 
464  SetLastError(0xdeadbeef);
466  err = GetLastError();
467  ok(!ret, "WinHttpTimeToSystemTime succeeded\n");
468  ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
469 
470  SetLastError(0xdeadbeef);
471  ret = WinHttpTimeToSystemTime(time_string1, &time);
472  err = GetLastError();
473  ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
474  ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
475  ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
476  "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
477 
478  SetLastError(0xdeadbeef);
479  ret = WinHttpTimeToSystemTime(time_string2, &time);
480  err = GetLastError();
481  ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err);
482  ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
483  ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
484  "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
485 }
486 
487 static void test_WinHttpAddHeaders(void)
488 {
489  HINTERNET session, request, connection;
490  BOOL ret, reverse;
493  DWORD err, index, len, oldlen;
494 
495  static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
496  static const WCHAR test_verb[] = {'P','O','S','T',0};
497  static const WCHAR test_header_begin[] =
498  {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
499  static const WCHAR full_path_test_header_begin[] =
500  {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0',
501  '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
502  static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
503  static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
504  static const WCHAR test_header_name2[] = {'n','a','m','e',0};
505  static const WCHAR test_header_name3[] = {'a',0};
506  static const WCHAR test_header_range[] = {'R','a','n','g','e',0};
507  static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0};
508  static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0};
509 
510  static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
511  static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
512  static const WCHAR test_flag_coalesce_comma[] =
513  {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
514  static const WCHAR test_flag_coalesce_comma_reverse[] =
515  {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
516  static const WCHAR test_flag_coalesce_semicolon[] =
517  {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
518  static const WCHAR test_flag_coalesce_semicolon_reverse[] =
519  {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
520 
521  static const WCHAR field[] = {'f','i','e','l','d',0};
522  static const WCHAR value[] = {'v','a','l','u','e',' ',0};
523  static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
524  static const WCHAR empty[] = {0};
525 
526  static const WCHAR test_headers[][14] =
527  {
528  {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
529  {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
530  {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
531  {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
532  {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
533  {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
534  {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
535  {0},
536  {':',0},
537  {'a',':',0},
538  {':','b',0},
539  {'c','d',0},
540  {' ','e',' ',':','f',0},
541  {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0},
542  {'n','a','m','e',':',' ','v','a','l','u','e',0},
543  {'n','a','m','e',':',0}
544  };
545  static const WCHAR test_indices[][6] =
546  {
547  {'t','e','s','t','1',0},
548  {'t','e','s','t','2',0},
549  {'t','e','s','t','3',0},
550  {'t','e','s','t','4',0}
551  };
552 
555  ok(session != NULL, "WinHttpOpen failed to open session.\n");
556 
557  connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0);
558  ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
559 
560  request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
563  {
564  skip("Network unreachable, skipping.\n");
565  goto done;
566  }
567  ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
568 
569  index = 0;
570  len = sizeof(buffer);
572  test_header_name, buffer, &len, &index);
573  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
574  SetLastError(0xdeadbeef);
576  err = GetLastError();
577  ok(ret, "WinHttpAddRequestHeaders failed to add new header, got %d with error %u.\n", ret, err);
578  ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err);
579 
580  index = 0;
581  len = sizeof(buffer);
583  test_header_name, buffer, &len, &index);
584  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
585  ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
586  ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
587  ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
588 
590  test_header_name, buffer, &len, &index);
591  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
592 
593  /* Try to fetch the header info with a buffer that's big enough to fit the
594  * string but not the NULL terminator.
595  */
596  index = 0;
597  len = 5*sizeof(WCHAR);
598  memset(check_buffer, 0xab, sizeof(check_buffer));
599  memcpy(buffer, check_buffer, sizeof(buffer));
601  test_header_name, buffer, &len, &index);
602  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
603  ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
604  "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
605  ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
606 
607  /* Try with a NULL buffer */
608  index = 0;
609  len = sizeof(buffer);
610  SetLastError(0xdeadbeef);
612  test_header_name, NULL, &len, &index);
613  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
614  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
615  ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
616  ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
617 
618  /* Try with a NULL buffer and a length that's too small */
619  index = 0;
620  len = 10;
621  SetLastError(0xdeadbeef);
623  test_header_name, NULL, &len, &index);
624  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
626  "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError());
627  ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
628  ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
629 
630  index = 0;
631  len = 0;
632  SetLastError(0xdeadbeef);
634  test_header_name, NULL, &len, &index);
635  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
637  "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
638  ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
639  ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
640 
641  /* valid query */
642  oldlen = len;
643  index = 0;
644  len = sizeof(buffer);
645  memset(buffer, 0xff, sizeof(buffer));
647  test_header_name, buffer, &len, &index);
648  ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
649  ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
650  ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
651  ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
652  ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
653  memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
654  "WinHttpQueryHeaders returned invalid beginning of header string.\n");
655  ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
656  "WinHttpQueryHeaders returned invalid end of header string.\n");
657  ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
658 
659  index = 0;
660  len = 0;
661  SetLastError(0xdeadbeef);
663  test_header_name, NULL, &len, &index);
664  ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
666  "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
667  ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
668  ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
669 
670  oldlen = len;
671  index = 0;
672  len = sizeof(buffer);
673  memset(buffer, 0xff, sizeof(buffer));
675  test_header_name, buffer, &len, &index);
676  ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
677  ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
678  ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
679  "no double NULL terminator\n");
680  ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
681  memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
682  "invalid beginning of header string.\n");
683  ok(index == 0, "header index was incremented\n");
684 
685  /* tests for more indices */
687  ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
688 
689  index = 0;
690  len = sizeof(buffer);
692  test_header_name, buffer, &len, &index);
693  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
694  ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
695  ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
696 
697  len = sizeof(buffer);
699  test_header_name, buffer, &len, &index);
700  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
701  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
702  ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
703 
705  ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
706 
707  index = 0;
708  len = sizeof(buffer);
710  test_header_name, buffer, &len, &index);
711  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
712  ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
713  reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
714  ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
715 
716  len = sizeof(buffer);
718  test_header_name, buffer, &len, &index);
719  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
720  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
721  ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
722 
723  /* add if new flag */
725  ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
726 
727  index = 0;
728  len = sizeof(buffer);
730  test_header_name, buffer, &len, &index);
731  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
732  ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
733  ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
734 
735  len = sizeof(buffer);
737  test_header_name, buffer, &len, &index);
738  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
739  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
740  ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
741 
742  len = sizeof(buffer);
744  test_header_name, buffer, &len, &index);
745  ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
746 
747  /* coalesce flag */
749  ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
750 
751  index = 0;
752  len = sizeof(buffer);
754  test_header_name, buffer, &len, &index);
755  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
756  ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
757  ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
758  reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
759 
760  len = sizeof(buffer);
762  test_header_name, buffer, &len, &index);
763  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
764  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
765  ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
766 
767  len = sizeof(buffer);
769  test_header_name, buffer, &len, &index);
770  ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
771 
772  /* coalesce with comma flag */
774  ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\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  ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
783  reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
784  "WinHttpQueryHeaders returned incorrect string.\n");
785 
786  len = sizeof(buffer);
788  test_header_name, buffer, &len, &index);
789  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
790  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
791  ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
792 
793  len = sizeof(buffer);
795  test_header_name, buffer, &len, &index);
796  ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
797 
798 
799  /* coalesce with semicolon flag */
801  ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
802 
803  index = 0;
804  len = sizeof(buffer);
806  test_header_name, buffer, &len, &index);
807  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
808  ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
809  ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
810  reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
811  "WinHttpQueryHeaders returned incorrect string.\n");
812 
813  len = sizeof(buffer);
815  test_header_name, buffer, &len, &index);
816  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
817  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
818  ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
819 
820  len = sizeof(buffer);
822  test_header_name, buffer, &len, &index);
823  ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
824 
825  /* add and replace flags */
827  ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
828 
829  index = 0;
830  len = sizeof(buffer);
832  test_header_name, buffer, &len, &index);
833  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
834  ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
835  ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
836 
837  len = sizeof(buffer);
839  test_header_name, buffer, &len, &index);
840  ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
841  ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
842  ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
843 
844  len = sizeof(buffer);
846  test_header_name, buffer, &len, &index);
847  ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
848 
850  ok(!ret, "WinHttpAddRequestHeaders failed\n");
851 
853  ok(ret, "WinHttpAddRequestHeaders failed\n");
854 
855  index = 0;
856  memset(buffer, 0xff, sizeof(buffer));
857  len = sizeof(buffer);
859  test_header_name3, buffer, &len, &index);
860  ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
861  ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n");
862 
864  ok(!ret, "WinHttpAddRequestHeaders failed\n");
865 
867  ok(!ret, "WinHttpAddRequestHeaders failed\n");
868 
870  ok(!ret, "WinHttpAddRequestHeaders failed\n");
871 
873  ok(ret, "WinHttpAddRequestHeaders failed\n");
874 
875  index = 0;
876  buffer[0] = 0;
877  len = sizeof(buffer);
879  field, buffer, &len, &index);
880  ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
881  ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
882 
883  SetLastError(0xdeadbeef);
884  ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, 0,
886  err = GetLastError();
887  ok(!ret, "unexpected success\n");
888  ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err);
889 
890  ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, ~0u,
892  ok(ret, "failed to add header: %u\n", GetLastError());
893 
894  index = 0;
895  len = sizeof(buffer);
897  test_header_range, buffer, &len, &index);
898  ok(ret, "failed to get range header %u\n", GetLastError());
899  ok(!memcmp(buffer, test_header_bytes, sizeof(test_header_bytes)), "incorrect string returned\n");
900  ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len);
901  ok(index == 1, "wrong index %u\n", index);
902 
903  index = 0;
904  len = sizeof(buffer);
906  test_header_name2, buffer, &len, &index);
907  ok(!ret, "unexpected success\n");
908 
909  SetLastError(0xdeadbeef);
911  err = GetLastError();
912  ok(!ret, "unexpected success\n");
913  ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
914 
916  ok(ret, "got %u\n", GetLastError());
917 
918  index = 0;
919  len = sizeof(buffer);
921  test_header_name2, buffer, &len, &index);
922  ok(ret, "got %u\n", GetLastError());
923  ok(index == 1, "wrong index %u\n", index);
924  ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
925 
927  ok(ret, "got %u\n", GetLastError());
928 
929  index = 0;
930  len = sizeof(buffer);
931  SetLastError(0xdeadbeef);
933  test_header_name2, buffer, &len, &index);
934  err = GetLastError();
935  ok(!ret, "unexpected success\n");
936  ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err);
937 
938  ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0);
939  ok(ret, "got %u\n", GetLastError());
940 
941  index = 0;
942  len = sizeof(buffer);
944  test_header_name2, buffer, &len, &index);
945  ok(ret, "got %u\n", GetLastError());
946  ok(index == 1, "wrong index %u\n", index);
947  ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n");
948 
950  ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
951  done:
952  ret = WinHttpCloseHandle(connection);
953  ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
954  ret = WinHttpCloseHandle(session);
955  ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
956 
957 }
958 
960 {
961  DWORD flags = *(DWORD *)buf;
962 
963  if (!flags)
964  {
965  trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
966  return;
967  }
968 #define X(x) if (flags & x) trace("%s\n", #x);
976 #undef X
977 }
978 
979 static void test_secure_connection(void)
980 {
981  static const char data_start[] = "<!DOCTYPE html PUBLIC";
982  HINTERNET ses, con, req;
983  DWORD size, status, policy, bitness, read_size, err, available_size, protocols;
984  BOOL ret;
987  char buffer[32];
988 
989  ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
990  ok(ses != NULL, "failed to open session %u\n", GetLastError());
991 
993  ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
994  ok(ret, "failed to set redirect policy %u\n", GetLastError());
995 
998  err = GetLastError();
999  ok(ret || err == ERROR_INVALID_PARAMETER /* < win7 */, "failed to set protocols %u\n", err);
1000 
1001  con = WinHttpConnect(ses, test_winehq, 443, 0);
1002  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1003 
1004  /* try without setting WINHTTP_FLAG_SECURE */
1005  req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1006  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1007 
1009  err = GetLastError();
1010  ok(!ret, "unexpected success\n");
1012  "setting client cert context returned %u\n", err);
1013 
1014  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1015  err = GetLastError();
1017  {
1018  skip("Connection failed, skipping.\n");
1019  goto cleanup;
1020  }
1021  ok(ret, "failed to send request %u\n", GetLastError());
1022 
1024  ok(ret, "failed to receive response %u\n", GetLastError());
1025 
1026  status = 0xdeadbeef;
1027  size = sizeof(status);
1029  ok(ret, "header query failed %u\n", GetLastError());
1030  ok(status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status);
1031 
1032  WinHttpCloseHandle(req);
1033 
1035  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1036 
1038  err = GetLastError();
1039  ok(ret || broken(!ret && err == ERROR_INVALID_PARAMETER) /* winxp */, "failed to set client cert context %u\n", err);
1040 
1042 
1043  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1044  err = GetLastError();
1047  {
1048  skip("secure connection failed, skipping remaining secure tests\n");
1049  goto cleanup;
1050  }
1051  ok(ret, "failed to send request %u\n", GetLastError());
1052 
1053  size = sizeof(cert);
1055  ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
1057 
1058  size = sizeof(bitness);
1060  ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
1061 
1062  size = sizeof(info);
1064  ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
1065 
1066  if (ret)
1067  {
1068  trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
1069  trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
1070  trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
1071  trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
1072  trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
1073  trace("dwKeySize %u\n", info.dwKeySize);
1074  LocalFree( info.lpszSubjectInfo );
1075  LocalFree( info.lpszIssuerInfo );
1076  }
1077 
1079  ok(ret, "failed to receive response %u\n", GetLastError());
1080 
1081  available_size = 0;
1082  ret = WinHttpQueryDataAvailable(req, &available_size);
1083  ok(ret, "failed to query available data %u\n", GetLastError());
1084  ok(available_size > 2014, "available_size = %u\n", available_size);
1085 
1086  status = 0xdeadbeef;
1087  size = sizeof(status);
1089  ok(ret, "failed unexpectedly %u\n", GetLastError());
1090  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1091 
1092  size = 0;
1094  ok(!ret, "succeeded unexpectedly\n");
1095 
1096  read_size = 0;
1097  for (;;)
1098  {
1099  size = 0;
1100  ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
1101  ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
1102  if (!size) break;
1103  read_size += size;
1104 
1105  if (read_size <= 32)
1106  ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer);
1107  }
1108  ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size);
1109 
1110 cleanup:
1111  WinHttpCloseHandle(req);
1112  WinHttpCloseHandle(con);
1113  WinHttpCloseHandle(ses);
1114 }
1115 
1117 {
1118  static const WCHAR empty[] = {0};
1119  HINTERNET ses, con, req;
1120  DWORD size, status, error;
1121  WCHAR *version;
1122  BOOL ret;
1123 
1124  ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1125  ok(ses != NULL, "failed to open session %u\n", GetLastError());
1126 
1127  con = WinHttpConnect(ses, test_winehq, 0, 0);
1128  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1129 
1130  req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1131  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1132 
1133  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1134  error = GetLastError();
1136  {
1137  skip("connection failed, skipping\n");
1138  goto done;
1139  }
1140  ok(ret, "failed to send request %u\n", GetLastError());
1141 
1143  if (!ret && GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE) /* win2k */
1144  {
1145  win_skip("invalid response\n");
1146  goto done;
1147  }
1148  ok(ret, "failed to receive response %u\n", GetLastError());
1149 
1150  status = 0xdeadbeef;
1151  size = sizeof(status);
1153  ok(ret, "failed unexpectedly %u\n", GetLastError());
1154  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1155 
1156  WinHttpCloseHandle(req);
1157 
1158  req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
1159  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1160 
1161  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1162  error = GetLastError();
1164  {
1165  skip("connection failed, skipping\n");
1166  goto done;
1167  }
1168  ok(ret, "failed to send request %u\n", GetLastError());
1169 
1171  ok(ret, "failed to receive response %u\n", GetLastError());
1172 
1173  size = 0;
1174  SetLastError(0xdeadbeef);
1176  error = GetLastError();
1177  ok(!ret, "succeeded unexpectedly\n");
1178  ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
1179 
1182  ok(ret, "failed unexpectedly %u\n", GetLastError());
1183  ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
1185 
1186  status = 0xdeadbeef;
1187  size = sizeof(status);
1189  ok(ret, "failed unexpectedly %u\n", GetLastError());
1190  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
1191 
1192 done:
1193  WinHttpCloseHandle(req);
1194  WinHttpCloseHandle(con);
1195  WinHttpCloseHandle(ses);
1196 }
1197 
1198 static const WCHAR Connections[] = {
1199  'S','o','f','t','w','a','r','e','\\',
1200  'M','i','c','r','o','s','o','f','t','\\',
1201  'W','i','n','d','o','w','s','\\',
1202  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1203  'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
1204  'C','o','n','n','e','c','t','i','o','n','s',0 };
1205 static const WCHAR WinHttpSettings[] = {
1206  'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
1207 
1209 {
1210  LONG l;
1211  HKEY key;
1212  DWORD ret = 0;
1213 
1215  if (!l)
1216  {
1217  DWORD size = 0;
1218 
1220  if (!l)
1221  {
1222  if (size <= len)
1224  &size );
1225  if (!l)
1226  ret = size;
1227  }
1228  RegCloseKey( key );
1229  }
1230  return ret;
1231 }
1232 
1234 {
1235  HKEY hkey;
1237  {
1238  if (len) RegSetValueExW( hkey, WinHttpSettings, 0, type, buf, len );
1239  else RegDeleteValueW( hkey, WinHttpSettings );
1240  RegCloseKey( hkey );
1241  }
1242 }
1243 
1245 {
1246  BOOL wow64;
1248  if (sizeof(void *) > sizeof(int) || wow64)
1249  {
1252  }
1253  else
1254  set_proxy( KEY_WRITE, buf, len, type );
1255 }
1256 
1258 {
1259  static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1260  static WCHAR normalString[] = { 'f','o','o',0 };
1261  DWORD type, len;
1262  BYTE *saved_proxy_settings = NULL;
1264  BOOL ret;
1265 
1266  /* FIXME: it would be simpler to read the current settings using
1267  * WinHttpGetDefaultProxyConfiguration and save them using
1268  * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1269  *
1270  * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1271  * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1272  * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1273  * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1274  * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1275  * the lpszProxy and lpszProxyBypass values are ignored.
1276  * Thus, if a proxy is set with proxycfg, then calling
1277  * WinHttpGetDefaultProxyConfiguration followed by
1278  * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1279  * getting deleted from the registry.
1280  *
1281  * Instead I read the current registry value and restore it directly.
1282  */
1284  if (len)
1285  {
1286  saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1287  len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1288  }
1289 
1290  if (0)
1291  {
1292  /* Crashes on Vista and higher */
1293  SetLastError(0xdeadbeef);
1296  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1297  }
1298 
1299  /* test with invalid access type */
1300  info.dwAccessType = 0xdeadbeef;
1301  info.lpszProxy = info.lpszProxyBypass = NULL;
1302  SetLastError(0xdeadbeef);
1305  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1306 
1307  /* at a minimum, the proxy server must be set */
1308  info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1309  info.lpszProxy = info.lpszProxyBypass = NULL;
1310  SetLastError(0xdeadbeef);
1313  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1314  info.lpszProxyBypass = normalString;
1315  SetLastError(0xdeadbeef);
1318  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1319 
1320  /* the proxy server can't have wide characters */
1321  info.lpszProxy = wideString;
1322  SetLastError(0xdeadbeef);
1324  if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1325  skip("couldn't set default proxy configuration: access denied\n");
1326  else
1328  broken(ret), /* Earlier winhttp versions on W2K/XP */
1329  "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1330 
1331  info.lpszProxy = normalString;
1332  SetLastError(0xdeadbeef);
1334  if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1335  skip("couldn't set default proxy configuration: access denied\n");
1336  else
1337  {
1338  ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError());
1339  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1340  "got %u\n", GetLastError());
1341  }
1342  set_default_proxy_reg_value( saved_proxy_settings, len, type );
1343 }
1344 
1345 static void test_Timeouts (void)
1346 {
1347  BOOL ret;
1348  DWORD value, size;
1349  HINTERNET ses, req, con;
1350 
1351  ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1352  ok(ses != NULL, "failed to open session %u\n", GetLastError());
1353 
1354  SetLastError(0xdeadbeef);
1355  ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1357  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1358 
1359  SetLastError(0xdeadbeef);
1360  ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1362  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1363 
1364  SetLastError(0xdeadbeef);
1365  ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1367  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1368 
1369  SetLastError(0xdeadbeef);
1370  ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1372  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1373 
1374  SetLastError(0xdeadbeef);
1375  ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1376  ok(ret, "%u\n", GetLastError());
1377  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
1378  "expected ERROR_SUCCESS, got %u\n", GetLastError());
1379 
1380  SetLastError(0xdeadbeef);
1381  ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1382  ok(ret, "%u\n", GetLastError());
1383 
1384  SetLastError(0xdeadbeef);
1385  ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1386  ok(ret, "%u\n", GetLastError());
1387 
1388  SetLastError(0xdeadbeef);
1389  value = 0xdeadbeef;
1390  size = sizeof(DWORD);
1392  ok(ret, "%u\n", GetLastError());
1393  ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1394 
1395  SetLastError(0xdeadbeef);
1396  value = 0xdeadbeef;
1397  size = sizeof(DWORD);
1399  ok(ret, "%u\n", GetLastError());
1400  ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1401 
1402  SetLastError(0xdeadbeef);
1403  value = 0xdeadbeef;
1404  size = sizeof(DWORD);
1406  ok(ret, "%u\n", GetLastError());
1407  ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1408 
1409  SetLastError(0xdeadbeef);
1410  value = 0xdeadbeef;
1411  size = sizeof(DWORD);
1413  ok(ret, "%u\n", GetLastError());
1414  ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1415 
1416  SetLastError(0xdeadbeef);
1417  value = 0;
1419  ok(ret, "%u\n", GetLastError());
1420 
1421  SetLastError(0xdeadbeef);
1422  value = 0xdeadbeef;
1423  size = sizeof(DWORD);
1425  ok(ret, "%u\n", GetLastError());
1426  ok(value == 0, "Expected 0, got %u\n", value);
1427 
1428  SetLastError(0xdeadbeef);
1429  value = 0;
1431  ok(ret, "%u\n", GetLastError());
1432 
1433  SetLastError(0xdeadbeef);
1434  value = 0xdeadbeef;
1435  size = sizeof(DWORD);
1437  ok(ret, "%u\n", GetLastError());
1438  ok(value == 0, "Expected 0, got %u\n", value);
1439 
1440  SetLastError(0xdeadbeef);
1441  value = 0;
1443  ok(ret, "%u\n", GetLastError());
1444 
1445  SetLastError(0xdeadbeef);
1446  value = 0xdeadbeef;
1447  size = sizeof(DWORD);
1449  ok(ret, "%u\n", GetLastError());
1450  ok(value == 0, "Expected 0, got %u\n", value);
1451 
1452  SetLastError(0xdeadbeef);
1453  value = 0;
1455  ok(ret, "%u\n", GetLastError());
1456 
1457  SetLastError(0xdeadbeef);
1458  value = 0xdeadbeef;
1459  size = sizeof(DWORD);
1461  ok(ret, "%u\n", GetLastError());
1462  ok(value == 0, "Expected 0, got %u\n", value);
1463 
1464  SetLastError(0xdeadbeef);
1465  value = 0xbeefdead;
1467  ok(ret, "%u\n", GetLastError());
1468 
1469  SetLastError(0xdeadbeef);
1470  value = 0xdeadbeef;
1471  size = sizeof(DWORD);
1473  ok(ret, "%u\n", GetLastError());
1474  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1475 
1476  SetLastError(0xdeadbeef);
1477  value = 0xbeefdead;
1479  ok(ret, "%u\n", GetLastError());
1480 
1481  SetLastError(0xdeadbeef);
1482  value = 0xdeadbeef;
1483  size = sizeof(DWORD);
1485  ok(ret, "%u\n", GetLastError());
1486  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1487 
1488  SetLastError(0xdeadbeef);
1489  value = 0xbeefdead;
1491  ok(ret, "%u\n", GetLastError());
1492 
1493  SetLastError(0xdeadbeef);
1494  value = 0xdeadbeef;
1495  size = sizeof(DWORD);
1497  ok(ret, "%u\n", GetLastError());
1498  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1499 
1500  SetLastError(0xdeadbeef);
1501  value = 0xbeefdead;
1503  ok(ret, "%u\n", GetLastError());
1504 
1505  SetLastError(0xdeadbeef);
1506  value = 0xdeadbeef;
1507  size = sizeof(DWORD);
1509  ok(ret, "%u\n", GetLastError());
1510  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1511 
1512  con = WinHttpConnect(ses, test_winehq, 0, 0);
1513  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1514 
1515  /* Timeout values should match the last one set for session */
1516  SetLastError(0xdeadbeef);
1517  value = 0xdeadbeef;
1518  size = sizeof(DWORD);
1520  ok(ret, "%u\n", GetLastError());
1521  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1522 
1523  SetLastError(0xdeadbeef);
1524  value = 0xdeadbeef;
1525  size = sizeof(DWORD);
1527  ok(ret, "%u\n", GetLastError());
1528  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1529 
1530  SetLastError(0xdeadbeef);
1531  value = 0xdeadbeef;
1532  size = sizeof(DWORD);
1534  ok(ret, "%u\n", GetLastError());
1535  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1536 
1537  SetLastError(0xdeadbeef);
1538  value = 0xdeadbeef;
1539  size = sizeof(DWORD);
1541  ok(ret, "%u\n", GetLastError());
1542  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1543 
1544  SetLastError(0xdeadbeef);
1545  ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1547  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1548 
1549  SetLastError(0xdeadbeef);
1550  ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1552  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1553 
1554  SetLastError(0xdeadbeef);
1555  ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1557  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1558 
1559  SetLastError(0xdeadbeef);
1560  ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1562  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1563 
1564  SetLastError(0xdeadbeef);
1565  ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1567  "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1568 
1569  SetLastError(0xdeadbeef);
1570  ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1572  "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1573 
1574  SetLastError(0xdeadbeef);
1575  value = 0;
1578  "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1579 
1580  SetLastError(0xdeadbeef);
1581  value = 0;
1584  "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1585 
1586  SetLastError(0xdeadbeef);
1587  value = 0;
1590  "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1591 
1592  SetLastError(0xdeadbeef);
1593  value = 0;
1596  "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1597 
1598  /* Changing timeout values for session should affect the values for connection */
1599  SetLastError(0xdeadbeef);
1600  value = 0xdead;
1602  ok(ret, "%u\n", GetLastError());
1603 
1604  SetLastError(0xdeadbeef);
1605  value = 0xdeadbeef;
1606  size = sizeof(DWORD);
1608  ok(ret, "%u\n", GetLastError());
1609  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1610 
1611  SetLastError(0xdeadbeef);
1612  value = 0xdead;
1614  ok(ret, "%u\n", GetLastError());
1615 
1616  SetLastError(0xdeadbeef);
1617  value = 0xdeadbeef;
1618  size = sizeof(DWORD);
1620  ok(ret, "%u\n", GetLastError());
1621  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1622 
1623  SetLastError(0xdeadbeef);
1624  value = 0xdead;
1626  ok(ret, "%u\n", GetLastError());
1627 
1628  SetLastError(0xdeadbeef);
1629  value = 0xdeadbeef;
1630  size = sizeof(DWORD);
1632  ok(ret, "%u\n", GetLastError());
1633  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1634 
1635  SetLastError(0xdeadbeef);
1636  value = 0xdead;
1638  ok(ret, "%u\n", GetLastError());
1639 
1640  SetLastError(0xdeadbeef);
1641  value = 0xdeadbeef;
1642  size = sizeof(DWORD);
1644  ok(ret, "%u\n", GetLastError());
1645  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1646 
1647  req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1648  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1649 
1650  /* Timeout values should match the last one set for session */
1651  SetLastError(0xdeadbeef);
1652  value = 0xdeadbeef;
1653  size = sizeof(DWORD);
1655  ok(ret, "%u\n", GetLastError());
1656  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1657 
1658  SetLastError(0xdeadbeef);
1659  value = 0xdeadbeef;
1660  size = sizeof(DWORD);
1662  ok(ret, "%u\n", GetLastError());
1663  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1664 
1665  SetLastError(0xdeadbeef);
1666  value = 0xdeadbeef;
1667  size = sizeof(DWORD);
1669  ok(ret, "%u\n", GetLastError());
1670  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1671 
1672  SetLastError(0xdeadbeef);
1673  value = 0xdeadbeef;
1674  size = sizeof(DWORD);
1676  ok(ret, "%u\n", GetLastError());
1677  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1678 
1679  SetLastError(0xdeadbeef);
1680  ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1682  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1683 
1684  SetLastError(0xdeadbeef);
1685  ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1687  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1688 
1689  SetLastError(0xdeadbeef);
1690  ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1692  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1693 
1694  SetLastError(0xdeadbeef);
1695  ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1697  "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1698 
1699  SetLastError(0xdeadbeef);
1700  ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1701  ok(ret, "%u\n", GetLastError());
1702 
1703  SetLastError(0xdeadbeef);
1704  ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1705  ok(ret, "%u\n", GetLastError());
1706 
1707  SetLastError(0xdeadbeef);
1708  ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1709  ok(ret, "%u\n", GetLastError());
1710 
1711  SetLastError(0xdeadbeef);
1712  value = 0xdeadbeef;
1713  size = sizeof(DWORD);
1715  ok(ret, "%u\n", GetLastError());
1716  ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1717 
1718  SetLastError(0xdeadbeef);
1719  value = 0xdeadbeef;
1720  size = sizeof(DWORD);
1722  ok(ret, "%u\n", GetLastError());
1723  ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1724 
1725  SetLastError(0xdeadbeef);
1726  value = 0xdeadbeef;
1727  size = sizeof(DWORD);
1729  ok(ret, "%u\n", GetLastError());
1730  ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1731 
1732  SetLastError(0xdeadbeef);
1733  value = 0xdeadbeef;
1734  size = sizeof(DWORD);
1736  ok(ret, "%u\n", GetLastError());
1737  ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1738 
1739  SetLastError(0xdeadbeef);
1740  value = 0;
1742  ok(ret, "%u\n", GetLastError());
1743 
1744  SetLastError(0xdeadbeef);
1745  value = 0xdeadbeef;
1746  size = sizeof(DWORD);
1748  ok(ret, "%u\n", GetLastError());
1749  ok(value == 0, "Expected 0, got %u\n", value);
1750 
1751  SetLastError(0xdeadbeef);
1752  value = 0;
1754  ok(ret, "%u\n", GetLastError());
1755 
1756  SetLastError(0xdeadbeef);
1757  value = 0xdeadbeef;
1758  size = sizeof(DWORD);
1760  ok(ret, "%u\n", GetLastError());
1761  ok(value == 0, "Expected 0, got %u\n", value);
1762 
1763  SetLastError(0xdeadbeef);
1764  value = 0;
1766  ok(ret, "%u\n", GetLastError());
1767 
1768  SetLastError(0xdeadbeef);
1769  value = 0xdeadbeef;
1770  size = sizeof(DWORD);
1772  ok(ret, "%u\n", GetLastError());
1773  ok(value == 0, "Expected 0, got %u\n", value);
1774 
1775  SetLastError(0xdeadbeef);
1776  value = 0;
1778  ok(ret, "%u\n", GetLastError());
1779 
1780  SetLastError(0xdeadbeef);
1781  value = 0xdeadbeef;
1782  size = sizeof(DWORD);
1784  ok(ret, "%u\n", GetLastError());
1785  ok(value == 0, "Expected 0, got %u\n", value);
1786 
1787  SetLastError(0xdeadbeef);
1788  value = 0xbeefdead;
1790  ok(ret, "%u\n", GetLastError());
1791 
1792  SetLastError(0xdeadbeef);
1793  value = 0xdeadbeef;
1794  size = sizeof(DWORD);
1796  ok(ret, "%u\n", GetLastError());
1797  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1798 
1799  SetLastError(0xdeadbeef);
1800  value = 0xbeefdead;
1802  ok(ret, "%u\n", GetLastError());
1803 
1804  SetLastError(0xdeadbeef);
1805  value = 0xdeadbeef;
1806  size = sizeof(DWORD);
1808  ok(ret, "%u\n", GetLastError());
1809  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1810 
1811  SetLastError(0xdeadbeef);
1812  value = 0xbeefdead;
1814  ok(ret, "%u\n", GetLastError());
1815 
1816  SetLastError(0xdeadbeef);
1817  value = 0xdeadbeef;
1818  size = sizeof(DWORD);
1820  ok(ret, "%u\n", GetLastError());
1821  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1822 
1823  SetLastError(0xdeadbeef);
1824  value = 0xbeefdead;
1826  ok(ret, "%u\n", GetLastError());
1827 
1828  SetLastError(0xdeadbeef);
1829  value = 0xdeadbeef;
1830  size = sizeof(DWORD);
1832  ok(ret, "%u\n", GetLastError());
1833  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1834 
1835  /* Changing timeout values for session should not affect the values for a request,
1836  * neither should the other way around.
1837  */
1838  SetLastError(0xdeadbeef);
1839  value = 0xbeefdead;
1841  ok(ret, "%u\n", GetLastError());
1842 
1843  SetLastError(0xdeadbeef);
1844  value = 0xdeadbeef;
1845  size = sizeof(DWORD);
1847  ok(ret, "%u\n", GetLastError());
1848  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1849 
1850  SetLastError(0xdeadbeef);
1851  value = 0xbeefdead;
1853  ok(ret, "%u\n", GetLastError());
1854 
1855  SetLastError(0xdeadbeef);
1856  value = 0xdeadbeef;
1857  size = sizeof(DWORD);
1859  ok(ret, "%u\n", GetLastError());
1860  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1861 
1862  SetLastError(0xdeadbeef);
1863  value = 0xbeefdead;
1865  ok(ret, "%u\n", GetLastError());
1866 
1867  SetLastError(0xdeadbeef);
1868  value = 0xdeadbeef;
1869  size = sizeof(DWORD);
1871  ok(ret, "%u\n", GetLastError());
1872  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1873 
1874  SetLastError(0xdeadbeef);
1875  value = 0xbeefdead;
1877  ok(ret, "%u\n", GetLastError());
1878 
1879  SetLastError(0xdeadbeef);
1880  value = 0xdeadbeef;
1881  size = sizeof(DWORD);
1883  ok(ret, "%u\n", GetLastError());
1884  ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1885 
1886  SetLastError(0xdeadbeef);
1887  value = 0xbeef;
1889  ok(ret, "%u\n", GetLastError());
1890 
1891  SetLastError(0xdeadbeef);
1892  value = 0xdeadbeef;
1893  size = sizeof(DWORD);
1895  ok(ret, "%u\n", GetLastError());
1896  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1897 
1898  SetLastError(0xdeadbeef);
1899  value = 0xbeef;
1901  ok(ret, "%u\n", GetLastError());
1902 
1903  SetLastError(0xdeadbeef);
1904  value = 0xdeadbeef;
1905  size = sizeof(DWORD);
1907  ok(ret, "%u\n", GetLastError());
1908  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1909 
1910  SetLastError(0xdeadbeef);
1911  value = 0xbeef;
1913  ok(ret, "%u\n", GetLastError());
1914 
1915  SetLastError(0xdeadbeef);
1916  value = 0xdeadbeef;
1917  size = sizeof(DWORD);
1919  ok(ret, "%u\n", GetLastError());
1920  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1921 
1922  SetLastError(0xdeadbeef);
1923  value = 0xbeef;
1925  ok(ret, "%u\n", GetLastError());
1926 
1927  SetLastError(0xdeadbeef);
1928  value = 0xdeadbeef;
1929  size = sizeof(DWORD);
1931  ok(ret, "%u\n", GetLastError());
1932  ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1933 
1934  WinHttpCloseHandle(req);
1935  WinHttpCloseHandle(con);
1936  WinHttpCloseHandle(ses);
1937 }
1938 
1939 static void test_resolve_timeout(void)
1940 {
1941  static const WCHAR nxdomain[] =
1942  {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1943  HINTERNET ses, con, req;
1944  DWORD timeout;
1945  BOOL ret;
1946 
1947  if (! proxy_active())
1948  {
1949  ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1950  ok(ses != NULL, "failed to open session %u\n", GetLastError());
1951 
1952  timeout = 10000;
1954  ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1955 
1956  con = WinHttpConnect(ses, nxdomain, 0, 0);
1957  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1958 
1959  req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1960  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1961 
1962  SetLastError(0xdeadbeef);
1963  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1964  if (ret)
1965  {
1966  skip("nxdomain returned success. Broken ISP redirects?\n");
1967  goto done;
1968  }
1970  "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1971 
1972  WinHttpCloseHandle(req);
1973  WinHttpCloseHandle(con);
1974  WinHttpCloseHandle(ses);
1975  }
1976  else
1977  skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1978 
1979  ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1980  ok(ses != NULL, "failed to open session %u\n", GetLastError());
1981 
1982  timeout = 10000;
1984  ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1985 
1986  con = WinHttpConnect(ses, test_winehq, 0, 0);
1987  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1988 
1989  req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1990  ok(req != NULL, "failed to open a request %u\n", GetLastError());
1991 
1992  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1994  {
1995  skip("connection failed, skipping\n");
1996  goto done;
1997  }
1998  ok(ret, "failed to send request\n");
1999 
2000  done:
2001  WinHttpCloseHandle(req);
2002  WinHttpCloseHandle(con);
2003  WinHttpCloseHandle(ses);
2004 }
2005 
2006 static const char page1[] =
2007 "<HTML>\r\n"
2008 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
2009 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2010 "</HTML>\r\n\r\n";
2011 
2012 static const char okmsg[] =
2013 "HTTP/1.1 200 OK\r\n"
2014 "Server: winetest\r\n"
2015 "\r\n";
2016 
2017 static const char notokmsg[] =
2018 "HTTP/1.1 400 Bad Request\r\n"
2019 "\r\n";
2020 
2021 static const char cookiemsg[] =
2022 "HTTP/1.1 200 OK\r\n"
2023 "Set-Cookie: name = value \r\n"
2024 "Set-Cookie: NAME = value \r\n"
2025 "\r\n";
2026 
2027 static const char cookiemsg2[] =
2028 "HTTP/1.1 200 OK\r\n"
2029 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n"
2030 "\r\n";
2031 
2032 static const char nocontentmsg[] =
2033 "HTTP/1.1 204 No Content\r\n"
2034 "Server: winetest\r\n"
2035 "\r\n";
2036 
2037 static const char notmodified[] =
2038 "HTTP/1.1 304 Not Modified\r\n"
2039 "\r\n";
2040 
2041 static const char noauthmsg[] =
2042 "HTTP/1.1 401 Unauthorized\r\n"
2043 "Server: winetest\r\n"
2044 "Connection: close\r\n"
2045 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2046 "Content-Length: 12\r\n"
2047 "Content-Type: text/plain\r\n"
2048 "\r\n";
2049 
2050 static const char okauthmsg[] =
2051 "HTTP/1.1 200 OK\r\n"
2052 "Server: winetest\r\n"
2053 "Connection: close\r\n"
2054 "Content-Length: 11\r\n"
2055 "Content-Type: text/plain\r\n"
2056 "\r\n";
2057 
2058 static const char headmsg[] =
2059 "HTTP/1.1 200 OK\r\n"
2060 "Content-Length: 100\r\n"
2061 "\r\n";
2062 
2063 static const char multiauth[] =
2064 "HTTP/1.1 401 Unauthorized\r\n"
2065 "Server: winetest\r\n"
2066 "WWW-Authenticate: Bearer\r\n"
2067 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2068 "WWW-Authenticate: NTLM\r\n"
2069 "Content-Length: 10\r\n"
2070 "Content-Type: text/plain\r\n"
2071 "\r\n";
2072 
2073 static const char largeauth[] =
2074 "HTTP/1.1 401 Unauthorized\r\n"
2075 "Server: winetest\r\n"
2076 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2077 "WWW-Authenticate: NTLM\r\n"
2078 "Content-Length: 10240\r\n"
2079 "Content-Type: text/plain\r\n"
2080 "\r\n";
2081 
2082 static const char unauthorized[] = "Unauthorized";
2083 static const char hello_world[] = "Hello World";
2084 static const char auth_unseen[] = "Auth Unseen";
2085 
2086 struct server_info
2087 {
2088  HANDLE event;
2089  int port;
2090 };
2091 
2092 #define BIG_BUFFER_LEN 0x2250
2093 
2095 {
2096  struct server_info *si = param;
2097  int r, c = -1, i, on;
2098  SOCKET s;
2099  struct sockaddr_in sa;
2100  char buffer[0x100];
2101  WSADATA wsaData;
2102  int last_request = 0;
2103 
2104  WSAStartup(MAKEWORD(1,1), &wsaData);
2105 
2106  s = socket(AF_INET, SOCK_STREAM, 0);
2107  if (s == INVALID_SOCKET)
2108  return 1;
2109 
2110  on = 1;
2111  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2112 
2113  memset(&sa, 0, sizeof sa);
2114  sa.sin_family = AF_INET;
2115  sa.sin_port = htons(si->port);
2116  sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2117 
2118  r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
2119  if (r < 0)
2120  return 1;
2121 
2122  listen(s, 0);
2123  SetEvent(si->event);
2124  do
2125  {
2126  if (c == -1) c = accept(s, NULL, NULL);
2127 
2128  memset(buffer, 0, sizeof buffer);
2129  for(i = 0; i < sizeof buffer - 1; i++)
2130  {
2131  r = recv(c, &buffer[i], 1, 0);
2132  if (r != 1)
2133  break;
2134  if (i < 4) continue;
2135  if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
2136  buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
2137  break;
2138  }
2139  if (strstr(buffer, "GET /basic"))
2140  {
2141  send(c, okmsg, sizeof okmsg - 1, 0);
2142  send(c, page1, sizeof page1 - 1, 0);
2143  }
2144  if (strstr(buffer, "/auth_with_creds"))
2145  {
2146  send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2147  if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2148  send(c, hello_world, sizeof hello_world - 1, 0);
2149  else
2150  send(c, auth_unseen, sizeof auth_unseen - 1, 0);
2151  continue;
2152  }
2153  if (strstr(buffer, "/auth"))
2154  {
2155  if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2156  {
2157  send(c, okauthmsg, sizeof okauthmsg - 1, 0);
2158  send(c, hello_world, sizeof hello_world - 1, 0);
2159  }
2160  else
2161  {
2162  send(c, noauthmsg, sizeof noauthmsg - 1, 0);
2163  send(c, unauthorized, sizeof unauthorized - 1, 0);
2164  }
2165  continue;
2166  }
2167  if (strstr(buffer, "/big"))
2168  {
2169  char msg[BIG_BUFFER_LEN];
2170  memset(msg, 'm', sizeof(msg));
2171  send(c, okmsg, sizeof(okmsg) - 1, 0);
2172  send(c, msg, sizeof(msg), 0);
2173  }
2174  if (strstr(buffer, "/no_headers"))
2175  {
2176  send(c, page1, sizeof page1 - 1, 0);
2177  }
2178  if (strstr(buffer, "GET /no_content"))
2179  {
2180  send(c, nocontentmsg, sizeof nocontentmsg - 1, 0);
2181  continue;
2182  }
2183  if (strstr(buffer, "GET /not_modified"))
2184  {
2185  if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0);
2186  else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2187  continue;
2188  }
2189  if (strstr(buffer, "HEAD /head"))
2190  {
2191  send(c, headmsg, sizeof headmsg - 1, 0);
2192  continue;
2193  }
2194  if (strstr(buffer, "GET /multiauth"))
2195  {
2196  send(c, multiauth, sizeof multiauth - 1, 0);
2197  }
2198  if (strstr(buffer, "GET /largeauth"))
2199  {
2200  if (strstr(buffer, "Authorization: NTLM"))
2201  send(c, okmsg, sizeof(okmsg) - 1, 0);
2202  else
2203  {
2204  send(c, largeauth, sizeof largeauth - 1, 0);
2205 #ifdef __REACTOS__
2206  memset(buffer, 'A', sizeof(buffer));
2207  for (i = 0; i < (10240 / sizeof(buffer)); i++) send(c, buffer, sizeof(buffer), 0);
2208 #else
2209  for (i = 0; i < 10240; i++) send(c, "A", 1, 0);
2210 #endif
2211  continue;
2212  }
2213  }
2214  if (strstr(buffer, "GET /cookie5"))
2215  {
2216  if (strstr(buffer, "Cookie: name2=value\r\n"))
2217  send(c, okmsg, sizeof(okmsg) - 1, 0);
2218  else
2219  send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2220  }
2221  if (strstr(buffer, "GET /cookie4"))
2222  {
2223  send(c, cookiemsg2, sizeof(cookiemsg2) - 1, 0);
2224  }
2225  if (strstr(buffer, "GET /cookie3"))
2226  {
2227  if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") ||
2228  broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL))
2229  send(c, okmsg, sizeof(okmsg) - 1, 0);
2230  else
2231  send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2232  }
2233  if (strstr(buffer, "GET /cookie2"))
2234  {
2235  if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") ||
2236  broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL))
2237  send(c, okmsg, sizeof(okmsg) - 1, 0);
2238  else
2239  send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2240  }
2241  else if (strstr(buffer, "GET /cookie"))
2242  {
2243  if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0);
2244  else send(c, notokmsg, sizeof(notokmsg) - 1, 0);
2245  }
2246  if (strstr(buffer, "GET /quit"))
2247  {
2248  send(c, okmsg, sizeof okmsg - 1, 0);
2249  send(c, page1, sizeof page1 - 1, 0);
2250  last_request = 1;
2251  }
2252  shutdown(c, 2);
2253  closesocket(c);
2254  c = -1;
2255 
2256  } while (!last_request);
2257 
2258  closesocket(s);
2259  return 0;
2260 }
2261 
2262 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
2263 {
2264  static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0};
2265  static const WCHAR test_header_end_raw[] = {0,0};
2266  HINTERNET ses, con, req;
2267  char buffer[0x100];
2268  WCHAR buffer2[0x100];
2269  DWORD count, status, size, error, supported, first, target;
2270  BOOL ret;
2271 
2273  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2274 
2275  SetLastError(0xdeadbeef);
2276  ret = WinHttpSetOption(ses, 0, buffer, sizeof(buffer));
2277  ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError());
2278 
2279  SetLastError(0xdeadbeef);
2280  ret = WinHttpQueryOption(ses, 0, buffer, &size);
2281  ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
2282 
2283  con = WinHttpConnect(ses, localhostW, port, 0);
2284  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2285 
2286  SetLastError(0xdeadbeef);
2287  ret = WinHttpSetOption(con, 0, buffer, sizeof(buffer));
2289 
2290  SetLastError(0xdeadbeef);
2291  ret = WinHttpQueryOption(con, 0, buffer, &size);
2292  ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
2293 
2294  req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
2295  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2296 
2297  SetLastError(0xdeadbeef);
2298  ret = WinHttpSetOption(req, 0, buffer, sizeof(buffer));
2299  ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError());
2300 
2301  SetLastError(0xdeadbeef);
2302  ret = WinHttpQueryOption(req, 0, buffer, &size);
2303  ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
2304 
2305  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2306  ok(ret, "failed to send request %u\n", GetLastError());
2307 
2309  ok(ret, "failed to receive response %u\n", GetLastError());
2310 
2311  status = 0xdeadbeef;
2312  size = sizeof(status);
2314  ok(ret, "failed to query status code %u\n", GetLastError());
2315  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2316 
2317  supported = first = target = 0xdeadbeef;
2318  SetLastError(0xdeadbeef);
2319  ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2320  error = GetLastError();
2321  ok(!ret, "unexpected success\n");
2322  todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2323  ok(supported == 0xdeadbeef, "got %x\n", supported);
2324  ok(first == 0xdeadbeef, "got %x\n", first);
2325  ok(target == 0xdeadbeef, "got %x\n", target);
2326 
2327  size = sizeof(buffer2);
2328  memset(buffer2, 0, sizeof(buffer2));
2330  ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2331  ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)),
2332  "WinHttpQueryHeaders returned invalid end of header string\n");
2333 
2334  size = sizeof(buffer2);
2335  memset(buffer2, 0, sizeof(buffer2));
2337  ok(ret, "failed to query for raw headers: %u\n", GetLastError());
2338  ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)),
2339  "WinHttpQueryHeaders returned invalid end of header string\n");
2340  ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n");
2341 
2342  count = 0;
2343  memset(buffer, 0, sizeof(buffer));
2344  ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
2345  ok(ret, "failed to read data %u\n", GetLastError());
2346  ok(count == sizeof page1 - 1, "count was wrong\n");
2347  ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2348 
2349  WinHttpCloseHandle(req);
2350  WinHttpCloseHandle(con);
2351  WinHttpCloseHandle(ses);
2352 }
2353 
2355 {
2356  static const WCHAR authW[] = {'/','a','u','t','h',0};
2357  static const WCHAR auth_with_credsW[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0};
2358  static WCHAR userW[] = {'u','s','e','r',0};
2359  static WCHAR passW[] = {'p','w','d',0};
2360  static WCHAR pass2W[] = {'p','w','d','2',0};
2361  HINTERNET ses, con, req;
2362  DWORD status, size, error, supported, first, target;
2363  char buffer[32];
2364  BOOL ret;
2365 
2367  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2368 
2369  con = WinHttpConnect(ses, localhostW, port, 0);
2370  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2371 
2372  req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2373  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2374 
2375  SetLastError(0xdeadbeef);
2377  error = GetLastError();
2378  ok(!ret, "expected failure\n");
2379  ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2380 
2381  SetLastError(0xdeadbeef);
2383  error = GetLastError();
2384  ok(!ret, "expected failure\n");
2386 
2387  supported = 0xdeadbeef;
2388  SetLastError(0xdeadbeef);
2389  ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL);
2390  error = GetLastError();
2391  ok(!ret, "expected failure\n");
2393  ok(supported == 0xdeadbeef, "got %x\n", supported);
2394 
2395  supported = first = 0xdeadbeef;
2396  SetLastError(0xdeadbeef);
2397  ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL);
2398  error = GetLastError();
2399  ok(!ret, "expected failure\n");
2401  ok(supported == 0xdeadbeef, "got %x\n", supported);
2402  ok(first == 0xdeadbeef, "got %x\n", first);
2403 
2404  supported = first = target = 0xdeadbeef;
2405  SetLastError(0xdeadbeef);
2406  ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2407  error = GetLastError();
2408  ok(!ret, "expected failure\n");
2409  todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error);
2410  ok(supported == 0xdeadbeef, "got %x\n", supported);
2411  ok(first == 0xdeadbeef, "got %x\n", first);
2412  ok(target == 0xdeadbeef, "got %x\n", target);
2413 
2414  supported = first = target = 0xdeadbeef;
2415  SetLastError(0xdeadbeef);
2416  ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target);
2417  error = GetLastError();
2418  ok(!ret, "expected failure\n");
2419  ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error);
2420  ok(supported == 0xdeadbeef, "got %x\n", supported);
2421  ok(first == 0xdeadbeef, "got %x\n", first);
2422  ok(target == 0xdeadbeef, "got %x\n", target);
2423 
2424  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2425  ok(ret, "failed to send request %u\n", GetLastError());
2426 
2428  ok(ret, "failed to receive response %u\n", GetLastError());
2429 
2430  status = 0xdeadbeef;
2431  size = sizeof(status);
2433  ok(ret, "failed to query status code %u\n", GetLastError());
2434  ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status);
2435 
2436  size = 0;
2437  ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2438  error = GetLastError();
2439  ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2440  if (ret)
2441  {
2442  ok(size == 12, "expected 12, got %u\n", size);
2443  ok(!memcmp(buffer, unauthorized, 12), "got %s\n", buffer);
2444  }
2445 
2446  supported = first = target = 0xdeadbeef;
2447  SetLastError(0xdeadbeef);
2448  ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2449  error = GetLastError();
2450  ok(ret, "failed to query authentication schemes %u\n", error);
2451  ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2452  ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported);
2453  ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2454  ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2455 
2456  SetLastError(0xdeadbeef);
2458  error = GetLastError();
2459  ok(ret, "failed to set credentials %u\n", error);
2460  ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error);
2461 
2463  ok(ret, "failed to set credentials %u\n", GetLastError());
2464 
2466  ok(ret, "failed to set credentials %u\n", GetLastError());
2467 
2468  SetLastError(0xdeadbeef);
2470  error = GetLastError();
2471  ok(!ret, "expected failure\n");
2472  ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2473 
2474  SetLastError(0xdeadbeef);
2476  error = GetLastError();
2477  ok(!ret, "expected failure\n");
2478  ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2479 
2480  SetLastError(0xdeadbeef);
2482  error = GetLastError();
2483  ok(!ret, "expected failure\n");
2484  ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2485 
2486  SetLastError(0xdeadbeef);
2488  error = GetLastError();
2489  ok(!ret, "expected failure\n");
2490  ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2491 
2493  ok(ret, "failed to set credentials %u\n", GetLastError());
2494 
2495  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2496  ok(ret, "failed to send request %u\n", GetLastError());
2497 
2499  ok(ret, "failed to receive response %u\n", GetLastError());
2500 
2501  status = 0xdeadbeef;
2502  size = sizeof(status);
2504  ok(ret, "failed to query status code %u\n", GetLastError());
2505  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2506 
2507  size = 0;
2508  ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2509  error = GetLastError();
2510  ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2511  if (ret)
2512  {
2513  ok(size == 11, "expected 11, got %u\n", size);
2514  ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2515  }
2516 
2517  WinHttpCloseHandle(req);
2518  WinHttpCloseHandle(con);
2519  WinHttpCloseHandle(ses);
2520 
2521  /* now set the credentials first to show that they get sent with the first request */
2523  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2524 
2525  con = WinHttpConnect(ses, localhostW, port, 0);
2526  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2527 
2528  req = WinHttpOpenRequest(con, NULL, auth_with_credsW, NULL, NULL, NULL, 0);
2529  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2530 
2532  ok(ret, "failed to set credentials %u\n", GetLastError());
2533 
2534  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2535  ok(ret, "failed to send request %u\n", GetLastError());
2536 
2538  ok(ret, "failed to receive response %u\n", GetLastError());
2539 
2540  status = 0xdeadbeef;
2541  size = sizeof(status);
2543  ok(ret, "failed to query status code %u\n", GetLastError());
2544  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2545 
2546  size = 0;
2547  ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
2548  error = GetLastError();
2549  ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
2550  if (ret)
2551  {
2552  ok(size == 11, "expected 11, got %u\n", size);
2553  ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
2554  }
2555 
2556  WinHttpCloseHandle(req);
2557  WinHttpCloseHandle(con);
2558  WinHttpCloseHandle(ses);
2559 
2560  /* credentials set with WinHttpSetCredentials take precedence over those set through options */
2561 
2563  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2564 
2565  con = WinHttpConnect(ses, localhostW, port, 0);
2566  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2567 
2568  req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2569  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2570 
2572  ok(ret, "failed to set credentials %u\n", GetLastError());
2573 
2574  ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2575  ok(ret, "failed to set username %u\n", GetLastError());
2576 
2577  ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W));
2578  ok(ret, "failed to set password %u\n", GetLastError());
2579 
2580  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2581  ok(ret, "failed to send request %u\n", GetLastError());
2582 
2584  ok(ret, "failed to receive response %u\n", GetLastError());
2585 
2586  status = 0xdeadbeef;
2587  size = sizeof(status);
2589  ok(ret, "failed to query status code %u\n", GetLastError());
2590  ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
2591 
2592  WinHttpCloseHandle(req);
2593  WinHttpCloseHandle(con);
2594  WinHttpCloseHandle(ses);
2595 
2597  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2598 
2599  con = WinHttpConnect(ses, localhostW, port, 0);
2600  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2601 
2602  req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
2603  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2604 
2605  ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2606  ok(ret, "failed to set username %u\n", GetLastError());
2607 
2608  ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2609  ok(ret, "failed to set password %u\n", GetLastError());
2610 
2612  ok(ret, "failed to set credentials %u\n", GetLastError());
2613 
2614  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2615  ok(ret, "failed to send request %u\n", GetLastError());
2616 
2618  ok(ret, "failed to receive response %u\n", GetLastError());
2619 
2620  status = 0xdeadbeef;
2621  size = sizeof(status);
2623  ok(ret, "failed to query status code %u\n", GetLastError());
2624  ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status);
2625 
2626  WinHttpCloseHandle(req);
2627  WinHttpCloseHandle(con);
2628  WinHttpCloseHandle(ses);
2629 }
2630 
2632 {
2633  static const WCHAR multiauthW[] = {'/','m','u','l','t','i','a','u','t','h',0};
2634  static const WCHAR getW[] = {'G','E','T',0};
2635  HINTERNET ses, con, req;
2636  DWORD supported, first, target;
2637  BOOL ret;
2638 
2640  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2641 
2642  con = WinHttpConnect(ses, localhostW, port, 0);
2643  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2644 
2645  req = WinHttpOpenRequest(con, getW, multiauthW, NULL, NULL, NULL, 0);
2646  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2647 
2649  WINHTTP_NO_REQUEST_DATA,0, 0, 0 );
2650  ok(ret, "expected success\n");
2651 
2653  ok(ret, "expected success\n");
2654 
2655  supported = first = target = 0xdeadbeef;
2656  ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target);
2657  ok(ret, "expected success\n");
2658  ok(supported == (WINHTTP_AUTH_SCHEME_BASIC | WINHTTP_AUTH_SCHEME_NTLM), "got %x\n", supported);
2659  ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target);
2660  ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first);
2661 
2662  WinHttpCloseHandle(req);
2663  WinHttpCloseHandle(con);
2664  WinHttpCloseHandle(ses);
2665 }
2666 
2668 {
2669  static const WCHAR largeauthW[] = {'/','l','a','r','g','e','a','u','t','h',0};
2670  static const WCHAR getW[] = {'G','E','T',0};
2671  static WCHAR userW[] = {'u','s','e','r',0};
2672  static WCHAR passW[] = {'p','w','d',0};
2673  HINTERNET ses, con, req;
2674  DWORD status, size;
2675  BOOL ret;
2676 
2678  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2679 
2680  con = WinHttpConnect(ses, localhostW, port, 0);
2681  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2682 
2683  req = WinHttpOpenRequest(con, getW, largeauthW, NULL, NULL, NULL, 0);
2684  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2685 
2687  ok(ret, "expected success\n");
2688 
2690  ok(ret, "expected success\n");
2691 
2692  size = sizeof(status);
2694  &status, &size, NULL);
2695  ok(ret, "expected success\n");
2696  ok(status == HTTP_STATUS_DENIED, "got %d\n", status);
2697 
2699  ok(ret, "expected success\n");
2700 
2702  ok(ret, "expected success %d\n", GetLastError());
2703 
2705  ok(ret, "expected success\n");
2706 
2707  size = sizeof(status);
2709  &status, &size, NULL);
2710  ok(ret, "expected success\n");
2711  ok(status == HTTP_STATUS_OK, "got %d\n", status);
2712 
2713  WinHttpCloseHandle(req);
2714  WinHttpCloseHandle(con);
2715  WinHttpCloseHandle(ses);
2716 }
2717 
2718 static void test_no_headers(int port)
2719 {
2720  static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2721  HINTERNET ses, con, req;
2722  DWORD error;
2723  BOOL ret;
2724 
2726  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2727 
2728  con = WinHttpConnect(ses, localhostW, port, 0);
2729  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2730 
2731  req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
2732  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2733 
2734  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2735  if (!ret)
2736  {
2737  error = GetLastError();
2739  }
2740  else
2741  {
2742  SetLastError(0xdeadbeef);
2744  error = GetLastError();
2745  ok(!ret, "expected failure\n");
2747  }
2748 
2749  WinHttpCloseHandle(req);
2750  WinHttpCloseHandle(con);
2751  WinHttpCloseHandle(ses);
2752 }
2753 
2754 static void test_no_content(int port)
2755 {
2756  static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0};
2757  HINTERNET ses, con, req;
2758  char buf[128];
2759  DWORD size, len = sizeof(buf), bytes_read, status;
2760  BOOL ret;
2761 
2763  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2764 
2765  con = WinHttpConnect(ses, localhostW, port, 0);
2766  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2767 
2768  req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0);
2769  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2770 
2771  size = 12345;
2772  SetLastError(0xdeadbeef);
2774  todo_wine {
2775  ok(!ret, "expected error\n");
2777  "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError());
2778  ok(size == 12345 || broken(size == 0) /* Win <= 2003 */,
2779  "expected 12345, got %u\n", size);
2780  }
2781 
2782  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2783  ok(ret, "expected success\n");
2784 
2786  ok(ret, "expected success\n");
2787 
2788  status = 0xdeadbeef;
2789  size = sizeof(status);
2791  NULL, &status, &size, NULL);
2792  ok(ret, "expected success\n");
2793  ok(status == HTTP_STATUS_NO_CONTENT, "expected status 204, got %d\n", status);
2794 
2795  SetLastError(0xdeadbeef);
2796  size = sizeof(status);
2797  status = 12345;
2799  NULL, &status, &size, 0);
2800  ok(!ret, "expected no content-length header\n");
2801  ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError());
2802  ok(status == 12345, "expected 0, got %d\n", status);
2803 
2804  SetLastError(0xdeadbeef);
2805  size = 12345;
2807  ok(ret, "expected success\n");
2808  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2809  "wrong error %u\n", GetLastError());
2810  ok(!size, "expected 0, got %u\n", size);
2811 
2812  SetLastError(0xdeadbeef);
2813  ret = WinHttpReadData(req, buf, len, &bytes_read);
2814  ok(ret, "expected success\n");
2815  ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */,
2816  "wrong error %u\n", GetLastError());
2817  ok(!bytes_read, "expected 0, got %u\n", bytes_read);
2818 
2819  size = 12345;
2821  ok(ret, "expected success\n");
2822  ok(size == 0, "expected 0, got %d\n", size);
2823 
2824  WinHttpCloseHandle(req);
2825 
2826  size = 12345;
2827  SetLastError(0xdeadbeef);
2829  ok(!ret, "expected error\n");
2831  "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError());
2832  ok(size == 12345, "expected 12345, got %u\n", size);
2833 
2834  WinHttpCloseHandle(con);
2835  WinHttpCloseHandle(ses);
2836 }
2837 
2838 static void test_head_request(int port)
2839 {
2840  static const WCHAR verbW[] = {'H','E','A','D',0};
2841  static const WCHAR headW[] = {'/','h','e','a','d',0};
2842  HINTERNET ses, con, req;
2843  char buf[128];
2844  DWORD size, len, count, status;
2845  BOOL ret;
2846 
2848  ok(ses != NULL, "failed to open session %u\n", GetLastError());
2849 
2850  con = WinHttpConnect(ses, localhostW, port, 0);
2851  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2852 
2853  req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0);
2854  ok(req != NULL, "failed to open a request %u\n", GetLastError());
2855 
2856  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
2857  ok(ret, "failed to send request %u\n", GetLastError());
2858 
2860  ok(ret, "failed to receive response %u\n", GetLastError());
2861 
2862  status = 0xdeadbeef;
2863  size = sizeof(status);
2865  NULL, &status, &size, NULL);
2866  ok(ret, "failed to get status code %u\n", GetLastError());
2867  ok(status == HTTP_STATUS_OK, "got %u\n", status);
2868 
2869  len = 0xdeadbeef;
2870  size = sizeof(len);
2872  NULL, &len, &size, 0);
2873  ok(ret, "failed to get content-length header %u\n", GetLastError());
2874  ok(len == HTTP_STATUS_CONTINUE, "got %u\n", len);
2875 
2876  count = 0xdeadbeef;
2878  ok(ret, "failed to query data available %u\n", GetLastError());
2879  ok(!count, "got %u\n", count);
2880 
2881  len = sizeof(buf);
2882  count = 0xdeadbeef;
2883  ret = WinHttpReadData(req, buf, len, &count);
2884  ok(ret, "failed to read data %u\n", GetLastError());
2885  ok(!count, "got %u\n", count);
2886 
2887  count = 0xdeadbeef;
2889  ok(ret, "failed to query data available %u\n", GetLastError());
2890  ok(!count, "got %u\n", count);
2891 
2892  WinHttpCloseHandle(req);
2893  WinHttpCloseHandle(con);
2894  WinHttpCloseHandle(ses);
2895 }
2896 
2897 static void test_not_modified(int port)
2898 {
2899  static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0};
2900  static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '};
2901  static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
2902  BOOL ret;
2903  HINTERNET session, request, connection;
2905  SYSTEMTIME st;
2906  WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32];
2907 
2908  memcpy(today, ifmodifiedW, sizeof(ifmodifiedW));
2909  GetSystemTime(&st);
2910  WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]);
2911 
2914  ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError());
2915 
2916  connection = WinHttpConnect(session, localhostW, port, 0);
2917  ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError());
2918 
2919  request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER,
2921  ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError());
2922 
2923  ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0);
2924  ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError());
2925 
2927  ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError());
2928 
2929  index = 0;
2930  len = sizeof(buffer);
2932  ifmodified2W, buffer, &len, &index);
2933  ok(ret, "failed to get header %u\n", GetLastError());
2934 
2935  status = 0xdeadbeef;
2936  size = sizeof(status);
2938  NULL, &status, &size, NULL);
2939  ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
2940  ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status);
2941 
2942  size = 0xdeadbeef;
2944  ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError());
2945  ok(!size, "got %u\n", size);
2946 
2948  WinHttpCloseHandle(connection);
2949  WinHttpCloseHandle(session);
2950  start = GetTickCount() - start;
2951  ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start);
2952 }
2953 
2954 static void test_bad_header( int port )
2955 {
2956  static const WCHAR bad_headerW[] =
2957  {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2958  't','e','x','t','/','h','t','m','l','\n','\r',0};
2959  static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
2960  static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2961  WCHAR buffer[32];
2962  HINTERNET ses, con, req;
2963  DWORD index, len;
2964  BOOL ret;
2965 
2967  ok( ses != NULL, "failed to open session %u\n", GetLastError() );
2968 
2969  con = WinHttpConnect( ses, localhostW, port, 0 );
2970  ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2971 
2972  req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2973  ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2974 
2975  ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2976  ok( ret, "failed to add header %u\n", GetLastError() );
2977 
2978  index = 0;
2979  buffer[0] = 0;
2980  len = sizeof(buffer);
2982  content_typeW, buffer, &len, &index );
2983  ok( ret, "failed to query headers %u\n", GetLastError() );
2984  ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2985 
2986  WinHttpCloseHandle( req );
2987  WinHttpCloseHandle( con );
2988  WinHttpCloseHandle( ses );
2989 }
2990 
2991 static void test_multiple_reads(int port)
2992 {
2993  static const WCHAR bigW[] = {'b','i','g',0};
2994  HINTERNET ses, con, req;
2995  DWORD total_len = 0;
2996  BOOL ret;
2997 
2999  ok(ses != NULL, "failed to open session %u\n", GetLastError());
3000 
3001  con = WinHttpConnect(ses, localhostW, port, 0);
3002  ok(con != NULL, "failed to open a connection %u\n", GetLastError());
3003 
3004  req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0);
3005  ok(req != NULL, "failed to open a request %u\n", GetLastError());
3006 
3007  ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
3008  ok(ret, "failed to send request %u\n", GetLastError());
3009 
3011  ok(ret == TRUE, "expected success\n");
3012 
3013  for (;;)
3014  {
3015  DWORD len = 0xdeadbeef;
3016  ret = WinHttpQueryDataAvailable( req, &len );
3017  ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3018  if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3019  if (len)
3020  {
3021  DWORD bytes_read;
3022  char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 );
3023 
3024  ret = WinHttpReadData( req, buf, len, &bytes_read );
3025  ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len );
3026 
3027  HeapFree( GetProcessHeap(), 0, buf );
3028  if (!bytes_read) break;
3029  total_len += bytes_read;
3030  }
3031  if (!len) break;
3032  }
3033  ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len);
3034 
3035  WinHttpCloseHandle(req);
3036  WinHttpCloseHandle(con);
3037  WinHttpCloseHandle(ses);
3038 }
3039 
3040 static void test_cookies( int port )
3041 {
3042  static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0};
3043  static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0};
3044  static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0};
3045  static const WCHAR cookie4W[] = {'/','c','o','o','k','i','e','4',0};
3046  static const WCHAR cookie5W[] = {'/','c','o','o','k','i','e','5',0};
3047  static const WCHAR cookieheaderW[] =
3048  {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0};
3049  HINTERNET ses, con, req;
3050  DWORD status, size;
3051  BOOL ret;
3052 
3054  ok( ses != NULL, "failed to open session %u\n", GetLastError() );
3055 
3056  con = WinHttpConnect( ses, localhostW, port, 0 );
3057  ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3058 
3059  req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 );
3060  ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3061 
3062  ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3063  ok( ret, "failed to send request %u\n", GetLastError() );
3064 
3065  ret = WinHttpReceiveResponse( req, NULL );
3066  ok( ret, "failed to receive response %u\n", GetLastError() );
3067 
3068  status = 0xdeadbeef;
3069  size = sizeof(status);
3071  ok( ret, "failed to query status code %u\n", GetLastError() );
3072  ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3073 
3074  WinHttpCloseHandle( req );
3075 
3076  req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
3077  ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3078 
3079  ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3080  ok( ret, "failed to send request %u\n", GetLastError() );
3081 
3082  ret = WinHttpReceiveResponse( req, NULL );
3083  ok( ret, "failed to receive response %u\n", GetLastError() );
3084 
3085  status = 0xdeadbeef;
3086  size = sizeof(status);
3088  ok( ret, "failed to query status code %u\n", GetLastError() );
3089  ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3090 
3091  WinHttpCloseHandle( req );
3092  WinHttpCloseHandle( con );
3093 
3094  con = WinHttpConnect( ses, localhostW, port, 0 );
3095  ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
3096 
3097  req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 );
3098  ok( req != NULL, "failed to open a request %u\n", GetLastError() );
3099 
3100  ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
3101  ok( ret, "failed to send request %u\n", GetLastError() );
3102 
3103  ret = WinHttpReceiveResponse( req, NULL );
3104  ok( ret, "failed to receive response %u\n", GetLastError() );
3105 
3106  status = 0xdeadbeef;
3107  size = sizeof(status);
3109  ok( ret, "failed to query status code %u\n", GetLastError() );
3110  ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status );
3111 
3112  WinHttpCloseHandle( req );
3113 
3114  req =