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