1 /*
2  * Wininet - HTTP tests
3  *
4  * Copyright 2002 Aric Stewart
5  * Copyright 2004 Mike McCormack
6  * Copyright 2005 Hans Leidekker
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <limits.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wininet.h"
31 #include "winineti.h"
32 #include "winsock2.h"
33 
34 #include "wine/test.h"
35 
36 /* Undocumented security flags */
37 #define _SECURITY_FLAG_CERT_REV_FAILED    0x00800000
38 #define _SECURITY_FLAG_CERT_INVALID_CA    0x01000000
39 #define _SECURITY_FLAG_CERT_INVALID_CN    0x02000000
40 #define _SECURITY_FLAG_CERT_INVALID_DATE  0x04000000
41 
42 #define TEST_URL "http://test.winehq.org/tests/hello.html"
43 
44 static BOOL first_connection_to_test_url = TRUE;
45 
46 /* Adapted from dlls/urlmon/tests/protocol.c */
47 
48 #define SET_EXPECT2(status, num) \
49     expect[status] = num
50 
51 #define SET_EXPECT(status) \
52     SET_EXPECT2(status, 1)
53 
54 #define SET_OPTIONAL2(status, num) \
55     optional[status] = num
56 
57 #define SET_OPTIONAL(status) \
58     SET_OPTIONAL2(status, 1)
59 
60 /* SET_WINE_ALLOW's should be used with an appropriate
61  * todo_wine CHECK_NOTIFIED at a later point in the code */
62 #define SET_WINE_ALLOW2(status, num) \
63     wine_allow[status] = num
64 
65 #define SET_WINE_ALLOW(status) \
66     SET_WINE_ALLOW2(status, 1)
67 
68 #define CHECK_EXPECT(status) \
69     do { \
70         if (!expect[status] && !optional[status] && wine_allow[status]) \
71         { \
72             todo_wine ok(expect[status], "unexpected status %d (%s)\n", status, \
73                          status < MAX_INTERNET_STATUS && status_string[status] ? \
74                          status_string[status] : "unknown");            \
75             wine_allow[status]--; \
76         } \
77         else \
78         { \
79             ok(expect[status] || optional[status], "unexpected status %d (%s)\n", status,   \
80                status < MAX_INTERNET_STATUS && status_string[status] ? \
81                status_string[status] : "unknown");                      \
82             if (expect[status]) expect[status]--; \
83             else if(optional[status]) optional[status]--; \
84         } \
85         notified[status]++; \
86     }while(0)
87 
88 /* CLEAR_NOTIFIED used in cases when notification behavior
89  * differs between Windows versions */
90 #define CLEAR_NOTIFIED(status) \
91     expect[status] = optional[status] = wine_allow[status] = notified[status] = 0;
92 
93 #define CHECK_NOTIFIED2(status, num) \
94     do { \
95         ok(notified[status] + optional[status] == (num), \
96            "expected status %d (%s) %d times, received %d times\n", \
97            status, status < MAX_INTERNET_STATUS && status_string[status] ? \
98            status_string[status] : "unknown", (num), notified[status]); \
99         CLEAR_NOTIFIED(status);                                         \
100     }while(0)
101 
102 #define CHECK_NOTIFIED(status) \
103     CHECK_NOTIFIED2(status, 1)
104 
105 #define CHECK_NOT_NOTIFIED(status) \
106     CHECK_NOTIFIED2(status, 0)
107 
108 #define MAX_INTERNET_STATUS (INTERNET_STATUS_COOKIE_HISTORY+1)
109 static int expect[MAX_INTERNET_STATUS], optional[MAX_INTERNET_STATUS],
110     wine_allow[MAX_INTERNET_STATUS], notified[MAX_INTERNET_STATUS];
111 static const char *status_string[MAX_INTERNET_STATUS];
112 
113 static HANDLE complete_event, conn_close_event, conn_wait_event, server_req_rec_event, request_sent_event;
114 static DWORD req_error;
115 static BOOL is_ie7plus = TRUE;
116 
117 #define TESTF_REDIRECT      0x01
118 #define TESTF_COMPRESSED    0x02
119 #define TESTF_CHUNKED       0x04
120 
121 typedef struct {
122     const char *url;
123     const char *redirected_url;
124     const char *host;
125     const char *path;
126     const char *headers;
127     DWORD flags;
128     const char *post_data;
129     const char *content;
130 } test_data_t;
131 
132 static const test_data_t test_data[] = {
133     {
134         "http://test.winehq.org/tests/data.php",
135         "http://test.winehq.org/tests/data.php",
136         "test.winehq.org",
137         "/tests/data.php",
138         "",
139         TESTF_CHUNKED
140     },
141     {
142         "http://test.winehq.org/tests/redirect",
143         "http://test.winehq.org/tests/hello.html",
144         "test.winehq.org",
145         "/tests/redirect",
146         "",
147         TESTF_REDIRECT
148     },
149     {
150         "http://test.winehq.org/tests/gzip.php",
151         "http://test.winehq.org/tests/gzip.php",
152         "test.winehq.org",
153         "/tests/gzip.php",
154         "Accept-Encoding: gzip, deflate",
155         TESTF_COMPRESSED
156     },
157     {
158         "http://test.winehq.org/tests/post.php",
159         "http://test.winehq.org/tests/post.php",
160         "test.winehq.org",
161         "/tests/post.php",
162         "Content-Type: application/x-www-form-urlencoded",
163         0,
164         "mode=Test",
165         "mode => Test\n"
166     }
167 };
168 
169 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET ,INTERNET_STATUS_CALLBACK);
170 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackW)(HINTERNET ,INTERNET_STATUS_CALLBACK);
171 static BOOL (WINAPI *pInternetGetSecurityInfoByURLA)(LPSTR,PCCERT_CHAIN_CONTEXT*,DWORD*);
172 
173 static int strcmp_wa(LPCWSTR strw, const char *stra)
174 {
175     WCHAR buf[512];
176     MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
177     return lstrcmpW(strw, buf);
178 }
179 
180 static BOOL proxy_active(void)
181 {
182     HKEY internet_settings;
183     DWORD proxy_enable;
184     DWORD size;
185 
186     if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
187                       0, KEY_QUERY_VALUE, &internet_settings) != ERROR_SUCCESS)
188         return FALSE;
189 
190     size = sizeof(DWORD);
191     if (RegQueryValueExA(internet_settings, "ProxyEnable", NULL, NULL, (LPBYTE) &proxy_enable, &size) != ERROR_SUCCESS)
192         proxy_enable = 0;
193 
194     RegCloseKey(internet_settings);
195 
196     return proxy_enable != 0;
197 }
198 
199 static void init_events(void)
200 {
201     complete_event = CreateEventW(NULL, FALSE, FALSE, NULL);
202     conn_close_event = CreateEventW(NULL, FALSE, FALSE, NULL);
203     conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
204     server_req_rec_event = CreateEventW(NULL, FALSE, FALSE, NULL);
205     request_sent_event = CreateEventW(NULL, FALSE, FALSE, NULL);
206 }
207 
208 static void free_events(void)
209 {
210     CloseHandle(complete_event);
211     CloseHandle(conn_close_event);
212     CloseHandle(conn_wait_event);
213     CloseHandle(server_req_rec_event);
214     CloseHandle(request_sent_event);
215 }
216 
217 static void reset_events(void)
218 {
219     ResetEvent(complete_event);
220     ResetEvent(conn_close_event);
221     ResetEvent(conn_wait_event);
222     ResetEvent(server_req_rec_event);
223     ResetEvent(request_sent_event);
224 }
225 
226 #define test_status_code(a,b) _test_status_code(__LINE__,a,b, FALSE)
227 #define test_status_code_todo(a,b) _test_status_code(__LINE__,a,b, TRUE)
228 static void _test_status_code(unsigned line, HINTERNET req, DWORD excode, BOOL is_todo)
229 {
230     DWORD code, size, index;
231     char exbuf[12], bufa[10];
232     WCHAR bufw[10];
233     BOOL res;
234 
235     code = 0xdeadbeef;
236     size = sizeof(code);
237     res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, NULL);
238     ok_(__FILE__,line)(res, "[1] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE|number) failed: %u\n", GetLastError());
239     todo_wine_if (is_todo)
240         ok_(__FILE__,line)(code == excode, "code = %d, expected %d\n", code, excode);
241     ok_(__FILE__,line)(size == sizeof(code), "size = %u\n", size);
242 
243     code = 0xdeadbeef;
244     index = 0;
245     size = sizeof(code);
246     res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, &index);
247     ok_(__FILE__,line)(res, "[2] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE|number index) failed: %u\n", GetLastError());
248     ok_(__FILE__,line)(!index, "index = %d, expected 0\n", index);
249     ok_(__FILE__,line)(size == sizeof(code), "size = %u\n", size);
250 
251     sprintf(exbuf, "%u", excode);
252 
253     size = sizeof(bufa);
254     res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE, bufa, &size, NULL);
255     ok_(__FILE__,line)(res, "[3] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
256     todo_wine_if (is_todo)
257         ok_(__FILE__,line)(!strcmp(bufa, exbuf), "unexpected status code %s, expected %s\n", bufa, exbuf);
258     ok_(__FILE__,line)(size == strlen(exbuf), "unexpected size %d for \"%s\"\n", size, exbuf);
259 
260     size = 0;
261     res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE, NULL, &size, NULL);
262     ok_(__FILE__,line)(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
263                        "[4] HttpQueryInfoA(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
264     ok_(__FILE__,line)(size == strlen(exbuf)+1, "unexpected size %d for \"%s\"\n", size, exbuf);
265 
266     size = sizeof(bufw);
267     res = HttpQueryInfoW(req, HTTP_QUERY_STATUS_CODE, bufw, &size, NULL);
268     ok_(__FILE__,line)(res, "[5] HttpQueryInfoW(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
269     todo_wine_if (is_todo)
270         ok_(__FILE__,line)(!strcmp_wa(bufw, exbuf), "unexpected status code %s, expected %s\n", bufa, exbuf);
271     ok_(__FILE__,line)(size == strlen(exbuf)*sizeof(WCHAR), "unexpected size %d for \"%s\"\n", size, exbuf);
272 
273     size = 0;
274     res = HttpQueryInfoW(req, HTTP_QUERY_STATUS_CODE, bufw, &size, NULL);
275     ok_(__FILE__,line)(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
276                        "[6] HttpQueryInfoW(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
277     ok_(__FILE__,line)(size == (strlen(exbuf)+1)*sizeof(WCHAR), "unexpected size %d for \"%s\"\n", size, exbuf);
278 
279     if(0) {
280     size = sizeof(bufw);
281     res = HttpQueryInfoW(req, HTTP_QUERY_STATUS_CODE, NULL, &size, NULL);
282     ok(!res && GetLastError() == ERROR_INVALID_PARAMETER, "HttpQueryInfo(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
283     ok(size == sizeof(bufw), "unexpected size %d\n", size);
284     }
285 
286     code = 0xdeadbeef;
287     index = 1;
288     size = sizeof(code);
289     res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, &index);
290     ok_(__FILE__,line)(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
291                        "[7] HttpQueryInfoA failed: %x(%d)\n", res, GetLastError());
292 
293     code = 0xdeadbeef;
294     size = sizeof(code);
295     res = HttpQueryInfoA(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_REQUEST_HEADERS, &code, &size, NULL);
296     ok_(__FILE__,line)(!res && GetLastError() == ERROR_HTTP_INVALID_QUERY_REQUEST,
297                        "[8] HttpQueryInfoA failed: %x(%d)\n", res, GetLastError());
298 }
299 
300 #define test_request_flags(a,b) _test_request_flags(__LINE__,a,b,FALSE)
301 #define test_request_flags_todo(a,b) _test_request_flags(__LINE__,a,b,TRUE)
302 static void _test_request_flags(unsigned line, HINTERNET req, DWORD exflags, BOOL is_todo)
303 {
304     DWORD flags, size;
305     BOOL res;
306 
307     flags = 0xdeadbeef;
308     size = sizeof(flags);
309     res = InternetQueryOptionW(req, INTERNET_OPTION_REQUEST_FLAGS, &flags, &size);
310     ok_(__FILE__,line)(res, "InternetQueryOptionW(INTERNET_OPTION_REQUEST_FLAGS) failed: %u\n", GetLastError());
311 
312     /* FIXME: Remove once we have INTERNET_REQFLAG_CACHE_WRITE_DISABLED implementation */
313     flags &= ~INTERNET_REQFLAG_CACHE_WRITE_DISABLED;
314     todo_wine_if (is_todo)
315         ok_(__FILE__,line)(flags == exflags, "flags = %x, expected %x\n", flags, exflags);
316 }
317 
318 #define test_request_url(a,b) _test_request_url(__LINE__,a,b)
319 static void _test_request_url(unsigned line, HINTERNET req, const char *expected_url)
320 {
321     char buf[INTERNET_MAX_URL_LENGTH];
322     DWORD size = sizeof(buf);
323     BOOL res;
324 
325     res = InternetQueryOptionA(req, INTERNET_OPTION_URL, buf, &size);
326     ok_(__FILE__,line)(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
327     ok_(__FILE__,line)(size == strlen(expected_url), "size = %u\n", size);
328     ok_(__FILE__,line)(!strcmp(buf, expected_url), "unexpected URL %s, expected %s\n", buf, expected_url);
329 }
330 
331 #define test_http_version(a) _test_http_version(__LINE__,a)
332 static void _test_http_version(unsigned line, HINTERNET req)
333 {
334     HTTP_VERSION_INFO v = {0xdeadbeef, 0xdeadbeef};
335     DWORD size;
336     BOOL res;
337 
338     size = sizeof(v);
339     res = InternetQueryOptionW(req, INTERNET_OPTION_HTTP_VERSION, &v, &size);
340     ok_(__FILE__,line)(res, "InternetQueryOptionW(INTERNET_OPTION_HTTP_VERSION) failed: %u\n", GetLastError());
341     ok_(__FILE__,line)(v.dwMajorVersion == 1, "dwMajorVersion = %d\n", v.dwMajorVersion);
342     ok_(__FILE__,line)(v.dwMinorVersion == 1, "dwMinorVersion = %d\n", v.dwMinorVersion);
343 }
344 
345 static int close_handle_cnt;
346 
347 static VOID WINAPI callback(
348      HINTERNET hInternet,
349      DWORD_PTR dwContext,
350      DWORD dwInternetStatus,
351      LPVOID lpvStatusInformation,
352      DWORD dwStatusInformationLength
353 )
354 {
355     ros_skip_flaky
356     CHECK_EXPECT(dwInternetStatus);
357     switch (dwInternetStatus)
358     {
359         case INTERNET_STATUS_RESOLVING_NAME:
360             if(winetest_debug > 1)
361                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RESOLVING_NAME \"%s\" %d\n",
362                       GetCurrentThreadId(), hInternet, dwContext,
363                       (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
364             *(LPSTR)lpvStatusInformation = '\0';
365             break;
366         case INTERNET_STATUS_NAME_RESOLVED:
367             if(winetest_debug > 1)
368                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_NAME_RESOLVED \"%s\" %d\n",
369                       GetCurrentThreadId(), hInternet, dwContext,
370                       (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
371             *(LPSTR)lpvStatusInformation = '\0';
372             break;
373         case INTERNET_STATUS_CONNECTING_TO_SERVER:
374             if(winetest_debug > 1)
375                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTING_TO_SERVER \"%s\" %d\n",
376                       GetCurrentThreadId(), hInternet, dwContext,
377                       (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
378             ok(dwStatusInformationLength == strlen(lpvStatusInformation)+1, "unexpected size %u\n",
379                dwStatusInformationLength);
380             *(LPSTR)lpvStatusInformation = '\0';
381             break;
382         case INTERNET_STATUS_CONNECTED_TO_SERVER:
383             if(winetest_debug > 1)
384                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTED_TO_SERVER \"%s\" %d\n",
385                       GetCurrentThreadId(), hInternet, dwContext,
386                       (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
387             ok(dwStatusInformationLength == strlen(lpvStatusInformation)+1, "unexpected size %u\n",
388                dwStatusInformationLength);
389             *(LPSTR)lpvStatusInformation = '\0';
390             break;
391         case INTERNET_STATUS_SENDING_REQUEST:
392             if(winetest_debug > 1)
393                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_SENDING_REQUEST %p %d\n",
394                       GetCurrentThreadId(), hInternet, dwContext,
395                       lpvStatusInformation,dwStatusInformationLength);
396             break;
397         case INTERNET_STATUS_REQUEST_SENT:
398             ok(dwStatusInformationLength == sizeof(DWORD),
399                 "info length should be sizeof(DWORD) instead of %d\n",
400                 dwStatusInformationLength);
401             if(winetest_debug > 1)
402                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REQUEST_SENT 0x%x %d\n",
403                       GetCurrentThreadId(), hInternet, dwContext,
404                       *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
405             break;
406         case INTERNET_STATUS_RECEIVING_RESPONSE:
407             if(winetest_debug > 1)
408                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RECEIVING_RESPONSE %p %d\n",
409                       GetCurrentThreadId(), hInternet, dwContext,
410                       lpvStatusInformation,dwStatusInformationLength);
411             break;
412         case INTERNET_STATUS_RESPONSE_RECEIVED:
413             ok(dwStatusInformationLength == sizeof(DWORD),
414                 "info length should be sizeof(DWORD) instead of %d\n",
415                 dwStatusInformationLength);
416             if(winetest_debug > 1)
417                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RESPONSE_RECEIVED 0x%x %d\n",
418                       GetCurrentThreadId(), hInternet, dwContext,
419                       *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
420             break;
421         case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
422             if(winetest_debug > 1)
423                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CTL_RESPONSE_RECEIVED %p %d\n",
424                       GetCurrentThreadId(), hInternet,dwContext,
425                       lpvStatusInformation,dwStatusInformationLength);
426             break;
427         case INTERNET_STATUS_PREFETCH:
428             if(winetest_debug > 1)
429                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_PREFETCH %p %d\n",
430                       GetCurrentThreadId(), hInternet, dwContext,
431                       lpvStatusInformation,dwStatusInformationLength);
432             break;
433         case INTERNET_STATUS_CLOSING_CONNECTION:
434             if(winetest_debug > 1)
435                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CLOSING_CONNECTION %p %d\n",
436                       GetCurrentThreadId(), hInternet, dwContext,
437                       lpvStatusInformation,dwStatusInformationLength);
438             break;
439         case INTERNET_STATUS_CONNECTION_CLOSED:
440             if(winetest_debug > 1)
441                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTION_CLOSED %p %d\n",
442                       GetCurrentThreadId(), hInternet, dwContext,
443                       lpvStatusInformation,dwStatusInformationLength);
444             break;
445         case INTERNET_STATUS_HANDLE_CREATED:
446             ok(dwStatusInformationLength == sizeof(HINTERNET),
447                 "info length should be sizeof(HINTERNET) instead of %d\n",
448                 dwStatusInformationLength);
449             if(winetest_debug > 1)
450                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CREATED %p %d\n",
451                       GetCurrentThreadId(), hInternet, dwContext,
452                       *(HINTERNET *)lpvStatusInformation,dwStatusInformationLength);
453             CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
454             SET_EXPECT(INTERNET_STATUS_DETECTING_PROXY);
455             break;
456         case INTERNET_STATUS_HANDLE_CLOSING:
457             ok(dwStatusInformationLength == sizeof(HINTERNET),
458                 "info length should be sizeof(HINTERNET) instead of %d\n",
459                 dwStatusInformationLength);
460             if(winetest_debug > 1)
461                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CLOSING %p %d\n",
462                       GetCurrentThreadId(), hInternet, dwContext,
463                       *(HINTERNET *)lpvStatusInformation, dwStatusInformationLength);
464             if(!InterlockedDecrement(&close_handle_cnt))
465                 SetEvent(complete_event);
466             break;
467         case INTERNET_STATUS_REQUEST_COMPLETE:
468         {
469             INTERNET_ASYNC_RESULT *iar = (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
470             ok(dwStatusInformationLength == sizeof(INTERNET_ASYNC_RESULT),
471                 "info length should be sizeof(INTERNET_ASYNC_RESULT) instead of %d\n",
472                 dwStatusInformationLength);
473             ok(iar->dwResult == 1 || iar->dwResult == 0, "iar->dwResult = %ld\n", iar->dwResult);
474             if(winetest_debug > 1)
475                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REQUEST_COMPLETE {%ld,%d} %d\n",
476                       GetCurrentThreadId(), hInternet, dwContext,
477                       iar->dwResult,iar->dwError,dwStatusInformationLength);
478             req_error = iar->dwError;
479             if(!close_handle_cnt)
480                 SetEvent(complete_event);
481             break;
482         }
483         case INTERNET_STATUS_REDIRECT:
484             if(winetest_debug > 1)
485                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REDIRECT \"%s\" %d\n",
486                       GetCurrentThreadId(), hInternet, dwContext,
487                       (LPCSTR)lpvStatusInformation, dwStatusInformationLength);
488             *(LPSTR)lpvStatusInformation = '\0';
489             CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
490             SET_EXPECT(INTERNET_STATUS_DETECTING_PROXY);
491             break;
492         case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
493             if(winetest_debug > 1)
494                 trace("%04x:Callback %p 0x%lx INTERNET_STATUS_INTERMEDIATE_RESPONSE %p %d\n",
495                       GetCurrentThreadId(), hInternet, dwContext,
496                       lpvStatusInformation, dwStatusInformationLength);
497             break;
498         default:
499             if(winetest_debug > 1)
500                 trace("%04x:Callback %p 0x%lx %d %p %d\n",
501                       GetCurrentThreadId(), hInternet, dwContext, dwInternetStatus,
502                       lpvStatusInformation, dwStatusInformationLength);
503     }
504 }
505 
506 typedef struct {
507     HINTERNET session;
508     HINTERNET connection;
509     HINTERNET request;
510 } test_request_t;
511 
512 #define open_simple_request(a,b,c,d,e) _open_simple_request(__LINE__,a,b,c,d,e)
513 static void _open_simple_request(unsigned line, test_request_t *req, const char *host,
514         int port, const char *verb, const char *url)
515 {
516     req->session = InternetOpenA(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
517     ok_(__FILE__,line)(req->session != NULL, "InternetOpenA failed: %u\n", GetLastError());
518 
519     req->connection = InternetConnectA(req->session, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
520     ok_(__FILE__,line)(req->connection != NULL, "InternetConnectA failed: %u\n", GetLastError());
521 
522     req->request = HttpOpenRequestA(req->connection, verb, url, NULL, NULL, NULL, 0, 0);
523     ok_(__FILE__,line)(req->request != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
524 }
525 
526 #define close_request(a) _close_request(__LINE__,a)
527 static void _close_request(unsigned line, test_request_t *req)
528 {
529     BOOL ret;
530 
531     ret = InternetCloseHandle(req->request);
532     ok_(__FILE__,line)(ret, "InternetCloseHandle(request) failed: %u\n", GetLastError());
533     ret = InternetCloseHandle(req->connection);
534     ok_(__FILE__,line)(ret, "InternetCloseHandle(connection) failed: %u\n", GetLastError());
535     ret = InternetCloseHandle(req->session);
536     ok_(__FILE__,line)(ret, "InternetCloseHandle(session) failed: %u\n", GetLastError());
537 }
538 
539 #define receive_simple_request(a,b,c) _receive_simple_request(__LINE__,a,b,c)
540 static DWORD _receive_simple_request(unsigned line, HINTERNET req, char *buf, size_t buf_size)
541 {
542     DWORD read = 0;
543     BOOL ret;
544 
545     ret = InternetReadFile(req, buf, buf_size, &read);
546     ok_(__FILE__,line)(ret, "InternetReadFile failed: %u\n", GetLastError());
547 
548     return read;
549 }
550 
551 static void close_async_handle(HINTERNET handle, int handle_cnt)
552 {
553     BOOL res;
554 
555     close_handle_cnt = handle_cnt;
556 
557     SET_EXPECT2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
558     res = InternetCloseHandle(handle);
559     ok(res, "InternetCloseHandle failed: %u\n", GetLastError());
560     WaitForSingleObject(complete_event, INFINITE);
561     CHECK_NOTIFIED2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
562 }
563 
564 static void InternetReadFile_test(int flags, const test_data_t *test)
565 {
566     char *post_data = NULL;
567     BOOL res, on_async = TRUE;
568     CHAR buffer[4000];
569     WCHAR wbuffer[4000];
570     DWORD length, length2, index, exlen = 0, post_len = 0;
571     const char *types[2] = { "*", NULL };
572     HINTERNET hi, hic = 0, hor = 0;
573 
574     trace("Starting InternetReadFile test with flags 0x%x on url %s\n",flags,test->url);
575     reset_events();
576 
577     trace("InternetOpenA <--\n");
578     hi = InternetOpenA((test->flags & TESTF_COMPRESSED) ? "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" : "",
579             INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
580     ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
581     trace("InternetOpenA -->\n");
582 
583     if (hi == 0x0) goto abort;
584 
585     pInternetSetStatusCallbackA(hi,&callback);
586 
587     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
588 
589     trace("InternetConnectA <--\n");
590     hic=InternetConnectA(hi, test->host, INTERNET_INVALID_PORT_NUMBER,
591                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
592     ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
593     trace("InternetConnectA -->\n");
594 
595     if (hic == 0x0) goto abort;
596 
597     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
598     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
599 
600     trace("HttpOpenRequestA <--\n");
601     hor = HttpOpenRequestA(hic, test->post_data ? "POST" : "GET", test->path, NULL, NULL, types,
602                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
603                            0xdeadbead);
604     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
605         /*
606          * If the internet name can't be resolved we are probably behind
607          * a firewall or in some other way not directly connected to the
608          * Internet. Not enough reason to fail the test. Just ignore and
609          * abort.
610          */
611     } else  {
612         ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
613     }
614     trace("HttpOpenRequestA -->\n");
615 
616     if (hor == 0x0) goto abort;
617 
618     test_request_flags(hor, INTERNET_REQFLAG_NO_HEADERS);
619     test_request_url(hor, test->url);
620 
621     length = sizeof(buffer);
622     res = HttpQueryInfoA(hor, HTTP_QUERY_RAW_HEADERS, buffer, &length, 0x0);
623     ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
624     ok(length == 0 || (length == 1 && !*buffer) /* win10 */, "HTTP_QUERY_RAW_HEADERS: expected length 0, but got %d\n", length);
625     ok(!strcmp(buffer, ""), "HTTP_QUERY_RAW_HEADERS: expected string \"\", but got \"%s\"\n", buffer);
626 
627     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
628     CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
629     CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
630     SET_OPTIONAL2(INTERNET_STATUS_COOKIE_SENT,2);
631     SET_OPTIONAL2(INTERNET_STATUS_COOKIE_RECEIVED,2);
632     if (first_connection_to_test_url)
633     {
634         SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
635         SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
636     }
637     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
638     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
639     SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1);
640     SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1);
641     SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1);
642     SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1);
643     if(test->flags & TESTF_REDIRECT) {
644         SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
645         SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
646     }
647     SET_EXPECT(INTERNET_STATUS_REDIRECT);
648     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER);
649     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER);
650     if (flags & INTERNET_FLAG_ASYNC)
651         SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
652 
653     if(test->flags & TESTF_COMPRESSED) {
654         BOOL b = TRUE;
655 
656         res = InternetSetOptionA(hor, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
657         ok(res || broken(!res && GetLastError() == ERROR_INTERNET_INVALID_OPTION),
658            "InternetSetOption failed: %u\n", GetLastError());
659         if(!res)
660             goto abort;
661     }
662 
663     test_status_code(hor, 0);
664 
665     trace("HttpSendRequestA -->\n");
666     if(test->post_data) {
667         post_len = strlen(test->post_data);
668         post_data = HeapAlloc(GetProcessHeap(), 0, post_len);
669         memcpy(post_data, test->post_data, post_len);
670     }
671     SetLastError(0xdeadbeef);
672     res = HttpSendRequestA(hor, test->headers, -1, post_data, post_len);
673     if (flags & INTERNET_FLAG_ASYNC)
674         ok(!res && (GetLastError() == ERROR_IO_PENDING),
675             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
676     else
677         ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED),
678            "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
679     trace("HttpSendRequestA <--\n");
680 
681     if (flags & INTERNET_FLAG_ASYNC) {
682         WaitForSingleObject(complete_event, INFINITE);
683         ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
684     }
685     HeapFree(GetProcessHeap(), 0, post_data);
686 
687     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
688     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_RECEIVED);
689     if (first_connection_to_test_url)
690     {
691         if (! proxy_active())
692         {
693             CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
694             CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
695         }
696         else
697         {
698             CLEAR_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
699             CLEAR_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
700         }
701     }
702     else
703     {
704         CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
705         CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
706     }
707     CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1);
708     CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1);
709     CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1);
710     CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1);
711     if(test->flags & TESTF_REDIRECT)
712         CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
713     if (flags & INTERNET_FLAG_ASYNC)
714         CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
715     /* Sent on WinXP only if first_connection_to_test_url is TRUE, on Win98 always sent */
716     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
717     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
718 
719     test_request_flags(hor, 0);
720 
721     length = 100;
722     res = InternetQueryOptionA(hor,INTERNET_OPTION_URL,buffer,&length);
723     ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed with error %d\n", GetLastError());
724 
725     length = sizeof(buffer)-2;
726     memset(buffer, 0x77, sizeof(buffer));
727     SetLastError(0xdeadbeef);
728     res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length,0x0);
729     ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
730     ok(GetLastError() == 0 ||
731                 broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
732     /* show that the function writes data past the length returned */
733     ok(buffer[length-2], "Expected any header character, got 0x00\n");
734     ok(!buffer[length-1], "Expected 0x00, got %02X\n", buffer[length-1]);
735     ok(!buffer[length], "Expected 0x00, got %02X\n", buffer[length]);
736     ok(buffer[length+1] == 0x77, "Expected 0x77, got %02X\n", buffer[length+1]);
737 
738     length2 = length;
739     res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length2,0x0);
740     ok(!res, "Expected 0x00, got %d\n", res);
741     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
742     ok(length2 == length+1, "Expected %d, got %d\n", length+1, length2);
743     /* the in length of the buffer must be +1 but the length returned does not count this */
744     length2 = length+1;
745     memset(buffer, 0x77, sizeof(buffer));
746     res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length2,0x0);
747     ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
748     ok(buffer[length2] == 0x00, "Expected 0x00, got %02X\n", buffer[length2]);
749     ok(buffer[length2+1] == 0x77, "Expected 0x77, got %02X\n", buffer[length2+1]);
750     ok(length2 == length, "Value should not have changed: %d != %d\n", length2, length);
751 
752     length = sizeof(wbuffer)-2*sizeof(WCHAR);
753     memset(wbuffer, 0x77, sizeof(wbuffer));
754     res = HttpQueryInfoW(hor, HTTP_QUERY_RAW_HEADERS, wbuffer, &length, 0x0);
755     ok(res, "HttpQueryInfoW(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
756     ok(length % sizeof(WCHAR) == 0, "Expected that length is a multiple of sizeof(WCHAR), got %d.\n", length);
757     length /= sizeof(WCHAR);
758     /* show that the function writes data past the length returned */
759     ok(wbuffer[length-2], "Expected any header character, got 0x0000\n");
760     ok(!wbuffer[length-1], "Expected 0x0000, got %04X\n", wbuffer[length-1]);
761     ok(!wbuffer[length], "Expected 0x0000, got %04X\n", wbuffer[length]);
762     ok(wbuffer[length+1] == 0x7777 || broken(wbuffer[length+1] != 0x7777),
763        "Expected 0x7777, got %04X\n", wbuffer[length+1]);
764 
765     length2 = length*sizeof(WCHAR);
766     res = HttpQueryInfoW(hor,HTTP_QUERY_RAW_HEADERS,wbuffer,&length2,0x0);
767     ok(!res, "Expected 0x00, got %d\n", res);
768     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
769     ok(length2 % sizeof(WCHAR) == 0, "Expected that length is a multiple of sizeof(WCHAR), got %d.\n", length2);
770     length2 /= sizeof(WCHAR);
771     ok(length2 == length+1, "Expected %d, got %d\n", length+1, length2);
772     /* the in length of the buffer must be +1 but the length returned does not count this */
773     length2 = (length+1)*sizeof(WCHAR);
774     memset(wbuffer, 0x77, sizeof(wbuffer));
775     res = HttpQueryInfoW(hor,HTTP_QUERY_RAW_HEADERS,wbuffer,&length2,0x0);
776     ok(res, "HttpQueryInfoW(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
777     ok(length2 % sizeof(WCHAR) == 0, "Expected that length is a multiple of sizeof(WCHAR), got %d.\n", length2);
778     length2 /= sizeof(WCHAR);
779     ok(!wbuffer[length2], "Expected 0x0000, got %04X\n", wbuffer[length2]);
780     ok(wbuffer[length2+1] == 0x7777, "Expected 0x7777, got %04X\n", wbuffer[length2+1]);
781     ok(length2 == length, "Value should not have changed: %d != %d\n", length2, length);
782 
783     test_request_url(hor, test->redirected_url);
784 
785     index = 0;
786     length = 0;
787     SetLastError(0xdeadbeef);
788     ok(HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,NULL,&length,&index) == FALSE,"Query worked\n");
789     if(test->flags & TESTF_COMPRESSED)
790         ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
791            "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", GetLastError());
792     ok(index == 0, "Index was incremented\n");
793 
794     index = 0;
795     length = 16;
796     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,&index);
797     trace("Option HTTP_QUERY_CONTENT_LENGTH -> %i  %s  (%u)\n",res,buffer,GetLastError());
798     if(test->flags & TESTF_COMPRESSED)
799         ok(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
800            "expected ERROR_HTTP_HEADER_NOT_FOUND, got %x (%u)\n", res, GetLastError());
801     ok(!res || index == 1, "Index was not incremented although result is %x (index = %u)\n", res, index);
802 
803     length = 100;
804     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
805     buffer[length]=0;
806     trace("Option HTTP_QUERY_CONTENT_TYPE -> %i  %s\n",res,buffer);
807 
808     length = 100;
809     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_ENCODING,buffer,&length,0x0);
810     buffer[length]=0;
811     trace("Option HTTP_QUERY_CONTENT_ENCODING -> %i  %s\n",res,buffer);
812 
813     SetLastError(0xdeadbeef);
814     res = InternetReadFile(NULL, buffer, 100, &length);
815     ok(!res, "InternetReadFile should have failed\n");
816     ok(GetLastError() == ERROR_INVALID_HANDLE,
817         "InternetReadFile should have set last error to ERROR_INVALID_HANDLE instead of %u\n",
818         GetLastError());
819 
820     length = 100;
821     if(winetest_debug > 1)
822         trace("Entering Query loop\n");
823 
824     while (TRUE)
825     {
826         if (flags & INTERNET_FLAG_ASYNC)
827             SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
828 
829         /* IE11 calls those in InternetQueryDataAvailable call. */
830         SET_OPTIONAL(INTERNET_STATUS_RECEIVING_RESPONSE);
831         SET_OPTIONAL(INTERNET_STATUS_RESPONSE_RECEIVED);
832 
833         length = 0;
834         res = InternetQueryDataAvailable(hor,&length,0x0,0x0);
835 
836         CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
837 
838         if (flags & INTERNET_FLAG_ASYNC)
839         {
840             if (res)
841             {
842                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
843                 if(exlen) {
844                     ok(length >= exlen, "length %u < exlen %u\n", length, exlen);
845                     exlen = 0;
846                 }
847             }
848             else if (GetLastError() == ERROR_IO_PENDING)
849             {
850                 if(winetest_debug > 1)
851                     trace("pending\n");
852                 /* on some tests, InternetQueryDataAvailable returns non-zero length and ERROR_IO_PENDING */
853                 if(!(test->flags & TESTF_CHUNKED))
854                     ok(!length, "InternetQueryDataAvailable returned ERROR_IO_PENDING and %u length\n", length);
855                 WaitForSingleObject(complete_event, INFINITE);
856                 exlen = length;
857                 ok(exlen, "length = 0\n");
858                 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
859                 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
860                 ok(req_error, "req_error = 0\n");
861                 continue;
862             }else {
863                 ok(0, "InternetQueryDataAvailable failed: %u\n", GetLastError());
864             }
865         }else {
866             ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
867         }
868         CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
869 
870         if(winetest_debug > 1)
871             trace("length %u\n", length);
872         if(test->flags & TESTF_CHUNKED)
873             ok(length <= 8192, "length = %d, expected <= 8192\n", length);
874         if (length)
875         {
876             char *buffer;
877             buffer = HeapAlloc(GetProcessHeap(),0,length+1);
878 
879             res = InternetReadFile(hor,buffer,length,&length);
880 
881             buffer[length]=0;
882 
883             if(winetest_debug > 1)
884                 trace("ReadFile -> %s %i\n", res ? "TRUE" : "FALSE", length);
885 
886             if(test->content)
887                 ok(!strcmp(buffer, test->content), "buffer = '%s', expected '%s'\n", buffer, test->content);
888             HeapFree(GetProcessHeap(),0,buffer);
889         }else {
890             ok(!on_async, "Returned zero size in response to request complete\n");
891             break;
892         }
893         on_async = FALSE;
894     }
895     if(test->flags & TESTF_REDIRECT) {
896         CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
897         CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
898     }
899 abort:
900     if(winetest_debug > 1)
901         trace("aborting\n");
902     close_async_handle(hi, 2);
903     first_connection_to_test_url = FALSE;
904 }
905 
906 static void InternetReadFile_chunked_test(void)
907 {
908     BOOL res;
909     CHAR buffer[4000];
910     DWORD length, got;
911     const char *types[2] = { "*", NULL };
912     HINTERNET hi, hic = 0, hor = 0;
913 
914     trace("Starting InternetReadFile chunked test\n");
915 
916     trace("InternetOpenA <--\n");
917     hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
918     ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
919     trace("InternetOpenA -->\n");
920 
921     if (hi == 0x0) goto abort;
922 
923     trace("InternetConnectA <--\n");
924     hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER,
925                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
926     ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
927     trace("InternetConnectA -->\n");
928 
929     if (hic == 0x0) goto abort;
930 
931     trace("HttpOpenRequestA <--\n");
932     hor = HttpOpenRequestA(hic, "GET", "/tests/chunked", NULL, NULL, types,
933                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
934                            0xdeadbead);
935     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
936         /*
937          * If the internet name can't be resolved we are probably behind
938          * a firewall or in some other way not directly connected to the
939          * Internet. Not enough reason to fail the test. Just ignore and
940          * abort.
941          */
942     } else  {
943         ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
944     }
945     trace("HttpOpenRequestA -->\n");
946 
947     if (hor == 0x0) goto abort;
948 
949     trace("HttpSendRequestA -->\n");
950     SetLastError(0xdeadbeef);
951     res = HttpSendRequestA(hor, "", -1, NULL, 0);
952     ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED),
953        "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
954     trace("HttpSendRequestA <--\n");
955 
956     test_request_flags(hor, 0);
957 
958     length = 100;
959     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
960     buffer[length]=0;
961     trace("Option CONTENT_TYPE -> %i  %s\n",res,buffer);
962 
963     SetLastError( 0xdeadbeef );
964     length = 100;
965     res = HttpQueryInfoA(hor,HTTP_QUERY_TRANSFER_ENCODING,buffer,&length,0x0);
966     buffer[length]=0;
967     trace("Option TRANSFER_ENCODING -> %i  %s\n",res,buffer);
968     ok( res || ( proxy_active() && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND ),
969         "Failed to get TRANSFER_ENCODING option, error %u\n", GetLastError() );
970     ok( !strcmp( buffer, "chunked" ) || ( ! res && proxy_active() && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND ),
971         "Wrong transfer encoding '%s'\n", buffer );
972 
973     SetLastError( 0xdeadbeef );
974     length = 16;
975     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0);
976     ok( !res, "Found CONTENT_LENGTH option '%s'\n", buffer );
977     ok( GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "Wrong error %u\n", GetLastError() );
978 
979     length = 100;
980     trace("Entering Query loop\n");
981 
982     while (TRUE)
983     {
984         res = InternetQueryDataAvailable(hor,&length,0x0,0x0);
985         ok(!(!res && length != 0),"InternetQueryDataAvailable failed with non-zero length\n");
986         ok(res, "InternetQueryDataAvailable failed, error %d\n", GetLastError());
987         trace("got %u available\n",length);
988         if (length)
989         {
990             char *buffer = HeapAlloc(GetProcessHeap(),0,length+1);
991 
992             SetLastError(0xdeadbeef);
993             res = InternetReadFile(hor,buffer,length,&got);
994             ok(GetLastError() == 0 ||
995                 broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
996 
997             buffer[got]=0;
998             trace("ReadFile -> %i %i\n",res,got);
999             ok( length == got, "only got %u of %u available\n", got, length );
1000             ok( buffer[got-1] == '\n', "received partial line '%s'\n", buffer );
1001 
1002             HeapFree(GetProcessHeap(),0,buffer);
1003             if (!got) break;
1004         }
1005         if (length == 0)
1006         {
1007             got = 0xdeadbeef;
1008             SetLastError(0xdeadbeef);
1009             res = InternetReadFile( hor, buffer, 1, &got );
1010             ok( res, "InternetReadFile failed: %u\n", GetLastError() );
1011             ok(GetLastError() == 0 ||
1012                 broken(GetLastError() == 0xdeadbeef /* XP/W2K3 */), "Last Error not reset %u\n", GetLastError());
1013             ok( !got, "got %u\n", got );
1014             break;
1015         }
1016     }
1017 abort:
1018     trace("aborting\n");
1019     if (hor != 0x0) {
1020         res = InternetCloseHandle(hor);
1021         ok (res, "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n");
1022     }
1023     if (hi != 0x0) {
1024         res = InternetCloseHandle(hi);
1025         ok (res, "InternetCloseHandle of handle opened by InternetOpenA failed\n");
1026     }
1027 }
1028 
1029 static void InternetReadFileExA_test(int flags)
1030 {
1031     DWORD rc;
1032     DWORD length;
1033     const char *types[2] = { "*", NULL };
1034     HINTERNET hi, hic = 0, hor = 0;
1035     INTERNET_BUFFERSA inetbuffers;
1036 
1037     trace("Starting InternetReadFileExA test with flags 0x%x\n",flags);
1038     reset_events();
1039 
1040     trace("InternetOpenA <--\n");
1041     hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
1042     ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
1043     trace("InternetOpenA -->\n");
1044 
1045     if (hi == 0x0) goto abort;
1046 
1047     pInternetSetStatusCallbackA(hi,&callback);
1048 
1049     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1050 
1051     trace("InternetConnectA <--\n");
1052     hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER,
1053                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
1054     ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
1055     trace("InternetConnectA -->\n");
1056 
1057     if (hic == 0x0) goto abort;
1058 
1059     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1060     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1061 
1062     trace("HttpOpenRequestA <--\n");
1063     hor = HttpOpenRequestA(hic, "GET", "/tests/redirect", NULL, NULL, types,
1064                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RELOAD,
1065                            0xdeadbead);
1066     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
1067         /*
1068          * If the internet name can't be resolved we are probably behind
1069          * a firewall or in some other way not directly connected to the
1070          * Internet. Not enough reason to fail the test. Just ignore and
1071          * abort.
1072          */
1073     } else  {
1074         ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
1075     }
1076     trace("HttpOpenRequestA -->\n");
1077 
1078     if (hor == 0x0) goto abort;
1079 
1080     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1081     CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
1082     CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
1083     if (first_connection_to_test_url)
1084     {
1085         SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
1086         SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
1087     }
1088     SET_OPTIONAL2(INTERNET_STATUS_COOKIE_SENT, 2);
1089     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
1090     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
1091     SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, 2);
1092     SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, 2);
1093     SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, 2);
1094     SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, 2);
1095     SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
1096     SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
1097     SET_EXPECT(INTERNET_STATUS_REDIRECT);
1098     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER);
1099     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER);
1100     if (flags & INTERNET_FLAG_ASYNC)
1101         SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
1102     else
1103         SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_COMPLETE);
1104 
1105     trace("HttpSendRequestA -->\n");
1106     SetLastError(0xdeadbeef);
1107     rc = HttpSendRequestA(hor, "", -1, NULL, 0);
1108     if (flags & INTERNET_FLAG_ASYNC)
1109         ok(((rc == 0)&&(GetLastError() == ERROR_IO_PENDING)),
1110             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
1111     else
1112         ok((rc != 0) || GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED,
1113            "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
1114     trace("HttpSendRequestA <--\n");
1115 
1116     if (!rc && (GetLastError() == ERROR_IO_PENDING)) {
1117         WaitForSingleObject(complete_event, INFINITE);
1118         ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
1119     }
1120 
1121     if (first_connection_to_test_url)
1122     {
1123         CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
1124         CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
1125     }
1126     else
1127     {
1128         CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
1129         CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
1130     }
1131     CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, 2);
1132     CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, 2);
1133     CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, 2);
1134     CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, 2);
1135     CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
1136     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
1137     CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
1138     if (flags & INTERNET_FLAG_ASYNC)
1139         CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1140     else
1141         todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1142     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
1143     /* Sent on WinXP only if first_connection_to_test_url is TRUE, on Win98 always sent */
1144     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
1145     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
1146 
1147     if(is_ie7plus) {
1148         rc = InternetReadFileExW(hor, NULL, 0, 0xdeadcafe);
1149         ok(!rc && (GetLastError() == ERROR_INVALID_PARAMETER),
1150            "InternetReadFileEx should have failed with ERROR_INVALID_PARAMETER instead of %s, %u\n",
1151            rc ? "TRUE" : "FALSE", GetLastError());
1152     }
1153 
1154     /* tests invalid dwStructSize */
1155     inetbuffers.dwStructSize = sizeof(inetbuffers)+1;
1156     inetbuffers.lpcszHeader = NULL;
1157     inetbuffers.dwHeadersLength = 0;
1158     inetbuffers.dwBufferLength = 10;
1159     inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, 10);
1160     inetbuffers.dwOffsetHigh = 1234;
1161     inetbuffers.dwOffsetLow = 5678;
1162     rc = InternetReadFileExA(hor, &inetbuffers, 0, 0xdeadcafe);
1163     ok(!rc && (GetLastError() == ERROR_INVALID_PARAMETER),
1164         "InternetReadFileEx should have failed with ERROR_INVALID_PARAMETER instead of %s, %u\n",
1165         rc ? "TRUE" : "FALSE", GetLastError());
1166     HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
1167 
1168     test_request_flags(hor, 0);
1169 
1170     /* tests to see whether lpcszHeader is used - it isn't */
1171     inetbuffers.dwStructSize = sizeof(inetbuffers);
1172     inetbuffers.lpcszHeader = (LPCSTR)0xdeadbeef;
1173     inetbuffers.dwHeadersLength = 255;
1174     inetbuffers.dwBufferLength = 0;
1175     inetbuffers.lpvBuffer = NULL;
1176     inetbuffers.dwOffsetHigh = 1234;
1177     inetbuffers.dwOffsetLow = 5678;
1178     rc = InternetReadFileExA(hor, &inetbuffers, 0, 0xdeadcafe);
1179     ok(rc, "InternetReadFileEx failed with error %u\n", GetLastError());
1180     trace("read %i bytes\n", inetbuffers.dwBufferLength);
1181 
1182     rc = InternetReadFileExA(NULL, &inetbuffers, 0, 0xdeadcafe);
1183     ok(!rc && (GetLastError() == ERROR_INVALID_HANDLE),
1184         "InternetReadFileEx should have failed with ERROR_INVALID_HANDLE instead of %s, %u\n",
1185         rc ? "TRUE" : "FALSE", GetLastError());
1186 
1187     length = 0;
1188     trace("Entering Query loop\n");
1189 
1190     while (TRUE)
1191     {
1192         inetbuffers.dwStructSize = sizeof(inetbuffers);
1193         inetbuffers.dwBufferLength = 1024;
1194         inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, inetbuffers.dwBufferLength+1);
1195         inetbuffers.dwOffsetHigh = 1234;
1196         inetbuffers.dwOffsetLow = 5678;
1197 
1198         SET_WINE_ALLOW(INTERNET_STATUS_RECEIVING_RESPONSE);
1199         SET_WINE_ALLOW(INTERNET_STATUS_RESPONSE_RECEIVED);
1200         SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
1201         rc = InternetReadFileExA(hor, &inetbuffers, IRF_ASYNC | IRF_USE_CONTEXT, 0xcafebabe);
1202         if (!rc)
1203         {
1204             if (GetLastError() == ERROR_IO_PENDING)
1205             {
1206                 trace("InternetReadFileEx -> PENDING\n");
1207                 ok(flags & INTERNET_FLAG_ASYNC,
1208                    "Should not get ERROR_IO_PENDING without INTERNET_FLAG_ASYNC\n");
1209                 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1210                 WaitForSingleObject(complete_event, INFINITE);
1211                 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1212                 CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1213                 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
1214             }
1215             else
1216             {
1217                 trace("InternetReadFileEx -> FAILED %u\n", GetLastError());
1218                 break;
1219             }
1220         }
1221         else
1222         {
1223             trace("InternetReadFileEx -> SUCCEEDED\n");
1224             CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1225             if (inetbuffers.dwBufferLength)
1226             {
1227                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1228                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1229             }
1230             else
1231             {
1232                 /* Win98 still sends these when 0 bytes are read, WinXP does not */
1233                 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1234                 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1235             }
1236         }
1237 
1238         trace("read %i bytes\n", inetbuffers.dwBufferLength);
1239         ((char *)inetbuffers.lpvBuffer)[inetbuffers.dwBufferLength] = '\0';
1240 
1241         ok(inetbuffers.dwOffsetHigh == 1234 && inetbuffers.dwOffsetLow == 5678,
1242             "InternetReadFileEx sets offsets to 0x%x%08x\n",
1243             inetbuffers.dwOffsetHigh, inetbuffers.dwOffsetLow);
1244 
1245         HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
1246 
1247         if (!inetbuffers.dwBufferLength)
1248             break;
1249 
1250         length += inetbuffers.dwBufferLength;
1251     }
1252     ok(length > 0, "failed to read any of the document\n");
1253     trace("Finished. Read %d bytes\n", length);
1254 
1255 abort:
1256     close_async_handle(hi, 2);
1257     first_connection_to_test_url = FALSE;
1258 }
1259 
1260 static void InternetOpenUrlA_test(void)
1261 {
1262   HINTERNET myhinternet, myhttp;
1263   char buffer[0x400];
1264   DWORD size, readbytes, totalbytes=0;
1265   BOOL ret;
1266 
1267   ret = DeleteUrlCacheEntryA(TEST_URL);
1268   ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND,
1269           "DeleteUrlCacheEntry returned %x, GetLastError() = %d\n", ret, GetLastError());
1270 
1271   myhinternet = InternetOpenA("Winetest",0,NULL,NULL,INTERNET_FLAG_NO_CACHE_WRITE);
1272   ok((myhinternet != 0), "InternetOpen failed, error %u\n",GetLastError());
1273   size = 0x400;
1274   ret = InternetCanonicalizeUrlA(TEST_URL, buffer, &size,ICU_BROWSER_MODE);
1275   ok( ret, "InternetCanonicalizeUrl failed, error %u\n",GetLastError());
1276 
1277   SetLastError(0);
1278   myhttp = InternetOpenUrlA(myhinternet, TEST_URL, 0, 0,
1279 			   INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_TRANSFER_BINARY,0);
1280   if (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1281     return; /* WinXP returns this when not connected to the net */
1282   ok((myhttp != 0),"InternetOpenUrl failed, error %u\n",GetLastError());
1283   ret = InternetReadFile(myhttp, buffer,0x400,&readbytes);
1284   ok( ret, "InternetReadFile failed, error %u\n",GetLastError());
1285   totalbytes += readbytes;
1286   while (readbytes && InternetReadFile(myhttp, buffer,0x400,&readbytes))
1287     totalbytes += readbytes;
1288   trace("read 0x%08x bytes\n",totalbytes);
1289 
1290   InternetCloseHandle(myhttp);
1291   InternetCloseHandle(myhinternet);
1292 
1293   ret = DeleteUrlCacheEntryA(TEST_URL);
1294   ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "INTERNET_FLAG_NO_CACHE_WRITE flag doesn't work\n");
1295 }
1296 
1297 static void HttpSendRequestEx_test(void)
1298 {
1299     HINTERNET hSession;
1300     HINTERNET hConnect;
1301     HINTERNET hRequest;
1302 
1303     INTERNET_BUFFERSA BufferIn;
1304     DWORD dwBytesWritten, dwBytesRead, error;
1305     CHAR szBuffer[256];
1306     int i;
1307     BOOL ret;
1308 
1309     static char szPostData[] = "mode=Test";
1310     static const char szContentType[] = "Content-Type: application/x-www-form-urlencoded";
1311 
1312     hSession = InternetOpenA("Wine Regression Test",
1313             INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1314     ok( hSession != NULL ,"Unable to open Internet session\n");
1315     hConnect = InternetConnectA(hSession, "test.winehq.org",
1316             INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1317             0);
1318     ok( hConnect != NULL, "Unable to connect to http://test.winehq.org\n");
1319     hRequest = HttpOpenRequestA(hConnect, "POST", "/tests/post.php",
1320             NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1321     if (!hRequest && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1322     {
1323         skip( "Network unreachable, skipping test\n" );
1324         goto done;
1325     }
1326     ok( hRequest != NULL, "Failed to open request handle err %u\n", GetLastError());
1327 
1328     test_request_flags(hRequest, INTERNET_REQFLAG_NO_HEADERS);
1329 
1330     BufferIn.dwStructSize = sizeof(BufferIn);
1331     BufferIn.Next = (INTERNET_BUFFERSA*)0xdeadcab;
1332     BufferIn.lpcszHeader = szContentType;
1333     BufferIn.dwHeadersLength = sizeof(szContentType)-1;
1334     BufferIn.dwHeadersTotal = sizeof(szContentType)-1;
1335     BufferIn.lpvBuffer = szPostData;
1336     BufferIn.dwBufferLength = 3;
1337     BufferIn.dwBufferTotal = sizeof(szPostData)-1;
1338     BufferIn.dwOffsetLow = 0;
1339     BufferIn.dwOffsetHigh = 0;
1340 
1341     SetLastError(0xdeadbeef);
1342     ret = HttpSendRequestExA(hRequest, &BufferIn, NULL, 0 ,0);
1343     error = GetLastError();
1344     ok(ret, "HttpSendRequestEx Failed with error %u\n", error);
1345     ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", error);
1346 
1347     test_request_flags(hRequest, INTERNET_REQFLAG_NO_HEADERS);
1348 
1349     for (i = 3; szPostData[i]; i++)
1350         ok(InternetWriteFile(hRequest, &szPostData[i], 1, &dwBytesWritten),
1351                 "InternetWriteFile failed\n");
1352 
1353     test_request_flags(hRequest, INTERNET_REQFLAG_NO_HEADERS);
1354 
1355     ok(HttpEndRequestA(hRequest, NULL, 0, 0), "HttpEndRequest Failed\n");
1356 
1357     test_request_flags(hRequest, 0);
1358 
1359     ok(InternetReadFile(hRequest, szBuffer, 255, &dwBytesRead),
1360             "Unable to read response\n");
1361     szBuffer[dwBytesRead] = 0;
1362 
1363     ok(dwBytesRead == 13,"Read %u bytes instead of 13\n",dwBytesRead);
1364     ok(strncmp(szBuffer,"mode => Test\n",dwBytesRead)==0 || broken(proxy_active()),"Got string %s\n",szBuffer);
1365 
1366     ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
1367 done:
1368     ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
1369     ok(InternetCloseHandle(hSession), "Close session handle failed\n");
1370 }
1371 
1372 static void InternetOpenRequest_test(void)
1373 {
1374     HINTERNET session, connect, request;
1375     static const char *types[] = { "*", "", NULL };
1376     static const WCHAR slash[] = {'/', 0}, any[] = {'*', 0}, empty[] = {0};
1377     static const WCHAR *typesW[] = { any, empty, NULL };
1378     BOOL ret;
1379 
1380     session = InternetOpenA("Wine Regression Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1381     ok(session != NULL ,"Unable to open Internet session\n");
1382 
1383     connect = InternetConnectA(session, NULL, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1384                               INTERNET_SERVICE_HTTP, 0, 0);
1385     ok(connect == NULL, "InternetConnectA should have failed\n");
1386     ok(GetLastError() == ERROR_INVALID_PARAMETER, "InternetConnectA with NULL server named should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
1387 
1388     connect = InternetConnectA(session, "", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1389                               INTERNET_SERVICE_HTTP, 0, 0);
1390     ok(connect == NULL, "InternetConnectA should have failed\n");
1391     ok(GetLastError() == ERROR_INVALID_PARAMETER, "InternetConnectA with blank server named should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
1392 
1393     connect = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1394                               INTERNET_SERVICE_HTTP, 0, 0);
1395     ok(connect != NULL, "Unable to connect to http://test.winehq.org with error %d\n", GetLastError());
1396 
1397     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1398     if (!request && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1399     {
1400         skip( "Network unreachable, skipping test\n" );
1401         goto done;
1402     }
1403     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1404 
1405     ret = HttpSendRequestW(request, NULL, 0, NULL, 0);
1406     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1407     ok(InternetCloseHandle(request), "Close request handle failed\n");
1408 
1409     request = HttpOpenRequestW(connect, NULL, slash, NULL, NULL, typesW, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1410     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1411 
1412     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1413     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1414     ok(InternetCloseHandle(request), "Close request handle failed\n");
1415 
1416 done:
1417     ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1418     ok(InternetCloseHandle(session), "Close session handle failed\n");
1419 }
1420 
1421 static void test_cache_read(void)
1422 {
1423     HINTERNET session, connection, req;
1424     FILETIME now, tomorrow, yesterday;
1425     BYTE content[1000], buf[2000];
1426     char file_path[MAX_PATH];
1427     ULARGE_INTEGER li;
1428     HANDLE file;
1429     DWORD size;
1430     unsigned i;
1431     BOOL res;
1432 
1433     static const char cache_only_url[] = "http://test.winehq.org/tests/cache-only";
1434     BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n";
1435 
1436     trace("Testing cache read...\n");
1437     reset_events();
1438 
1439     for(i = 0; i < sizeof(content); i++)
1440         content[i] = '0' + (i%10);
1441 
1442     GetSystemTimeAsFileTime(&now);
1443     li.u.HighPart = now.dwHighDateTime;
1444     li.u.LowPart = now.dwLowDateTime;
1445     li.QuadPart += (LONGLONG)10000000 * 3600 * 24;
1446     tomorrow.dwHighDateTime = li.u.HighPart;
1447     tomorrow.dwLowDateTime = li.u.LowPart;
1448     li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2;
1449     yesterday.dwHighDateTime = li.u.HighPart;
1450     yesterday.dwLowDateTime = li.u.LowPart;
1451 
1452     res = CreateUrlCacheEntryA(cache_only_url, sizeof(content), "", file_path, 0);
1453     ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError());
1454 
1455     file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1456     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1457 
1458     WriteFile(file, content, sizeof(content), &size, NULL);
1459     CloseHandle(file);
1460 
1461     res = CommitUrlCacheEntryA(cache_only_url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY,
1462                                cache_headers, sizeof(cache_headers)-1, "", 0);
1463     ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError());
1464 
1465     session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
1466     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
1467 
1468     pInternetSetStatusCallbackA(session, callback);
1469 
1470     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1471     connection = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT,
1472             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
1473     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
1474     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1475 
1476     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
1477     req = HttpOpenRequestA(connection, "GET", "/tests/cache-only", NULL, NULL, NULL, 0, 0xdeadbead);
1478     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
1479     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
1480 
1481     SET_WINE_ALLOW(INTERNET_STATUS_CONNECTING_TO_SERVER);
1482     SET_WINE_ALLOW(INTERNET_STATUS_CONNECTED_TO_SERVER);
1483     SET_WINE_ALLOW(INTERNET_STATUS_SENDING_REQUEST);
1484     SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_SENT);
1485     SET_WINE_ALLOW(INTERNET_STATUS_RECEIVING_RESPONSE);
1486     SET_WINE_ALLOW(INTERNET_STATUS_RESPONSE_RECEIVED);
1487     SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_COMPLETE);
1488 
1489     res = HttpSendRequestA(req, NULL, -1, NULL, 0);
1490     todo_wine
1491     ok(res, "HttpSendRequest failed: %u\n", GetLastError());
1492 
1493     if(res) {
1494         size = 0;
1495         res = InternetQueryDataAvailable(req, &size, 0, 0);
1496         ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
1497         ok(size  == sizeof(content), "size = %u\n", size);
1498 
1499         size = sizeof(buf);
1500         res = InternetReadFile(req, buf, sizeof(buf), &size);
1501         ok(res, "InternetReadFile failed: %u\n", GetLastError());
1502         ok(size == sizeof(content), "size = %u\n", size);
1503         ok(!memcmp(content, buf, sizeof(content)), "unexpected content\n");
1504     }
1505 
1506     close_async_handle(session, 2);
1507 
1508     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
1509     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
1510     CLEAR_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
1511     CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
1512     CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
1513     CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
1514     CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
1515 
1516     res = DeleteUrlCacheEntryA(cache_only_url);
1517     ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError());
1518 }
1519 
1520 static void test_http_cache(void)
1521 {
1522     HINTERNET session, connect, request;
1523     char file_name[MAX_PATH], url[INTERNET_MAX_URL_LENGTH];
1524     DWORD size, file_size;
1525     BYTE buf[100];
1526     HANDLE file;
1527     BOOL ret;
1528     FILETIME filetime_zero = {0};
1529 
1530     static const char cached_content[] = "data read from cache";
1531     static const char *types[] = { "*", "", NULL };
1532 
1533     session = InternetOpenA("Wine Regression Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1534     ok(session != NULL ,"Unable to open Internet session\n");
1535 
1536     connect = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1537                               INTERNET_SERVICE_HTTP, 0, 0);
1538     ok(connect != NULL, "Unable to connect to http://test.winehq.org with error %d\n", GetLastError());
1539 
1540     request = HttpOpenRequestA(connect, NULL, "/tests/hello.html", NULL, NULL, types, INTERNET_FLAG_NEED_FILE, 0);
1541     if (!request && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1542     {
1543         skip( "Network unreachable, skipping test\n" );
1544 
1545         ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1546         ok(InternetCloseHandle(session), "Close session handle failed\n");
1547 
1548         return;
1549     }
1550     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1551 
1552     size = sizeof(url);
1553     ret = InternetQueryOptionA(request, INTERNET_OPTION_URL, url, &size);
1554     ok(ret, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
1555     ok(!strcmp(url, "http://test.winehq.org/tests/hello.html"), "Wrong URL %s\n", url);
1556 
1557     size = sizeof(file_name);
1558     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1559     ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1560     ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1561     ok(!size, "size = %d\n", size);
1562 
1563     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1564     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1565 
1566     size = sizeof(file_name);
1567     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1568     ok(ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) failed: %u\n", GetLastError());
1569 
1570     file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
1571                       FILE_ATTRIBUTE_NORMAL, NULL);
1572     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1573     file_size = GetFileSize(file, NULL);
1574     ok(file_size == 106, "file size = %u\n", file_size);
1575 
1576     size = sizeof(buf);
1577     ret = InternetReadFile(request, buf, sizeof(buf), &size);
1578     ok(ret, "InternetReadFile failed: %u\n", GetLastError());
1579     ok(size == 100, "size = %u\n", size);
1580 
1581     file_size = GetFileSize(file, NULL);
1582     ok(file_size == 106, "file size = %u\n", file_size);
1583     CloseHandle(file);
1584 
1585     ret = DeleteFileA(file_name);
1586     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, "Deleting file returned %x(%u)\n", ret, GetLastError());
1587 
1588     ok(InternetCloseHandle(request), "Close request handle failed\n");
1589 
1590     file = CreateFileA(file_name, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1591             FILE_ATTRIBUTE_NORMAL, NULL);
1592     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1593     ret = WriteFile(file, cached_content, sizeof(cached_content), &size, NULL);
1594     ok(ret && size, "WriteFile failed: %d, %d\n", ret, size);
1595     ret = CommitUrlCacheEntryA(url, file_name, filetime_zero, filetime_zero, NORMAL_CACHE_ENTRY, NULL, 0, NULL, 0);
1596     ok(ret, "CommitUrlCacheEntry failed: %d\n", GetLastError());
1597     CloseHandle(file);
1598 
1599     /* Send the same request, requiring it to be retrieved from the cache */
1600     request = HttpOpenRequestA(connect, "GET", "/tests/hello.html", NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
1601 
1602     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1603     ok(ret, "HttpSendRequest failed\n");
1604 
1605     size = sizeof(buf);
1606     ret = InternetReadFile(request, buf, sizeof(buf), &size);
1607     ok(ret, "InternetReadFile failed: %u\n", GetLastError());
1608     ok(size == 100, "size = %u\n", size);
1609     buf[99] = 0;
1610     todo_wine ok(!strcmp((char*)buf, cached_content), "incorrect page data: %s\n", (char*)buf);
1611 
1612     ok(InternetCloseHandle(request), "Close request handle failed\n");
1613 
1614     DeleteUrlCacheEntryA(url);
1615     request = HttpOpenRequestA(connect, "GET", "/tests/hello.html", NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
1616     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1617     todo_wine ok(!ret, "HttpSendRequest succeeded\n");
1618     if(!ret)
1619         ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() = %d\n", GetLastError());
1620     ok(InternetCloseHandle(request), "Close request handle failed\n");
1621 
1622     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1623     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1624 
1625     size = sizeof(file_name);
1626     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1627     ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1628     ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1629     ok(!size, "size = %d\n", size);
1630 
1631     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
1632     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1633 
1634     size = sizeof(file_name);
1635     file_name[0] = 0;
1636     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1637     if (ret)
1638     {
1639         file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1640                       FILE_ATTRIBUTE_NORMAL, NULL);
1641         ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1642         CloseHandle(file);
1643     }
1644     else
1645     {
1646         /* < IE8 */
1647         ok(file_name[0] == 0, "Didn't expect a file name\n");
1648     }
1649 
1650     ok(InternetCloseHandle(request), "Close request handle failed\n");
1651     ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1652     ok(InternetCloseHandle(session), "Close session handle failed\n");
1653 
1654     test_cache_read();
1655 }
1656 
1657 static void InternetLockRequestFile_test(void)
1658 {
1659     char file_name[MAX_PATH];
1660     test_request_t req;
1661     HANDLE lock, lock2;
1662     DWORD size;
1663     BOOL ret;
1664 
1665     open_simple_request(&req, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, "/tests/hello.html");
1666 
1667     size = sizeof(file_name);
1668     ret = InternetQueryOptionA(req.request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1669     ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1670     ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1671     ok(!size, "size = %d\n", size);
1672 
1673     lock = NULL;
1674     ret = InternetLockRequestFile(req.request, &lock);
1675     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "InternetLockRequestFile returned: %x(%u)\n", ret, GetLastError());
1676 
1677     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
1678     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1679 
1680     size = sizeof(file_name);
1681     ret = InternetQueryOptionA(req.request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1682     ok(ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) failed: %u\n", GetLastError());
1683 
1684     ret = InternetLockRequestFile(req.request, &lock);
1685     ok(ret, "InternetLockRequestFile returned: %x(%u)\n", ret, GetLastError());
1686     ok(lock != NULL, "lock == NULL\n");
1687 
1688     ret = InternetLockRequestFile(req.request, &lock2);
1689     ok(ret, "InternetLockRequestFile returned: %x(%u)\n", ret, GetLastError());
1690     ok(lock == lock2, "lock != lock2\n");
1691 
1692     ret = InternetUnlockRequestFile(lock2);
1693     ok(ret, "InternetUnlockRequestFile failed: %u\n", GetLastError());
1694 
1695     ret = DeleteFileA(file_name);
1696     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, "Deleting file returned %x(%u)\n", ret, GetLastError());
1697 
1698     ok(InternetCloseHandle(req.request), "Close request handle failed\n");
1699 
1700     ret = DeleteFileA(file_name);
1701     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, "Deleting file returned %x(%u)\n", ret, GetLastError());
1702 
1703     ret = InternetUnlockRequestFile(lock);
1704     ok(ret, "InternetUnlockRequestFile failed: %u\n", GetLastError());
1705 
1706     ret = DeleteFileA(file_name);
1707     ok(ret, "Deleting file returned %x(%u)\n", ret, GetLastError());
1708 }
1709 
1710 static void HttpHeaders_test(void)
1711 {
1712     HINTERNET hSession;
1713     HINTERNET hConnect;
1714     HINTERNET hRequest;
1715     CHAR      buffer[256];
1716     WCHAR     wbuffer[256];
1717     DWORD     len = 256;
1718     DWORD     oldlen;
1719     DWORD     index = 0;
1720     BOOL      ret;
1721 
1722     hSession = InternetOpenA("Wine Regression Test",
1723             INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1724     ok( hSession != NULL ,"Unable to open Internet session\n");
1725     hConnect = InternetConnectA(hSession, "test.winehq.org",
1726             INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1727             0);
1728     ok( hConnect != NULL, "Unable to connect to http://test.winehq.org\n");
1729     hRequest = HttpOpenRequestA(hConnect, "POST", "/tests/post.php",
1730             NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1731     if (!hRequest && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1732     {
1733         skip( "Network unreachable, skipping test\n" );
1734         goto done;
1735     }
1736     ok( hRequest != NULL, "Failed to open request handle\n");
1737 
1738     index = 0;
1739     len = sizeof(buffer);
1740     strcpy(buffer,"Warning");
1741     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1742                buffer,&len,&index)==0,"Warning hearder reported as Existing\n");
1743 
1744     ok(HttpAddRequestHeadersA(hRequest,"Warning:test1",-1,HTTP_ADDREQ_FLAG_ADD),
1745             "Failed to add new header\n");
1746 
1747     index = 0;
1748     len = sizeof(buffer);
1749     strcpy(buffer,"Warning");
1750     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1751                 buffer,&len,&index),"Unable to query header\n");
1752     ok(index == 1, "Index was not incremented\n");
1753     ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1754     ok(len == 5, "Invalid length (exp. 5, got %d)\n", len);
1755     ok((len < sizeof(buffer)) && (buffer[len] == 0), "Buffer not NULL-terminated\n"); /* len show only 5 characters but the buffer is NULL-terminated*/
1756     len = sizeof(buffer);
1757     strcpy(buffer,"Warning");
1758     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1759                 buffer,&len,&index)==0,"Second Index Should Not Exist\n");
1760 
1761     index = 0;
1762     len = 5; /* could store the string but not the NULL terminator */
1763     strcpy(buffer,"Warning");
1764     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1765                 buffer,&len,&index) == FALSE,"Query succeeded on a too small buffer\n");
1766     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1767     ok(index == 0, "Index was incremented\n");
1768     ok(strcmp(buffer,"Warning")==0, "incorrect string was returned(%s)\n",buffer); /* string not touched */
1769     ok(len == 6, "Invalid length (exp. 6, got %d)\n", len); /* unlike success, the length includes the NULL-terminator */
1770 
1771     /* a call with NULL will fail but will return the length */
1772     index = 0;
1773     len = sizeof(buffer);
1774     SetLastError(0xdeadbeef);
1775     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1776                 NULL,&len,&index) == FALSE,"Query worked\n");
1777     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1778     ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1779     ok(index == 0, "Index was incremented\n");
1780 
1781     /* even for a len that is too small */
1782     index = 0;
1783     len = 15;
1784     SetLastError(0xdeadbeef);
1785     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1786                 NULL,&len,&index) == FALSE,"Query worked\n");
1787     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1788     ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1789     ok(index == 0, "Index was incremented\n");
1790 
1791     index = 0;
1792     len = 0;
1793     SetLastError(0xdeadbeef);
1794     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1795                 NULL,&len,&index) == FALSE,"Query worked\n");
1796     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1797     ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1798     ok(index == 0, "Index was incremented\n");
1799     oldlen = len;   /* bytes; at least long enough to hold buffer & nul */
1800 
1801 
1802     /* a working query */
1803     index = 0;
1804     len = sizeof(buffer);
1805     memset(buffer, 'x', sizeof(buffer));
1806     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1807                 buffer,&len,&index),"Unable to query header\n");
1808     ok(len + sizeof(CHAR) <= oldlen, "Result longer than advertised\n");
1809     ok((len < sizeof(buffer)-sizeof(CHAR)) && (buffer[len/sizeof(CHAR)] == 0),"No NUL at end\n");
1810     ok(len == strlen(buffer) * sizeof(CHAR), "Length wrong\n");
1811     /* what's in the middle differs between Wine and Windows so currently we check only the beginning and the end */
1812     ok(strncmp(buffer, "POST /tests/post.php HTTP/1", 25)==0, "Invalid beginning of headers string\n");
1813     ok(strcmp(buffer + strlen(buffer) - 4, "\r\n\r\n")==0, "Invalid end of headers string\n");
1814     ok(index == 0, "Index was incremented\n");
1815 
1816     /* Like above two tests, but for W version */
1817 
1818     index = 0;
1819     len = 0;
1820     SetLastError(0xdeadbeef);
1821     ok(HttpQueryInfoW(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1822                 NULL,&len,&index) == FALSE,"Query worked\n");
1823     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1824     ok(len > 80, "Invalid length (exp. more than 80, got %d)\n", len);
1825     ok(index == 0, "Index was incremented\n");
1826     oldlen = len;   /* bytes; at least long enough to hold buffer & nul */
1827 
1828     /* a working query */
1829     index = 0;
1830     len = sizeof(wbuffer);
1831     memset(wbuffer, 'x', sizeof(wbuffer));
1832     ok(HttpQueryInfoW(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1833                 wbuffer,&len,&index),"Unable to query header\n");
1834     ok(len + sizeof(WCHAR) <= oldlen, "Result longer than advertised\n");
1835     ok(len == lstrlenW(wbuffer) * sizeof(WCHAR), "Length wrong\n");
1836     ok((len < sizeof(wbuffer)-sizeof(WCHAR)) && (wbuffer[len/sizeof(WCHAR)] == 0),"No NUL at end\n");
1837     ok(index == 0, "Index was incremented\n");
1838 
1839     /* end of W version tests */
1840 
1841     /* Without HTTP_QUERY_FLAG_REQUEST_HEADERS */
1842     index = 0;
1843     len = sizeof(buffer);
1844     memset(buffer, 'x', sizeof(buffer));
1845     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,
1846                 buffer,&len,&index) == TRUE,"Query failed\n");
1847     ok(len == 2 || len == 4 /* win10 */, "Expected 2 or 4, got %d\n", len);
1848     ok(memcmp(buffer, "\r\n\r\n", len) == 0, "Expected CRLF, got '%s'\n", buffer);
1849     ok(index == 0, "Index was incremented\n");
1850 
1851     ok(HttpAddRequestHeadersA(hRequest,"Warning:test2",-1,HTTP_ADDREQ_FLAG_ADD),
1852             "Failed to add duplicate header using HTTP_ADDREQ_FLAG_ADD\n");
1853 
1854     index = 0;
1855     len = sizeof(buffer);
1856     strcpy(buffer,"Warning");
1857     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1858                 buffer,&len,&index),"Unable to query header\n");
1859     ok(index == 1, "Index was not incremented\n");
1860     ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1861     len = sizeof(buffer);
1862     strcpy(buffer,"Warning");
1863     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1864                 buffer,&len,&index),"Failed to get second header\n");
1865     ok(index == 2, "Index was not incremented\n");
1866     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1867     len = sizeof(buffer);
1868     strcpy(buffer,"Warning");
1869     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1870                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1871 
1872     ok(HttpAddRequestHeadersA(hRequest,"Warning:test3",-1,HTTP_ADDREQ_FLAG_REPLACE), "Failed to replace header using HTTP_ADDREQ_FLAG_REPLACE\n");
1873 
1874     index = 0;
1875     len = sizeof(buffer);
1876     strcpy(buffer,"Warning");
1877     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1878                 buffer,&len,&index),"Unable to query header\n");
1879     ok(index == 1, "Index was not incremented\n");
1880     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1881     len = sizeof(buffer);
1882     strcpy(buffer,"Warning");
1883     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1884                 buffer,&len,&index),"Failed to get second header\n");
1885     ok(index == 2, "Index was not incremented\n");
1886     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1887     len = sizeof(buffer);
1888     strcpy(buffer,"Warning");
1889     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1890                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1891 
1892     ok(HttpAddRequestHeadersA(hRequest,"Warning:test4",-1,HTTP_ADDREQ_FLAG_ADD_IF_NEW)==0, "HTTP_ADDREQ_FLAG_ADD_IF_NEW replaced existing header\n");
1893 
1894     index = 0;
1895     len = sizeof(buffer);
1896     strcpy(buffer,"Warning");
1897     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1898                 buffer,&len,&index),"Unable to query header\n");
1899     ok(index == 1, "Index was not incremented\n");
1900     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1901     len = sizeof(buffer);
1902     strcpy(buffer,"Warning");
1903     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1904                 buffer,&len,&index),"Failed to get second header\n");
1905     ok(index == 2, "Index was not incremented\n");
1906     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1907     len = sizeof(buffer);
1908     strcpy(buffer,"Warning");
1909     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1910                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1911 
1912     ok(HttpAddRequestHeadersA(hRequest,"Warning:test4",-1, HTTP_ADDREQ_FLAG_COALESCE), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1913 
1914     index = 0;
1915     len = sizeof(buffer);
1916     strcpy(buffer,"Warning");
1917     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1918                 buffer,&len,&index),"Unable to query header\n");
1919     ok(index == 1, "Index was not incremented\n");
1920     ok(strcmp(buffer,"test2, test4")==0, "incorrect string was returned(%s)\n", buffer);
1921     len = sizeof(buffer);
1922     strcpy(buffer,"Warning");
1923     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1924     ok(index == 2, "Index was not incremented\n");
1925     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1926     len = sizeof(buffer);
1927     strcpy(buffer,"Warning");
1928     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1929 
1930     ok(HttpAddRequestHeadersA(hRequest,"Warning:test5",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1931 
1932     index = 0;
1933     len = sizeof(buffer);
1934     strcpy(buffer,"Warning");
1935     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1936     ok(index == 1, "Index was not incremented\n");
1937     ok(strcmp(buffer,"test2, test4, test5")==0, "incorrect string was returned(%s)\n",buffer);
1938     len = sizeof(buffer);
1939     strcpy(buffer,"Warning");
1940     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1941     ok(index == 2, "Index was not incremented\n");
1942     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1943     len = sizeof(buffer);
1944     strcpy(buffer,"Warning");
1945     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1946 
1947     ok(HttpAddRequestHeadersA(hRequest,"Warning:test6",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1948 
1949     index = 0;
1950     len = sizeof(buffer);
1951     strcpy(buffer,"Warning");
1952     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1953     ok(index == 1, "Index was not incremented\n");
1954     ok(strcmp(buffer,"test2, test4, test5; test6")==0, "incorrect string was returned(%s)\n",buffer);
1955     len = sizeof(buffer);
1956     strcpy(buffer,"Warning");
1957     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1958     ok(index == 2, "Index was not incremented\n");
1959     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1960     len = sizeof(buffer);
1961     strcpy(buffer,"Warning");
1962     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1963 
1964     ok(HttpAddRequestHeadersA(hRequest,"Warning:test7",-1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE), "HTTP_ADDREQ_FLAG_ADD with HTTP_ADDREQ_FLAG_REPALCE Did not work\n");
1965 
1966     index = 0;
1967     len = sizeof(buffer);
1968     strcpy(buffer,"Warning");
1969     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1970     ok(index == 1, "Index was not incremented\n");
1971     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1972     len = sizeof(buffer);
1973     strcpy(buffer,"Warning");
1974     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1975     ok(index == 2, "Index was not incremented\n");
1976     ok(strcmp(buffer,"test7")==0, "incorrect string was returned(%s)\n",buffer);
1977     len = sizeof(buffer);
1978     strcpy(buffer,"Warning");
1979     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1980 
1981     /* Ensure that blank headers are ignored and don't cause a failure */
1982     ok(HttpAddRequestHeadersA(hRequest,"\r\nBlankTest:value\r\n\r\n",-1, HTTP_ADDREQ_FLAG_ADD_IF_NEW), "Failed to add header with blank entries in list\n");
1983 
1984     index = 0;
1985     len = sizeof(buffer);
1986     strcpy(buffer,"BlankTest");
1987     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1988     ok(index == 1, "Index was not incremented\n");
1989     ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer);
1990 
1991     /* Ensure that malformed header separators are ignored and don't cause a failure */
1992     ok(HttpAddRequestHeadersA(hRequest,"\r\rMalformedTest:value\n\nMalformedTestTwo: value2\rMalformedTestThree: value3\n\n\r\r\n",-1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE),
1993         "Failed to add header with malformed entries in list\n");
1994 
1995     index = 0;
1996     len = sizeof(buffer);
1997     strcpy(buffer,"MalformedTest");
1998     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1999     ok(index == 1, "Index was not incremented\n");
2000     ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer);
2001     index = 0;
2002     len = sizeof(buffer);
2003     strcpy(buffer,"MalformedTestTwo");
2004     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2005     ok(index == 1, "Index was not incremented\n");
2006     ok(strcmp(buffer,"value2")==0, "incorrect string was returned(%s)\n",buffer);
2007     index = 0;
2008     len = sizeof(buffer);
2009     strcpy(buffer,"MalformedTestThree");
2010     ok(HttpQueryInfoA(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
2011     ok(index == 1, "Index was not incremented\n");
2012     ok(strcmp(buffer,"value3")==0, "incorrect string was returned(%s)\n",buffer);
2013 
2014     ret = HttpAddRequestHeadersA(hRequest, "Authorization: Basic\r\n", -1, HTTP_ADDREQ_FLAG_ADD);
2015     ok(ret, "unable to add header %u\n", GetLastError());
2016 
2017     index = 0;
2018     buffer[0] = 0;
2019     len = sizeof(buffer);
2020     ret = HttpQueryInfoA(hRequest, HTTP_QUERY_AUTHORIZATION|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &len, &index);
2021     ok(ret, "unable to query header %u\n", GetLastError());
2022     ok(index == 1, "index was not incremented\n");
2023     ok(!strcmp(buffer, "Basic"), "incorrect string was returned (%s)\n", buffer);
2024 
2025     ret = HttpAddRequestHeadersA(hRequest, "Authorization:\r\n", -1, HTTP_ADDREQ_FLAG_REPLACE);
2026     ok(ret, "unable to remove header %u\n", GetLastError());
2027 
2028     index = 0;
2029     len = sizeof(buffer);
2030     SetLastError(0xdeadbeef);
2031     ok(!HttpQueryInfoA(hRequest, HTTP_QUERY_AUTHORIZATION|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &len, &index),
2032        "header still present\n");
2033     ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "got %u\n", GetLastError());
2034 
2035     ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
2036 done:
2037     ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
2038     ok(InternetCloseHandle(hSession), "Close session handle failed\n");
2039 }
2040 
2041 static const char garbagemsg[] =
2042 "Garbage: Header\r\n";
2043 
2044 static const char contmsg[] =
2045 "HTTP/1.1 100 Continue\r\n";
2046 
2047 static const char expandcontmsg[] =
2048 "HTTP/1.1 100 Continue\r\n"
2049 "Server: winecontinue\r\n"
2050 "Tag: something witty\r\n";
2051 
2052 static const char okmsg[] =
2053 "HTTP/1.1 200 OK\r\n"
2054 "Server: winetest\r\n"
2055 "\r\n";
2056 
2057 static const char okmsg201[] =
2058 "HTTP/1.1 201 OK\r\n"
2059 "Server: winetest\r\n"
2060 "\r\n";
2061 
2062 static const char okmsg2[] =
2063 "HTTP/1.1 200 OK\r\n"
2064 "Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
2065 "Server: winetest\r\n"
2066 "Content-Length: 0\r\n"
2067 "Set-Cookie: one\r\n"
2068 "Set-Cookie: two\r\n"
2069 "\r\n";
2070 
2071 static DWORD64 content_length;
2072 static const char largemsg[] =
2073 "HTTP/1.1 200 OK\r\n"
2074 "Content-Length: %I64u\r\n"
2075 "\r\n";
2076 
2077 static const char okmsg_cookie_path[] =
2078 "HTTP/1.1 200 OK\r\n"
2079 "Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
2080 "Server: winetest\r\n"
2081 "Content-Length: 0\r\n"
2082 "Set-Cookie: subcookie2=data; path=/test_cookie_set_path\r\n"
2083 "\r\n";
2084 
2085 static const char okmsg_cookie[] =
2086 "HTTP/1.1 200 OK\r\n"
2087 "Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
2088 "Server: winetest\r\n"
2089 "Content-Length: 0\r\n"
2090 "Set-Cookie: testcookie=testvalue\r\n"
2091 "\r\n";
2092 
2093 static const char notokmsg[] =
2094 "HTTP/1.1 400 Bad Request\r\n"
2095 "Server: winetest\r\n"
2096 "\r\n";
2097 
2098 static const char noauthmsg[] =
2099 "HTTP/1.1 401 Unauthorized\r\n"
2100 "Server: winetest\r\n"
2101 "Connection: close\r\n"
2102 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
2103 "\r\n";
2104 
2105 static const char noauthmsg2[] =
2106 "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed\r\n"
2107 "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"
2108 "\0d`0|6\n"
2109 "Server: winetest\r\n";
2110 
2111 static const char proxymsg[] =
2112 "HTTP/1.1 407 Proxy Authentication Required\r\n"
2113 "Server: winetest\r\n"
2114 "Proxy-Connection: close\r\n"
2115 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
2116 "\r\n";
2117 
2118 static const char page1[] =
2119 "<HTML>\r\n"
2120 "<HEAD><TITLE>wininet test page</TITLE></HEAD>\r\n"
2121 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
2122 "</HTML>\r\n\r\n";
2123 
2124 static const char ok_with_length[] =
2125 "HTTP/1.1 200 OK\r\n"
2126 "Connection: Keep-Alive\r\n"
2127 "Content-Length: 18\r\n\r\n"
2128 "HTTP/1.1 211 OK\r\n\r\n";
2129 
2130 static const char ok_with_length2[] =
2131 "HTTP/1.1 210 OK\r\n"
2132 "Connection: Keep-Alive\r\n"
2133 "Content-Length: 19\r\n\r\n"
2134 "HTTP/1.1 211 OK\r\n\r\n";
2135 
2136 struct server_info {
2137     HANDLE hEvent;
2138     int port;
2139 };
2140 
2141 static int test_cache_gzip;
2142 static const char *send_buffer;
2143 static int server_socket;
2144 
2145 static DWORD CALLBACK server_thread(LPVOID param)
2146 {
2147     struct server_info *si = param;
2148     int r, c = -1, i, on, count = 0;
2149     SOCKET s;
2150     struct sockaddr_in sa;
2151     char *buffer;
2152     size_t buffer_size;
2153     WSADATA wsaData;
2154     int last_request = 0;
2155     char host_header[22];
2156     char host_header_override[30];
2157     static int test_no_cache = 0;
2158 
2159     WSAStartup(MAKEWORD(1,1), &wsaData);
2160 
2161     s = socket(AF_INET, SOCK_STREAM, 0);
2162     if (s == INVALID_SOCKET)
2163         return 1;
2164 
2165     on = 1;
2166     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
2167 
2168     memset(&sa, 0, sizeof sa);
2169     sa.sin_family = AF_INET;
2170     sa.sin_port = htons(si->port);
2171     sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
2172 
2173     r = bind(s, (struct sockaddr*) &sa, sizeof sa);
2174     if (r<0)
2175         return 1;
2176 
2177     listen(s, 0);
2178 
2179     SetEvent(si->hEvent);
2180 
2181     sprintf(host_header, "Host: localhost:%d", si->port);
2182     sprintf(host_header_override, "Host: test.local:%d\r\n", si->port);
2183     buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size = 1000);
2184 
2185     do
2186     {
2187         if(c == -1)
2188             c = accept(s, NULL, NULL);
2189 
2190         memset(buffer, 0, buffer_size);
2191         for(i=0;; i++)
2192         {
2193             if(i == buffer_size)
2194                 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, buffer_size *= 2);
2195 
2196             r = recv(c, buffer+i, 1, 0);
2197             if (r != 1)
2198                 break;
2199             if (i<4) continue;
2200             if (buffer[i-2] == '\n' && buffer[i] == '\n' &&
2201                 buffer[i-3] == '\r' && buffer[i-1] == '\r')
2202                 break;
2203         }
2204         if (strstr(buffer, "GET /test1"))
2205         {
2206             if (!strstr(buffer, "Content-Length: 0"))
2207             {
2208                 send(c, okmsg, sizeof okmsg-1, 0);
2209                 send(c, page1, sizeof page1-1, 0);
2210             }
2211             else
2212                 send(c, notokmsg, sizeof notokmsg-1, 0);
2213         }
2214         if (strstr(buffer, "CONNECT "))
2215         {
2216             if (!strstr(buffer, "Content-Length: 0"))
2217                 send(c, notokmsg, sizeof notokmsg-1, 0);
2218             else
2219                 send(c, proxymsg, sizeof proxymsg-1, 0);
2220         }
2221         if (strstr(buffer, "/test2"))
2222         {
2223             if (strstr(buffer, "Proxy-Authorization: Basic bWlrZToxMTAx"))
2224             {
2225                 send(c, okmsg, sizeof okmsg-1, 0);
2226                 send(c, page1, sizeof page1-1, 0);
2227             }
2228             else
2229                 send(c, proxymsg, sizeof proxymsg-1, 0);
2230         }
2231         if (strstr(buffer, "/test3"))
2232         {
2233             if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2234                 send(c, okmsg, sizeof okmsg-1, 0);
2235             else
2236                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2237         }
2238         if (strstr(buffer, "/test4"))
2239         {
2240             if (strstr(buffer, "Connection: Close"))
2241                 send(c, okmsg, sizeof okmsg-1, 0);
2242             else
2243                 send(c, notokmsg, sizeof notokmsg-1, 0);
2244         }
2245         if (strstr(buffer, "POST /test5") ||
2246             strstr(buffer, "RPC_IN_DATA /test5") ||
2247             strstr(buffer, "RPC_OUT_DATA /test5"))
2248         {
2249             if (strstr(buffer, "Content-Length: 0"))
2250             {
2251                 send(c, okmsg, sizeof okmsg-1, 0);
2252                 send(c, page1, sizeof page1-1, 0);
2253             }
2254             else
2255                 send(c, notokmsg, sizeof notokmsg-1, 0);
2256         }
2257         if (strstr(buffer, "GET /test6"))
2258         {
2259             send(c, contmsg, sizeof contmsg-1, 0);
2260             send(c, contmsg, sizeof contmsg-1, 0);
2261             send(c, okmsg, sizeof okmsg-1, 0);
2262             send(c, page1, sizeof page1-1, 0);
2263         }
2264         if (strstr(buffer, "POST /test7"))
2265         {
2266             if (strstr(buffer, "Content-Length: 100"))
2267             {
2268                 if (strstr(buffer, "POST /test7b"))
2269                     recvfrom(c, buffer, buffer_size, 0, NULL, NULL);
2270                 send(c, okmsg, sizeof okmsg-1, 0);
2271                 send(c, page1, sizeof page1-1, 0);
2272             }
2273             else
2274                 send(c, notokmsg, sizeof notokmsg-1, 0);
2275         }
2276         if (strstr(buffer, "/test8"))
2277         {
2278             if (!strstr(buffer, "Connection: Close") &&
2279                  strstr(buffer, "Connection: Keep-Alive") &&
2280                 !strstr(buffer, "Cache-Control: no-cache") &&
2281                 !strstr(buffer, "Pragma: no-cache") &&
2282                  strstr(buffer, host_header))
2283                 send(c, okmsg, sizeof okmsg-1, 0);
2284             else
2285                 send(c, notokmsg, sizeof notokmsg-1, 0);
2286         }
2287         if (strstr(buffer, "/test9"))
2288         {
2289             if (!strstr(buffer, "Connection: Close") &&
2290                 !strstr(buffer, "Connection: Keep-Alive") &&
2291                 !strstr(buffer, "Cache-Control: no-cache") &&
2292                 !strstr(buffer, "Pragma: no-cache") &&
2293                  strstr(buffer, host_header))
2294                 send(c, okmsg, sizeof okmsg-1, 0);
2295             else
2296                 send(c, notokmsg, sizeof notokmsg-1, 0);
2297         }
2298         if (strstr(buffer, "/testA"))
2299         {
2300             if (!strstr(buffer, "Connection: Close") &&
2301                 !strstr(buffer, "Connection: Keep-Alive") &&
2302                 (strstr(buffer, "Cache-Control: no-cache") ||
2303                  strstr(buffer, "Pragma: no-cache")) &&
2304                  strstr(buffer, host_header))
2305                 send(c, okmsg, sizeof okmsg-1, 0);
2306             else
2307                 send(c, notokmsg, sizeof notokmsg-1, 0);
2308         }
2309         if (strstr(buffer, "/testC"))
2310         {
2311             if (strstr(buffer, "cookie=biscuit"))
2312                 send(c, okmsg, sizeof okmsg-1, 0);
2313             else
2314                 send(c, notokmsg, sizeof notokmsg-1, 0);
2315         }
2316         if (strstr(buffer, "/testD"))
2317         {
2318             send(c, okmsg2, sizeof okmsg2-1, 0);
2319         }
2320         if (strstr(buffer, "/testE"))
2321         {
2322             send(c, noauthmsg2, sizeof noauthmsg2-1, 0);
2323         }
2324         if (strstr(buffer, "GET /quit"))
2325         {
2326             send(c, okmsg, sizeof okmsg-1, 0);
2327             send(c, page1, sizeof page1-1, 0);
2328             last_request = 1;
2329         }
2330         if (strstr(buffer, "GET /testF"))
2331         {
2332             send(c, expandcontmsg, sizeof expandcontmsg-1, 0);
2333             send(c, garbagemsg, sizeof garbagemsg-1, 0);
2334             send(c, contmsg, sizeof contmsg-1, 0);
2335             send(c, garbagemsg, sizeof garbagemsg-1, 0);
2336             send(c, okmsg, sizeof okmsg-1, 0);
2337             send(c, page1, sizeof page1-1, 0);
2338         }
2339         if (strstr(buffer, "GET /testG"))
2340         {
2341             send(c, page1, sizeof page1-1, 0);
2342         }
2343 
2344         if (strstr(buffer, "GET /testJ"))
2345         {
2346             if (count == 0)
2347             {
2348                 count++;
2349                 send(c, ok_with_length, sizeof(ok_with_length)-1, 0);
2350             }
2351             else
2352             {
2353                 send(c, ok_with_length2, sizeof(ok_with_length2)-1, 0);
2354                 count = 0;
2355             }
2356         }
2357         if (strstr(buffer, "GET /testH"))
2358         {
2359             send(c, ok_with_length2, sizeof(ok_with_length2)-1, 0);
2360             recvfrom(c, buffer, buffer_size, 0, NULL, NULL);
2361             send(c, ok_with_length, sizeof(ok_with_length)-1, 0);
2362         }
2363 
2364         if (strstr(buffer, "GET /test_no_content"))
2365         {
2366             static const char nocontentmsg[] = "HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n";
2367             send(c, nocontentmsg, sizeof(nocontentmsg)-1, 0);
2368         }
2369         if (strstr(buffer, "GET /test_conn_close"))
2370         {
2371             static const char conn_close_response[] = "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nsome content";
2372             send(c, conn_close_response, sizeof(conn_close_response)-1, 0);
2373             WaitForSingleObject(conn_close_event, INFINITE);
2374             trace("closing connection\n");
2375         }
2376         if (strstr(buffer, "GET /test_cache_control_no_cache"))
2377         {
2378             static const char no_cache_response[] = "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\n\r\nsome content";
2379             if(!test_no_cache++)
2380                 send(c, no_cache_response, sizeof(no_cache_response)-1, 0);
2381             else
2382                 send(c, okmsg, sizeof(okmsg)-1, 0);
2383         }
2384         if (strstr(buffer, "GET /test_cache_control_no_store"))
2385         {
2386             static const char no_cache_response[] = "HTTP/1.1 200 OK\r\nCache-Control: junk, \t No-StOrE\r\n\r\nsome content";
2387             send(c, no_cache_response, sizeof(no_cache_response)-1, 0);
2388         }
2389         if (strstr(buffer, "GET /test_cache_gzip"))
2390         {
2391             static const char gzip_response[] = "HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\nContent-Type: text/html\r\n\r\n"
2392                 "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x4b\xaf\xca\x2c\x50\x28"
2393                 "\x49\x2d\x2e\xe1\x02\x00\x62\x92\xc7\x6c\x0a\x00\x00\x00";
2394             if(!test_cache_gzip++)
2395                 send(c, gzip_response, sizeof(gzip_response), 0);
2396             else
2397                 send(c, notokmsg, sizeof(notokmsg)-1, 0);
2398         }
2399         if (strstr(buffer, "HEAD /test_head")) {
2400             static const char head_response[] =
2401                 "HTTP/1.1 200 OK\r\n"
2402                 "Connection: Keep-Alive\r\n"
2403                 "Content-Length: 100\r\n"
2404                 "\r\n";
2405 
2406             send(c, head_response, sizeof(head_response), 0);
2407             continue;
2408         }
2409         if (strstr(buffer, "GET /send_from_buffer"))
2410             send(c, send_buffer, strlen(send_buffer), 0);
2411         if (strstr(buffer, "/test_cache_control_verb"))
2412         {
2413             if (!memcmp(buffer, "GET ", sizeof("GET ")-1) &&
2414                 !strstr(buffer, "Cache-Control: no-cache\r\n")) send(c, okmsg, sizeof(okmsg)-1, 0);
2415             else if (strstr(buffer, "Cache-Control: no-cache\r\n")) send(c, okmsg, sizeof(okmsg)-1, 0);
2416             else send(c, notokmsg, sizeof(notokmsg)-1, 0);
2417         }
2418         if (strstr(buffer, "/test_request_content_length"))
2419         {
2420             static char msg[] = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\n\r\n";
2421             static int seen_content_length;
2422 
2423             if (!seen_content_length)
2424             {
2425                 if (strstr(buffer, "Content-Length: 0"))
2426                 {
2427                     seen_content_length = 1;
2428                     send(c, msg, sizeof msg-1, 0);
2429                 }
2430                 else send(c, notokmsg, sizeof notokmsg-1, 0);
2431                 WaitForSingleObject(complete_event, 5000);
2432             }
2433             else
2434             {
2435                 if (strstr(buffer, "Content-Length: 0")) send(c, msg, sizeof msg-1, 0);
2436                 else send(c, notokmsg, sizeof notokmsg-1, 0);
2437                 WaitForSingleObject(complete_event, 5000);
2438             }
2439         }
2440         if (strstr(buffer, "GET /test_premature_disconnect"))
2441             trace("closing connection\n");
2442         if (strstr(buffer, "HEAD /upload.txt"))
2443         {
2444             if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2445                 send(c, okmsg, sizeof okmsg-1, 0);
2446             else
2447                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2448         }
2449         if (strstr(buffer, "PUT /upload2.txt"))
2450         {
2451             if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2452                 send(c, okmsg, sizeof okmsg-1, 0);
2453             else
2454                 send(c, notokmsg, sizeof notokmsg-1, 0);
2455         }
2456         if (strstr(buffer, "HEAD /upload3.txt"))
2457         {
2458             if (strstr(buffer, "Authorization: Basic dXNlcjE6cHdkMQ=="))
2459                 send(c, okmsg, sizeof okmsg-1, 0);
2460             else
2461                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2462         }
2463         if (strstr(buffer, "HEAD /upload4.txt"))
2464         {
2465             if (strstr(buffer, "Authorization: Bearer dXNlcjE6cHdkMQ=="))
2466                 send(c, okmsg, sizeof okmsg-1, 0);
2467             else if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
2468                 send(c, okmsg201, sizeof okmsg-1, 0);
2469             else
2470                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2471         }
2472         if (strstr(buffer, "/test_cookie_path1"))
2473         {
2474             if (strstr(buffer, "subcookie=data"))
2475                  send(c, okmsg, sizeof okmsg-1, 0);
2476              else
2477                  send(c, notokmsg, sizeof notokmsg-1, 0);
2478         }
2479         if (strstr(buffer, "/test_cookie_path2"))
2480         {
2481             if (strstr(buffer, "subcookie2=data"))
2482                  send(c, okmsg, sizeof okmsg-1, 0);
2483              else
2484                  send(c, notokmsg, sizeof notokmsg-1, 0);
2485         }
2486         if (strstr(buffer, "/test_cookie_set_path"))
2487         {
2488             send(c, okmsg_cookie_path, sizeof okmsg_cookie_path-1, 0);
2489         }
2490         if (strstr(buffer, "/test_cookie_merge"))
2491         {
2492             if (strstr(buffer, "subcookie=data") &&
2493                 !strstr(buffer, "manual_cookie=test"))
2494                  send(c, okmsg, sizeof okmsg-1, 0);
2495              else
2496                  send(c, notokmsg, sizeof notokmsg-1, 0);
2497         }
2498         if (strstr(buffer, "/test_cookie_set_host_override"))
2499         {
2500             send(c, okmsg_cookie, sizeof okmsg_cookie-1, 0);
2501         }
2502         if (strstr(buffer, "/test_cookie_check_host_override"))
2503         {
2504             if (strstr(buffer, "Cookie:") && strstr(buffer, "testcookie=testvalue"))
2505                 send(c, okmsg, sizeof okmsg-1, 0);
2506             else
2507                 send(c, notokmsg, sizeof notokmsg-1, 0);
2508         }
2509         if (strstr(buffer, "/test_cookie_check_different_host"))
2510         {
2511             if (!strstr(buffer, "foo") &&
2512                 strstr(buffer, "cookie=biscuit"))
2513                 send(c, okmsg, sizeof okmsg-1, 0);
2514             else
2515                 send(c, notokmsg, sizeof notokmsg-1, 0);
2516         }
2517         if (strstr(buffer, "/test_host_override"))
2518         {
2519             if (strstr(buffer, host_header_override))
2520                 send(c, okmsg, sizeof okmsg-1, 0);
2521             else
2522                 send(c, notokmsg, sizeof notokmsg-1, 0);
2523         }
2524         if (strstr(buffer, "/async_read"))
2525         {
2526             const char *page1_mid = page1 + (sizeof page1 - 1)/2;
2527             const char *page1_end = page1 + sizeof page1 - 1;
2528             send(c, okmsg, sizeof okmsg-1, 0);
2529             send(c, page1, page1_mid - page1, 0);
2530             WaitForSingleObject(conn_wait_event, INFINITE);
2531             send(c, page1_mid, page1_end - page1_mid, 0);
2532         }
2533         if (strstr(buffer, "/socket"))
2534         {
2535             server_socket = c;
2536             SetEvent(server_req_rec_event);
2537             WaitForSingleObject(conn_wait_event, INFINITE);
2538         }
2539         if (strstr(buffer, "/echo_request"))
2540         {
2541             send(c, okmsg, sizeof(okmsg)-1, 0);
2542             send(c, buffer, strlen(buffer), 0);
2543         }
2544         if (strstr(buffer, "GET /test_remove_dot_segments"))
2545         {
2546             send(c, okmsg, sizeof(okmsg)-1, 0);
2547         }
2548 
2549         if (strstr(buffer, "HEAD /test_large_content"))
2550         {
2551             char msg[sizeof(largemsg) + 16];
2552             sprintf(msg, largemsg, content_length);
2553             send(c, msg, strlen(msg), 0);
2554         }
2555         if (strstr(buffer, "HEAD /test_auth_host1"))
2556         {
2557             if (strstr(buffer, "Authorization: Basic dGVzdDE6cGFzcw=="))
2558                 send(c, okmsg, sizeof okmsg-1, 0);
2559             else
2560                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2561         }
2562         if (strstr(buffer, "HEAD /test_auth_host2"))
2563         {
2564             if (strstr(buffer, "Authorization: Basic dGVzdDE6cGFzczI="))
2565                 send(c, okmsg, sizeof okmsg-1, 0);
2566             else
2567                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
2568         }
2569         shutdown(c, 2);
2570         closesocket(c);
2571         c = -1;
2572     } while (!last_request);
2573 
2574     closesocket(s);
2575     HeapFree(GetProcessHeap(), 0, buffer);
2576 
2577     return 0;
2578 }
2579 
2580 static void test_basic_request(int port, const char *verb, const char *url)
2581 {
2582     test_request_t req;
2583     DWORD r, count, error;
2584     char buffer[0x100];
2585 
2586     trace("basic request %s %s\n", verb, url);
2587 
2588     open_simple_request(&req, "localhost", port, verb, url);
2589 
2590     SetLastError(0xdeadbeef);
2591     r = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
2592     error = GetLastError();
2593     ok(error == ERROR_SUCCESS || broken(error != ERROR_SUCCESS), "expected ERROR_SUCCESS, got %u\n", error);
2594     ok(r, "HttpSendRequest failed: %u\n", GetLastError());
2595 
2596     count = 0;
2597     memset(buffer, 0, sizeof buffer);
2598     SetLastError(0xdeadbeef);
2599     r = InternetReadFile(req.request, buffer, sizeof buffer, &count);
2600     ok(r, "InternetReadFile failed %u\n", GetLastError());
2601     ok(count == sizeof page1 - 1, "count was wrong\n");
2602     ok(!memcmp(buffer, page1, sizeof page1), "http data wrong, got: %s\n", buffer);
2603 
2604     close_request(&req);
2605 }
2606 
2607 static void test_proxy_indirect(int port)
2608 {
2609     test_request_t req;
2610     DWORD r, sz;
2611     char buffer[0x40];
2612 
2613     open_simple_request(&req, "localhost", port, NULL, "/test2");
2614 
2615     r = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
2616     ok(r, "HttpSendRequest failed %u\n", GetLastError());
2617 
2618     sz = sizeof buffer;
2619     r = HttpQueryInfoA(req.request, HTTP_QUERY_PROXY_AUTHENTICATE, buffer, &sz, NULL);
2620     ok(r || GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo failed: %d\n", GetLastError());
2621     if (!r)
2622     {
2623         skip("missing proxy header, not testing remaining proxy headers\n");
2624         goto out;
2625     }
2626     ok(!strcmp(buffer, "Basic realm=\"placebo\""), "proxy auth info wrong\n");
2627 
2628     test_status_code(req.request, 407);
2629     test_request_flags(req.request, 0);
2630 
2631     sz = sizeof buffer;
2632     r = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &sz, NULL);
2633     ok(r, "HttpQueryInfo failed\n");
2634     ok(!strcmp(buffer, "Proxy Authentication Required"), "proxy text wrong\n");
2635 
2636     sz = sizeof buffer;
2637     r = HttpQueryInfoA(req.request, HTTP_QUERY_VERSION, buffer, &sz, NULL);
2638     ok(r, "HttpQueryInfo failed\n");
2639     ok(!strcmp(buffer, "HTTP/1.1"), "http version wrong\n");
2640 
2641     sz = sizeof buffer;
2642     r = HttpQueryInfoA(req.request, HTTP_QUERY_SERVER, buffer, &sz, NULL);
2643     ok(r, "HttpQueryInfo failed\n");
2644     ok(!strcmp(buffer, "winetest"), "http server wrong\n");
2645 
2646     sz = sizeof buffer;
2647     r = HttpQueryInfoA(req.request, HTTP_QUERY_CONTENT_ENCODING, buffer, &sz, NULL);
2648     ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo should fail\n");
2649     ok(r == FALSE, "HttpQueryInfo failed\n");
2650 
2651 out:
2652     close_request(&req);
2653 }
2654 
2655 static void test_proxy_direct(int port)
2656 {
2657     HINTERNET hi, hc, hr;
2658     DWORD r, sz, error;
2659     char buffer[0x40], *url;
2660     WCHAR bufferW[0x40];
2661     static const char url_fmt[] = "http://test.winehq.org:%u/test2";
2662     static CHAR username[] = "mike",
2663                 password[] = "1101",
2664                 useragent[] = "winetest";
2665     static const WCHAR usernameW[]  = {'m','i','k','e',0},
2666                        passwordW[]  = {'1','1','0','1',0},
2667                        useragentW[] = {'w','i','n','e','t','e','s','t',0};
2668 
2669     /* specify proxy type without the proxy and bypass */
2670     SetLastError(0xdeadbeef);
2671     hi = InternetOpenW(NULL, INTERNET_OPEN_TYPE_PROXY, NULL, NULL, 0);
2672     error = GetLastError();
2673     ok(error == ERROR_INVALID_PARAMETER ||
2674         broken(error == ERROR_SUCCESS) /* WinXPProSP2 */, "got %u\n", error);
2675     ok(hi == NULL || broken(!!hi) /* WinXPProSP2 */, "open should have failed\n");
2676 
2677     sprintf(buffer, "localhost:%d\n", port);
2678     hi = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0);
2679     ok(hi != NULL, "open failed\n");
2680 
2681     /* try connect without authorization */
2682     hc = InternetConnectA(hi, "test.winehq.org", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2683     ok(hc != NULL, "connect failed\n");
2684 
2685     hr = HttpOpenRequestA(hc, NULL, "/test2", NULL, NULL, NULL, 0, 0);
2686     ok(hr != NULL, "HttpOpenRequest failed\n");
2687 
2688     sz = 0;
2689     SetLastError(0xdeadbeef);
2690     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, NULL, &sz);
2691     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2692     ok(!r, "unexpected success\n");
2693     ok(sz == 1, "got %u\n", sz);
2694 
2695     sz = 0;
2696     SetLastError(0xdeadbeef);
2697     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, NULL, &sz);
2698     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2699     ok(!r, "unexpected success\n");
2700     ok(sz == 1, "got %u\n", sz);
2701 
2702     sz = sizeof(buffer);
2703     SetLastError(0xdeadbeef);
2704     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz);
2705     ok(r, "unexpected failure %u\n", GetLastError());
2706     ok(!sz, "got %u\n", sz);
2707 
2708     sz = sizeof(buffer);
2709     SetLastError(0xdeadbeef);
2710     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2711     ok(r, "unexpected failure %u\n", GetLastError());
2712     ok(!sz, "got %u\n", sz);
2713 
2714     sz = 0;
2715     SetLastError(0xdeadbeef);
2716     r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, NULL, &sz);
2717     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2718     ok(!r, "unexpected success\n");
2719     ok(sz == 1, "got %u\n", sz);
2720 
2721     sz = 0;
2722     SetLastError(0xdeadbeef);
2723     r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, NULL, &sz);
2724     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2725     ok(!r, "unexpected success\n");
2726     ok(sz == 1, "got %u\n", sz);
2727 
2728     sz = sizeof(buffer);
2729     SetLastError(0xdeadbeef);
2730     r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, buffer, &sz);
2731     ok(r, "unexpected failure %u\n", GetLastError());
2732     ok(!sz, "got %u\n", sz);
2733 
2734     sz = sizeof(buffer);
2735     SetLastError(0xdeadbeef);
2736     r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, buffer, &sz);
2737     ok(r, "unexpected failure %u\n", GetLastError());
2738     ok(!sz, "got %u\n", sz);
2739 
2740     sz = 0;
2741     SetLastError(0xdeadbeef);
2742     r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, NULL, &sz);
2743     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2744     ok(!r, "unexpected success\n");
2745     ok(sz == 34, "got %u\n", sz);
2746 
2747     sz = sizeof(buffer);
2748     SetLastError(0xdeadbeef);
2749     r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, buffer, &sz);
2750     ok(r, "unexpected failure %u\n", GetLastError());
2751     ok(sz == 33, "got %u\n", sz);
2752 
2753     r = HttpSendRequestW(hr, NULL, 0, NULL, 0);
2754     ok(r || broken(!r), "HttpSendRequest failed %u\n", GetLastError());
2755     if (!r)
2756     {
2757         win_skip("skipping proxy tests on broken wininet\n");
2758         goto done;
2759     }
2760 
2761     test_status_code(hr, 407);
2762 
2763     /* set the user + password then try again */
2764     r = InternetSetOptionA(hi, INTERNET_OPTION_PROXY_USERNAME, username, 4);
2765     ok(!r, "unexpected success\n");
2766 
2767     r = InternetSetOptionA(hc, INTERNET_OPTION_PROXY_USERNAME, username, 4);
2768     ok(r, "failed to set user\n");
2769 
2770     r = InternetSetOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, username, 4);
2771     ok(r, "failed to set user\n");
2772 
2773     buffer[0] = 0;
2774     sz = 3;
2775     SetLastError(0xdeadbeef);
2776     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2777     ok(!r, "unexpected failure %u\n", GetLastError());
2778     ok(!buffer[0], "got %s\n", buffer);
2779     ok(sz == strlen(username) + 1, "got %u\n", sz);
2780 
2781     buffer[0] = 0;
2782     sz = 0;
2783     SetLastError(0xdeadbeef);
2784     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2785     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2786     ok(!r, "unexpected success\n");
2787     ok(sz == strlen(username) + 1, "got %u\n", sz);
2788 
2789     bufferW[0] = 0;
2790     sz = 0;
2791     SetLastError(0xdeadbeef);
2792     r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_USERNAME, bufferW, &sz);
2793     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2794     ok(!r, "unexpected success\n");
2795     ok(sz == (lstrlenW(usernameW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2796 
2797     buffer[0] = 0;
2798     sz = sizeof(buffer);
2799     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2800     ok(r, "failed to get username\n");
2801     ok(!strcmp(buffer, username), "got %s\n", buffer);
2802     ok(sz == strlen(username), "got %u\n", sz);
2803 
2804     buffer[0] = 0;
2805     sz = sizeof(bufferW);
2806     r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_USERNAME, bufferW, &sz);
2807     ok(r, "failed to get username\n");
2808     ok(!lstrcmpW(bufferW, usernameW), "wrong username\n");
2809     ok(sz == lstrlenW(usernameW), "got %u\n", sz);
2810 
2811     r = InternetSetOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, username, 1);
2812     ok(r, "failed to set user\n");
2813 
2814     buffer[0] = 0;
2815     sz = sizeof(buffer);
2816     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_USERNAME, buffer, &sz);
2817     ok(r, "failed to get username\n");
2818     ok(!strcmp(buffer, username), "got %s\n", buffer);
2819     ok(sz == strlen(username), "got %u\n", sz);
2820 
2821     r = InternetSetOptionA(hi, INTERNET_OPTION_USER_AGENT, useragent, 1);
2822     ok(r, "failed to set useragent\n");
2823 
2824     buffer[0] = 0;
2825     sz = 0;
2826     SetLastError(0xdeadbeef);
2827     r = InternetQueryOptionA(hi, INTERNET_OPTION_USER_AGENT, buffer, &sz);
2828     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2829     ok(!r, "unexpected success\n");
2830     ok(sz == strlen(useragent) + 1, "got %u\n", sz);
2831 
2832     buffer[0] = 0;
2833     sz = sizeof(buffer);
2834     r = InternetQueryOptionA(hi, INTERNET_OPTION_USER_AGENT, buffer, &sz);
2835     ok(r, "failed to get user agent\n");
2836     ok(!strcmp(buffer, useragent), "got %s\n", buffer);
2837     ok(sz == strlen(useragent), "got %u\n", sz);
2838 
2839     bufferW[0] = 0;
2840     sz = 0;
2841     SetLastError(0xdeadbeef);
2842     r = InternetQueryOptionW(hi, INTERNET_OPTION_USER_AGENT, bufferW, &sz);
2843     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2844     ok(!r, "unexpected success\n");
2845     ok(sz == (lstrlenW(useragentW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2846 
2847     bufferW[0] = 0;
2848     sz = sizeof(bufferW);
2849     r = InternetQueryOptionW(hi, INTERNET_OPTION_USER_AGENT, bufferW, &sz);
2850     ok(r, "failed to get user agent\n");
2851     ok(!lstrcmpW(bufferW, useragentW), "wrong user agent\n");
2852     ok(sz == lstrlenW(useragentW), "got %u\n", sz);
2853 
2854     r = InternetSetOptionA(hr, INTERNET_OPTION_USERNAME, username, 1);
2855     ok(r, "failed to set user\n");
2856 
2857     buffer[0] = 0;
2858     sz = 0;
2859     SetLastError(0xdeadbeef);
2860     r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, buffer, &sz);
2861     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2862     ok(!r, "unexpected success\n");
2863     ok(sz == strlen(username) + 1, "got %u\n", sz);
2864 
2865     buffer[0] = 0;
2866     sz = sizeof(buffer);
2867     r = InternetQueryOptionA(hr, INTERNET_OPTION_USERNAME, buffer, &sz);
2868     ok(r, "failed to get user\n");
2869     ok(!strcmp(buffer, username), "got %s\n", buffer);
2870     ok(sz == strlen(username), "got %u\n", sz);
2871 
2872     bufferW[0] = 0;
2873     sz = 0;
2874     SetLastError(0xdeadbeef);
2875     r = InternetQueryOptionW(hr, INTERNET_OPTION_USERNAME, bufferW, &sz);
2876     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2877     ok(!r, "unexpected success\n");
2878     ok(sz == (lstrlenW(usernameW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2879 
2880     bufferW[0] = 0;
2881     sz = sizeof(bufferW);
2882     r = InternetQueryOptionW(hr, INTERNET_OPTION_USERNAME, bufferW, &sz);
2883     ok(r, "failed to get user\n");
2884     ok(!lstrcmpW(bufferW, usernameW), "wrong user\n");
2885     ok(sz == lstrlenW(usernameW), "got %u\n", sz);
2886 
2887     r = InternetSetOptionA(hr, INTERNET_OPTION_PASSWORD, password, 1);
2888     ok(r, "failed to set password\n");
2889 
2890     buffer[0] = 0;
2891     sz = 0;
2892     SetLastError(0xdeadbeef);
2893     r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, buffer, &sz);
2894     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2895     ok(!r, "unexpected success\n");
2896     ok(sz == strlen(password) + 1, "got %u\n", sz);
2897 
2898     buffer[0] = 0;
2899     sz = sizeof(buffer);
2900     r = InternetQueryOptionA(hr, INTERNET_OPTION_PASSWORD, buffer, &sz);
2901     ok(r, "failed to get password\n");
2902     ok(!strcmp(buffer, password), "got %s\n", buffer);
2903     ok(sz == strlen(password), "got %u\n", sz);
2904 
2905     bufferW[0] = 0;
2906     sz = 0;
2907     SetLastError(0xdeadbeef);
2908     r = InternetQueryOptionW(hr, INTERNET_OPTION_PASSWORD, bufferW, &sz);
2909     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2910     ok(!r, "unexpected success\n");
2911     ok(sz == (lstrlenW(passwordW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2912 
2913     bufferW[0] = 0;
2914     sz = sizeof(bufferW);
2915     r = InternetQueryOptionW(hr, INTERNET_OPTION_PASSWORD, bufferW, &sz);
2916     ok(r, "failed to get password\n");
2917     ok(!lstrcmpW(bufferW, passwordW), "wrong password\n");
2918     ok(sz == lstrlenW(passwordW), "got %u\n", sz);
2919 
2920     url = HeapAlloc(GetProcessHeap(), 0, strlen(url_fmt) + 11);
2921     sprintf(url, url_fmt, port);
2922     buffer[0] = 0;
2923     sz = 0;
2924     SetLastError(0xdeadbeef);
2925     r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, buffer, &sz);
2926     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2927     ok(!r, "unexpected success\n");
2928     ok(sz == strlen(url) + 1, "got %u\n", sz);
2929 
2930     buffer[0] = 0;
2931     sz = sizeof(buffer);
2932     r = InternetQueryOptionA(hr, INTERNET_OPTION_URL, buffer, &sz);
2933     ok(r, "failed to get url\n");
2934     ok(!strcmp(buffer, url), "got %s\n", buffer);
2935     ok(sz == strlen(url), "got %u\n", sz);
2936 
2937     bufferW[0] = 0;
2938     sz = 0;
2939     SetLastError(0xdeadbeef);
2940     r = InternetQueryOptionW(hr, INTERNET_OPTION_URL, bufferW, &sz);
2941     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2942     ok(!r, "unexpected success\n");
2943     ok(sz == (strlen(url) + 1) * sizeof(WCHAR), "got %u\n", sz);
2944 
2945     bufferW[0] = 0;
2946     sz = sizeof(bufferW);
2947     r = InternetQueryOptionW(hr, INTERNET_OPTION_URL, bufferW, &sz);
2948     ok(r, "failed to get url\n");
2949     ok(!strcmp_wa(bufferW, url), "wrong url\n");
2950     ok(sz == strlen(url), "got %u\n", sz);
2951     HeapFree(GetProcessHeap(), 0, url);
2952 
2953     r = InternetSetOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, password, 4);
2954     ok(r, "failed to set password\n");
2955 
2956     buffer[0] = 0;
2957     sz = 0;
2958     SetLastError(0xdeadbeef);
2959     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz);
2960     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2961     ok(!r, "unexpected success\n");
2962     ok(sz == strlen(password) + 1, "got %u\n", sz);
2963 
2964     buffer[0] = 0;
2965     sz = sizeof(buffer);
2966     r = InternetQueryOptionA(hr, INTERNET_OPTION_PROXY_PASSWORD, buffer, &sz);
2967     ok(r, "failed to get password\n");
2968     ok(!strcmp(buffer, password), "got %s\n", buffer);
2969     ok(sz == strlen(password), "got %u\n", sz);
2970 
2971     bufferW[0] = 0;
2972     sz = 0;
2973     SetLastError(0xdeadbeef);
2974     r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_PASSWORD, bufferW, &sz);
2975     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2976     ok(!r, "unexpected success\n");
2977     ok(sz == (lstrlenW(passwordW) + 1) * sizeof(WCHAR), "got %u\n", sz);
2978 
2979     bufferW[0] = 0;
2980     sz = sizeof(bufferW);
2981     r = InternetQueryOptionW(hr, INTERNET_OPTION_PROXY_PASSWORD, bufferW, &sz);
2982     ok(r, "failed to get password\n");
2983     ok(!lstrcmpW(bufferW, passwordW), "wrong password\n");
2984     ok(sz == lstrlenW(passwordW), "got %u\n", sz);
2985 
2986     r = HttpSendRequestW(hr, NULL, 0, NULL, 0);
2987     if (!r)
2988     {
2989         win_skip("skipping proxy tests on broken wininet\n");
2990         goto done;
2991     }
2992     ok(r, "HttpSendRequest failed %u\n", GetLastError());
2993     sz = sizeof buffer;
2994     r = HttpQueryInfoA(hr, HTTP_QUERY_STATUS_CODE, buffer, &sz, NULL);
2995     ok(r, "HttpQueryInfo failed\n");
2996     ok(!strcmp(buffer, "200"), "proxy code wrong\n");
2997 
2998     InternetCloseHandle(hr);
2999     InternetCloseHandle(hc);
3000     InternetCloseHandle(hi);
3001 
3002     sprintf(buffer, "localhost:%d\n", port);
3003     hi = InternetOpenA("winetest", INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0);
3004     ok(hi != NULL, "InternetOpen failed\n");
3005 
3006     hc = InternetConnectA(hi, "test.winehq.org", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3007     ok(hc != NULL, "InternetConnect failed\n");
3008 
3009     hr = HttpOpenRequestA(hc, "POST", "/test2", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
3010     ok(hr != NULL, "HttpOpenRequest failed\n");
3011 
3012     r = HttpSendRequestA(hr, NULL, 0, (char *)"data", sizeof("data"));
3013     ok(r, "HttpSendRequest failed %u\n", GetLastError());
3014 
3015     test_status_code(hr, 407);
3016 
3017 done:
3018     InternetCloseHandle(hr);
3019     InternetCloseHandle(hc);
3020     InternetCloseHandle(hi);
3021 }
3022 
3023 static void test_header_handling_order(int port)
3024 {
3025     static const char authorization[] = "Authorization: Basic dXNlcjpwd2Q=";
3026     static const char connection[]    = "Connection: Close";
3027     static const char *types[2] = { "*", NULL };
3028     char data[32];
3029     HINTERNET session, connect, request;
3030     DWORD size, status, data_len;
3031     BOOL ret;
3032 
3033     session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3034     ok(session != NULL, "InternetOpen failed\n");
3035 
3036     connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3037     ok(connect != NULL, "InternetConnect failed\n");
3038 
3039     request = HttpOpenRequestA(connect, NULL, "/test3", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3040     ok(request != NULL, "HttpOpenRequest failed\n");
3041 
3042     ret = HttpAddRequestHeadersA(request, authorization, ~0u, HTTP_ADDREQ_FLAG_ADD);
3043     ok(ret, "HttpAddRequestHeaders failed\n");
3044 
3045     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
3046     ok(ret, "HttpSendRequest failed\n");
3047 
3048     test_status_code(request, 200);
3049     test_request_flags(request, 0);
3050 
3051     InternetCloseHandle(request);
3052 
3053     request = HttpOpenRequestA(connect, NULL, "/test4", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3054     ok(request != NULL, "HttpOpenRequest failed\n");
3055 
3056     ret = HttpSendRequestA(request, connection, ~0u, NULL, 0);
3057     ok(ret, "HttpSendRequest failed\n");
3058 
3059     status = 0;
3060     size = sizeof(status);
3061     ret = HttpQueryInfoA( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
3062     ok(ret, "HttpQueryInfo failed\n");
3063     ok(status == 200 || status == 400 /* IE6 */, "got status %u, expected 200 or 400\n", status);
3064 
3065     InternetCloseHandle(request);
3066     InternetCloseHandle(connect);
3067 
3068     connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3069     ok(connect != NULL, "InternetConnect failed\n");
3070 
3071     request = HttpOpenRequestA(connect, "POST", "/test7", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3072     ok(request != NULL, "HttpOpenRequest failed\n");
3073 
3074     ret = HttpAddRequestHeadersA(request, "Content-Length: 100\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
3075     ok(ret, "HttpAddRequestHeaders failed\n");
3076 
3077     ret = HttpSendRequestA(request, connection, ~0u, NULL, 0);
3078     ok(ret, "HttpSendRequest failed\n");
3079 
3080     status = 0;
3081     size = sizeof(status);
3082     ret = HttpQueryInfoA( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
3083     ok(ret, "HttpQueryInfo failed\n");
3084     ok(status == 200, "got status %u, expected 200\n", status);
3085 
3086     InternetCloseHandle(request);
3087     InternetCloseHandle(connect);
3088 
3089     connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3090     ok(connect != NULL, "InternetConnect failed\n");
3091 
3092     request = HttpOpenRequestA(connect, "POST", "/test7b", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
3093     ok(request != NULL, "HttpOpenRequest failed\n");
3094 
3095     ret = HttpAddRequestHeadersA(request, "Content-Length: 100\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
3096     ok(ret, "HttpAddRequestHeaders failed\n");
3097 
3098     data_len = sizeof(data);
3099     memset(data, 'a', sizeof(data));
3100     ret = HttpSendRequestA(request, NULL, 0, data, data_len);
3101     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
3102 
3103     status = 0;
3104     size = sizeof(status);
3105     ret = HttpQueryInfoA( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
3106     ok(ret, "HttpQueryInfo failed\n");
3107     ok(status == 200, "got status %u, expected 200\n", status);
3108 
3109     InternetCloseHandle(request);
3110     InternetCloseHandle(connect);
3111     InternetCloseHandle(session);
3112 }
3113 
3114 static void test_connection_header(int port)
3115 {
3116     HINTERNET ses, con, req;
3117     BOOL ret;
3118 
3119     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3120     ok(ses != NULL, "InternetOpen failed\n");
3121 
3122     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3123     ok(con != NULL, "InternetConnect failed\n");
3124 
3125     req = HttpOpenRequestA(con, NULL, "/test8", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3126     ok(req != NULL, "HttpOpenRequest failed\n");
3127 
3128     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3129     ok(ret, "HttpSendRequest failed\n");
3130 
3131     test_status_code(req, 200);
3132 
3133     InternetCloseHandle(req);
3134 
3135     req = HttpOpenRequestA(con, NULL, "/test9", NULL, NULL, NULL, 0, 0);
3136     ok(req != NULL, "HttpOpenRequest failed\n");
3137 
3138     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3139     ok(ret, "HttpSendRequest failed\n");
3140 
3141     test_status_code(req, 200);
3142 
3143     InternetCloseHandle(req);
3144 
3145     req = HttpOpenRequestA(con, NULL, "/test9", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
3146     ok(req != NULL, "HttpOpenRequest failed\n");
3147 
3148     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3149     ok(ret, "HttpSendRequest failed\n");
3150 
3151     test_status_code(req, 200);
3152 
3153     InternetCloseHandle(req);
3154 
3155     req = HttpOpenRequestA(con, "POST", "/testA", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
3156     ok(req != NULL, "HttpOpenRequest failed\n");
3157 
3158     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3159     ok(ret, "HttpSendRequest failed\n");
3160 
3161     test_status_code(req, 200);
3162 
3163     InternetCloseHandle(req);
3164     InternetCloseHandle(con);
3165     InternetCloseHandle(ses);
3166 }
3167 
3168 static void test_header_override(int port)
3169 {
3170     char buffer[128], host_header_override[30], full_url[128];
3171     HINTERNET ses, con, req;
3172     DWORD size, count, err;
3173     BOOL ret;
3174 
3175     sprintf(host_header_override, "Host: test.local:%d\r\n", port);
3176     sprintf(full_url, "http://localhost:%d/test_host_override", port);
3177 
3178     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3179     ok(ses != NULL, "InternetOpen failed\n");
3180 
3181     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3182     ok(con != NULL, "InternetConnect failed\n");
3183 
3184     req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3185     ok(req != NULL, "HttpOpenRequest failed\n");
3186 
3187     size = sizeof(buffer) - 1;
3188     count = 0;
3189     memset(buffer, 0, sizeof(buffer));
3190     ret = HttpQueryInfoA(req, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &count);
3191     err = GetLastError();
3192     ok(!ret, "HttpQueryInfo succeeded\n");
3193     ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "Expected error ERROR_HTTP_HEADER_NOT_FOUND, got %d\n", err);
3194 
3195     test_request_url(req, full_url);
3196 
3197     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_COALESCE);
3198     ok(ret, "HttpAddRequestHeaders failed\n");
3199 
3200     size = sizeof(buffer) - 1;
3201     count = 0;
3202     memset(buffer, 0, sizeof(buffer));
3203     ret = HttpQueryInfoA(req, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &count);
3204     ok(ret, "HttpQueryInfo failed\n");
3205 
3206     test_request_url(req, full_url);
3207 
3208     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3209     ok(ret, "HttpSendRequest failed\n");
3210 
3211     test_status_code(req, 200);
3212 
3213     InternetCloseHandle(req);
3214     req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3215     ok(req != NULL, "HttpOpenRequest failed\n");
3216 
3217     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_COALESCE);
3218     ok(ret, "HttpAddRequestHeaders failed\n");
3219 
3220     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_COALESCE);
3221     ok(ret, "HttpAddRequestHeaders failed\n");
3222 
3223     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3224     ok(ret, "HttpSendRequest failed\n");
3225 
3226     test_status_code(req, 400);
3227 
3228     InternetCloseHandle(req);
3229     req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3230     ok(req != NULL, "HttpOpenRequest failed\n");
3231 
3232     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3233     ok(ret, "HttpAddRequestHeaders failed\n");
3234 
3235     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3236     ok(ret, "HttpSendRequest failed\n");
3237 
3238     test_status_code(req, 200);
3239 
3240     InternetCloseHandle(req);
3241     req = HttpOpenRequestA(con, NULL, "/test_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3242     ok(req != NULL, "HttpOpenRequest failed\n");
3243 
3244     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_REPLACE);
3245     if(ret) { /* win10 returns success */
3246         trace("replacing host header is supported.\n");
3247 
3248         ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3249         ok(ret, "HttpSendRequest failed\n");
3250 
3251         test_status_code(req, 200);
3252     }else {
3253         trace("replacing host header is not supported.\n");
3254 
3255         err = GetLastError();
3256         ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "Expected error ERROR_HTTP_HEADER_NOT_FOUND, got %d\n", err);
3257 
3258         ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3259         ok(ret, "HttpSendRequest failed\n");
3260 
3261         test_status_code(req, 400);
3262     }
3263 
3264     InternetCloseHandle(req);
3265     InternetSetCookieA("http://localhost", "cookie", "biscuit");
3266     req = HttpOpenRequestA(con, NULL, "/testC", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3267     ok(req != NULL, "HttpOpenRequest failed\n");
3268 
3269     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3270     ok(ret, "HttpAddRequestHeaders failed\n");
3271 
3272     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3273     ok(ret, "HttpSendRequest failed\n");
3274 
3275     test_status_code(req, 200);
3276 
3277     InternetCloseHandle(req);
3278     req = HttpOpenRequestA(con, NULL, "/test_cookie_set_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3279     ok(req != NULL, "HttpOpenRequest failed\n");
3280 
3281     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3282     ok(ret, "HttpAddRequestHeaders failed\n");
3283 
3284     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3285     ok(ret, "HttpSendRequest failed\n");
3286 
3287     test_status_code(req, 200);
3288 
3289     InternetCloseHandle(req);
3290     req = HttpOpenRequestA(con, NULL, "/test_cookie_check_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3291     ok(req != NULL, "HttpOpenRequest failed\n");
3292 
3293     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3294     ok(ret, "HttpAddRequestHeaders failed\n");
3295 
3296     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3297     ok(ret, "HttpSendRequest failed\n");
3298 
3299     test_status_code(req, 200);
3300 
3301     InternetCloseHandle(req);
3302     req = HttpOpenRequestA(con, NULL, "/test_cookie_check_host_override", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3303     ok(req != NULL, "HttpOpenRequest failed\n");
3304 
3305     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3306     ok(ret, "HttpSendRequest failed\n");
3307 
3308     test_status_code(req, 200);
3309 
3310     InternetCloseHandle(req);
3311     InternetSetCookieA("http://test.local", "foo", "bar");
3312     req = HttpOpenRequestA(con, NULL, "/test_cookie_check_different_host", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3313     ok(req != NULL, "HttpOpenRequest failed\n");
3314 
3315     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3316     ok(ret, "HttpSendRequest failed\n");
3317 
3318     test_status_code(req, 200);
3319 
3320     InternetCloseHandle(req);
3321     req = HttpOpenRequestA(con, NULL, "/test_cookie_check_different_host", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
3322     ok(req != NULL, "HttpOpenRequest failed\n");
3323 
3324     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3325     ok(ret, "HttpAddRequestHeaders failed\n");
3326 
3327     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3328     ok(ret, "HttpSendRequest failed\n");
3329 
3330     test_status_code(req, 200);
3331 
3332     InternetCloseHandle(req);
3333     InternetCloseHandle(con);
3334     InternetCloseHandle(ses);
3335 
3336     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3337     ok(ses != NULL, "InternetOpenA failed\n");
3338 
3339     con = InternetConnectA(ses, "localhost", port, "test1", "pass", INTERNET_SERVICE_HTTP, 0, 0);
3340     ok(con != NULL, "InternetConnectA failed %u\n", GetLastError());
3341 
3342     req = HttpOpenRequestA( con, "HEAD", "/test_auth_host1", NULL, NULL, NULL, 0, 0);
3343     ok(req != NULL, "HttpOpenRequestA failed %u\n", GetLastError());
3344 
3345     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3346     ok(ret, "HttpSendRequestA failed %u\n", GetLastError());
3347 
3348     test_status_code(req, 200);
3349 
3350     InternetCloseHandle(req);
3351     InternetCloseHandle(con);
3352     InternetCloseHandle(ses);
3353 
3354     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3355     ok(ses != NULL, "InternetOpenA failed\n");
3356 
3357     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3358     ok(con != NULL, "InternetConnectA failed %u\n", GetLastError());
3359 
3360     req = HttpOpenRequestA(con, "HEAD", "/test_auth_host1", NULL, NULL, NULL, 0, 0);
3361     ok(req != NULL, "HttpOpenRequestA failed %u\n", GetLastError());
3362 
3363     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3364     ok(ret, "HttpAddRequestHeaders failed\n");
3365 
3366     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
3367     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
3368 
3369     test_status_code(req, 200);
3370 
3371     InternetCloseHandle(req);
3372     InternetCloseHandle(con);
3373     InternetCloseHandle(ses);
3374 
3375     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3376     ok(ses != NULL, "InternetOpenA failed\n");
3377 
3378     con = InternetConnectA(ses, "localhost", port, "test1", "pass2", INTERNET_SERVICE_HTTP, 0, 0);
3379     ok(con != NULL, "InternetConnectA failed %u\n", GetLastError());
3380 
3381     req = HttpOpenRequestA(con, "HEAD", "/test_auth_host2", NULL, NULL, NULL, 0, 0);
3382     ok(req != NULL, "HttpOpenRequestA failed %u\n", GetLastError());
3383 
3384     ret = HttpAddRequestHeadersA(req, host_header_override, ~0u, HTTP_ADDREQ_FLAG_ADD);
3385     ok(ret, "HttpAddRequestHeaders failed\n");
3386 
3387     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3388     ok(ret, "HttpSendRequestA failed %u\n", GetLastError());
3389 
3390     test_status_code(req, 200);
3391 
3392     InternetCloseHandle(req);
3393     InternetCloseHandle(con);
3394     InternetCloseHandle(ses);
3395 
3396     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3397     ok(ses != NULL, "InternetOpenA failed\n");
3398 
3399     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3400     ok(con != NULL, "InternetConnectA failed %u\n", GetLastError());
3401 
3402     req = HttpOpenRequestA(con, "HEAD", "/test_auth_host2", NULL, NULL, NULL, 0, 0);
3403     ok(req != NULL, "HttpOpenRequestA failed %u\n", GetLastError());
3404 
3405     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3406     ok(ret, "HttpSendRequestA failed %u\n", GetLastError());
3407 
3408     test_status_code(req, 200);
3409 
3410     InternetCloseHandle(req);
3411     InternetCloseHandle(con);
3412     InternetCloseHandle(ses);
3413 }
3414 
3415 static void test_connection_closing(int port)
3416 {
3417     HINTERNET session, connection, req;
3418     DWORD res;
3419 
3420     reset_events();
3421 
3422     session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3423     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3424 
3425     pInternetSetStatusCallbackA(session, callback);
3426 
3427     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3428     connection = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3429     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3430     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3431 
3432     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3433     req = HttpOpenRequestA(connection, "GET", "/testJ", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0xdeadbeaf);
3434     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3435     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3436 
3437     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3438     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3439     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3440     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3441     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3442     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3443     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3444     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3445     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION);
3446     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED);
3447     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3448 
3449     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3450     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3451        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3452     WaitForSingleObject(complete_event, INFINITE);
3453     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3454 
3455     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3456     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3457     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3458     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3459     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3460     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3461     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3462     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3463     CLEAR_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3464     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3465     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3466 
3467     test_status_code(req, 200);
3468 
3469     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3470     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3471     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3472     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3473     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3474     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3475     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3476     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3477     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3478 
3479     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3480     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3481             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3482     WaitForSingleObject(complete_event, INFINITE);
3483     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3484 
3485     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3486     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3487     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3488     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3489     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3490     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3491     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3492     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3493     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3494 
3495     test_status_code(req, 210);
3496 
3497     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3498     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3499     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3500     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3501     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3502     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3503     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3504     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3505     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION);
3506     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED);
3507     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3508 
3509     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3510     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3511        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3512     WaitForSingleObject(complete_event, INFINITE);
3513     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3514 
3515     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3516     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3517     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3518     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3519     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3520     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3521     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3522     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3523     CLEAR_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3524     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3525     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3526 
3527     test_status_code(req, 200);
3528 
3529     SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
3530     SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
3531 
3532     close_async_handle(session, 2);
3533 }
3534 
3535 static void test_successive_HttpSendRequest(int port)
3536 {
3537     HINTERNET session, connection, req;
3538     DWORD res;
3539 
3540     reset_events();
3541 
3542     session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3543     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3544 
3545     pInternetSetStatusCallbackA(session, callback);
3546 
3547     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3548     connection = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3549     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3550     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3551 
3552     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3553     req = HttpOpenRequestA(connection, "GET", "/testH", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0xdeadbeaf);
3554     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3555     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3556 
3557     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3558     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3559     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3560     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3561     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3562     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3563     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3564     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3565     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3566 
3567     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3568     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3569             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3570     WaitForSingleObject(complete_event, INFINITE);
3571     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3572 
3573     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3574     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3575     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3576     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3577     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3578     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3579     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3580     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3581     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3582 
3583     test_status_code(req, 210);
3584 
3585     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3586     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
3587     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3588     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3589     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3590     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3591     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION);
3592     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED);
3593     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3594 
3595     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
3596     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3597        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3598     WaitForSingleObject(complete_event, INFINITE);
3599     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3600 
3601     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3602     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
3603     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3604     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3605     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3606     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3607     CLEAR_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3608     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3609     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3610 
3611     test_status_code(req, 200);
3612 
3613     SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
3614     SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
3615 
3616     close_async_handle(session, 2);
3617 }
3618 
3619 static void test_no_content(int port)
3620 {
3621     HINTERNET session, connection, req;
3622     DWORD res;
3623 
3624     trace("Testing 204 no content response...\n");
3625 
3626     reset_events();
3627 
3628     session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3629     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3630 
3631     pInternetSetStatusCallbackA(session, callback);
3632 
3633     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3634     connection = InternetConnectA(session, "localhost", port,
3635             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3636     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3637     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3638 
3639     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3640     req = HttpOpenRequestA(connection, "GET", "/test_no_content", NULL, NULL, NULL,
3641             INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
3642     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3643     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3644 
3645     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3646     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3647     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3648     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3649     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3650     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3651     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3652     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
3653     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
3654     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3655 
3656     res = HttpSendRequestA(req, NULL, -1, NULL, 0);
3657     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3658        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3659     WaitForSingleObject(complete_event, INFINITE);
3660     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3661 
3662     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3663     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3664     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3665     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3666     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3667     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3668     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3669     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3670 
3671     close_async_handle(session, 2);
3672 
3673     /*
3674      * The connection should be closed before closing handle. This is true for most
3675      * wininet versions (including Wine), but some old win2k versions fail to do that.
3676      */
3677     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3678     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3679 }
3680 
3681 static void test_conn_close(int port)
3682 {
3683     HINTERNET session, connection, req;
3684     DWORD res, avail, size;
3685     BYTE buf[1024];
3686 
3687     trace("Testing connection close connection...\n");
3688 
3689     reset_events();
3690 
3691     session = InternetOpenA("", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
3692     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3693 
3694     pInternetSetStatusCallbackA(session, callback);
3695 
3696     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3697     connection = InternetConnectA(session, "localhost", port,
3698             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3699     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
3700     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3701 
3702     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
3703     req = HttpOpenRequestA(connection, "GET", "/test_conn_close", NULL, NULL, NULL,
3704             INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
3705     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3706     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
3707 
3708     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
3709     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
3710     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
3711     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
3712     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
3713     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
3714     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
3715     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3716 
3717     res = HttpSendRequestA(req, NULL, -1, NULL, 0);
3718     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3719        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3720     WaitForSingleObject(complete_event, INFINITE);
3721     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3722 
3723     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
3724     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
3725     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
3726     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
3727     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
3728     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3729     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3730     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3731 
3732     avail = 0;
3733     res = InternetQueryDataAvailable(req, &avail, 0, 0);
3734     ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
3735     ok(avail != 0, "avail = 0\n");
3736 
3737     size = 0;
3738     res = InternetReadFile(req, buf, avail, &size);
3739     ok(res, "InternetReadFile failed: %u\n", GetLastError());
3740 
3741     /* IE11 calls those in InternetQueryDataAvailable call. */
3742     SET_OPTIONAL(INTERNET_STATUS_RECEIVING_RESPONSE);
3743     SET_OPTIONAL(INTERNET_STATUS_RESPONSE_RECEIVED);
3744 
3745     res = InternetQueryDataAvailable(req, &avail, 0, 0);
3746     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3747        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3748     ok(!avail, "avail = %u, expected 0\n", avail);
3749 
3750     CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
3751 
3752     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
3753     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
3754     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
3755     SetEvent(conn_close_event);
3756     WaitForSingleObject(complete_event, INFINITE);
3757     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
3758     CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
3759     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
3760     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
3761     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
3762 
3763     close_async_handle(session, 2);
3764 }
3765 
3766 static void test_no_cache(int port)
3767 {
3768     static const char cache_control_no_cache[] = "/test_cache_control_no_cache";
3769     static const char cache_control_no_store[] = "/test_cache_control_no_store";
3770     static const char cache_url_fmt[] = "http://localhost:%d%s";
3771 
3772     char cache_url[256], buf[256];
3773     HINTERNET ses, con, req;
3774     DWORD read, size;
3775     BOOL ret;
3776 
3777     trace("Testing no-cache header\n");
3778 
3779     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3780     ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3781 
3782     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3783     ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3784 
3785     req = HttpOpenRequestA(con, NULL, cache_control_no_cache, NULL, NULL, NULL, 0, 0);
3786     ok(req != NULL, "HttpOpenRequest failed\n");
3787 
3788     sprintf(cache_url, cache_url_fmt, port, cache_control_no_cache);
3789     DeleteUrlCacheEntryA(cache_url);
3790 
3791     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3792     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3793     size = 0;
3794     while(InternetReadFile(req, buf, sizeof(buf), &read) && read)
3795         size += read;
3796     ok(size == 12, "read %d bytes of data\n", size);
3797     InternetCloseHandle(req);
3798 
3799     req = HttpOpenRequestA(con, NULL, cache_control_no_cache, NULL, NULL, NULL, 0, 0);
3800     ok(req != NULL, "HttpOpenRequest failed\n");
3801 
3802     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3803     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3804     size = 0;
3805     while(InternetReadFile(req, buf, sizeof(buf), &read) && read)
3806         size += read;
3807     ok(size == 0, "read %d bytes of data\n", size);
3808     InternetCloseHandle(req);
3809     DeleteUrlCacheEntryA(cache_url);
3810 
3811     req = HttpOpenRequestA(con, NULL, cache_control_no_store, NULL, NULL, NULL, 0, 0);
3812     ok(req != NULL, "HttpOpenRequest failed\n");
3813 
3814     sprintf(cache_url, cache_url_fmt, port, cache_control_no_store);
3815     DeleteUrlCacheEntryA(cache_url);
3816 
3817     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
3818     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3819     size = 0;
3820     while(InternetReadFile(req, buf, sizeof(buf), &read) && read)
3821         size += read;
3822     ok(size == 12, "read %d bytes of data\n", size);
3823     InternetCloseHandle(req);
3824 
3825     ret = DeleteUrlCacheEntryA(cache_url);
3826     ok(!ret && GetLastError()==ERROR_FILE_NOT_FOUND, "cache entry should not exist\n");
3827 
3828     InternetCloseHandle(con);
3829     InternetCloseHandle(ses);
3830 }
3831 
3832 static void test_cache_read_gzipped(int port)
3833 {
3834     static const char cache_url_fmt[] = "http://localhost:%d%s";
3835     static const char get_gzip[] = "/test_cache_gzip";
3836     static const char content[] = "gzip test\n";
3837     static const char text_html[] = "text/html";
3838     static const char raw_header[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
3839 
3840     HINTERNET ses, con, req;
3841     DWORD read, size;
3842     char cache_url[256], buf[256];
3843     BOOL ret;
3844 
3845     trace("Testing reading compressed content from cache\n");
3846 
3847     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3848     ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3849 
3850     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3851     ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3852 
3853     req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3854     ok(req != NULL, "HttpOpenRequest failed\n");
3855 
3856     ret = TRUE;
3857     ret = InternetSetOptionA(req, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3858     if(!ret && GetLastError()==ERROR_INTERNET_INVALID_OPTION) {
3859         win_skip("INTERNET_OPTION_HTTP_DECODING not supported\n");
3860         InternetCloseHandle(req);
3861         InternetCloseHandle(con);
3862         InternetCloseHandle(ses);
3863         return;
3864     }
3865     ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3866 
3867     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3868     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3869     size = 0;
3870     while(InternetReadFile(req, buf+size, sizeof(buf)-size, &read) && read)
3871         size += read;
3872     ok(size == 10, "read %d bytes of data\n", size);
3873     buf[size] = 0;
3874     ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3875 
3876     size = sizeof(buf)-1;
3877     ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_TYPE, buf, &size, 0);
3878     ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) failed: %d\n", GetLastError());
3879     buf[size] = 0;
3880     ok(!strncmp(text_html, buf, size), "buf = %s\n", buf);
3881 
3882     size = sizeof(buf)-1;
3883     ret = HttpQueryInfoA(req, HTTP_QUERY_RAW_HEADERS_CRLF, buf, &size, 0);
3884     ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) failed: %d\n", GetLastError());
3885     buf[size] = 0;
3886     ok(!strncmp(raw_header, buf, size), "buf = %s\n", buf);
3887     InternetCloseHandle(req);
3888 
3889     req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
3890     ok(req != NULL, "HttpOpenRequest failed\n");
3891 
3892     ret = TRUE;
3893     ret = InternetSetOptionA(req, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3894     ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3895 
3896     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3897     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3898     size = 0;
3899     while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3900         size += read;
3901     todo_wine ok(size == 10, "read %d bytes of data\n", size);
3902     buf[size] = 0;
3903     ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3904 
3905     size = sizeof(buf);
3906     ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_ENCODING, buf, &size, 0);
3907     ok(!ret && GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND,
3908             "HttpQueryInfo(HTTP_QUERY_CONTENT_ENCODING) returned %d, %d\n",
3909             ret, GetLastError());
3910 
3911     size = sizeof(buf)-1;
3912     ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_TYPE, buf, &size, 0);
3913     todo_wine ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_TYPE) failed: %d\n", GetLastError());
3914     buf[size] = 0;
3915     todo_wine ok(!strncmp(text_html, buf, size), "buf = %s\n", buf);
3916     InternetCloseHandle(req);
3917 
3918     /* Decompression doesn't work while reading from cache */
3919     test_cache_gzip = 0;
3920     sprintf(cache_url, cache_url_fmt, port, get_gzip);
3921     DeleteUrlCacheEntryA(cache_url);
3922 
3923     req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3924     ok(req != NULL, "HttpOpenRequest failed\n");
3925 
3926     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3927     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3928     size = 0;
3929     while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3930         size += read;
3931     ok(size == 31, "read %d bytes of data\n", size);
3932     InternetCloseHandle(req);
3933 
3934     req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
3935     ok(req != NULL, "HttpOpenRequest failed\n");
3936 
3937     ret = TRUE;
3938     ret = InternetSetOptionA(req, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3939     ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3940 
3941     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3942     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3943     size = 0;
3944     while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3945         size += read;
3946     todo_wine ok(size == 31, "read %d bytes of data\n", size);
3947 
3948     size = sizeof(buf);
3949     ret = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_ENCODING, buf, &size, 0);
3950     todo_wine ok(ret, "HttpQueryInfo(HTTP_QUERY_CONTENT_ENCODING) failed: %d\n", GetLastError());
3951     InternetCloseHandle(req);
3952 
3953     InternetCloseHandle(con);
3954     InternetCloseHandle(ses);
3955 
3956     /* Decompression doesn't work while reading from cache */
3957     test_cache_gzip = 0;
3958     sprintf(cache_url, cache_url_fmt, port, get_gzip);
3959     DeleteUrlCacheEntryA(cache_url);
3960 
3961     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3962     ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3963 
3964     ret = TRUE;
3965     ret = InternetSetOptionA(ses, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
3966     ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
3967 
3968     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3969     ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3970 
3971     req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
3972     ok(req != NULL, "HttpOpenRequest failed\n");
3973 
3974     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
3975     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
3976     size = 0;
3977     while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
3978         size += read;
3979     ok(size == 10, "read %d bytes of data\n", size);
3980     buf[size] = 0;
3981     ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
3982     InternetCloseHandle(req);
3983 
3984     InternetCloseHandle(con);
3985     InternetCloseHandle(ses);
3986 
3987     /* Decompression doesn't work while reading from cache */
3988     test_cache_gzip = 0;
3989     sprintf(cache_url, cache_url_fmt, port, get_gzip);
3990     DeleteUrlCacheEntryA(cache_url);
3991 
3992     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
3993     ok(ses != NULL,"InternetOpen failed with error %u\n", GetLastError());
3994 
3995     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3996     ok(con != NULL, "InternetConnect failed with error %u\n", GetLastError());
3997 
3998     ret = TRUE;
3999     ret = InternetSetOptionA(con, INTERNET_OPTION_HTTP_DECODING, &ret, sizeof(ret));
4000     ok(ret, "InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %d\n", GetLastError());
4001 
4002     req = HttpOpenRequestA(con, NULL, get_gzip, NULL, NULL, NULL, 0, 0);
4003     ok(req != NULL, "HttpOpenRequest failed\n");
4004 
4005     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", -1, NULL, 0);
4006     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
4007     size = 0;
4008     while(InternetReadFile(req, buf+size, sizeof(buf)-1-size, &read) && read)
4009         size += read;
4010     ok(size == 10, "read %d bytes of data\n", size);
4011     buf[size] = 0;
4012     ok(!strncmp(buf, content, size), "incorrect page content: %s\n", buf);
4013     InternetCloseHandle(req);
4014 
4015     InternetCloseHandle(con);
4016     InternetCloseHandle(ses);
4017 
4018     DeleteUrlCacheEntryA(cache_url);
4019 }
4020 
4021 static void test_HttpSendRequestW(int port)
4022 {
4023     static const WCHAR header[] = {'U','A','-','C','P','U',':',' ','x','8','6',0};
4024     HINTERNET ses, con, req;
4025     DWORD error;
4026     BOOL ret;
4027 
4028     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
4029     ok(ses != NULL, "InternetOpen failed\n");
4030 
4031     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4032     ok(con != NULL, "InternetConnect failed\n");
4033 
4034     req = HttpOpenRequestA(con, NULL, "/test1", NULL, NULL, NULL, 0, 0);
4035     ok(req != NULL, "HttpOpenRequest failed\n");
4036 
4037     SetLastError(0xdeadbeef);
4038     ret = HttpSendRequestW(req, header, ~0u, NULL, 0);
4039     error = GetLastError();
4040     ok(!ret, "HttpSendRequestW succeeded\n");
4041     ok(error == ERROR_IO_PENDING ||
4042        broken(error == ERROR_HTTP_HEADER_NOT_FOUND) ||  /* IE6 */
4043        broken(error == ERROR_INVALID_PARAMETER),        /* IE5 */
4044        "got %u expected ERROR_IO_PENDING\n", error);
4045 
4046     InternetCloseHandle(req);
4047     InternetCloseHandle(con);
4048     InternetCloseHandle(ses);
4049 }
4050 
4051 static void test_cookie_header(int port)
4052 {
4053     HINTERNET ses, con, req;
4054     DWORD size, error;
4055     BOOL ret;
4056     char buffer[256];
4057 
4058     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4059     ok(ses != NULL, "InternetOpen failed\n");
4060 
4061     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4062     ok(con != NULL, "InternetConnect failed\n");
4063 
4064     InternetSetCookieA("http://localhost", "cookie", "biscuit");
4065 
4066     req = HttpOpenRequestA(con, NULL, "/testC", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4067     ok(req != NULL, "HttpOpenRequest failed\n");
4068 
4069     buffer[0] = 0;
4070     size = sizeof(buffer);
4071     SetLastError(0xdeadbeef);
4072     ret = HttpQueryInfoA(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
4073     error = GetLastError();
4074     ok(!ret, "HttpQueryInfo succeeded\n");
4075     ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "got %u expected ERROR_HTTP_HEADER_NOT_FOUND\n", error);
4076 
4077     ret = HttpAddRequestHeadersA(req, "Cookie: cookie=not biscuit\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD);
4078     ok(ret, "HttpAddRequestHeaders failed: %u\n", GetLastError());
4079 
4080     buffer[0] = 0;
4081     size = sizeof(buffer);
4082     ret = HttpQueryInfoA(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
4083     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
4084     ok(!!strstr(buffer, "cookie=not biscuit"), "got '%s' expected \'cookie=not biscuit\'\n", buffer);
4085 
4086     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4087     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
4088 
4089     test_status_code(req, 200);
4090 
4091     buffer[0] = 0;
4092     size = sizeof(buffer);
4093     ret = HttpQueryInfoA(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
4094     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
4095     ok(!strstr(buffer, "cookie=not biscuit"), "'%s' should not contain \'cookie=not biscuit\'\n", buffer);
4096     ok(!!strstr(buffer, "cookie=biscuit"), "'%s' should contain \'cookie=biscuit\'\n", buffer);
4097 
4098     InternetCloseHandle(req);
4099 
4100     InternetSetCookieA("http://localhost/testCCCC", "subcookie", "data");
4101 
4102     req = HttpOpenRequestA(con, NULL, "/test_cookie_path1", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4103     ok(req != NULL, "HttpOpenRequest failed\n");
4104 
4105     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4106     ok(ret, "HttpSendRequest failed\n");
4107 
4108     test_status_code(req, 200);
4109     InternetCloseHandle(req);
4110 
4111     req = HttpOpenRequestA(con, NULL, "/test_cookie_path1/abc", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4112     ok(req != NULL, "HttpOpenRequest failed\n");
4113 
4114     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4115     ok(ret, "HttpSendRequest failed\n");
4116 
4117     test_status_code(req, 200);
4118     InternetCloseHandle(req);
4119 
4120     req = HttpOpenRequestA(con, NULL, "/test_cookie_set_path", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4121     ok(req != NULL, "HttpOpenRequest failed\n");
4122 
4123     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4124     ok(ret, "HttpSendRequest failed\n");
4125 
4126     test_status_code(req, 200);
4127     InternetCloseHandle(req);
4128 
4129     req = HttpOpenRequestA(con, NULL, "/test_cookie_path2", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4130     ok(req != NULL, "HttpOpenRequest failed\n");
4131 
4132     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4133     ok(ret, "HttpSendRequest failed\n");
4134 
4135     test_status_code(req, 400);
4136     InternetCloseHandle(req);
4137 
4138     req = HttpOpenRequestA(con, NULL, "/test_cookie_merge", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
4139     ok(req != NULL, "HttpOpenRequest failed\n");
4140 
4141     ret = HttpAddRequestHeadersA(req, "Cookie: manual_cookie=test\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD);
4142     ok(ret, "HttpAddRequestHeaders failed: %u\n", GetLastError());
4143 
4144     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
4145     ok(ret, "HttpSendRequest failed\n");
4146 
4147     test_status_code(req, 200);
4148     InternetCloseHandle(req);
4149 
4150     InternetCloseHandle(con);
4151     InternetCloseHandle(ses);
4152 }
4153 
4154 static void test_basic_authentication(int port)
4155 {
4156     HINTERNET session, connect, request;
4157     BOOL ret;
4158 
4159     session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4160     ok(session != NULL, "InternetOpen failed\n");
4161 
4162     connect = InternetConnectA(session, "localhost", port, "user", "pwd", INTERNET_SERVICE_HTTP, 0, 0);
4163     ok(connect != NULL, "InternetConnect failed\n");
4164 
4165     request = HttpOpenRequestA(connect, NULL, "/test3", NULL, NULL, NULL, 0, 0);
4166     ok(request != NULL, "HttpOpenRequest failed\n");
4167 
4168     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4169     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4170 
4171     test_status_code(request, 200);
4172     test_request_flags(request, 0);
4173 
4174     InternetCloseHandle(request);
4175     InternetCloseHandle(connect);
4176     InternetCloseHandle(session);
4177 }
4178 
4179 static void test_premature_disconnect(int port)
4180 {
4181     test_request_t req;
4182     DWORD err;
4183     BOOL ret;
4184 
4185     open_simple_request(&req, "localhost", port, NULL, "/premature_disconnect");
4186 
4187     SetLastError(0xdeadbeef);
4188     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4189     err = GetLastError();
4190     todo_wine ok(!ret, "HttpSendRequest succeeded\n");
4191     todo_wine ok(err == ERROR_HTTP_INVALID_SERVER_RESPONSE, "got %u\n", err);
4192 
4193     close_request(&req);
4194 }
4195 
4196 static void test_invalid_response_headers(int port)
4197 {
4198     test_request_t req;
4199     DWORD size;
4200     BOOL ret;
4201     char buffer[256];
4202 
4203     open_simple_request(&req, "localhost", port, NULL, "/testE");
4204 
4205     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4206     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4207 
4208     test_status_code(req.request, 401);
4209     test_request_flags(req.request, 0);
4210 
4211     buffer[0] = 0;
4212     size = sizeof(buffer);
4213     ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL);
4214     ok(ret, "HttpQueryInfo failed\n");
4215     ok(!strcmp(buffer, "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"),
4216        "headers wrong \"%s\"\n", buffer);
4217 
4218     buffer[0] = 0;
4219     size = sizeof(buffer);
4220     ret = HttpQueryInfoA(req.request, HTTP_QUERY_SERVER, buffer, &size, NULL);
4221     ok(ret, "HttpQueryInfo failed\n");
4222     ok(!strcmp(buffer, "winetest"), "server wrong \"%s\"\n", buffer);
4223 
4224     close_request(&req);
4225 }
4226 
4227 static void test_response_without_headers(int port)
4228 {
4229     test_request_t req;
4230     DWORD r, count, size;
4231     char buffer[1024];
4232 
4233     open_simple_request(&req, "localhost", port, NULL, "/testG");
4234 
4235     test_request_flags(req.request, INTERNET_REQFLAG_NO_HEADERS);
4236 
4237     r = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4238     ok(r, "HttpSendRequest failed %u\n", GetLastError());
4239 
4240     test_request_flags_todo(req.request, INTERNET_REQFLAG_NO_HEADERS);
4241 
4242     count = 0;
4243     memset(buffer, 0, sizeof buffer);
4244     r = InternetReadFile(req.request, buffer, sizeof buffer, &count);
4245     ok(r, "InternetReadFile failed %u\n", GetLastError());
4246     todo_wine ok(count == sizeof page1 - 1, "count was wrong\n");
4247     todo_wine ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
4248 
4249     test_status_code(req.request, 200);
4250     test_request_flags_todo(req.request, INTERNET_REQFLAG_NO_HEADERS);
4251 
4252     buffer[0] = 0;
4253     size = sizeof(buffer);
4254     r = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &size, NULL );
4255     ok(r, "HttpQueryInfo failed %u\n", GetLastError());
4256     ok(!strcmp(buffer, "OK"), "expected OK got: \"%s\"\n", buffer);
4257 
4258     buffer[0] = 0;
4259     size = sizeof(buffer);
4260     r = HttpQueryInfoA(req.request, HTTP_QUERY_VERSION, buffer, &size, NULL);
4261     ok(r, "HttpQueryInfo failed %u\n", GetLastError());
4262     ok(!strcmp(buffer, "HTTP/1.0"), "expected HTTP/1.0 got: \"%s\"\n", buffer);
4263 
4264     buffer[0] = 0;
4265     size = sizeof(buffer);
4266     r = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL);
4267     ok(r, "HttpQueryInfo failed %u\n", GetLastError());
4268     ok(!strcmp(buffer, "HTTP/1.0 200 OK"), "raw headers wrong: \"%s\"\n", buffer);
4269 
4270     close_request(&req);
4271 }
4272 
4273 static void test_head_request(int port)
4274 {
4275     DWORD len, content_length;
4276     test_request_t req;
4277     BYTE buf[100];
4278     BOOL ret;
4279 
4280     open_simple_request(&req, "localhost", port, "HEAD", "/test_head");
4281 
4282     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4283     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
4284 
4285     len = sizeof(content_length);
4286     content_length = -1;
4287     ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &content_length, &len, 0);
4288     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
4289     ok(len == sizeof(DWORD), "len = %u\n", len);
4290     ok(content_length == 100, "content_length = %u\n", content_length);
4291 
4292     len = -1;
4293     ret = InternetReadFile(req.request, buf, sizeof(buf), &len);
4294     ok(ret, "InternetReadFile failed: %u\n", GetLastError());
4295 
4296     len = -1;
4297     ret = InternetReadFile(req.request, buf, sizeof(buf), &len);
4298     ok(ret, "InternetReadFile failed: %u\n", GetLastError());
4299 
4300     close_request(&req);
4301 }
4302 
4303 static void test_HttpQueryInfo(int port)
4304 {
4305     test_request_t req;
4306     DWORD size, index, error;
4307     char buffer[1024];
4308     BOOL ret;
4309 
4310     open_simple_request(&req, "localhost", port, NULL, "/testD");
4311 
4312     size = sizeof(buffer);
4313     ret = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &size, &index);
4314     error = GetLastError();
4315     ok(!ret || broken(ret), "HttpQueryInfo succeeded\n");
4316     if (!ret) ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "got %u expected ERROR_HTTP_HEADER_NOT_FOUND\n", error);
4317 
4318     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4319     ok(ret, "HttpSendRequest failed\n");
4320 
4321     index = 0;
4322     size = sizeof(buffer);
4323     ret = HttpQueryInfoA(req.request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &index);
4324     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4325     ok(index == 1, "expected 1 got %u\n", index);
4326 
4327     index = 0;
4328     size = sizeof(buffer);
4329     ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
4330     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4331     ok(index == 1, "expected 1 got %u\n", index);
4332 
4333     index = 0;
4334     size = sizeof(buffer);
4335     ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
4336     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4337     ok(index == 0, "expected 0 got %u\n", index);
4338 
4339     size = sizeof(buffer);
4340     ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
4341     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4342     ok(index == 0, "expected 0 got %u\n", index);
4343 
4344     index = 0xdeadbeef; /* invalid start index */
4345     size = sizeof(buffer);
4346     ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
4347     todo_wine ok(!ret, "HttpQueryInfo should have failed\n");
4348     todo_wine ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
4349        "Expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", GetLastError());
4350 
4351     index = 0;
4352     size = sizeof(buffer);
4353     ret = HttpQueryInfoA(req.request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer, &size, &index);
4354     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4355     ok(index == 0, "expected 0 got %u\n", index);
4356 
4357     size = sizeof(buffer);
4358     ret = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buffer, &size, &index);
4359     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4360     ok(index == 0, "expected 0 got %u\n", index);
4361 
4362     size = sizeof(buffer);
4363     ret = HttpQueryInfoA(req.request, HTTP_QUERY_VERSION, buffer, &size, &index);
4364     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4365     ok(index == 0, "expected 0 got %u\n", index);
4366 
4367     test_status_code(req.request, 200);
4368 
4369     index = 0xdeadbeef;
4370     size = sizeof(buffer);
4371     ret = HttpQueryInfoA(req.request, HTTP_QUERY_FORWARDED, buffer, &size, &index);
4372     ok(!ret, "HttpQueryInfo succeeded\n");
4373     ok(index == 0xdeadbeef, "expected 0xdeadbeef got %u\n", index);
4374 
4375     index = 0;
4376     size = sizeof(buffer);
4377     ret = HttpQueryInfoA(req.request, HTTP_QUERY_SERVER, buffer, &size, &index);
4378     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4379     ok(index == 1, "expected 1 got %u\n", index);
4380 
4381     index = 0;
4382     size = sizeof(buffer);
4383     strcpy(buffer, "Server");
4384     ret = HttpQueryInfoA(req.request, HTTP_QUERY_CUSTOM, buffer, &size, &index);
4385     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4386     ok(index == 1, "expected 1 got %u\n", index);
4387 
4388     index = 0;
4389     size = sizeof(buffer);
4390     ret = HttpQueryInfoA(req.request, HTTP_QUERY_SET_COOKIE, buffer, &size, &index);
4391     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4392     ok(index == 1, "expected 1 got %u\n", index);
4393 
4394     size = sizeof(buffer);
4395     ret = HttpQueryInfoA(req.request, HTTP_QUERY_SET_COOKIE, buffer, &size, &index);
4396     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
4397     ok(index == 2, "expected 2 got %u\n", index);
4398 
4399     close_request(&req);
4400 }
4401 
4402 static void test_options(int port)
4403 {
4404     INTERNET_DIAGNOSTIC_SOCKET_INFO idsi;
4405     HINTERNET ses, con, req;
4406     DWORD size, error;
4407     DWORD_PTR ctx;
4408     BOOL ret;
4409 
4410     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4411     ok(ses != NULL, "InternetOpen failed\n");
4412 
4413     SetLastError(0xdeadbeef);
4414     ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, 0);
4415     error = GetLastError();
4416     ok(!ret, "InternetSetOption succeeded\n");
4417     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4418 
4419     SetLastError(0xdeadbeef);
4420     ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, sizeof(ctx));
4421     ok(!ret, "InternetSetOption succeeded\n");
4422     error = GetLastError();
4423     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4424 
4425     SetLastError(0xdeadbeef);
4426     ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, 0);
4427     ok(!ret, "InternetSetOption succeeded\n");
4428     error = GetLastError();
4429     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4430 
4431     ctx = 1;
4432     ret = InternetSetOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
4433     ok(ret, "InternetSetOption failed %u\n", GetLastError());
4434 
4435     SetLastError(0xdeadbeef);
4436     ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, NULL);
4437     error = GetLastError();
4438     ok(!ret, "InternetQueryOption succeeded\n");
4439     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4440 
4441     SetLastError(0xdeadbeef);
4442     ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, NULL);
4443     error = GetLastError();
4444     ok(!ret, "InternetQueryOption succeeded\n");
4445     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4446 
4447     size = 0;
4448     SetLastError(0xdeadbeef);
4449     ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, &size);
4450     error = GetLastError();
4451     ok(!ret, "InternetQueryOption succeeded\n");
4452     ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
4453 
4454     size = sizeof(ctx);
4455     SetLastError(0xdeadbeef);
4456     ret = InternetQueryOptionA(NULL, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4457     error = GetLastError();
4458     ok(!ret, "InternetQueryOption succeeded\n");
4459     ok(error == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %u\n", error);
4460 
4461     ctx = 0xdeadbeef;
4462     size = sizeof(ctx);
4463     ret = InternetQueryOptionA(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4464     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4465     ok(ctx == 1, "expected 1 got %lu\n", ctx);
4466 
4467     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4468     ok(con != NULL, "InternetConnect failed\n");
4469 
4470     ctx = 0xdeadbeef;
4471     size = sizeof(ctx);
4472     ret = InternetQueryOptionA(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4473     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4474     ok(ctx == 0, "expected 0 got %lu\n", ctx);
4475 
4476     ctx = 2;
4477     ret = InternetSetOptionA(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
4478     ok(ret, "InternetSetOption failed %u\n", GetLastError());
4479 
4480     ctx = 0xdeadbeef;
4481     size = sizeof(ctx);
4482     ret = InternetQueryOptionA(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4483     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4484     ok(ctx == 2, "expected 2 got %lu\n", ctx);
4485 
4486     req = HttpOpenRequestA(con, NULL, "/test1", NULL, NULL, NULL, 0, 0);
4487     ok(req != NULL, "HttpOpenRequest failed\n");
4488 
4489     ctx = 0xdeadbeef;
4490     size = sizeof(ctx);
4491     ret = InternetQueryOptionA(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4492     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4493     ok(ctx == 0, "expected 0 got %lu\n", ctx);
4494 
4495     ctx = 3;
4496     ret = InternetSetOptionA(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
4497     ok(ret, "InternetSetOption failed %u\n", GetLastError());
4498 
4499     ctx = 0xdeadbeef;
4500     size = sizeof(ctx);
4501     ret = InternetQueryOptionA(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
4502     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4503     ok(ctx == 3, "expected 3 got %lu\n", ctx);
4504 
4505     size = sizeof(idsi);
4506     ret = InternetQueryOptionA(req, INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, &idsi, &size);
4507     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
4508 
4509     size = 0;
4510     SetLastError(0xdeadbeef);
4511     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, NULL, &size);
4512     error = GetLastError();
4513     ok(!ret, "InternetQueryOption succeeded\n");
4514     ok(error == ERROR_INTERNET_INVALID_OPERATION, "expected ERROR_INTERNET_INVALID_OPERATION, got %u\n", error);
4515 
4516     /* INTERNET_OPTION_PROXY */
4517     SetLastError(0xdeadbeef);
4518     ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, NULL, NULL);
4519     error = GetLastError();
4520     ok(!ret, "InternetQueryOption succeeded\n");
4521     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4522 
4523     SetLastError(0xdeadbeef);
4524     ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, &ctx, NULL);
4525     error = GetLastError();
4526     ok(!ret, "InternetQueryOption succeeded\n");
4527     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
4528 
4529     size = 0;
4530     SetLastError(0xdeadbeef);
4531     ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, NULL, &size);
4532     error = GetLastError();
4533     ok(!ret, "InternetQueryOption succeeded\n");
4534     ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
4535     ok(size >= sizeof(INTERNET_PROXY_INFOA), "expected size to be greater or equal to the struct size\n");
4536 
4537     InternetCloseHandle(req);
4538     InternetCloseHandle(con);
4539     InternetCloseHandle(ses);
4540 }
4541 
4542 typedef struct {
4543     const char *response_text;
4544     int status_code;
4545     const char *status_text;
4546     const char *raw_headers;
4547 } http_status_test_t;
4548 
4549 static const http_status_test_t http_status_tests[] = {
4550     {
4551         "HTTP/1.1 200 OK\r\n"
4552         "Content-Length: 1\r\n"
4553         "\r\nx",
4554         200,
4555         "OK"
4556     },
4557     {
4558         "HTTP/1.1 404 Fail\r\n"
4559         "Content-Length: 1\r\n"
4560         "\r\nx",
4561         404,
4562         "Fail"
4563     },
4564     {
4565         "HTTP/1.1 200\r\n"
4566         "Content-Length: 1\r\n"
4567         "\r\nx",
4568         200,
4569         ""
4570     },
4571     {
4572         "HTTP/1.1 410 \r\n"
4573         "Content-Length: 1\r\n"
4574         "\r\nx",
4575         410,
4576         ""
4577     }
4578 };
4579 
4580 static void test_http_status(int port)
4581 {
4582     test_request_t req;
4583     char buf[1000];
4584     DWORD i, size;
4585     BOOL res;
4586 
4587     for(i = 0; i < ARRAY_SIZE(http_status_tests); i++) {
4588         send_buffer = http_status_tests[i].response_text;
4589 
4590         open_simple_request(&req, "localhost", port, NULL, "/send_from_buffer");
4591 
4592         res = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4593         ok(res, "HttpSendRequest failed\n");
4594 
4595         test_status_code(req.request, http_status_tests[i].status_code);
4596 
4597         size = sizeof(buf);
4598         res = HttpQueryInfoA(req.request, HTTP_QUERY_STATUS_TEXT, buf, &size, NULL);
4599         ok(res, "HttpQueryInfo failed: %u\n", GetLastError());
4600         ok(!strcmp(buf, http_status_tests[i].status_text), "[%u] Unexpected status text \"%s\", expected \"%s\"\n",
4601            i, buf, http_status_tests[i].status_text);
4602 
4603         close_request(&req);
4604     }
4605 }
4606 
4607 static void test_cache_control_verb(int port)
4608 {
4609     HINTERNET session, connect, request;
4610     BOOL ret;
4611 
4612     session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4613     ok(session != NULL, "InternetOpen failed\n");
4614 
4615     connect = InternetConnectA(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4616     ok(connect != NULL, "InternetConnect failed\n");
4617 
4618     request = HttpOpenRequestA(connect, "RPC_OUT_DATA", "/test_cache_control_verb", NULL, NULL, NULL,
4619                               INTERNET_FLAG_NO_CACHE_WRITE, 0);
4620     ok(request != NULL, "HttpOpenRequest failed\n");
4621     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4622     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4623     test_status_code(request, 200);
4624     InternetCloseHandle(request);
4625 
4626     request = HttpOpenRequestA(connect, "POST", "/test_cache_control_verb", NULL, NULL, NULL,
4627                               INTERNET_FLAG_NO_CACHE_WRITE, 0);
4628     ok(request != NULL, "HttpOpenRequest failed\n");
4629     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4630     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4631     test_status_code(request, 200);
4632     InternetCloseHandle(request);
4633 
4634     request = HttpOpenRequestA(connect, "HEAD", "/test_cache_control_verb", NULL, NULL, NULL,
4635                               INTERNET_FLAG_NO_CACHE_WRITE, 0);
4636     ok(request != NULL, "HttpOpenRequest failed\n");
4637     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4638     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4639     test_status_code(request, 200);
4640     InternetCloseHandle(request);
4641 
4642     request = HttpOpenRequestA(connect, "GET", "/test_cache_control_verb", NULL, NULL, NULL,
4643                               INTERNET_FLAG_NO_CACHE_WRITE, 0);
4644     ok(request != NULL, "HttpOpenRequest failed\n");
4645     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
4646     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4647     test_status_code(request, 200);
4648     InternetCloseHandle(request);
4649 
4650     InternetCloseHandle(connect);
4651     InternetCloseHandle(session);
4652 }
4653 
4654 static void test_request_content_length(int port)
4655 {
4656     char data[] = {'t','e','s','t'};
4657     test_request_t req;
4658     BOOL ret;
4659 
4660     reset_events();
4661     open_simple_request(&req, "localhost", port, "POST", "/test_request_content_length");
4662 
4663     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
4664     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4665     test_status_code(req.request, 200);
4666 
4667     SetEvent(complete_event);
4668 
4669     ret = HttpSendRequestA(req.request, NULL, 0, data, sizeof(data));
4670     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
4671     test_status_code(req.request, 200);
4672 
4673     SetEvent(complete_event);
4674     close_request(&req);
4675 }
4676 
4677 static void test_accept_encoding(int port)
4678 {
4679     HINTERNET ses, con, req;
4680     char buf[1000];
4681     BOOL ret;
4682 
4683     ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
4684     ok(ses != NULL, "InternetOpen failed\n");
4685 
4686     con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
4687     ok(con != NULL, "InternetConnect failed\n");
4688 
4689     req = HttpOpenRequestA(con, "GET", "/echo_request", "HTTP/1.0", NULL, NULL, 0, 0);
4690     ok(req != NULL, "HttpOpenRequest failed\n");
4691 
4692     ret = HttpAddRequestHeadersA(req, "Accept-Encoding: gzip\r\n", ~0u, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
4693     ok(ret, "HttpAddRequestHeaders failed\n");
4694 
4695     ret = HttpSendRequestA(req, NULL,  0, NULL, 0);
4696     ok(ret, "HttpSendRequestA failed\n");
4697 
4698     test_status_code(req, 200);
4699     receive_simple_request(req, buf, sizeof(buf));
4700     ok(strstr(buf, "Accept-Encoding: gzip") != NULL, "Accept-Encoding header not found in %s\n", buf);
4701 
4702     InternetCloseHandle(req);
4703 
4704     req = HttpOpenRequestA(con, "GET", "/echo_request", "HTTP/1.0", NULL, NULL, 0, 0);
4705     ok(req != NULL, "HttpOpenRequest failed\n");
4706 
4707     ret = HttpSendRequestA(req, "Accept-Encoding: gzip", ~0u, NULL, 0);
4708     ok(ret, "HttpSendRequestA failed\n");
4709 
4710     test_status_code(req, 200);
4711     receive_simple_request(req, buf, sizeof(buf));
4712     ok(strstr(buf, "Accept-Encoding: gzip") != NULL, "Accept-Encoding header not found in %s\n", buf);
4713 
4714     InternetCloseHandle(req);
4715     InternetCloseHandle(con);
4716     InternetCloseHandle(ses);
4717 }
4718 
4719 static void test_basic_auth_credentials_reuse(int port)
4720 {
4721     HINTERNET ses, con, req;
4722     DWORD status, size;
4723     BOOL ret;
4724     char buffer[0x40];
4725 
4726     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4727     ok( ses != NULL, "InternetOpenA failed\n" );
4728 
4729     con = InternetConnectA( ses, "localhost", port, "user", "pwd",
4730                             INTERNET_SERVICE_HTTP, 0, 0 );
4731     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4732 
4733     req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4734     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4735 
4736     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4737     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4738 
4739     size = sizeof(buffer);
4740     SetLastError(0xdeadbeef);
4741     ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4742     ok(ret, "unexpected failure %u\n", GetLastError());
4743     ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4744     ok(size == 4, "got %u\n", size);
4745 
4746     size = sizeof(buffer);
4747     SetLastError(0xdeadbeef);
4748     ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4749     ok(ret, "unexpected failure %u\n", GetLastError());
4750     ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4751     ok(size == 3, "got %u\n", size);
4752 
4753     status = 0xdeadbeef;
4754     size = sizeof(status);
4755     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4756     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4757     ok( status == 200, "got %u\n", status );
4758 
4759     InternetCloseHandle( req );
4760     InternetCloseHandle( con );
4761     InternetCloseHandle( ses );
4762 
4763     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4764     ok( ses != NULL, "InternetOpenA failed\n" );
4765 
4766     con = InternetConnectA( ses, "localhost", port, NULL, NULL,
4767                             INTERNET_SERVICE_HTTP, 0, 0 );
4768     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4769 
4770     req = HttpOpenRequestA( con, "PUT", "/upload2.txt", NULL, NULL, NULL, 0, 0 );
4771     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4772 
4773     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4774     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4775 
4776     size = sizeof(buffer);
4777     SetLastError(0xdeadbeef);
4778     ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4779     ok(ret, "unexpected failure %u\n", GetLastError());
4780     ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4781     ok(size == 4, "got %u\n", size);
4782 
4783     size = sizeof(buffer);
4784     SetLastError(0xdeadbeef);
4785     ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4786     ok(ret, "unexpected failure %u\n", GetLastError());
4787     ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4788     ok(size == 3, "got %u\n", size);
4789 
4790     status = 0xdeadbeef;
4791     size = sizeof(status);
4792     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4793     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4794     ok( status == 200, "got %u\n", status );
4795 
4796     InternetCloseHandle( req );
4797     InternetCloseHandle( con );
4798     InternetCloseHandle( ses );
4799 }
4800 
4801 static void test_basic_auth_credentials_end_session(int port)
4802 {
4803     HINTERNET ses, con, req;
4804     DWORD status, size;
4805     BOOL ret;
4806     char buffer[0x40];
4807 
4808     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4809     ok( ses != NULL, "InternetOpenA failed\n" );
4810 
4811     con = InternetConnectA( ses, "localhost", port, "user", "pwd",
4812                             INTERNET_SERVICE_HTTP, 0, 0 );
4813     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4814 
4815     req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4816     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4817 
4818     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4819     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4820 
4821     size = sizeof(buffer);
4822     SetLastError(0xdeadbeef);
4823     ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4824     ok(ret, "unexpected failure %u\n", GetLastError());
4825     ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4826     ok(size == 4, "got %u\n", size);
4827 
4828     size = sizeof(buffer);
4829     SetLastError(0xdeadbeef);
4830     ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4831     ok(ret, "unexpected failure %u\n", GetLastError());
4832     ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4833     ok(size == 3, "got %u\n", size);
4834 
4835     status = 0xdeadbeef;
4836     size = sizeof(status);
4837     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4838     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4839     ok( status == HTTP_STATUS_OK, "got %u\n", status );
4840 
4841     InternetCloseHandle( req );
4842     InternetCloseHandle( con );
4843     InternetCloseHandle( ses );
4844 
4845     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4846     ok( ses != NULL, "InternetOpenA failed\n" );
4847 
4848     /* Clear the cached credentials */
4849     ret = InternetSetOptionA(ses,  INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
4850     ok(ret, "unexpected failure %u\n", GetLastError());
4851 
4852     con = InternetConnectA( ses, "localhost", port, NULL, NULL,
4853                             INTERNET_SERVICE_HTTP, 0, 0 );
4854     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4855 
4856     req = HttpOpenRequestA( con, "PUT", "/upload2.txt", NULL, NULL, NULL, 0, 0 );
4857     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4858 
4859     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4860     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4861 
4862     size = sizeof(buffer);
4863     SetLastError(0xdeadbeef);
4864     ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4865     ok(ret, "unexpected failure %u\n", GetLastError());
4866     ok(!strcmp(buffer, ""), "got %s\n", buffer);
4867     ok(size == 0, "got %u\n", size);
4868 
4869     size = sizeof(buffer);
4870     SetLastError(0xdeadbeef);
4871     ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4872     ok(ret, "unexpected failure %u\n", GetLastError());
4873     ok(!strcmp(buffer, ""), "got %s\n", buffer);
4874     ok(size == 0, "got %u\n", size);
4875 
4876     status = 0xdeadbeef;
4877     size = sizeof(status);
4878     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4879     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4880     ok( status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status );
4881 
4882     InternetCloseHandle( req );
4883     InternetCloseHandle( con );
4884     InternetCloseHandle( ses );
4885 }
4886 
4887 static void test_basic_auth_credentials_different(int port)
4888 {
4889     HINTERNET ses, con, req;
4890     DWORD status, size;
4891     BOOL ret;
4892     char buffer[0x40];
4893 
4894     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4895     ok( ses != NULL, "InternetOpenA failed\n" );
4896 
4897     con = InternetConnectA( ses, "localhost", port, "user", "pwd",
4898                             INTERNET_SERVICE_HTTP, 0, 0 );
4899     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4900 
4901     req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4902     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4903 
4904     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4905     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4906 
4907     size = sizeof(buffer);
4908     SetLastError(0xdeadbeef);
4909     ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4910     ok(ret, "unexpected failure %u\n", GetLastError());
4911     ok(!strcmp(buffer, "user"), "got %s\n", buffer);
4912     ok(size == 4, "got %u\n", size);
4913 
4914     size = sizeof(buffer);
4915     SetLastError(0xdeadbeef);
4916     ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4917     ok(ret, "unexpected failure %u\n", GetLastError());
4918     ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
4919     ok(size == 3, "got %u\n", size);
4920 
4921     status = 0xdeadbeef;
4922     size = sizeof(status);
4923     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4924     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4925     ok( status == 200, "got %u\n", status );
4926 
4927     InternetCloseHandle( req );
4928     InternetCloseHandle( con );
4929     InternetCloseHandle( ses );
4930 
4931     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4932     ok( ses != NULL, "InternetOpenA failed\n" );
4933 
4934     con = InternetConnectA( ses, "localhost", port, "user1", "pwd1",
4935                             INTERNET_SERVICE_HTTP, 0, 0 );
4936     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4937 
4938     req = HttpOpenRequestA( con, "HEAD", "/upload3.txt", NULL, NULL, NULL, 0, 0 );
4939     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4940 
4941     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4942     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4943 
4944     size = sizeof(buffer);
4945     SetLastError(0xdeadbeef);
4946     ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
4947     ok(ret, "unexpected failure %u\n", GetLastError());
4948     ok(!strcmp(buffer, "user1"), "got %s\n", buffer);
4949     ok(size == 5, "got %u\n", size);
4950 
4951     size = sizeof(buffer);
4952     SetLastError(0xdeadbeef);
4953     ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
4954     ok(ret, "unexpected failure %u\n", GetLastError());
4955     ok(!strcmp(buffer, "pwd1"), "got %s\n", buffer);
4956     ok(size == 4, "got %u\n", size);
4957 
4958     status = 0xdeadbeef;
4959     size = sizeof(status);
4960     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
4961     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
4962     ok( status == 200, "got %u\n", status );
4963 
4964     InternetCloseHandle( req );
4965     InternetCloseHandle( con );
4966     InternetCloseHandle( ses );
4967 }
4968 
4969 /*
4970  * Manually set the Authorization for both calls.
4971  */
4972 static void test_basic_auth_credentials_manual(int port)
4973 {
4974     HINTERNET ses, con, req;
4975     DWORD status, size;
4976     BOOL ret;
4977 
4978     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
4979     ok( ses != NULL, "InternetOpenA failed\n" );
4980 
4981     /* Clear the cached credentials */
4982     ret = InternetSetOptionA(ses,  INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
4983     ok(ret, "unexpected failure %u\n", GetLastError());
4984 
4985     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
4986     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
4987 
4988     req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
4989     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
4990 
4991     /* Set Authorization Header */
4992     ret = HttpAddRequestHeadersA(req, "Authorization: Basic dXNlcjpwd2Q=\r\n", ~0u,
4993                             HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
4994     ok(ret, "HttpAddRequestHeaders Failed\n");
4995 
4996     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
4997     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
4998 
4999     status = 0xdeadbeef;
5000     size = sizeof(status);
5001     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5002     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5003     ok( status == 200, "got %u\n", status );
5004 
5005     InternetCloseHandle( req );
5006     InternetCloseHandle( con );
5007     InternetCloseHandle( ses );
5008 
5009     /* Show manual headers are cached. */
5010     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
5011     ok( ses != NULL, "InternetOpenA failed\n" );
5012 
5013     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
5014     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5015 
5016     req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
5017     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5018 
5019     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5020     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
5021 
5022     status = 0xdeadbeef;
5023     size = sizeof(status);
5024     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5025     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5026     ok( status == 401, "got %u\n", status );
5027 
5028     InternetCloseHandle( req );
5029     InternetCloseHandle( con );
5030     InternetCloseHandle( ses );
5031 
5032     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
5033     ok( ses != NULL, "InternetOpenA failed\n" );
5034 
5035     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
5036     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5037 
5038     req = HttpOpenRequestA( con, "HEAD", "/upload4.txt", NULL, NULL, NULL, 0, 0 );
5039     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5040 
5041     /* Set Authorization Header */
5042     ret = HttpAddRequestHeadersA(req, "Authorization: Bearer dXNlcjE6cHdkMQ==\r\n", ~0u,
5043                             HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
5044     ok(ret, "HttpAddRequestHeaders Failed\n");
5045 
5046     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5047     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
5048 
5049     status = 0xdeadbeef;
5050     size = sizeof(status);
5051     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5052     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5053     ok( status == 200, "got %u\n", status );
5054 
5055     InternetCloseHandle( req );
5056     InternetCloseHandle( con );
5057     InternetCloseHandle( ses );
5058 }
5059 
5060 /*
5061  * Manually set the Authorization for the bearer call, which shows the cached is used.
5062  */
5063 static void test_basic_auth_credentials_cached_manual(int port)
5064 {
5065     HINTERNET ses, con, req;
5066     DWORD status, size;
5067     BOOL ret;
5068 
5069     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
5070     ok( ses != NULL, "InternetOpenA failed\n" );
5071 
5072     /* Clear the cached credentials */
5073     ret = InternetSetOptionA(ses,  INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
5074     ok(ret, "unexpected failure %u\n", GetLastError());
5075 
5076      con = InternetConnectA( ses, "localhost", port, "user", "pwd",
5077                             INTERNET_SERVICE_HTTP, 0, 0 );
5078     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5079 
5080     req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
5081     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5082 
5083     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5084     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
5085 
5086     status = 0xdeadbeef;
5087     size = sizeof(status);
5088     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5089     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5090     ok( status == 200, "got %u\n", status );
5091 
5092     InternetCloseHandle( req );
5093     InternetCloseHandle( con );
5094     InternetCloseHandle( ses );
5095 
5096     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
5097     ok( ses != NULL, "InternetOpenA failed\n" );
5098 
5099     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
5100     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5101 
5102     req = HttpOpenRequestA( con, "HEAD", "/upload4.txt", NULL, NULL, NULL, 0, 0 );
5103     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5104 
5105     /* Setting an Authorization Header doesn't override the cached one. */
5106     ret = HttpAddRequestHeadersA(req, "Authorization: Bearer dXNlcjE6cHdkMQ==\r\n", ~0u,
5107                             HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
5108     ok(ret, "HttpAddRequestHeaders Failed\n");
5109 
5110     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5111     ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
5112 
5113     status = 0xdeadbeef;
5114     size = sizeof(status);
5115     ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
5116     ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
5117     ok( status == 201, "got %u\n", status );
5118 
5119     InternetCloseHandle( req );
5120     InternetCloseHandle( con );
5121     InternetCloseHandle( ses );
5122 }
5123 
5124 static void test_async_read(int port)
5125 {
5126     HINTERNET ses, con, req;
5127     INTERNET_BUFFERSA ib;
5128     char buffer[0x100];
5129     DWORD pending_reads;
5130     DWORD res, count, bytes;
5131     BOOL ret;
5132 
5133     reset_events();
5134 
5135     /* test asynchronous InternetReadFileEx */
5136     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
5137     ok( ses != NULL, "InternetOpenA failed\n" );
5138     pInternetSetStatusCallbackA( ses, &callback );
5139 
5140     SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5141     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
5142     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5143     CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5144 
5145     SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5146     req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
5147     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5148     CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5149 
5150     SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
5151     SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
5152     SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
5153     SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
5154     SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
5155     SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
5156     SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5157     SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5158     SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
5159     SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
5160     SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5161 
5162     SetLastError( 0xdeadbeef );
5163     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5164     ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
5165     ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5166     WaitForSingleObject( complete_event, INFINITE );
5167     ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5168 
5169     CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
5170     CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
5171     CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
5172     CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
5173     CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
5174     CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
5175     CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5176     CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5177     CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
5178     CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
5179     CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5180 
5181     pending_reads = 0;
5182     memset( &ib, 0, sizeof(ib) );
5183     memset( buffer, 0, sizeof(buffer) );
5184     ib.dwStructSize = sizeof(ib);
5185     for (count = 0; count < sizeof(buffer); count += ib.dwBufferLength)
5186     {
5187         ib.lpvBuffer = buffer + count;
5188         ib.dwBufferLength = min(16, sizeof(buffer) - count);
5189 
5190         SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5191         SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5192 
5193         ret = InternetReadFileExA( req, &ib, 0, 0xdeadbeef );
5194         if (!count) /* the first part should arrive immediately */
5195             ok( ret, "InternetReadFileExA failed %u\n", GetLastError() );
5196         ros_skip_flaky
5197         if (!ret)
5198         {
5199             ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5200             ros_skip_flaky
5201             CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5202             SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5203             if (!pending_reads++)
5204             {
5205                 res = WaitForSingleObject( complete_event, 0 );
5206                 ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
5207                 SetEvent( conn_wait_event );
5208             }
5209             res = WaitForSingleObject( complete_event, INFINITE );
5210             ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res );
5211             ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5212             todo_wine_if( pending_reads > 1 )
5213             ok( ib.dwBufferLength != 0, "expected ib.dwBufferLength != 0\n" );
5214             CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5215             CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5216         }
5217 
5218         CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5219         CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5220         if (!ib.dwBufferLength) break;
5221     }
5222 
5223     ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads );
5224     ok( !strcmp(buffer, page1), "unexpected buffer content\n" );
5225     close_async_handle( ses, 2 );
5226     ResetEvent( conn_wait_event );
5227 
5228     /* test asynchronous InternetReadFile */
5229     ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
5230     ok( ses != NULL, "InternetOpenA failed\n" );
5231     pInternetSetStatusCallbackA( ses, &callback );
5232 
5233     SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5234     con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
5235     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
5236     CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5237 
5238     SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
5239     req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
5240     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
5241     CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5242 
5243     SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
5244     SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
5245     SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
5246     SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
5247     SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
5248     SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
5249     SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5250     SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5251     SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
5252     SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
5253     SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5254 
5255     SetLastError( 0xdeadbeef );
5256     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
5257     ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
5258     ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5259     WaitForSingleObject( complete_event, INFINITE );
5260     ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5261 
5262     CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
5263     CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
5264     CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
5265     CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
5266     CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
5267     CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
5268     CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5269     CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5270     CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
5271     CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
5272     CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5273 
5274     pending_reads = 0;
5275     memset( buffer, 0, sizeof(buffer) );
5276     for (count = 0; count < sizeof(buffer); count += bytes)
5277     {
5278         SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
5279         SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
5280 
5281         bytes = 0xdeadbeef;
5282         ret = InternetReadFile( req, buffer + count, min(16, sizeof(buffer) - count), &bytes );
5283         if (!count) /* the first part should arrive immediately */
5284             ok( ret, "InternetReadFile failed %u\n", GetLastError() );
5285         if (!ret)
5286         {
5287             ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
5288             ok( bytes == 0, "expected 0, got %u\n", bytes );
5289             ros_skip_flaky
5290             CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5291             SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
5292             if (!pending_reads++)
5293             {
5294                 res = WaitForSingleObject( complete_event, 0 );
5295                 ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
5296                 SetEvent( conn_wait_event );
5297             }
5298             res = WaitForSingleObject( complete_event, INFINITE );
5299             ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res );
5300             ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
5301             ros_skip_flaky {
5302             todo_wine_if( pending_reads > 1 )
5303             ok( bytes != 0, "expected bytes != 0\n" );
5304             }
5305             ros_skip_flaky
5306             CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5307             ros_skip_flaky
5308             CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
5309         }
5310 
5311         CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
5312         CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
5313         if (!bytes) break;
5314     }
5315 
5316     ros_skip_flaky
5317     ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads );
5318     ok( !strcmp(buffer, page1), "unexpected buffer content\n" );
5319     close_async_handle( ses, 2 );
5320 }
5321 
5322 static void server_send_string(const char *msg)
5323 {
5324     send(server_socket, msg, strlen(msg), 0);
5325 }
5326 
5327 static size_t server_read_data(char *buf, size_t buf_size)
5328 {
5329     return recv(server_socket, buf, buf_size, 0);
5330 }
5331 
5332 #define server_read_request(a) _server_read_request(__LINE__,a)
5333 static void _server_read_request(unsigned line, const char *expected_request)
5334 {
5335     char buf[4000], *p;
5336     size_t size;
5337 
5338     size = server_read_data(buf, sizeof(buf) - 1);
5339     buf[size] = 0;
5340     p = strstr(buf, "\r\n");
5341     if(p) *p = 0;
5342     ok_(__FILE__,line)(p && !strcmp(buf, expected_request), "unexpected request %s\n", buf);
5343 }
5344 
5345 static BOOL skip_receive_notification_tests;
5346 static DWORD received_response_size;
5347 
5348 static void WINAPI readex_callback(HINTERNET handle, DWORD_PTR context, DWORD status, void *info, DWORD info_size)
5349 {
5350     switch(status) {
5351     case INTERNET_STATUS_RECEIVING_RESPONSE:
5352         if(!skip_receive_notification_tests)
5353             callback(handle, context, status, info, info_size);
5354         break;
5355     case INTERNET_STATUS_RESPONSE_RECEIVED:
5356         if(!skip_receive_notification_tests)
5357             callback(handle, context, status, info, info_size);
5358         received_response_size = *(DWORD*)info;
5359         break;
5360     case INTERNET_STATUS_REQUEST_SENT:
5361         callback(handle, context, status, info, info_size);
5362         SetEvent(request_sent_event);
5363         break;
5364     default:
5365         callback(handle, context, status, info, info_size);
5366     }
5367 }
5368 
5369 static void send_socket_request(test_request_t *req, BOOL new_connection)
5370 {
5371     BOOL ret;
5372 
5373     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
5374     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
5375     if(new_connection) {
5376         SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
5377         SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
5378     }
5379     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
5380     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
5381     if(!skip_receive_notification_tests)
5382         SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5383 
5384     SetLastError(0xdeadbeef);
5385     ret = HttpSendRequestA(req->request, NULL, 0, NULL, 0);
5386     ok(!ret, "HttpSendRequestA unexpectedly succeeded\n");
5387     ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError());
5388 
5389     if(new_connection)
5390         WaitForSingleObject(server_req_rec_event, INFINITE);
5391     WaitForSingleObject(request_sent_event, INFINITE);
5392 
5393     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
5394     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
5395     if(new_connection) {
5396         CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
5397         CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
5398     }
5399     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
5400     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
5401 }
5402 
5403 static void open_socket_request(int port, test_request_t *req, const char *verb)
5404 {
5405     /* We're connecting to new socket */
5406     if(!verb)
5407         reset_events();
5408 
5409     req->session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
5410     ok(req->session != NULL, "InternetOpenA failed\n");
5411     pInternetSetStatusCallbackA(req->session, readex_callback);
5412 
5413     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
5414     req->connection = InternetConnectA(req->session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef);
5415     ok(req->connection != NULL, "InternetConnectA failed %u\n", GetLastError());
5416     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED );
5417 
5418     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
5419     req->request = HttpOpenRequestA(req->connection, "GET", verb ? verb : "/socket",
5420                                     NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef);
5421     ok(req->request != NULL, "HttpOpenRequestA failed %u\n", GetLastError());
5422     CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
5423 
5424     send_socket_request(req, !verb);
5425 }
5426 
5427 static void open_read_test_request(int port, test_request_t *req, const char *response)
5428 {
5429     if(!skip_receive_notification_tests)
5430         SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5431 
5432     open_socket_request(port, req, NULL);
5433 
5434     if(!skip_receive_notification_tests) {
5435         SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5436         received_response_size = 0xdeadbeef;
5437     }
5438     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5439 
5440     server_send_string(response);
5441     WaitForSingleObject(complete_event, INFINITE);
5442 
5443     if(!skip_receive_notification_tests) {
5444         CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5445         CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5446         todo_wine
5447         ok(received_response_size == strlen(response), "received_response_size = %u\n", received_response_size);
5448     }
5449     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5450     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5451 }
5452 
5453 #define readex_expect_sync_data_len(a,b,c,d,e,f,g) _readex_expect_sync_data_len(__LINE__,a,b,c,d,e,f,g)
5454 static void _readex_expect_sync_data_len(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
5455                                          DWORD buf_size, const char *exdata, DWORD len, DWORD expect_receive)
5456 {
5457     BOOL ret;
5458 
5459     if(!skip_receive_notification_tests && expect_receive) {
5460         SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5461         SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5462         received_response_size = 0xdeadbeef;
5463     }
5464 
5465     memset(buf->lpvBuffer, 0xff, buf_size);
5466     buf->dwBufferLength = buf_size;
5467     ret = InternetReadFileExW(req, buf, flags, 0xdeadbeef);
5468     ok_(__FILE__,line)(ret, "InternetReadFileExW failed: %u\n", GetLastError());
5469     ok_(__FILE__,line)(buf->dwBufferLength == len, "dwBufferLength = %u, expected %u\n", buf->dwBufferLength, len);
5470     if(len && exdata)
5471         ok_(__FILE__,line)(!memcmp(buf->lpvBuffer, exdata, len), "Unexpected data\n");
5472 
5473     if(!skip_receive_notification_tests && expect_receive) {
5474         CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5475         CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5476         ok_(__FILE__,line)(received_response_size == len, "received_response_size = %u\n", received_response_size);
5477     }
5478 }
5479 
5480 #define readex_expect_sync_data(a,b,c,d,e,f) _readex_expect_sync_data(__LINE__,a,b,c,d,e,f)
5481 static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
5482                                      DWORD buf_size, const char *exdata, DWORD expect_receive)
5483 {
5484     _readex_expect_sync_data_len(line, req, flags, buf, buf_size, exdata, strlen(exdata), expect_receive);
5485 }
5486 
5487 #define read_expect_sync_data_len(a,b,c,d,e) _read_expect_sync_data_len(__LINE__,a,b,c,d,e)
5488 static void _read_expect_sync_data_len(unsigned line, HINTERNET req, void *buf, DWORD buf_size,
5489         const char *exdata, DWORD len)
5490 {
5491     DWORD ret_size = 0xdeadbeef;
5492     BOOL ret;
5493 
5494     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5495     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5496     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5497     received_response_size = 0xdeadbeef;
5498 
5499     memset(buf, 0xff, buf_size);
5500     ret = InternetReadFile(req, buf, buf_size, &ret_size);
5501     ok_(__FILE__,line)(ret, "InternetReadFileExW failed: %u\n", GetLastError());
5502     ok_(__FILE__,line)(ret_size == len, "dwBufferLength = %u, expected %u\n", ret_size, len);
5503     if(len && exdata)
5504         ok_(__FILE__,line)(!memcmp(buf, exdata, len), "Unexpected data\n");
5505 
5506     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5507     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5508     CLEAR_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5509     ok_(__FILE__,line)(received_response_size == len, "received_response_size = %u\n", received_response_size);
5510     ok_(__FILE__,line)(!req_error, "req_error = %u\n", req_error);
5511 }
5512 
5513 #define read_expect_sync_data(a,b,c,d) _read_expect_sync_data(__LINE__,a,b,c,d)
5514 static void _read_expect_sync_data(unsigned line, HINTERNET req, void *buf,
5515         DWORD buf_size, const char *exdata)
5516 {
5517     _read_expect_sync_data_len(line, req, buf, buf_size, exdata, strlen(exdata));
5518 }
5519 
5520 static void close_connection(void)
5521 {
5522     char c;
5523     SetEvent(conn_wait_event);
5524     recv(server_socket, &c, 1, 0);
5525 }
5526 
5527 #define send_response_and_wait(a,b,c,d,e,f,g,h) _send_response_and_wait(__LINE__,a,b,c,d,e,f,g,h)
5528 static void _send_response_and_wait(unsigned line, const char *response, BOOL do_close_connection,
5529                                     void *buf, DWORD *ret_size, const char *exdata,
5530                                     DWORD expected_size, DWORD expected_req_error, DWORD expected_receive_size)
5531 {
5532     if(!skip_receive_notification_tests)
5533         SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
5534     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5535 
5536     if(response)
5537         server_send_string(response);
5538 
5539     if(do_close_connection)
5540         close_connection();
5541 
5542     WaitForSingleObject(complete_event, INFINITE);
5543 
5544     if(!skip_receive_notification_tests)
5545         CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
5546     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5547     if(!skip_receive_notification_tests && expected_receive_size != -1)
5548         todo_wine_if(received_response_size != expected_receive_size) /* FIXME! remove when wine is fixed */
5549         ok_(__FILE__,line)(received_response_size == expected_receive_size,
5550                            "received_response_size = %u\n", received_response_size);
5551     ok_(__FILE__,line)(req_error == expected_req_error, "req_error = %u, expected %u\n", req_error, expected_req_error);
5552 
5553     /* If IRF_NO_WAIT is used, buffer is not changed. */
5554     ok_(__FILE__,line)(*ret_size == expected_size, "dwBufferLength = %u\n", *ret_size);
5555     if(exdata)
5556         ok_(__FILE__,line)(!memcmp(buf, exdata, strlen(exdata)), "unexpected buffer data\n");
5557     else if(buf)
5558         ok_(__FILE__,line)(!*(DWORD*)buf, "buffer data changed\n");
5559 }
5560 
5561 #define send_response_ex_and_wait(a,b,c,d,e,f) _send_response_ex_and_wait(__LINE__,a,b,c,d,e,f)
5562 static void _send_response_ex_and_wait(unsigned line, const char *response, BOOL close_connection,
5563                                        INTERNET_BUFFERSW *buf, const char *exdata, DWORD expected_req_error,
5564                                        DWORD expected_receive_size)
5565 {
5566     _send_response_and_wait(line, response, close_connection, buf->lpvBuffer, &buf->dwBufferLength,
5567                             exdata, exdata ? strlen(exdata) : buf->dwBufferLength, expected_req_error,
5568                             expected_receive_size);
5569 }
5570 
5571 static void send_response_len_and_wait(unsigned len, BOOL close_connection, INTERNET_BUFFERSW *buf)
5572 {
5573     char *response;
5574 
5575     response = HeapAlloc(GetProcessHeap(), 0, len+1);
5576     memset(response, 'x', len);
5577     response[len] = 0;
5578     send_response_ex_and_wait(response, close_connection, buf, NULL, 0, -1);
5579     HeapFree(GetProcessHeap(), 0, response);
5580 }
5581 
5582 #define readex_expect_async(a,b,c,d,e) _readex_expect_async(__LINE__,a,b,c,d,e)
5583 static void _readex_expect_async(unsigned line, HINTERNET req, DWORD flags, INTERNET_BUFFERSW *buf,
5584         DWORD buf_size, const char *exdata)
5585 {
5586     unsigned len = 0;
5587     BOOL ret;
5588 
5589     if(!skip_receive_notification_tests)
5590         SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5591 
5592     memset(buf->lpvBuffer, 0, max(buf_size, sizeof(DWORD)));
5593     buf->dwBufferLength = buf_size;
5594     ret = InternetReadFileExW(req, buf, flags, 0xdeadbeef);
5595     ok_(__FILE__,line)(!ret && GetLastError() == ERROR_IO_PENDING, "InternetReadFileExW returned %x (%u)\n", ret, GetLastError());
5596     ok_(__FILE__,line)(buf->dwBufferLength == buf_size, "dwBufferLength = %u, expected %u\n", buf->dwBufferLength, buf_size);
5597     if(exdata) {
5598         len = strlen(exdata);
5599         ok_(__FILE__,line)(!memcmp(buf->lpvBuffer, exdata, len), "unexpected buffer data\n");
5600     }else {
5601         ok_(__FILE__,line)(!*(DWORD*)buf->lpvBuffer, "buffer data changed\n");
5602     }
5603 
5604     if(!skip_receive_notification_tests)
5605         CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5606 }
5607 
5608 static void read_expect_async(HINTERNET req, void *buf, DWORD buf_size, DWORD *ret_size, const char *exdata)
5609 {
5610     unsigned len = 0;
5611     const char *p;
5612     BOOL ret;
5613 
5614     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5615 
5616     *ret_size = 0xdeadbeef;
5617     memset(buf, 0, buf_size);
5618     ret = InternetReadFile(req, buf, buf_size, ret_size);
5619     ok(!ret && GetLastError() == ERROR_IO_PENDING, "InternetReadFileExW returned %x (%u)\n", ret, GetLastError());
5620     ok(*ret_size == 0, "dwBufferLength = %u\n", *ret_size);
5621     if(exdata) {
5622         len = strlen(exdata);
5623         ok(!memcmp(buf, exdata, len), "unexpected buffer data\n");
5624     }
5625     for(p = (const char*)buf + len; p < (const char*)buf + buf_size; p++) {
5626         if(*p)
5627             ok(0, "buffer data changed\n");
5628     }
5629 
5630     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5631 }
5632 
5633 #define expect_data_available(a,b) _expect_data_available(__LINE__,a,b)
5634 static DWORD _expect_data_available(unsigned line, HINTERNET req, int exsize)
5635 {
5636     DWORD size = 0;
5637     BOOL res;
5638 
5639     res = InternetQueryDataAvailable(req, &size, 0, 0);
5640     ok_(__FILE__,line)(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
5641     if(exsize != -1)
5642         ok_(__FILE__,line)(size  == exsize, "size = %u, expected %u\n", size, exsize);
5643 
5644     return size;
5645 }
5646 
5647 #define async_query_data_available(a,b) _async_query_data_available(__LINE__,a,b)
5648 static void _async_query_data_available(unsigned line, HINTERNET req, DWORD *size)
5649 {
5650     BOOL res;
5651 
5652     if(!skip_receive_notification_tests)
5653         SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
5654 
5655     *size = 0xdeadbeef;
5656     res = InternetQueryDataAvailable(req, size, 0, 0);
5657     ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING,
5658                        "InternetQueryDataAvailable returned: %x(%u)\n", res, GetLastError());
5659     ok_(__FILE__,line)(!*size, "size = %u\n", *size);
5660 
5661     if(!skip_receive_notification_tests)
5662         CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5663 }
5664 
5665 static void test_http_read(int port)
5666 {
5667     INTERNET_BUFFERSW ib;
5668     test_request_t req;
5669     DWORD read_size;
5670     char buf[24000];
5671     DWORD avail, i;
5672 
5673     if(!is_ie7plus)
5674         return;
5675 
5676     memset(&ib, 0, sizeof(ib));
5677     ib.dwStructSize = sizeof(ib);
5678     ib.lpvBuffer = buf;
5679 
5680     trace("Testing InternetReadFileExW with IRF_ASYNC flag...\n");
5681 
5682     open_read_test_request(port, &req,
5683                            "HTTP/1.1 200 OK\r\n"
5684                            "Server: winetest\r\n"
5685                            "\r\n"
5686                            "xx");
5687 
5688     readex_expect_async(req.request, IRF_ASYNC, &ib, 4, "xx");
5689 
5690     send_response_ex_and_wait("yy1234567890", FALSE, &ib, "xxyy", 0, 2);
5691     readex_expect_sync_data(req.request, IRF_ASYNC, &ib, 4, "1234", 4);
5692     readex_expect_sync_data(req.request, IRF_ASYNC, &ib, 5, "56789", 5);
5693 
5694     readex_expect_async(req.request, IRF_ASYNC, &ib, sizeof(buf), "0");
5695     send_response_ex_and_wait("123", TRUE, &ib, "0123", 0, 4);
5696 
5697     close_async_handle(req.session, 2);
5698 
5699     trace("Testing InternetReadFileExW with no flags...\n");
5700 
5701     open_read_test_request(port, &req,
5702                            "HTTP/1.1 200 OK\r\n"
5703                            "Server: winetest\r\n"
5704                            "\r\n"
5705                            "xx");
5706 
5707     readex_expect_async(req.request, 0, &ib, 4, "xx");
5708 
5709     send_response_ex_and_wait("yy1234567890", FALSE, &ib, "xxyy", 0, 2);
5710     readex_expect_sync_data(req.request, 0, &ib, 4, "1234", 4);
5711     readex_expect_sync_data(req.request, 0, &ib, 5, "56789", 5);
5712 
5713     readex_expect_async(req.request, 0, &ib, sizeof(buf), "0");
5714     send_response_ex_and_wait("123", TRUE, &ib, "0123", 0, 4);
5715 
5716     close_async_handle(req.session, 2);
5717 
5718     trace("Testing InternetReadFile...\n");
5719 
5720     open_read_test_request(port, &req,
5721                            "HTTP/1.1 200 OK\r\n"
5722                            "Server: winetest\r\n"
5723                            "\r\n"
5724                            "xx");
5725 
5726     read_expect_async(req.request, buf, 4, &read_size, "xx");
5727 
5728     send_response_and_wait("yy1234567890", FALSE, buf, &read_size, "xxyy", 4, 0, 2);
5729     read_expect_sync_data(req.request, buf, 4, "1234");
5730     read_expect_sync_data(req.request, buf, 5, "56789");
5731 
5732     read_expect_async(req.request, buf, sizeof(buf), &read_size, "0");
5733     send_response_and_wait("123", TRUE, buf, &read_size, "0123", 4, 0, 4);
5734 
5735     close_async_handle(req.session, 2);
5736 
5737     trace("Testing InternetReadFileExW with IRF_NO_WAIT flag...\n");
5738 
5739     open_read_test_request(port, &req,
5740                            "HTTP/1.1 200 OK\r\n"
5741                            "Server: winetest\r\n"
5742                            "\r\n"
5743                            "xx");
5744 
5745     SET_OPTIONAL(INTERNET_STATUS_RECEIVING_RESPONSE);
5746 
5747     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "xx", 0);
5748 
5749     if(notified[INTERNET_STATUS_RECEIVING_RESPONSE]) {
5750         win_skip("Skipping receive notification tests on too old Windows.\n");
5751         skip_receive_notification_tests = TRUE;
5752     }
5753     CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
5754 
5755     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5756     send_response_ex_and_wait("1234567890", FALSE, &ib, NULL, 0, 10);
5757     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, 5, "12345", 0);
5758     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "67890", 0);
5759 
5760     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5761     send_response_ex_and_wait("12345", TRUE, &ib, NULL, 0, 5);
5762 
5763     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "12345", 0);
5764     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "", TRUE);
5765 
5766     close_async_handle(req.session, 2);
5767 
5768     open_read_test_request(port, &req,
5769                            "HTTP/1.1 200 OK\r\n"
5770                            "Server: winetest\r\n"
5771                            "Transfer-Encoding: chunked\r\n"
5772                            "\r\n"
5773                            "9\r\n123456789");
5774     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123456789", 0);
5775     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5776 
5777     send_response_ex_and_wait("\r\n1\r\na\r\n1\r\nb\r", FALSE, &ib, NULL, 0, 13);
5778     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5779     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5780 
5781     send_response_ex_and_wait("\n3\r\nab", FALSE, &ib, NULL, 0, 6);
5782     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5783     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5784 
5785     send_response_ex_and_wait("c", FALSE, &ib, NULL, 0, 1);
5786     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "c", 0);
5787     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5788 
5789     send_response_ex_and_wait("\r\n1\r\nx\r\n0\r\n\r\n", TRUE, &ib, NULL, 0, 13);
5790     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "x", 0);
5791     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "", 0);
5792 
5793     close_async_handle(req.session, 2);
5794 
5795     open_read_test_request(port, &req,
5796                            "HTTP/1.1 200 OK\r\n"
5797                            "Server: winetest\r\n"
5798                            "Transfer-Encoding: chunked\r\n"
5799                            "\r\n"
5800                            "3\r\n123\r\n");
5801     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123", 0);
5802     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5803 
5804     send_response_ex_and_wait("0\r\n\r\n", TRUE, &ib, NULL, 0, 5);
5805     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "", 0);
5806 
5807     close_async_handle(req.session, 2);
5808 
5809     open_read_test_request(port, &req,
5810                            "HTTP/1.1 200 OK\r\n"
5811                            "Server: winetest\r\n"
5812                            "Connection: close\r\n"
5813                            "\r\n");
5814     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5815     send_response_ex_and_wait("123", TRUE, &ib, NULL, 0, 3);
5816     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123", 0);
5817 
5818     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5819     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5820     close_async_handle(req.session, 2);
5821     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5822     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5823 
5824     trace("Testing InternetQueryDataAvailable...\n");
5825 
5826     open_read_test_request(port, &req,
5827                            "HTTP/1.1 200 OK\r\n"
5828                            "Server: winetest\r\n"
5829                            "\r\n"
5830                            "123");
5831     expect_data_available(req.request, 3);
5832     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "123", 0);
5833     readex_expect_async(req.request, IRF_NO_WAIT, &ib, sizeof(buf), NULL);
5834 
5835     send_response_len_and_wait(20000, TRUE, &ib);
5836     avail = expect_data_available(req.request, -1);
5837     ok(avail < 17000, "avail = %u\n", avail);
5838 
5839     SET_WINE_ALLOW(INTERNET_STATUS_CLOSING_CONNECTION);
5840     SET_WINE_ALLOW(INTERNET_STATUS_CONNECTION_CLOSED);
5841     close_async_handle(req.session, 2);
5842     todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5843     todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5844 
5845     open_read_test_request(port, &req,
5846                            "HTTP/1.1 200 OK\r\n"
5847                            "Server: winetest\r\n"
5848                            "Connection: close\r\n"
5849                            "\r\n"
5850                            "123");
5851 
5852     expect_data_available(req.request, 3);
5853     readex_expect_sync_data(req.request, 0, &ib, 3, "123", 0);
5854 
5855     async_query_data_available(req.request, &read_size);
5856     send_response_and_wait("1234567890", FALSE, NULL, &read_size, NULL, 10, 10, 10);
5857 
5858     readex_expect_sync_data(req.request, 0, &ib, 9, "123456789", 0);
5859     expect_data_available(req.request, 1);
5860     readex_expect_sync_data(req.request, 0, &ib, 1, "0", 0);
5861 
5862     async_query_data_available(req.request, &read_size);
5863     send_response_and_wait("1234567890", FALSE, NULL, &read_size, NULL, 10, 10, 10);
5864     expect_data_available(req.request, 10);
5865     for(i = 0; i < 10; i++)
5866         server_send_string("x");
5867     expect_data_available(req.request, 10);
5868 
5869     readex_expect_async(req.request, IRF_ASYNC, &ib, 21, "1234567890");
5870     send_response_ex_and_wait("X", FALSE, &ib, "1234567890xxxxxxxxxxX", 0, 11);
5871     async_query_data_available(req.request, &read_size);
5872 
5873     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5874     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5875     send_response_and_wait(NULL, TRUE, NULL, &read_size, NULL, 0, 0, 0);
5876     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5877     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5878 
5879     close_async_handle(req.session, 2);
5880 
5881     skip_receive_notification_tests = FALSE;
5882 }
5883 
5884 static void test_connection_break(int port)
5885 {
5886     INTERNET_BUFFERSW ib;
5887     test_request_t req;
5888     char buf[24000];
5889 
5890     if(!is_ie7plus)
5891         return;
5892 
5893     memset(&ib, 0, sizeof(ib));
5894     ib.dwStructSize = sizeof(ib);
5895     ib.lpvBuffer = buf;
5896 
5897     trace("Testing InternetReadFileExW on broken connection...\n");
5898 
5899     open_read_test_request(port, &req,
5900                            "HTTP/1.1 200 OK\r\n"
5901                            "Server: winetest\r\n"
5902                            "Content-Length: 10000\r\n"
5903                            "\r\n"
5904                            "xx");
5905 
5906     /* close connection and make sure that it's closed on handle release. */
5907     close_connection();
5908     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
5909     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
5910     close_async_handle(req.session, 2);
5911     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
5912     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
5913 }
5914 
5915 static void test_long_url(int port)
5916 {
5917     char long_path[INTERNET_MAX_PATH_LENGTH*2] = "/echo_request?";
5918     char buf[sizeof(long_path)*2], url[sizeof(buf)];
5919     test_request_t req;
5920     DWORD size, len;
5921     BOOL ret;
5922 
5923     if(!is_ie7plus)
5924         return;
5925 
5926     memset(long_path+strlen(long_path), 'x', sizeof(long_path)-strlen(long_path));
5927     long_path[sizeof(long_path)-1] = 0;
5928     open_simple_request(&req, "localhost", port, NULL, long_path);
5929 
5930     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
5931     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
5932     test_status_code(req.request, 200);
5933 
5934     receive_simple_request(req.request, buf, sizeof(buf));
5935     ok(strstr(buf, long_path) != NULL, "long pathnot found in %s\n", buf);
5936 
5937     sprintf(url, "http://localhost:%u%s", port, long_path);
5938 
5939     size = sizeof(buf);
5940     ret = InternetQueryOptionA(req.request, INTERNET_OPTION_URL, buf, &size);
5941     ok(ret, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
5942     len = strlen(url);
5943     ok(size == len, "size = %u, expected %u\n", size, len);
5944     ok(!strcmp(buf, url), "Wrong URL %s, expected %s\n", buf, url);
5945 
5946     close_request(&req);
5947 }
5948 
5949 static void test_persistent_connection(int port)
5950 {
5951     INTERNET_BUFFERSW ib;
5952     test_request_t req;
5953     char buf[24000];
5954 
5955     if(!is_ie7plus)
5956         return;
5957 
5958     memset(&ib, 0, sizeof(ib));
5959     ib.dwStructSize = sizeof(ib);
5960     ib.lpvBuffer = buf;
5961 
5962     skip_receive_notification_tests = TRUE;
5963 
5964     trace("Testing persistent connection...\n");
5965 
5966     open_read_test_request(port, &req,
5967                            "HTTP/1.1 200 OK\r\n"
5968                            "Server: winetest\r\n"
5969                            "Content-Length: 2\r\n"
5970                            "\r\n"
5971                            "xx");
5972     readex_expect_sync_data(req.request, IRF_ASYNC, &ib, 4, "xx", 0);
5973     close_async_handle(req.session, 2);
5974 
5975     open_socket_request(port, &req, "/test_simple_chunked");
5976     server_read_request("GET /test_simple_chunked HTTP/1.1");
5977 
5978     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5979     server_send_string("HTTP/1.1 200 OK\r\n"
5980                        "Server: winetest\r\n"
5981                        "Transfer-Encoding: chunked\r\n"
5982                        "\r\n"
5983                        "2\r\nab\r\n");
5984     WaitForSingleObject(complete_event, INFINITE);
5985     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
5986     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
5987 
5988     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
5989     readex_expect_async(req.request, IRF_ASYNC, &ib, sizeof(buf), NULL);
5990     send_response_ex_and_wait("3\r\nabc\r\n0\r\n\r\n", FALSE, &ib, "abc", 0, 13);
5991     close_async_handle(req.session, 2);
5992 
5993     open_socket_request(port, &req, "/chunked");
5994     server_read_request("GET /chunked HTTP/1.1");
5995 
5996     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
5997     server_send_string("HTTP/1.1 200 OK\r\n"
5998                        "Server: winetest\r\n"
5999                        "Transfer-Encoding: chunked\r\n"
6000                        "\r\n"
6001                        "2\r\nab\r\n");
6002     WaitForSingleObject(complete_event, INFINITE);
6003     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6004     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6005 
6006     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, 3, "ab", 0);
6007     readex_expect_async(req.request, IRF_ASYNC, &ib, 3, NULL);
6008     send_response_ex_and_wait("3\r\nabc\r\n", FALSE, &ib, "abc", 0, 13);
6009 
6010     /* send another request on the same request handle, it must drain remaining last chunk marker */
6011     server_send_string("0\r\n\r\n");
6012 
6013     send_socket_request(&req, FALSE);
6014     server_read_request("GET /chunked HTTP/1.1");
6015 
6016     ResetEvent(complete_event);
6017     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6018     server_send_string("HTTP/1.1 201 OK\r\n"
6019                        "Server: winetest\r\n"
6020                        "Content-Length: 0\r\n"
6021                        "Connection: keep-alive\r\n"
6022                        "\r\n");
6023     WaitForSingleObject(complete_event, INFINITE);
6024     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6025     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6026 
6027     test_status_code(req.request, 201);
6028     close_async_handle(req.session, 2);
6029 
6030     /* the connection is still valid */
6031     open_socket_request(port, &req, "/another_chunked");
6032     server_read_request("GET /another_chunked HTTP/1.1");
6033 
6034     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6035     server_send_string("HTTP/1.1 200 OK\r\n"
6036                        "Server: winetest\r\n"
6037                        "Transfer-Encoding: chunked\r\n"
6038                        "\r\n"
6039                        "2\r\nab\r\n");
6040     WaitForSingleObject(complete_event, INFINITE);
6041     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6042     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6043 
6044     readex_expect_sync_data(req.request, IRF_NO_WAIT, &ib, sizeof(buf), "ab", 0);
6045     readex_expect_async(req.request, IRF_ASYNC, &ib, sizeof(buf), NULL);
6046 
6047     /* we're missing trailing '\n'; the connection can't be drained without blocking,
6048      * so it will be closed */
6049     send_response_ex_and_wait("3\r\nabc\r\n0\r\n\r", FALSE, &ib, "abc", 0, 13);
6050 
6051     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6052     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6053     close_async_handle(req.session, 2);
6054     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6055     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6056 
6057     close_connection();
6058     skip_receive_notification_tests = FALSE;
6059 }
6060 
6061 static void test_redirect(int port)
6062 {
6063     char buf[4000], expect_url[INTERNET_MAX_URL_LENGTH];
6064     INTERNET_BUFFERSW ib;
6065     test_request_t req;
6066 
6067     if(!is_ie7plus)
6068         return;
6069 
6070     skip_receive_notification_tests = TRUE;
6071 
6072     memset(&ib, 0, sizeof(ib));
6073     ib.dwStructSize = sizeof(ib);
6074     ib.lpvBuffer = buf;
6075 
6076     trace("Testing redirection...\n");
6077 
6078     open_socket_request(port, &req, NULL);
6079 
6080     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6081     SET_EXPECT(INTERNET_STATUS_REDIRECT);
6082     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6083     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6084 
6085     server_send_string("HTTP/1.1 302 Found\r\n"
6086                        "Server: winetest\r\n"
6087                        "Location: test_redirection\r\n"
6088                        "Connection: keep-alive\r\n"
6089                        "Content-Length: 0\r\n"
6090                        "\r\n");
6091 
6092     server_read_request("GET /test_redirection HTTP/1.1");
6093 
6094     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6095 
6096     sprintf(expect_url, "http://localhost:%u/test_redirection", port);
6097     test_request_url(req.request, expect_url);
6098 
6099     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6100 
6101     server_send_string("HTTP/1.1 200 OK\r\n"
6102                        "Server: winetest\r\n"
6103                        "Content-Length: 3\r\n"
6104                        "\r\n"
6105                        "xxx");
6106 
6107     WaitForSingleObject(complete_event, INFINITE);
6108 
6109     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6110     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6111     CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
6112     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6113     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6114 
6115     test_status_code(req.request, 200);
6116 
6117     close_connection();
6118     close_async_handle(req.session, 2);
6119 
6120     trace("Test redirect to non-http URL...\n");
6121 
6122     open_socket_request(port, &req, NULL);
6123 
6124     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6125 
6126     server_send_string("HTTP/1.1 302 Found\r\n"
6127                        "Server: winetest\r\n"
6128                        "Location: test:non:http/url\r\n"
6129                        "Connection: keep-alive\r\n"
6130                        "Content-Length: 0\r\n"
6131                        "\r\n");
6132 
6133     WaitForSingleObject(complete_event, INFINITE);
6134 
6135     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6136     ok(req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error);
6137 
6138     sprintf(expect_url, "http://localhost:%u/socket", port);
6139     test_request_url(req.request, expect_url);
6140     test_status_code(req.request, 302);
6141 
6142     close_connection();
6143     close_async_handle(req.session, 2);
6144 
6145     trace("Test redirect to http URL with no host name...\n");
6146 
6147     open_socket_request(port, &req, NULL);
6148 
6149     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6150 
6151     server_send_string("HTTP/1.1 302 Found\r\n"
6152                        "Server: winetest\r\n"
6153                        "Location: http:///nohost\r\n"
6154                        "Connection: keep-alive\r\n"
6155                        "Content-Length: 0\r\n"
6156                        "\r\n");
6157 
6158     WaitForSingleObject(complete_event, INFINITE);
6159 
6160     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6161     ok(req_error == ERROR_INTERNET_INVALID_URL, "expected ERROR_INTERNET_INVALID_URL, got %u\n", req_error);
6162 
6163     sprintf(expect_url, "http://localhost:%u/socket", port);
6164     test_request_url(req.request, expect_url);
6165     test_status_code(req.request, 302);
6166 
6167     close_connection();
6168     close_async_handle(req.session, 2);
6169 
6170     skip_receive_notification_tests = FALSE;
6171 }
6172 
6173 static void test_remove_dot_segments(int port)
6174 {
6175     test_request_t req;
6176     BOOL ret;
6177 
6178     open_simple_request(&req, "localhost", port, NULL, "/A/../B/./C/../../test_remove_dot_segments");
6179 
6180     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
6181     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
6182     test_status_code(req.request, 200);
6183 
6184     close_request(&req);
6185 }
6186 
6187 struct large_test
6188 {
6189     DWORD64 content_length;
6190     BOOL ret;
6191 };
6192 
6193 static void test_large_content(int port)
6194 {
6195     struct large_test tests[] = {
6196         { 0,                   TRUE },
6197         { UINT_MAX-1,          TRUE },
6198         { UINT_MAX,            TRUE },
6199         { (DWORD64)UINT_MAX+1, FALSE },
6200         { ~0,                  FALSE },
6201     };
6202     test_request_t req;
6203     DWORD sizelen, len;
6204     DWORD read_size;
6205     DWORD64 len64;
6206     char buf[16];
6207     BOOL ret;
6208     size_t i;
6209 
6210     open_simple_request(&req, "localhost", port, "HEAD", "/test_large_content");
6211 
6212     for (i = 0; i < ARRAY_SIZE(tests); i++)
6213     {
6214         content_length = tests[i].content_length;
6215         ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
6216         ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
6217 
6218         len = ~0;
6219         sizelen = sizeof(len);
6220         SetLastError(0xdeadbeef);
6221         ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
6222                              &len, &sizelen, 0);
6223         if (tests[i].ret)
6224         {
6225             ok(ret, "HttpQueryInfo should have succeeded\n");
6226             ok(GetLastError() == ERROR_SUCCESS ||
6227                 broken(GetLastError() == 0xdeadbeef), /* xp, 2k8, vista */
6228                 "expected ERROR_SUCCESS, got %x\n", GetLastError());
6229             ok(len == (DWORD)tests[i].content_length, "expected %u, got %u\n",
6230                 (DWORD)tests[i].content_length, len);
6231         }
6232         else
6233         {
6234             ok(!ret, "HttpQueryInfo should have failed\n");
6235             ok(GetLastError() == ERROR_HTTP_INVALID_HEADER,
6236                 "expected ERROR_HTTP_INVALID_HEADER, got %x\n", GetLastError());
6237             ok(len == ~0, "expected ~0, got %u\n", len);
6238         }
6239         ok(sizelen == sizeof(DWORD), "sizelen %u\n", sizelen);
6240     }
6241 
6242     /* test argument size */
6243     len64 = ~0;
6244     sizelen = sizeof(len64);
6245     SetLastError(0xdeadbeef);
6246     ret = HttpQueryInfoA(req.request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
6247                          &len64, &len, 0);
6248     ok(!ret, "HttpQueryInfo should have failed\n");
6249     ok(GetLastError() == ERROR_HTTP_INVALID_HEADER,
6250         "expected ERROR_HTTP_INVALID_HEADER, got %x\n", GetLastError());
6251     ok(sizelen == sizeof(DWORD64), "sizelen %u\n", sizelen);
6252     ok(len64 == ~0, "len64 %x%08x\n", (DWORD)(len64 >> 32), (DWORD)len64);
6253 
6254     close_request(&req);
6255 
6256     /* test internal use of HttpQueryInfo on large size */
6257     open_read_test_request(port, &req,
6258                            "HTTP/1.1 200 OK\r\n"
6259                            "Server: winetest\r\n"
6260                            "Content-Length: 4294967296\r\n"
6261                            "\r\n"
6262                            "xx");
6263     read_expect_async(req.request, buf, 4, &read_size, "xx");
6264     send_response_and_wait("yy1234567890", FALSE, buf, &read_size, "xxyy", 4, 0, 2);
6265     read_expect_sync_data(req.request, buf, 10, "1234567890");
6266 
6267     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6268     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6269     close_async_handle(req.session, 2);
6270     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6271     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6272     close_connection();
6273 }
6274 
6275 static void test_http_connection(void)
6276 {
6277     struct server_info si;
6278     HANDLE hThread;
6279     DWORD id = 0, r;
6280 
6281     si.hEvent = CreateEventW(NULL, 0, 0, NULL);
6282     si.port = 7531;
6283 
6284     hThread = CreateThread(NULL, 0, server_thread, &si, 0, &id);
6285     ok( hThread != NULL, "create thread failed\n");
6286 
6287     r = WaitForSingleObject(si.hEvent, 10000);
6288     ok (r == WAIT_OBJECT_0, "failed to start wininet test server\n");
6289     if (r != WAIT_OBJECT_0)
6290     {
6291         CloseHandle(hThread);
6292         return;
6293     }
6294 
6295     test_basic_request(si.port, "GET", "/test1");
6296     test_proxy_indirect(si.port);
6297     test_proxy_direct(si.port);
6298     test_header_handling_order(si.port);
6299     test_basic_request(si.port, "POST", "/test5");
6300     test_basic_request(si.port, "RPC_IN_DATA", "/test5");
6301     test_basic_request(si.port, "RPC_OUT_DATA", "/test5");
6302     test_basic_request(si.port, "GET", "/test6");
6303     test_basic_request(si.port, "GET", "/testF");
6304     test_connection_header(si.port);
6305     test_header_override(si.port);
6306     test_cookie_header(si.port);
6307     test_basic_authentication(si.port);
6308     test_invalid_response_headers(si.port);
6309     test_response_without_headers(si.port);
6310     test_HttpQueryInfo(si.port);
6311     test_HttpSendRequestW(si.port);
6312     test_options(si.port);
6313     test_no_content(si.port);
6314     test_conn_close(si.port);
6315     test_no_cache(si.port);
6316     test_cache_read_gzipped(si.port);
6317     test_http_status(si.port);
6318     test_premature_disconnect(si.port);
6319     test_connection_closing(si.port);
6320     test_cache_control_verb(si.port);
6321     test_successive_HttpSendRequest(si.port);
6322     test_head_request(si.port);
6323     test_request_content_length(si.port);
6324     test_accept_encoding(si.port);
6325     test_basic_auth_credentials_reuse(si.port);
6326     test_basic_auth_credentials_end_session(si.port);
6327     test_basic_auth_credentials_different(si.port);
6328     test_basic_auth_credentials_manual(si.port);
6329     test_basic_auth_credentials_cached_manual(si.port);
6330     test_async_read(si.port);
6331     test_http_read(si.port);
6332     test_connection_break(si.port);
6333     test_long_url(si.port);
6334 #ifdef __REACTOS__
6335 if (!winetest_interactive)
6336 {
6337     skip("Skipping test_redirect and test_persistent_connection due to hang. See ROSTESTS-294.\n");
6338 }
6339 else
6340 {
6341 #endif
6342     test_redirect(si.port);
6343     test_persistent_connection(si.port);
6344 #ifdef __REACTOS__
6345 }
6346 #endif
6347     test_remove_dot_segments(si.port);
6348     test_large_content(si.port);
6349 
6350     /* send the basic request again to shutdown the server thread */
6351     test_basic_request(si.port, "GET", "/quit");
6352 
6353     r = WaitForSingleObject(hThread, 3000);
6354     ok( r == WAIT_OBJECT_0, "thread wait failed\n");
6355     CloseHandle(hThread);
6356 }
6357 
6358 static void release_cert_info(INTERNET_CERTIFICATE_INFOA *info)
6359 {
6360     LocalFree(info->lpszSubjectInfo);
6361     LocalFree(info->lpszIssuerInfo);
6362     LocalFree(info->lpszProtocolName);
6363     LocalFree(info->lpszSignatureAlgName);
6364     LocalFree(info->lpszEncryptionAlgName);
6365 }
6366 
6367 typedef struct {
6368     const char *ex_subject;
6369     const char *ex_issuer;
6370 } cert_struct_test_t;
6371 
6372 static const cert_struct_test_t test_winehq_org_cert = {
6373     "US\r\n"
6374     "55114\r\n"
6375     "MN\r\n"
6376     "Saint Paul\r\n"
6377     "Ste 120\r\n"
6378     "700 Raymond Ave\r\n"
6379     "CodeWeavers\r\n"
6380     "IT\r\n"
6381     "Secure Link SSL Wildcard\r\n"
6382     "*.winehq.org",
6383 
6384     "US\r\n"
6385     "VA\r\n"
6386     "Herndon\r\n"
6387     "Network Solutions L.L.C.\r\n"
6388     "Network Solutions OV Server CA 2"
6389 };
6390 
6391 static const cert_struct_test_t test_winehq_com_cert = {
6392     "US\r\n"
6393     "Minnesota\r\n"
6394     "Saint Paul\r\n"
6395     "WineHQ\r\n"
6396     "IT\r\n"
6397     "test.winehq.com\r\n"
6398     "webmaster@winehq.org",
6399 
6400     "US\r\n"
6401     "Minnesota\r\n"
6402     "Saint Paul\r\n"
6403     "WineHQ\r\n"
6404     "IT\r\n"
6405     "test.winehq.com\r\n"
6406     "webmaster@winehq.org"
6407 };
6408 
6409 static void test_cert_struct(HINTERNET req, const cert_struct_test_t *test)
6410 {
6411     INTERNET_CERTIFICATE_INFOA info;
6412     DWORD size;
6413     BOOL res;
6414 
6415     memset(&info, 0x5, sizeof(info));
6416 
6417     size = sizeof(info);
6418     res = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size);
6419     if (!res)
6420     {
6421         win_skip("Querying INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT failed, skipping tests\n");
6422         return;
6423     }
6424 
6425     ok(res, "InternetQueryOption failed: %u\n", GetLastError());
6426     ok(size == sizeof(info), "size = %u\n", size);
6427 
6428     ok(!strcmp(info.lpszSubjectInfo, test->ex_subject), "lpszSubjectInfo = %s\n", info.lpszSubjectInfo);
6429     ok(!strcmp(info.lpszIssuerInfo, test->ex_issuer), "lpszIssuerInfo = %s\n", info.lpszIssuerInfo);
6430     ok(!info.lpszSignatureAlgName, "lpszSignatureAlgName = %s\n", info.lpszSignatureAlgName);
6431     ok(!info.lpszEncryptionAlgName, "lpszEncryptionAlgName = %s\n", info.lpszEncryptionAlgName);
6432     ok(!info.lpszProtocolName, "lpszProtocolName = %s\n", info.lpszProtocolName);
6433     ok(info.dwKeySize >= 128 && info.dwKeySize <= 256, "dwKeySize = %u\n", info.dwKeySize);
6434 
6435     release_cert_info(&info);
6436 }
6437 
6438 #define test_security_info(a,b,c) _test_security_info(__LINE__,a,b,c)
6439 static void _test_security_info(unsigned line, const char *urlc, DWORD error, DWORD ex_flags)
6440 {
6441     char url[INTERNET_MAX_URL_LENGTH];
6442     const CERT_CHAIN_CONTEXT *chain;
6443     DWORD flags;
6444     BOOL res;
6445 
6446     if(!pInternetGetSecurityInfoByURLA) {
6447         win_skip("pInternetGetSecurityInfoByURLA not available\n");
6448         return;
6449     }
6450 
6451     strcpy(url, urlc);
6452     chain = (void*)0xdeadbeef;
6453     flags = 0xdeadbeef;
6454     res = pInternetGetSecurityInfoByURLA(url, &chain, &flags);
6455     if(error == ERROR_SUCCESS) {
6456         ok_(__FILE__,line)(res, "InternetGetSecurityInfoByURLA failed: %u\n", GetLastError());
6457         ok_(__FILE__,line)(chain != NULL, "chain = NULL\n");
6458         ok_(__FILE__,line)(flags == ex_flags, "flags = %x\n", flags);
6459         CertFreeCertificateChain(chain);
6460 
6461         SetLastError(0xdeadbeef);
6462         res = pInternetGetSecurityInfoByURLA(url, NULL, NULL);
6463         ok_(__FILE__,line)(!res && GetLastError() == ERROR_INVALID_PARAMETER,
6464                            "InternetGetSecurityInfoByURLA returned: %x(%u)\n", res, GetLastError());
6465 
6466         res = pInternetGetSecurityInfoByURLA(url, &chain, NULL);
6467         ok_(__FILE__,line)(res, "InternetGetSecurityInfoByURLA failed: %u\n", GetLastError());
6468         CertFreeCertificateChain(chain);
6469 
6470         res = pInternetGetSecurityInfoByURLA(url, NULL, &flags);
6471         ok_(__FILE__,line)(res, "InternetGetSecurityInfoByURLA failed: %u\n", GetLastError());
6472     }else {
6473         ok_(__FILE__,line)(!res && GetLastError() == error,
6474                            "InternetGetSecurityInfoByURLA returned: %x(%u), expected %u\n", res, GetLastError(), error);
6475     }
6476 }
6477 
6478 #define test_secflags_option(a,b,c) _test_secflags_option(__LINE__,a,b,c)
6479 static void _test_secflags_option(unsigned line, HINTERNET req, DWORD ex_flags, DWORD opt_flags)
6480 {
6481     DWORD flags, size;
6482     BOOL res;
6483 
6484     flags = 0xdeadbeef;
6485     size = sizeof(flags);
6486     res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
6487     ok_(__FILE__,line)(res, "InternetQueryOptionW(INTERNET_OPTION_SECURITY_FLAGS) failed: %u\n", GetLastError());
6488     ok_(__FILE__,line)((flags & ~opt_flags) == ex_flags, "INTERNET_OPTION_SECURITY_FLAGS flags = %x, expected %x\n",
6489                        flags, ex_flags);
6490 
6491     /* Option 98 is undocumented and seems to be the same as INTERNET_OPTION_SECURITY_FLAGS */
6492     flags = 0xdeadbeef;
6493     size = sizeof(flags);
6494     res = InternetQueryOptionW(req, 98, &flags, &size);
6495     ok_(__FILE__,line)(res, "InternetQueryOptionW(98) failed: %u\n", GetLastError());
6496     ok_(__FILE__,line)((flags & ~opt_flags) == ex_flags, "INTERNET_OPTION_SECURITY_FLAGS(98) flags = %x, expected %x\n",
6497                        flags, ex_flags);
6498 }
6499 
6500 #define set_secflags(a,b,c) _set_secflags(__LINE__,a,b,c)
6501 static void _set_secflags(unsigned line, HINTERNET req, BOOL use_undoc, DWORD flags)
6502 {
6503     BOOL res;
6504 
6505     res = InternetSetOptionW(req, use_undoc ? 99 : INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
6506     ok_(__FILE__,line)(res, "InternetSetOption(INTERNET_OPTION_SECURITY_FLAGS) failed: %u\n", GetLastError());
6507 }
6508 
6509 static void test_security_flags(void)
6510 {
6511     INTERNET_CERTIFICATE_INFOA *cert;
6512     HINTERNET ses, conn, req;
6513     DWORD size, flags;
6514     char buf[100];
6515     BOOL res;
6516 
6517     trace("Testing security flags...\n");
6518     reset_events();
6519 
6520     ses = InternetOpenA("WineTest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
6521     ok(ses != NULL, "InternetOpen failed\n");
6522 
6523     pInternetSetStatusCallbackA(ses, &callback);
6524 
6525     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6526     conn = InternetConnectA(ses, "test.winehq.com", INTERNET_DEFAULT_HTTPS_PORT,
6527                             NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0xdeadbeef);
6528     ok(conn != NULL, "InternetConnect failed with error %u\n", GetLastError());
6529     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6530 
6531     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6532     req = HttpOpenRequestA(conn, "GET", "/tests/hello.html", NULL, NULL, NULL,
6533                           INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE,
6534                           0xdeadbeef);
6535     ok(req != NULL, "HttpOpenRequest failed\n");
6536     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6537 
6538     flags = 0xdeadbeef;
6539     size = sizeof(flags);
6540     res = InternetQueryOptionW(req, 98, &flags, &size);
6541     if(!res && GetLastError() == ERROR_INVALID_PARAMETER) {
6542         win_skip("Incomplete security flags support, skipping\n");
6543 
6544         close_async_handle(ses, 2);
6545         return;
6546     }
6547 
6548     test_secflags_option(req, 0, 0);
6549     test_security_info("https://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6550 
6551     set_secflags(req, TRUE, SECURITY_FLAG_IGNORE_REVOCATION);
6552     test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION, 0);
6553 
6554     set_secflags(req, TRUE, SECURITY_FLAG_IGNORE_CERT_CN_INVALID);
6555     test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_CERT_CN_INVALID, 0);
6556 
6557     set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_UNKNOWN_CA);
6558     test_secflags_option(req, SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_CERT_CN_INVALID, 0);
6559 
6560     flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_SECURE;
6561     res = InternetSetOptionW(req, 99, &flags, sizeof(flags));
6562     ok(!res && GetLastError() == ERROR_INTERNET_OPTION_NOT_SETTABLE, "InternetSetOption(99) failed: %u\n", GetLastError());
6563 
6564     SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
6565     SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
6566     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6567     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6568     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6569     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6570     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6571     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6572     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6573     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6574     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
6575     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
6576     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6577     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6578     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6579 
6580     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6581     ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6582 
6583     WaitForSingleObject(complete_event, INFINITE);
6584     ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error);
6585 
6586     CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
6587     CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
6588     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6589     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6590     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6591     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6592     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6593     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6594     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
6595     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
6596     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6597     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6598     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6599 
6600     test_request_flags(req, 0);
6601     test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA
6602             |SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_STRENGTH_STRONG, 0);
6603 
6604     res = InternetReadFile(req, buf, sizeof(buf), &size);
6605     ok(res, "InternetReadFile failed: %u\n", GetLastError());
6606     ok(size, "size = 0\n");
6607 
6608     /* Collect all existing persistent connections */
6609     res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
6610     ok(res, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError());
6611 
6612     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6613     req = HttpOpenRequestA(conn, "GET", "/tests/hello.html", NULL, NULL, NULL,
6614                           INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE,
6615                           0xdeadbeef);
6616     ok(req != NULL, "HttpOpenRequest failed\n");
6617     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6618 
6619     flags = INTERNET_ERROR_MASK_COMBINED_SEC_CERT|INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY;
6620     res = InternetSetOptionA(req, INTERNET_OPTION_ERROR_MASK, (void*)&flags, sizeof(flags));
6621     ok(res, "InternetQueryOption(INTERNET_OPTION_ERROR_MASK failed: %u\n", GetLastError());
6622 
6623     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6624     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6625     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6626     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6627     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6628     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6629     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6630     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6631     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6632     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6633     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6634 
6635     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6636     ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6637 
6638     WaitForSingleObject(complete_event, INFINITE);
6639     ok(req_error == ERROR_INTERNET_SEC_CERT_ERRORS,
6640        "req_error = %d\n", req_error);
6641 
6642     size = 0;
6643     res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, NULL, &size);
6644     ok(res || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6645     ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %u\n", size);
6646     cert = HeapAlloc(GetProcessHeap(), 0, size);
6647     cert->lpszSubjectInfo = NULL;
6648     cert->lpszIssuerInfo = NULL;
6649     cert->lpszSignatureAlgName = (char *)0xdeadbeef;
6650     cert->lpszEncryptionAlgName = (char *)0xdeadbeef;
6651     cert->lpszProtocolName = (char *)0xdeadbeef;
6652     cert->dwKeySize = 0xdeadbeef;
6653     res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, cert, &size);
6654     ok(res, "InternetQueryOption failed: %u\n", GetLastError());
6655     if (res)
6656     {
6657         ok(cert->lpszSubjectInfo && strlen(cert->lpszSubjectInfo) > 1, "expected a non-empty subject name\n");
6658         ok(cert->lpszIssuerInfo && strlen(cert->lpszIssuerInfo) > 1, "expected a non-empty issuer name\n");
6659         ok(!cert->lpszSignatureAlgName, "unexpected signature algorithm name\n");
6660         ok(!cert->lpszEncryptionAlgName, "unexpected encryption algorithm name\n");
6661         ok(!cert->lpszProtocolName, "unexpected protocol name\n");
6662         ok(cert->dwKeySize != 0xdeadbeef, "unexpected key size\n");
6663 
6664         LocalFree(cert->lpszSubjectInfo);
6665         LocalFree(cert->lpszIssuerInfo);
6666     }
6667     HeapFree(GetProcessHeap(), 0, cert);
6668 
6669     ros_skip_flaky
6670     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6671     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6672     CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
6673     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
6674     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6675     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6676     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6677 
6678     if(req_error != ERROR_INTERNET_SEC_CERT_ERRORS) {
6679         win_skip("Unexpected cert errors %u, skipping security flags tests\n", req_error);
6680 
6681         close_async_handle(ses, 3);
6682         return;
6683     }
6684 
6685     size = sizeof(buf);
6686     res = HttpQueryInfoA(req, HTTP_QUERY_CONTENT_ENCODING, buf, &size, 0);
6687     ok(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfoA(HTTP_QUERY_CONTENT_ENCODING) failed: %u\n", GetLastError());
6688 
6689     test_request_flags(req, 8);
6690     /* IE11 finds both rev failure and invalid CA. Previous versions required rev failure
6691        to be ignored before invalid CA was reported. */
6692     test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA, _SECURITY_FLAG_CERT_REV_FAILED);
6693 
6694     set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_REVOCATION);
6695     test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA|SECURITY_FLAG_IGNORE_REVOCATION, _SECURITY_FLAG_CERT_REV_FAILED);
6696 
6697     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6698     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6699     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
6700     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
6701     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6702     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6703     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6704 
6705     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6706     ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6707 
6708     WaitForSingleObject(complete_event, INFINITE);
6709     ok(req_error == ERROR_INTERNET_INVALID_CA || req_error == ERROR_INTERNET_SEC_CERT_ERRORS, "req_error = %d\n", req_error);
6710 
6711     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
6712     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
6713     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6714     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6715     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6716     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6717     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6718 
6719     test_request_flags(req, INTERNET_REQFLAG_NO_HEADERS);
6720     test_secflags_option(req, SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6721     test_security_info("https://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6722 
6723     set_secflags(req, FALSE, SECURITY_FLAG_IGNORE_UNKNOWN_CA);
6724     test_secflags_option(req, _SECURITY_FLAG_CERT_INVALID_CA
6725             |SECURITY_FLAG_IGNORE_REVOCATION|SECURITY_FLAG_IGNORE_UNKNOWN_CA, 0);
6726     test_http_version(req);
6727 
6728     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6729     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6730     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6731     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6732     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6733     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6734     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6735     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6736     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
6737     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
6738     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6739     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6740     SET_OPTIONAL(INTERNET_STATUS_DETECTING_PROXY);
6741 
6742     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6743     ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6744 
6745     WaitForSingleObject(complete_event, INFINITE);
6746     ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error);
6747 
6748     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6749     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6750     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6751     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6752     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6753     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6754     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
6755     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
6756     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6757     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6758     CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
6759 
6760     test_request_flags(req, 0);
6761     test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_REVOCATION
6762             |SECURITY_FLAG_STRENGTH_STRONG|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6763 
6764     test_cert_struct(req, &test_winehq_com_cert);
6765     test_security_info("https://test.winehq.com/data/some_file.html?q", 0,
6766             _SECURITY_FLAG_CERT_INVALID_CA);
6767 
6768     res = InternetReadFile(req, buf, sizeof(buf), &size);
6769     ok(res, "InternetReadFile failed: %u\n", GetLastError());
6770     ok(size, "size = 0\n");
6771 
6772     close_async_handle(ses, 3);
6773 
6774     /* Collect all existing persistent connections */
6775     res = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
6776     ok(res, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError());
6777 
6778     /* Make another request, without setting security flags */
6779 
6780     ses = InternetOpenA("WineTest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
6781     ok(ses != NULL, "InternetOpen failed\n");
6782 
6783     pInternetSetStatusCallbackA(ses, &callback);
6784 
6785     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6786     conn = InternetConnectA(ses, "test.winehq.com", INTERNET_DEFAULT_HTTPS_PORT,
6787                             NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0xdeadbeef);
6788     ok(conn != NULL, "InternetConnect failed with error %u\n", GetLastError());
6789     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6790 
6791     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
6792     req = HttpOpenRequestA(conn, "GET", "/tests/hello.html", NULL, NULL, NULL,
6793                           INTERNET_FLAG_SECURE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE,
6794                           0xdeadbeef);
6795     ok(req != NULL, "HttpOpenRequest failed\n");
6796     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
6797 
6798     test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_STRENGTH_STRONG
6799             |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6800     test_http_version(req);
6801 
6802     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
6803     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
6804     SET_OPTIONAL(INTERNET_STATUS_CLOSING_CONNECTION); /* IE11 calls it, it probably reconnects. */
6805     SET_OPTIONAL(INTERNET_STATUS_CONNECTION_CLOSED); /* IE11 */
6806     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER); /* IE11 */
6807     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER); /* IE11 */
6808     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
6809     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
6810     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
6811     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
6812     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
6813     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
6814 
6815     res = HttpSendRequestA(req, NULL, 0, NULL, 0);
6816     ok(!res && GetLastError() == ERROR_IO_PENDING, "HttpSendRequest failed: %u\n", GetLastError());
6817 
6818     WaitForSingleObject(complete_event, INFINITE);
6819     ok(req_error == ERROR_SUCCESS, "req_error = %d\n", req_error);
6820 
6821     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTING_TO_SERVER, 2);
6822     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTED_TO_SERVER, 2);
6823     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
6824     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
6825     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
6826     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
6827     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
6828     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
6829     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
6830     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
6831 
6832     test_request_flags(req, 0);
6833     test_secflags_option(req, SECURITY_FLAG_SECURE|SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_STRENGTH_STRONG
6834             |SECURITY_FLAG_IGNORE_REVOCATION|_SECURITY_FLAG_CERT_INVALID_CA, 0);
6835 
6836     res = InternetReadFile(req, buf, sizeof(buf), &size);
6837     ok(res, "InternetReadFile failed: %u\n", GetLastError());
6838     ok(size, "size = 0\n");
6839 
6840     close_async_handle(ses, 2);
6841 
6842     test_security_info("http://test.winehq.com/data/some_file.html?q", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6843     test_security_info("file:///c:/dir/file.txt", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6844     test_security_info("xxx:///c:/dir/file.txt", ERROR_INTERNET_ITEM_NOT_FOUND, 0);
6845 }
6846 
6847 static void test_secure_connection(void)
6848 {
6849     static const WCHAR gizmo5[] = {'G','i','z','m','o','5',0};
6850     static const WCHAR testsite[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
6851     static const WCHAR get[] = {'G','E','T',0};
6852     static const WCHAR testpage[] = {'/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
6853     HINTERNET ses, con, req;
6854     DWORD size, flags;
6855     INTERNET_CERTIFICATE_INFOA *certificate_structA = NULL;
6856     INTERNET_CERTIFICATE_INFOW *certificate_structW = NULL;
6857     BOOL ret;
6858 
6859     ses = InternetOpenA("Gizmo5", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
6860     ok(ses != NULL, "InternetOpen failed\n");
6861 
6862     con = InternetConnectA(ses, "test.winehq.org",
6863                           INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL,
6864                           INTERNET_SERVICE_HTTP, 0, 0);
6865     ok(con != NULL, "InternetConnect failed\n");
6866 
6867     req = HttpOpenRequestA(con, "GET", "/tests/hello.html", NULL, NULL, NULL,
6868                           INTERNET_FLAG_SECURE, 0);
6869     ok(req != NULL, "HttpOpenRequest failed\n");
6870 
6871     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
6872     ok(ret || broken(GetLastError() == ERROR_INTERNET_CANNOT_CONNECT),
6873                      "HttpSendRequest failed: %d\n", GetLastError());
6874     if (!ret)
6875     {
6876         win_skip("Cannot connect to https.\n");
6877         goto done;
6878     }
6879 
6880     size = sizeof(flags);
6881     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
6882     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6883     ok(flags & SECURITY_FLAG_SECURE, "expected secure flag to be set\n");
6884 
6885     test_cert_struct(req, &test_winehq_org_cert);
6886 
6887     /* Querying the same option through InternetQueryOptionW still results in
6888      * ASCII strings being returned.
6889      */
6890     size = 0;
6891     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6892                                NULL, &size);
6893     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6894     ok(size == sizeof(INTERNET_CERTIFICATE_INFOW), "size = %d\n", size);
6895     certificate_structW = HeapAlloc(GetProcessHeap(), 0, size);
6896     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6897                               certificate_structW, &size);
6898     certificate_structA = (INTERNET_CERTIFICATE_INFOA *)certificate_structW;
6899     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6900     if (ret)
6901     {
6902         ok(certificate_structA->lpszSubjectInfo &&
6903            strlen(certificate_structA->lpszSubjectInfo) > 1,
6904            "expected a non-empty subject name\n");
6905         ok(certificate_structA->lpszIssuerInfo &&
6906            strlen(certificate_structA->lpszIssuerInfo) > 1,
6907            "expected a non-empty issuer name\n");
6908         ok(!certificate_structA->lpszSignatureAlgName,
6909            "unexpected signature algorithm name\n");
6910         ok(!certificate_structA->lpszEncryptionAlgName,
6911            "unexpected encryption algorithm name\n");
6912         ok(!certificate_structA->lpszProtocolName,
6913            "unexpected protocol name\n");
6914         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
6915         release_cert_info(certificate_structA);
6916     }
6917     HeapFree(GetProcessHeap(), 0, certificate_structW);
6918 
6919     InternetCloseHandle(req);
6920     InternetCloseHandle(con);
6921     InternetCloseHandle(ses);
6922 
6923     /* Repeating the tests with the W functions has the same result: */
6924     ses = InternetOpenW(gizmo5, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
6925     ok(ses != NULL, "InternetOpen failed\n");
6926 
6927     con = InternetConnectW(ses, testsite,
6928                           INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL,
6929                           INTERNET_SERVICE_HTTP, 0, 0);
6930     ok(con != NULL, "InternetConnect failed\n");
6931 
6932     req = HttpOpenRequestW(con, get, testpage, NULL, NULL, NULL,
6933                           INTERNET_FLAG_SECURE|INTERNET_FLAG_RELOAD, 0);
6934     ok(req != NULL, "HttpOpenRequest failed\n");
6935 
6936     ret = HttpSendRequestA(req, NULL, 0, NULL, 0);
6937     ok(ret, "HttpSendRequest failed: %d\n", GetLastError());
6938 
6939     size = sizeof(flags);
6940     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
6941     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6942     ok(flags & SECURITY_FLAG_SECURE, "expected secure flag to be set, got %x\n", flags);
6943 
6944     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6945                                NULL, &size);
6946     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6947     ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %d\n", size);
6948     certificate_structA = HeapAlloc(GetProcessHeap(), 0, size);
6949     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6950                                certificate_structA, &size);
6951     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6952     if (ret)
6953     {
6954         ok(certificate_structA->lpszSubjectInfo &&
6955            strlen(certificate_structA->lpszSubjectInfo) > 1,
6956            "expected a non-empty subject name\n");
6957         ok(certificate_structA->lpszIssuerInfo &&
6958            strlen(certificate_structA->lpszIssuerInfo) > 1,
6959            "expected a non-empty issuer name\n");
6960         ok(!certificate_structA->lpszSignatureAlgName,
6961            "unexpected signature algorithm name\n");
6962         ok(!certificate_structA->lpszEncryptionAlgName,
6963            "unexpected encryption algorithm name\n");
6964         ok(!certificate_structA->lpszProtocolName,
6965            "unexpected protocol name\n");
6966         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
6967         release_cert_info(certificate_structA);
6968     }
6969     HeapFree(GetProcessHeap(), 0, certificate_structA);
6970 
6971     /* Again, querying the same option through InternetQueryOptionW still
6972      * results in ASCII strings being returned.
6973      */
6974     size = 0;
6975     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6976                                NULL, &size);
6977     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
6978     ok(size == sizeof(INTERNET_CERTIFICATE_INFOW), "size = %d\n", size);
6979     certificate_structW = HeapAlloc(GetProcessHeap(), 0, size);
6980     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
6981                                certificate_structW, &size);
6982     certificate_structA = (INTERNET_CERTIFICATE_INFOA *)certificate_structW;
6983     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
6984     if (ret)
6985     {
6986         ok(certificate_structA->lpszSubjectInfo &&
6987            strlen(certificate_structA->lpszSubjectInfo) > 1,
6988            "expected a non-empty subject name\n");
6989         ok(certificate_structA->lpszIssuerInfo &&
6990            strlen(certificate_structA->lpszIssuerInfo) > 1,
6991            "expected a non-empty issuer name\n");
6992         ok(!certificate_structA->lpszSignatureAlgName,
6993            "unexpected signature algorithm name\n");
6994         ok(!certificate_structA->lpszEncryptionAlgName,
6995            "unexpected encryption algorithm name\n");
6996         ok(!certificate_structA->lpszProtocolName,
6997            "unexpected protocol name\n");
6998         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
6999         release_cert_info(certificate_structA);
7000     }
7001     HeapFree(GetProcessHeap(), 0, certificate_structW);
7002 
7003 done:
7004     InternetCloseHandle(req);
7005     InternetCloseHandle(con);
7006     InternetCloseHandle(ses);
7007 }
7008 
7009 static void test_user_agent_header(void)
7010 {
7011     HINTERNET ses, con, req;
7012     DWORD size, err;
7013     char buffer[64];
7014     BOOL ret;
7015 
7016     ses = InternetOpenA("Gizmo5", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
7017     ok(ses != NULL, "InternetOpen failed\n");
7018 
7019     con = InternetConnectA(ses, "test.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
7020     ok(con != NULL, "InternetConnect failed\n");
7021 
7022     req = HttpOpenRequestA(con, "GET", "/tests/hello.html", "HTTP/1.0", NULL, NULL, 0, 0);
7023     ok(req != NULL, "HttpOpenRequest failed\n");
7024 
7025     size = sizeof(buffer);
7026     ret = HttpQueryInfoA(req, HTTP_QUERY_USER_AGENT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7027     err = GetLastError();
7028     ok(!ret, "HttpQueryInfo succeeded\n");
7029     ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
7030 
7031     ret = HttpAddRequestHeadersA(req, "User-Agent: Gizmo Project\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
7032     ok(ret, "HttpAddRequestHeaders succeeded\n");
7033 
7034     size = sizeof(buffer);
7035     ret = HttpQueryInfoA(req, HTTP_QUERY_USER_AGENT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7036     err = GetLastError();
7037     ok(ret, "HttpQueryInfo failed\n");
7038 
7039     InternetCloseHandle(req);
7040 
7041     req = HttpOpenRequestA(con, "GET", "/", "HTTP/1.0", NULL, NULL, 0, 0);
7042     ok(req != NULL, "HttpOpenRequest failed\n");
7043 
7044     size = sizeof(buffer);
7045     ret = HttpQueryInfoA(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7046     err = GetLastError();
7047     ok(!ret, "HttpQueryInfo succeeded\n");
7048     ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
7049 
7050     ret = HttpAddRequestHeadersA(req, "Accept: audio/*, image/*, text/*\r\nUser-Agent: Gizmo Project\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
7051     ok(ret, "HttpAddRequestHeaders failed\n");
7052 
7053     buffer[0] = 0;
7054     size = sizeof(buffer);
7055     ret = HttpQueryInfoA(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7056     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
7057     ok(!strcmp(buffer, "audio/*, image/*, text/*"), "got '%s' expected 'audio/*, image/*, text/*'\n", buffer);
7058 
7059     InternetCloseHandle(req);
7060     InternetCloseHandle(con);
7061     InternetCloseHandle(ses);
7062 }
7063 
7064 static void test_bogus_accept_types_array(void)
7065 {
7066     HINTERNET ses, con, req;
7067     static const char *types[] = { (const char *)6240, "*/*", "%p", "", (const char *)0xffffffff, "*/*", NULL };
7068     DWORD size, error;
7069     char buffer[32];
7070     BOOL ret;
7071 
7072     ses = InternetOpenA("MERONG(0.9/;p)", INTERNET_OPEN_TYPE_DIRECT, "", "", 0);
7073     con = InternetConnectA(ses, "www.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
7074     req = HttpOpenRequestA(con, "POST", "/post/post_action.php", "HTTP/1.0", "", types, INTERNET_FLAG_FORMS_SUBMIT, 0);
7075 
7076     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
7077 
7078     buffer[0] = 0;
7079     size = sizeof(buffer);
7080     SetLastError(0xdeadbeef);
7081     ret = HttpQueryInfoA(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7082     error = GetLastError();
7083     ok(!ret || broken(ret), "HttpQueryInfo succeeded\n");
7084     if (!ret) ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", error);
7085     ok(broken(!strcmp(buffer, ", */*, %p, , , */*")) /* IE6 */ ||
7086        broken(!strcmp(buffer, "*/*, %p, */*")) /* IE7/8 */ ||
7087        !strcmp(buffer, ""), "got '%s' expected ''\n", buffer);
7088 
7089     InternetCloseHandle(req);
7090     InternetCloseHandle(con);
7091     InternetCloseHandle(ses);
7092 }
7093 
7094 struct context
7095 {
7096     HANDLE event;
7097     HINTERNET req;
7098 };
7099 
7100 static void WINAPI cb(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID info, DWORD size)
7101 {
7102     INTERNET_ASYNC_RESULT *result = info;
7103     struct context *ctx = (struct context *)context;
7104 
7105     if(winetest_debug > 1)
7106         trace("%p 0x%08lx %u %p 0x%08x\n", handle, context, status, info, size);
7107 
7108     switch(status) {
7109     case INTERNET_STATUS_REQUEST_COMPLETE:
7110         trace("request handle: 0x%08lx\n", result->dwResult);
7111         ctx->req = (HINTERNET)result->dwResult;
7112         SetEvent(ctx->event);
7113         break;
7114     case INTERNET_STATUS_HANDLE_CLOSING: {
7115         DWORD type = INTERNET_HANDLE_TYPE_CONNECT_HTTP, size = sizeof(type);
7116 
7117         if (InternetQueryOptionA(handle, INTERNET_OPTION_HANDLE_TYPE, &type, &size))
7118             ok(type != INTERNET_HANDLE_TYPE_CONNECT_HTTP, "unexpected callback\n");
7119         SetEvent(ctx->event);
7120         break;
7121     }
7122     case INTERNET_STATUS_NAME_RESOLVED:
7123     case INTERNET_STATUS_CONNECTING_TO_SERVER:
7124     case INTERNET_STATUS_CONNECTED_TO_SERVER: {
7125         char *str = info;
7126         ok(str[0] && str[1], "Got string: %s\n", str);
7127         ok(size == strlen(str)+1, "unexpected size %u\n", size);
7128     }
7129     }
7130 }
7131 
7132 static void test_open_url_async(void)
7133 {
7134     BOOL ret;
7135     HINTERNET ses, req;
7136     DWORD size, error;
7137     struct context ctx;
7138     ULONG type;
7139 
7140     /* Collect all existing persistent connections */
7141     ret = InternetSetOptionA(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
7142     ok(ret, "InternetSetOption(INTERNET_OPTION_END_BROWSER_SESSION) failed: %u\n", GetLastError());
7143 
7144     /*
7145      * Some versions of IE6 fail those tests. They pass some notification data as UNICODE string, while
7146      * other versions never do. They also hang of following tests. We disable it for everything older
7147      * than IE7.
7148      */
7149     if(!is_ie7plus)
7150         return;
7151 
7152     ctx.req = NULL;
7153     ctx.event = CreateEventA(NULL, TRUE, FALSE, "Z:_home_hans_jaman-installer.exe_ev1");
7154 
7155     ses = InternetOpenA("AdvancedInstaller", 0, NULL, NULL, INTERNET_FLAG_ASYNC);
7156     ok(ses != NULL, "InternetOpen failed\n");
7157 
7158     SetLastError(0xdeadbeef);
7159     ret = InternetSetOptionA(NULL, INTERNET_OPTION_CALLBACK, &cb, sizeof(DWORD_PTR));
7160     error = GetLastError();
7161     ok(!ret, "InternetSetOptionA succeeded\n");
7162     ok(error == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "got %u expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE\n", error);
7163 
7164     ret = InternetSetOptionA(ses, INTERNET_OPTION_CALLBACK, &cb, sizeof(DWORD_PTR));
7165     error = GetLastError();
7166     ok(!ret, "InternetSetOptionA failed\n");
7167     ok(error == ERROR_INTERNET_OPTION_NOT_SETTABLE, "got %u expected ERROR_INTERNET_OPTION_NOT_SETTABLE\n", error);
7168 
7169     pInternetSetStatusCallbackW(ses, cb);
7170     ResetEvent(ctx.event);
7171 
7172     req = InternetOpenUrlA(ses, "http://test.winehq.org", NULL, 0, 0, (DWORD_PTR)&ctx);
7173     ok(!req && GetLastError() == ERROR_IO_PENDING, "InternetOpenUrl failed\n");
7174 
7175     WaitForSingleObject(ctx.event, INFINITE);
7176 
7177     type = 0;
7178     size = sizeof(type);
7179     ret = InternetQueryOptionA(ctx.req, INTERNET_OPTION_HANDLE_TYPE, &type, &size);
7180     ok(ret, "InternetQueryOption failed: %u\n", GetLastError());
7181     ok(type == INTERNET_HANDLE_TYPE_HTTP_REQUEST,
7182        "expected INTERNET_HANDLE_TYPE_HTTP_REQUEST, got %u\n", type);
7183 
7184     size = 0;
7185     ret = HttpQueryInfoA(ctx.req, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &size, NULL);
7186     ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "HttpQueryInfo failed\n");
7187     ok(size > 0, "expected size > 0\n");
7188 
7189     ResetEvent(ctx.event);
7190     InternetCloseHandle(ctx.req);
7191     WaitForSingleObject(ctx.event, INFINITE);
7192 
7193     InternetCloseHandle(ses);
7194     CloseHandle(ctx.event);
7195 }
7196 
7197 enum api
7198 {
7199     internet_connect = 1,
7200     http_open_request,
7201     http_send_request_ex,
7202     internet_writefile,
7203     http_end_request,
7204     internet_close_handle
7205 };
7206 
7207 struct notification
7208 {
7209     enum api     function; /* api responsible for notification */
7210     unsigned int status;   /* status received */
7211     BOOL         async;    /* delivered from another thread? */
7212     BOOL         todo;
7213     BOOL         optional;
7214 };
7215 
7216 struct info
7217 {
7218     enum api     function;
7219     const struct notification *test;
7220     unsigned int count;
7221     unsigned int index;
7222     HANDLE       wait;
7223     DWORD        thread;
7224     unsigned int line;
7225     DWORD        expect_result;
7226     BOOL         is_aborted;
7227 };
7228 
7229 static CRITICAL_SECTION notification_cs;
7230 
7231 static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD buflen )
7232 {
7233     BOOL status_ok, function_ok;
7234     struct info *info = (struct info *)context;
7235     unsigned int i;
7236 
7237     EnterCriticalSection( &notification_cs );
7238 
7239     if(info->is_aborted) {
7240         LeaveCriticalSection(&notification_cs);
7241         return;
7242     }
7243 
7244     if (status == INTERNET_STATUS_HANDLE_CREATED)
7245     {
7246         DWORD size = sizeof(struct info *);
7247         HttpQueryInfoA( handle, INTERNET_OPTION_CONTEXT_VALUE, &info, &size, 0 );
7248     }else if(status == INTERNET_STATUS_REQUEST_COMPLETE) {
7249         INTERNET_ASYNC_RESULT *ar = (INTERNET_ASYNC_RESULT*)buffer;
7250 
7251         ok(buflen == sizeof(*ar), "unexpected buflen = %d\n", buflen);
7252         if(info->expect_result == ERROR_SUCCESS) {
7253             ok(ar->dwResult == 1, "ar->dwResult = %ld, expected 1\n", ar->dwResult);
7254         }else {
7255             ok(!ar->dwResult, "ar->dwResult = %ld, expected 1\n", ar->dwResult);
7256             ok(ar->dwError == info->expect_result, "ar->dwError = %d, expected %d\n", ar->dwError, info->expect_result);
7257         }
7258     }
7259 
7260     i = info->index;
7261     if (i >= info->count)
7262     {
7263         LeaveCriticalSection( &notification_cs );
7264         return;
7265     }
7266 
7267     while (info->test[i].status != status &&
7268         (info->test[i].optional || info->test[i].todo) &&
7269         i < info->count - 1 &&
7270         info->test[i].function == info->test[i + 1].function)
7271     {
7272         i++;
7273     }
7274 
7275     status_ok   = (info->test[i].status == status);
7276     function_ok = (info->test[i].function == info->function);
7277 
7278     if (!info->test[i].todo)
7279     {
7280         ok( status_ok, "%u: expected status %u got %u\n", info->line, info->test[i].status, status );
7281         ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function );
7282 
7283         if (info->test[i].async)
7284             ok(info->thread != GetCurrentThreadId(), "%u: expected thread %u got %u\n",
7285                info->line, info->thread, GetCurrentThreadId());
7286     }
7287     else
7288     {
7289         todo_wine ok( status_ok, "%u: expected status %u got %u\n", info->line, info->test[i].status, status );
7290         if (status_ok)
7291             todo_wine ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function );
7292     }
7293     if (i == info->count - 1 || info->test[i].function != info->test[i + 1].function) SetEvent( info->wait );
7294     info->index = i+1;
7295 
7296     LeaveCriticalSection( &notification_cs );
7297 }
7298 
7299 static void setup_test( struct info *info, enum api function, unsigned int line, DWORD expect_result )
7300 {
7301     info->function = function;
7302     info->line = line;
7303     info->expect_result = expect_result;
7304 }
7305 
7306 struct notification_data
7307 {
7308     const struct notification *test;
7309     const unsigned int count;
7310     const char *method;
7311     const char *host;
7312     const char *path;
7313     const char *data;
7314     BOOL expect_conn_failure;
7315 };
7316 
7317 static const struct notification async_send_request_ex_test[] =
7318 {
7319     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED, FALSE },
7320     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED, FALSE },
7321     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7322     { http_send_request_ex,  INTERNET_STATUS_COOKIE_SENT, TRUE, FALSE, TRUE },
7323     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, TRUE, FALSE, TRUE },
7324     { http_send_request_ex,  INTERNET_STATUS_NAME_RESOLVED, TRUE, FALSE, TRUE },
7325     { http_send_request_ex,  INTERNET_STATUS_CONNECTING_TO_SERVER, TRUE },
7326     { http_send_request_ex,  INTERNET_STATUS_CONNECTED_TO_SERVER, TRUE },
7327     { http_send_request_ex,  INTERNET_STATUS_SENDING_REQUEST, TRUE },
7328     { http_send_request_ex,  INTERNET_STATUS_REQUEST_SENT, TRUE },
7329     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7330     { internet_writefile,    INTERNET_STATUS_SENDING_REQUEST, FALSE },
7331     { internet_writefile,    INTERNET_STATUS_REQUEST_SENT, FALSE },
7332     { http_end_request,      INTERNET_STATUS_RECEIVING_RESPONSE, TRUE },
7333     { http_end_request,      INTERNET_STATUS_RESPONSE_RECEIVED, TRUE },
7334     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7335     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, FALSE, FALSE, TRUE },
7336     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, FALSE, FALSE, TRUE },
7337     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, },
7338     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, }
7339 };
7340 
7341 static const struct notification async_send_request_ex_test2[] =
7342 {
7343     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED, FALSE },
7344     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED, FALSE },
7345     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7346     { http_send_request_ex,  INTERNET_STATUS_COOKIE_SENT, TRUE, FALSE, TRUE },
7347     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, TRUE, FALSE, TRUE },
7348     { http_send_request_ex,  INTERNET_STATUS_NAME_RESOLVED, TRUE, FALSE, TRUE },
7349     { http_send_request_ex,  INTERNET_STATUS_CONNECTING_TO_SERVER, TRUE, TRUE },
7350     { http_send_request_ex,  INTERNET_STATUS_CONNECTED_TO_SERVER, TRUE, TRUE },
7351     { http_send_request_ex,  INTERNET_STATUS_SENDING_REQUEST, TRUE },
7352     { http_send_request_ex,  INTERNET_STATUS_REQUEST_SENT, TRUE },
7353     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7354     { http_end_request,      INTERNET_STATUS_RECEIVING_RESPONSE, TRUE },
7355     { http_end_request,      INTERNET_STATUS_RESPONSE_RECEIVED, TRUE },
7356     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7357     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, FALSE, FALSE, TRUE },
7358     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, FALSE, FALSE, TRUE },
7359     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, },
7360     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, }
7361 };
7362 
7363 static const struct notification async_send_request_ex_resolve_failure_test[] =
7364 {
7365     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED, FALSE },
7366     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED, FALSE },
7367     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7368     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, TRUE },
7369     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7370     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7371     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7372     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, FALSE, FALSE, TRUE },
7373     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, FALSE, FALSE, TRUE },
7374     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, },
7375     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, FALSE, }
7376 };
7377 
7378 static const struct notification async_send_request_ex_chunked_test[] =
7379 {
7380     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED },
7381     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED },
7382     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, TRUE, FALSE, TRUE },
7383     { http_send_request_ex,  INTERNET_STATUS_COOKIE_SENT, TRUE, FALSE, TRUE },
7384     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, TRUE, FALSE, TRUE },
7385     { http_send_request_ex,  INTERNET_STATUS_NAME_RESOLVED, TRUE, FALSE, TRUE },
7386     { http_send_request_ex,  INTERNET_STATUS_CONNECTING_TO_SERVER, TRUE },
7387     { http_send_request_ex,  INTERNET_STATUS_CONNECTED_TO_SERVER, TRUE },
7388     { http_send_request_ex,  INTERNET_STATUS_SENDING_REQUEST, TRUE },
7389     { http_send_request_ex,  INTERNET_STATUS_REQUEST_SENT, TRUE },
7390     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7391     { http_end_request,      INTERNET_STATUS_RECEIVING_RESPONSE, TRUE },
7392     { http_end_request,      INTERNET_STATUS_RESPONSE_RECEIVED, TRUE },
7393     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, TRUE },
7394     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION },
7395     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED },
7396     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING },
7397     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING }
7398 };
7399 
7400 static const struct notification_data notification_data[] = {
7401     {
7402         async_send_request_ex_chunked_test,
7403         ARRAY_SIZE(async_send_request_ex_chunked_test),
7404         "GET",
7405         "test.winehq.org",
7406         "tests/data.php"
7407     },
7408     {
7409         async_send_request_ex_test,
7410         ARRAY_SIZE(async_send_request_ex_test),
7411         "POST",
7412         "test.winehq.org",
7413         "tests/post.php",
7414         "Public ID=codeweavers"
7415     },
7416     {
7417         async_send_request_ex_test2,
7418         ARRAY_SIZE(async_send_request_ex_test2),
7419         "POST",
7420         "test.winehq.org",
7421         "tests/post.php"
7422     },
7423     {
7424         async_send_request_ex_resolve_failure_test,
7425         ARRAY_SIZE(async_send_request_ex_resolve_failure_test),
7426         "GET",
7427         "brokenhost",
7428         "index.html",
7429         NULL,
7430         TRUE
7431     }
7432 };
7433 
7434 static void test_async_HttpSendRequestEx(const struct notification_data *nd)
7435 {
7436     BOOL ret;
7437     HINTERNET ses, req, con;
7438     struct info info;
7439     DWORD size, written, error;
7440     INTERNET_BUFFERSA b;
7441     static const char *accept[2] = {"*/*", NULL};
7442     char buffer[32];
7443 
7444     trace("Async HttpSendRequestEx test (%s %s)\n", nd->method, nd->host);
7445 
7446     InitializeCriticalSection( &notification_cs );
7447 
7448     info.test  = nd->test;
7449     info.count = nd->count;
7450     info.index = 0;
7451     info.wait = CreateEventW( NULL, FALSE, FALSE, NULL );
7452     info.thread = GetCurrentThreadId();
7453     info.is_aborted = FALSE;
7454 
7455     ses = InternetOpenA( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC );
7456     ok( ses != NULL, "InternetOpen failed\n" );
7457 
7458     pInternetSetStatusCallbackA( ses, check_notification );
7459 
7460     setup_test( &info, internet_connect, __LINE__, ERROR_SUCCESS );
7461     con = InternetConnectA( ses, nd->host, 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)&info );
7462     ok( con != NULL, "InternetConnect failed %u\n", GetLastError() );
7463 
7464     WaitForSingleObject( info.wait, 10000 );
7465 
7466     setup_test( &info, http_open_request, __LINE__, ERROR_SUCCESS );
7467     req = HttpOpenRequestA( con, nd->method, nd->path, NULL, NULL, accept, 0, (DWORD_PTR)&info );
7468     ok( req != NULL, "HttpOpenRequest failed %u\n", GetLastError() );
7469 
7470     WaitForSingleObject( info.wait, 10000 );
7471 
7472     if(nd->data) {
7473         memset( &b, 0, sizeof(INTERNET_BUFFERSA) );
7474         b.dwStructSize = sizeof(INTERNET_BUFFERSA);
7475         b.lpcszHeader = "Content-Type: application/x-www-form-urlencoded";
7476         b.dwHeadersLength = strlen( b.lpcszHeader );
7477         b.dwBufferTotal = nd->data ? strlen( nd->data ) : 0;
7478     }
7479 
7480     setup_test( &info, http_send_request_ex, __LINE__,
7481             nd->expect_conn_failure ? ERROR_INTERNET_NAME_NOT_RESOLVED : ERROR_SUCCESS );
7482     ret = HttpSendRequestExA( req, nd->data ? &b : NULL, NULL, 0x28, 0 );
7483     ok( !ret && GetLastError() == ERROR_IO_PENDING, "HttpSendRequestExA failed %d %u\n", ret, GetLastError() );
7484 
7485     error = WaitForSingleObject( info.wait, 10000 );
7486     if(error != WAIT_OBJECT_0) {
7487         skip("WaitForSingleObject returned %d, assuming DNS problem\n", error);
7488         info.is_aborted = TRUE;
7489         goto abort;
7490     }
7491 
7492     size = sizeof(buffer);
7493     SetLastError( 0xdeadbeef );
7494     ret = HttpQueryInfoA( req, HTTP_QUERY_CONTENT_ENCODING, buffer, &size, 0 );
7495     error = GetLastError();
7496     ok( !ret, "HttpQueryInfoA failed %u\n", GetLastError() );
7497     if(nd->expect_conn_failure) {
7498         ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND got %u\n", error );
7499     }else {
7500         todo_wine
7501         ok(error == ERROR_INTERNET_INCORRECT_HANDLE_STATE,
7502             "expected ERROR_INTERNET_INCORRECT_HANDLE_STATE got %u\n", error );
7503     }
7504 
7505     if (nd->data)
7506     {
7507         written = 0;
7508         size = strlen( nd->data );
7509         setup_test( &info, internet_writefile, __LINE__, ERROR_SUCCESS );
7510         ret = InternetWriteFile( req, nd->data, size, &written );
7511         ok( ret, "InternetWriteFile failed %u\n", GetLastError() );
7512         ok( written == size, "expected %u got %u\n", written, size );
7513 
7514         WaitForSingleObject( info.wait, 10000 );
7515 
7516         SetLastError( 0xdeadbeef );
7517         ret = HttpEndRequestA( req, (void *)nd->data, 0x28, 0 );
7518         error = GetLastError();
7519         ok( !ret, "HttpEndRequestA succeeded\n" );
7520         ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error );
7521     }
7522 
7523     SetLastError( 0xdeadbeef );
7524     setup_test( &info, http_end_request, __LINE__,
7525             nd->expect_conn_failure ? ERROR_INTERNET_OPERATION_CANCELLED : ERROR_SUCCESS);
7526     ret = HttpEndRequestA( req, NULL, 0x28, 0 );
7527     error = GetLastError();
7528     ok( !ret, "HttpEndRequestA succeeded\n" );
7529     ok( error == ERROR_IO_PENDING, "expected ERROR_IO_PENDING got %u\n", error );
7530 
7531     WaitForSingleObject( info.wait, 10000 );
7532 
7533     setup_test( &info, internet_close_handle, __LINE__, ERROR_SUCCESS );
7534  abort:
7535     InternetCloseHandle( req );
7536     InternetCloseHandle( con );
7537     InternetCloseHandle( ses );
7538 
7539     WaitForSingleObject( info.wait, 10000 );
7540     Sleep(100);
7541     CloseHandle( info.wait );
7542     DeleteCriticalSection( &notification_cs );
7543 }
7544 
7545 static HINTERNET closetest_session, closetest_req, closetest_conn;
7546 static BOOL closetest_closed;
7547 
7548 static void WINAPI closetest_callback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
7549      LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
7550 {
7551     DWORD len, type;
7552     BOOL res;
7553 
7554     if(winetest_debug > 1)
7555         trace("closetest_callback %p: %d\n", hInternet, dwInternetStatus);
7556 
7557     ok(hInternet == closetest_session || hInternet == closetest_conn || hInternet == closetest_req,
7558        "Unexpected hInternet %p\n", hInternet);
7559     if(!closetest_closed)
7560         return;
7561 
7562     len = sizeof(type);
7563     res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_HANDLE_TYPE, &type, &len);
7564     ok(!res && GetLastError() == ERROR_INVALID_HANDLE,
7565        "InternetQueryOptionA(%p INTERNET_OPTION_HANDLE_TYPE) failed: %x %u, expected TRUE ERROR_INVALID_HANDLE\n",
7566        closetest_req, res, GetLastError());
7567 }
7568 
7569 static void test_InternetCloseHandle(void)
7570 {
7571     DWORD len, flags;
7572     BOOL res;
7573 
7574     closetest_session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
7575     ok(closetest_session != NULL,"InternetOpen failed with error %u\n", GetLastError());
7576 
7577     pInternetSetStatusCallbackA(closetest_session, closetest_callback);
7578 
7579     closetest_conn = InternetConnectA(closetest_session, "source.winehq.org", INTERNET_INVALID_PORT_NUMBER,
7580             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
7581     ok(closetest_conn != NULL,"InternetConnect failed with error %u\n", GetLastError());
7582 
7583     closetest_req = HttpOpenRequestA(closetest_conn, "GET", "winegecko.php", NULL, NULL, NULL,
7584             INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
7585 
7586     res = HttpSendRequestA(closetest_req, NULL, -1, NULL, 0);
7587     ok(!res && (GetLastError() == ERROR_IO_PENDING),
7588        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
7589 
7590     test_request_flags(closetest_req, INTERNET_REQFLAG_NO_HEADERS);
7591 
7592     res = InternetCloseHandle(closetest_session);
7593     ok(res, "InternetCloseHandle failed: %u\n", GetLastError());
7594     closetest_closed = TRUE;
7595     trace("Closed session handle\n");
7596 
7597     res = InternetCloseHandle(closetest_conn);
7598     ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "InternetCloseConnection(conn) failed: %x %u\n",
7599        res, GetLastError());
7600 
7601     res = InternetCloseHandle(closetest_req);
7602     ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "InternetCloseConnection(req) failed: %x %u\n",
7603        res, GetLastError());
7604 
7605     len = sizeof(flags);
7606     res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_REQUEST_FLAGS, &flags, &len);
7607     ok(!res && GetLastError() == ERROR_INVALID_HANDLE,
7608        "InternetQueryOptionA(%p INTERNET_OPTION_REQUEST_FLAGS) failed: %x %u, expected TRUE ERROR_INVALID_HANDLE\n",
7609        closetest_req, res, GetLastError());
7610 }
7611 
7612 static void test_connection_failure(void)
7613 {
7614     test_request_t req;
7615     DWORD error;
7616     BOOL ret;
7617 
7618     open_simple_request(&req, "localhost", 1, NULL, "/");
7619 
7620     SetLastError(0xdeadbeef);
7621     ret = HttpSendRequestA(req.request, NULL, 0, NULL, 0);
7622     error = GetLastError();
7623     ok(!ret, "unexpected success\n");
7624     ok(error == ERROR_INTERNET_CANNOT_CONNECT, "wrong error %u\n", error);
7625 
7626     close_request(&req);
7627 }
7628 
7629 static void test_default_service_port(void)
7630 {
7631     HINTERNET session, connect, request;
7632     DWORD size, error;
7633     char buffer[128];
7634     BOOL ret;
7635 
7636     if(!is_ie7plus)
7637         return;
7638 
7639     session = InternetOpenA("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
7640     ok(session != NULL, "InternetOpen failed\n");
7641 
7642     connect = InternetConnectA(session, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, NULL, NULL,
7643                               INTERNET_SERVICE_HTTP, 0, 0);
7644     ok(connect != NULL, "InternetConnect failed\n");
7645 
7646     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
7647     ok(request != NULL, "HttpOpenRequest failed\n");
7648 
7649     SetLastError(0xdeadbeef);
7650     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
7651     error = GetLastError();
7652     ok(!ret, "HttpSendRequest succeeded\n");
7653     ok(error == ERROR_INTERNET_SECURITY_CHANNEL_ERROR || error == ERROR_INTERNET_CANNOT_CONNECT,
7654        "got %u\n", error);
7655 
7656     size = sizeof(buffer);
7657     memset(buffer, 0, sizeof(buffer));
7658     ret = HttpQueryInfoA(request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7659     ok(ret, "HttpQueryInfo failed with error %u\n", GetLastError());
7660     ok(!strcmp(buffer, "test.winehq.org:80"), "Expected test.winehg.org:80, got '%s'\n", buffer);
7661 
7662     InternetCloseHandle(request);
7663     InternetCloseHandle(connect);
7664 
7665     connect = InternetConnectA(session, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, NULL, NULL,
7666                                INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
7667     ok(connect != NULL, "InternetConnect failed\n");
7668 
7669     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
7670     ok(request != NULL, "HttpOpenRequest failed\n");
7671 
7672     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
7673     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
7674 
7675     size = sizeof(buffer);
7676     memset(buffer, 0, sizeof(buffer));
7677     ret = HttpQueryInfoA(request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7678     ok(ret, "HttpQueryInfo failed with error %u\n", GetLastError());
7679     ok(!strcmp(buffer, "test.winehq.org"), "Expected test.winehg.org, got '%s'\n", buffer);
7680 
7681     InternetCloseHandle(request);
7682     InternetCloseHandle(connect);
7683 
7684     connect = InternetConnectA(session, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER, NULL, NULL,
7685                                INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
7686     ok(connect != NULL, "InternetConnect failed\n");
7687 
7688     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, NULL, 0, 0);
7689     ok(request != NULL, "HttpOpenRequest failed\n");
7690 
7691     ret = HttpSendRequestA(request, NULL, 0, NULL, 0);
7692     ok(ret, "HttpSendRequest failed with error %u\n", GetLastError());
7693 
7694     size = sizeof(buffer);
7695     memset(buffer, 0, sizeof(buffer));
7696     ret = HttpQueryInfoA(request, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
7697     ok(ret, "HttpQueryInfo failed with error %u\n", GetLastError());
7698     ok(!strcmp(buffer, "test.winehq.org:443"), "Expected test.winehg.org:443, got '%s'\n", buffer);
7699 
7700     InternetCloseHandle(request);
7701     InternetCloseHandle(connect);
7702     InternetCloseHandle(session);
7703 }
7704 
7705 static void init_status_tests(void)
7706 {
7707     memset(expect, 0, sizeof(expect));
7708     memset(optional, 0, sizeof(optional));
7709     memset(wine_allow, 0, sizeof(wine_allow));
7710     memset(notified, 0, sizeof(notified));
7711     memset(status_string, 0, sizeof(status_string));
7712 
7713 #define STATUS_STRING(status) status_string[status] = #status
7714     STATUS_STRING(INTERNET_STATUS_RESOLVING_NAME);
7715     STATUS_STRING(INTERNET_STATUS_NAME_RESOLVED);
7716     STATUS_STRING(INTERNET_STATUS_CONNECTING_TO_SERVER);
7717     STATUS_STRING(INTERNET_STATUS_CONNECTED_TO_SERVER);
7718     STATUS_STRING(INTERNET_STATUS_SENDING_REQUEST);
7719     STATUS_STRING(INTERNET_STATUS_REQUEST_SENT);
7720     STATUS_STRING(INTERNET_STATUS_RECEIVING_RESPONSE);
7721     STATUS_STRING(INTERNET_STATUS_RESPONSE_RECEIVED);
7722     STATUS_STRING(INTERNET_STATUS_CTL_RESPONSE_RECEIVED);
7723     STATUS_STRING(INTERNET_STATUS_PREFETCH);
7724     STATUS_STRING(INTERNET_STATUS_CLOSING_CONNECTION);
7725     STATUS_STRING(INTERNET_STATUS_CONNECTION_CLOSED);
7726     STATUS_STRING(INTERNET_STATUS_HANDLE_CREATED);
7727     STATUS_STRING(INTERNET_STATUS_HANDLE_CLOSING);
7728     STATUS_STRING(INTERNET_STATUS_DETECTING_PROXY);
7729     STATUS_STRING(INTERNET_STATUS_REQUEST_COMPLETE);
7730     STATUS_STRING(INTERNET_STATUS_REDIRECT);
7731     STATUS_STRING(INTERNET_STATUS_INTERMEDIATE_RESPONSE);
7732     STATUS_STRING(INTERNET_STATUS_USER_INPUT_REQUIRED);
7733     STATUS_STRING(INTERNET_STATUS_STATE_CHANGE);
7734     STATUS_STRING(INTERNET_STATUS_COOKIE_SENT);
7735     STATUS_STRING(INTERNET_STATUS_COOKIE_RECEIVED);
7736     STATUS_STRING(INTERNET_STATUS_PRIVACY_IMPACTED);
7737     STATUS_STRING(INTERNET_STATUS_P3P_HEADER);
7738     STATUS_STRING(INTERNET_STATUS_P3P_POLICYREF);
7739     STATUS_STRING(INTERNET_STATUS_COOKIE_HISTORY);
7740 #undef STATUS_STRING
7741 }
7742 
7743 static void WINAPI header_cb( HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD len )
7744 {
7745     BOOL ret;
7746     DWORD index, size;
7747     char buf[256];
7748 
7749     if (status == INTERNET_STATUS_SENDING_REQUEST)
7750     {
7751         ret = HttpAddRequestHeadersA( handle, "winetest: winetest", ~0u, HTTP_ADDREQ_FLAG_ADD );
7752         ok( ret, "HttpAddRequestHeadersA failed %u\n", GetLastError() );
7753         SetEvent( (HANDLE)ctx );
7754     }
7755     else if (status == INTERNET_STATUS_REQUEST_SENT)
7756     {
7757         index = 0;
7758         size = sizeof(buf);
7759         ret = HttpQueryInfoA( handle, HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
7760                               buf, &size, &index );
7761         ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
7762         ok( strstr( buf, "winetest: winetest" ) != NULL, "header missing\n" );
7763         SetEvent( (HANDLE)ctx );
7764     }
7765 }
7766 
7767 static void test_concurrent_header_access(void)
7768 {
7769     HINTERNET ses, con, req;
7770     DWORD err;
7771     BOOL ret;
7772     HANDLE wait = CreateEventW( NULL, FALSE, FALSE, NULL );
7773 
7774     ses = InternetOpenA( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC );
7775     ok( ses != NULL, "InternetOpenA failed\n" );
7776 
7777     con = InternetConnectA( ses, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
7778                             INTERNET_SERVICE_HTTP, 0, 0 );
7779     ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
7780 
7781     req = HttpOpenRequestA( con, NULL, "/", NULL, NULL, NULL, 0, (DWORD_PTR)wait );
7782     ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
7783 
7784     pInternetSetStatusCallbackA( req, header_cb );
7785 
7786     SetLastError( 0xdeadbeef );
7787     ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
7788     err = GetLastError();
7789     ok( !ret, "HttpSendRequestA succeeded\n" );
7790     ok( err == ERROR_IO_PENDING, "got %u\n", ERROR_IO_PENDING );
7791 
7792     WaitForSingleObject( wait, 5000 );
7793     WaitForSingleObject( wait, 5000 );
7794 
7795     InternetCloseHandle( req );
7796     InternetCloseHandle( con );
7797     InternetCloseHandle( ses );
7798     CloseHandle( wait );
7799 }
7800 
7801 START_TEST(http)
7802 {
7803     HMODULE hdll;
7804     hdll = GetModuleHandleA("wininet.dll");
7805 
7806     if(!GetProcAddress(hdll, "InternetGetCookieExW")) {
7807         win_skip("Too old IE (older than 6.0)\n");
7808         return;
7809     }
7810 
7811     pInternetSetStatusCallbackA = (void*)GetProcAddress(hdll, "InternetSetStatusCallbackA");
7812     pInternetSetStatusCallbackW = (void*)GetProcAddress(hdll, "InternetSetStatusCallbackW");
7813     pInternetGetSecurityInfoByURLA = (void*)GetProcAddress(hdll, "InternetGetSecurityInfoByURLA");
7814 
7815     if(!pInternetGetSecurityInfoByURLA) {
7816         is_ie7plus = FALSE;
7817         win_skip("IE6 found. It's too old for some tests.\n");
7818     }
7819 
7820     init_events();
7821     init_status_tests();
7822     test_InternetCloseHandle();
7823     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[0]);
7824     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[1]);
7825     InternetReadFile_test(0, &test_data[1]);
7826     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[2]);
7827     test_security_flags();
7828     InternetReadFile_test(0, &test_data[2]);
7829     InternetReadFileExA_test(INTERNET_FLAG_ASYNC);
7830     test_open_url_async();
7831     test_async_HttpSendRequestEx(&notification_data[0]);
7832     test_async_HttpSendRequestEx(&notification_data[1]);
7833     test_async_HttpSendRequestEx(&notification_data[2]);
7834     test_async_HttpSendRequestEx(&notification_data[3]);
7835     InternetOpenRequest_test();
7836     test_http_cache();
7837     InternetLockRequestFile_test();
7838     InternetOpenUrlA_test();
7839     HttpHeaders_test();
7840     test_http_connection();
7841     test_secure_connection();
7842     test_user_agent_header();
7843     test_bogus_accept_types_array();
7844     InternetReadFile_chunked_test();
7845     HttpSendRequestEx_test();
7846     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[3]);
7847     test_connection_failure();
7848     test_default_service_port();
7849     test_concurrent_header_access();
7850     free_events();
7851 }
7852