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