d3drm: Implement IDirect3DRMMesh_AddGroup.
[wine] / dlls / wininet / tests / http.c
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 "winsock.h"
31
32 #include "wine/test.h"
33
34 #define TEST_URL "http://test.winehq.org/tests/hello.html"
35
36 static BOOL first_connection_to_test_url = TRUE;
37
38 /* Adapted from dlls/urlmon/tests/protocol.c */
39
40 #define SET_EXPECT2(status, num) \
41     expect[status] = num
42
43 #define SET_EXPECT(status) \
44     SET_EXPECT2(status, 1)
45
46 #define SET_OPTIONAL2(status, num) \
47     optional[status] = num
48
49 #define SET_OPTIONAL(status) \
50     SET_OPTIONAL2(status, 1)
51
52 /* SET_WINE_ALLOW's should be used with an appropriate
53  * todo_wine CHECK_NOTIFIED at a later point in the code */
54 #define SET_WINE_ALLOW2(status, num) \
55     wine_allow[status] = num
56
57 #define SET_WINE_ALLOW(status) \
58     SET_WINE_ALLOW2(status, 1)
59
60 #define CHECK_EXPECT(status) \
61     do { \
62         if (!expect[status] && !optional[status] && wine_allow[status]) \
63         { \
64             todo_wine ok(expect[status], "unexpected status %d (%s)\n", status, \
65                          status < MAX_INTERNET_STATUS && status_string[status] ? \
66                          status_string[status] : "unknown");            \
67             wine_allow[status]--; \
68         } \
69         else \
70         { \
71             ok(expect[status] || optional[status], "unexpected status %d (%s)\n", status,   \
72                status < MAX_INTERNET_STATUS && status_string[status] ? \
73                status_string[status] : "unknown");                      \
74             if (expect[status]) expect[status]--; \
75             else optional[status]--; \
76         } \
77         notified[status]++; \
78     }while(0)
79
80 /* CLEAR_NOTIFIED used in cases when notification behavior
81  * differs between Windows versions */
82 #define CLEAR_NOTIFIED(status) \
83     expect[status] = optional[status] = wine_allow[status] = notified[status] = 0;
84
85 #define CHECK_NOTIFIED2(status, num) \
86     do { \
87         ok(notified[status] + optional[status] == (num), \
88            "expected status %d (%s) %d times, received %d times\n", \
89            status, status < MAX_INTERNET_STATUS && status_string[status] ? \
90            status_string[status] : "unknown", (num), notified[status]); \
91         CLEAR_NOTIFIED(status);                                         \
92     }while(0)
93
94 #define CHECK_NOTIFIED(status) \
95     CHECK_NOTIFIED2(status, 1)
96
97 #define CHECK_NOT_NOTIFIED(status) \
98     CHECK_NOTIFIED2(status, 0)
99
100 #define MAX_INTERNET_STATUS (INTERNET_STATUS_COOKIE_HISTORY+1)
101 static int expect[MAX_INTERNET_STATUS], optional[MAX_INTERNET_STATUS],
102     wine_allow[MAX_INTERNET_STATUS], notified[MAX_INTERNET_STATUS];
103 static const char *status_string[MAX_INTERNET_STATUS];
104
105 static HANDLE hCompleteEvent, conn_close_event;
106 static DWORD req_error;
107
108 #define TESTF_REDIRECT      0x01
109 #define TESTF_COMPRESSED    0x02
110 #define TESTF_CHUNKED       0x04
111
112 typedef struct {
113     const char *url;
114     const char *redirected_url;
115     const char *host;
116     const char *path;
117     const char *headers;
118     DWORD flags;
119     const char *post_data;
120     const char *content;
121 } test_data_t;
122
123 static const test_data_t test_data[] = {
124     {
125         "http://test.winehq.org/tests/data.php",
126         "http://test.winehq.org/tests/data.php",
127         "test.winehq.org",
128         "/tests/data.php",
129         "",
130         TESTF_CHUNKED
131     },
132     {
133         "http://test.winehq.org/tests/redirect",
134         "http://test.winehq.org/tests/hello.html",
135         "test.winehq.org",
136         "/tests/redirect",
137         "",
138         TESTF_REDIRECT
139     },
140     {
141         "http://www.codeweavers.com/",
142         "http://www.codeweavers.com/",
143         "www.codeweavers.com",
144         "",
145         "Accept-Encoding: gzip, deflate",
146         TESTF_COMPRESSED
147     },
148     {
149         "http://test.winehq.org/tests/post.php",
150         "http://test.winehq.org/tests/post.php",
151         "test.winehq.org",
152         "/tests/post.php",
153         "Content-Type: application/x-www-form-urlencoded",
154         0,
155         "mode=Test",
156         "mode => Test\n"
157     }
158 };
159
160 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET ,INTERNET_STATUS_CALLBACK);
161
162 static BOOL proxy_active(void)
163 {
164     HKEY internet_settings;
165     DWORD proxy_enable;
166     DWORD size;
167
168     if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
169                       0, KEY_QUERY_VALUE, &internet_settings) != ERROR_SUCCESS)
170         return FALSE;
171
172     size = sizeof(DWORD);
173     if (RegQueryValueExA(internet_settings, "ProxyEnable", NULL, NULL, (LPBYTE) &proxy_enable, &size) != ERROR_SUCCESS)
174         proxy_enable = 0;
175
176     RegCloseKey(internet_settings);
177
178     return proxy_enable != 0;
179 }
180
181 #define test_status_code(a,b) _test_status_code(__LINE__,a,b)
182 static void _test_status_code(unsigned line, HINTERNET req, DWORD excode)
183 {
184     DWORD code, size, index;
185     char exbuf[10], bufa[10];
186     BOOL res;
187
188     code = 0xdeadbeef;
189     size = sizeof(code);
190     res = HttpQueryInfo(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, NULL);
191     ok_(__FILE__,line)(res, "HttpQueryInfo(HTTP_QUERY_STATUS_CODE|number) failed: %u\n", GetLastError());
192     ok_(__FILE__,line)(code == excode, "code = %d, expected %d\n", code, excode);
193
194     code = 0xdeadbeef;
195     index = 0;
196     size = sizeof(code);
197     res = HttpQueryInfo(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, &index);
198     ok_(__FILE__,line)(res, "HttpQueryInfo(HTTP_QUERY_STATUS_CODE|number index) failed: %u\n", GetLastError());
199     ok_(__FILE__,line)(code == excode, "code = %d, expected %d\n", code, excode);
200     ok_(__FILE__,line)(!index, "index = %d, expected 0\n", code);
201
202     sprintf(exbuf, "%u", excode);
203
204     size = sizeof(bufa);
205     res = HttpQueryInfo(req, HTTP_QUERY_STATUS_CODE, bufa, &size, NULL);
206     ok_(__FILE__,line)(res, "HttpQueryInfo(HTTP_QUERY_STATUS_CODE) failed: %u\n", GetLastError());
207     ok_(__FILE__,line)(!strcmp(bufa, exbuf), "unexpected status code %s, expected %s", bufa, exbuf);
208
209     code = 0xdeadbeef;
210     index = 1;
211     size = sizeof(code);
212     res = HttpQueryInfo(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &code, &size, &index);
213     ok_(__FILE__,line)(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
214                        "[invalid 1] HttpQueryInfo failed: %x(%d)\n", res, GetLastError());
215
216     code = 0xdeadbeef;
217     size = sizeof(code);
218     res = HttpQueryInfo(req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_REQUEST_HEADERS, &code, &size, NULL);
219     ok_(__FILE__,line)(!res && GetLastError() == ERROR_HTTP_INVALID_QUERY_REQUEST,
220                        "[invalid 2] HttpQueryInfo failed: %x(%d)\n", res, GetLastError());
221 }
222
223 static int close_handle_cnt;
224
225 static VOID WINAPI callback(
226      HINTERNET hInternet,
227      DWORD_PTR dwContext,
228      DWORD dwInternetStatus,
229      LPVOID lpvStatusInformation,
230      DWORD dwStatusInformationLength
231 )
232 {
233     CHECK_EXPECT(dwInternetStatus);
234     switch (dwInternetStatus)
235     {
236         case INTERNET_STATUS_RESOLVING_NAME:
237             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RESOLVING_NAME \"%s\" %d\n",
238                 GetCurrentThreadId(), hInternet, dwContext,
239                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
240             *(LPSTR)lpvStatusInformation = '\0';
241             break;
242         case INTERNET_STATUS_NAME_RESOLVED:
243             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_NAME_RESOLVED \"%s\" %d\n",
244                 GetCurrentThreadId(), hInternet, dwContext,
245                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
246             *(LPSTR)lpvStatusInformation = '\0';
247             break;
248         case INTERNET_STATUS_CONNECTING_TO_SERVER:
249             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTING_TO_SERVER \"%s\" %d\n",
250                 GetCurrentThreadId(), hInternet, dwContext,
251                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
252             *(LPSTR)lpvStatusInformation = '\0';
253             break;
254         case INTERNET_STATUS_CONNECTED_TO_SERVER:
255             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTED_TO_SERVER \"%s\" %d\n",
256                 GetCurrentThreadId(), hInternet, dwContext,
257                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
258             *(LPSTR)lpvStatusInformation = '\0';
259             break;
260         case INTERNET_STATUS_SENDING_REQUEST:
261             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_SENDING_REQUEST %p %d\n",
262                 GetCurrentThreadId(), hInternet, dwContext,
263                 lpvStatusInformation,dwStatusInformationLength);
264             break;
265         case INTERNET_STATUS_REQUEST_SENT:
266             ok(dwStatusInformationLength == sizeof(DWORD),
267                 "info length should be sizeof(DWORD) instead of %d\n",
268                 dwStatusInformationLength);
269             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REQUEST_SENT 0x%x %d\n",
270                 GetCurrentThreadId(), hInternet, dwContext,
271                 *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
272             break;
273         case INTERNET_STATUS_RECEIVING_RESPONSE:
274             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RECEIVING_RESPONSE %p %d\n",
275                 GetCurrentThreadId(), hInternet, dwContext,
276                 lpvStatusInformation,dwStatusInformationLength);
277             break;
278         case INTERNET_STATUS_RESPONSE_RECEIVED:
279             ok(dwStatusInformationLength == sizeof(DWORD),
280                 "info length should be sizeof(DWORD) instead of %d\n",
281                 dwStatusInformationLength);
282             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_RESPONSE_RECEIVED 0x%x %d\n",
283                 GetCurrentThreadId(), hInternet, dwContext,
284                 *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
285             break;
286         case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
287             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CTL_RESPONSE_RECEIVED %p %d\n",
288                 GetCurrentThreadId(), hInternet,dwContext,
289                 lpvStatusInformation,dwStatusInformationLength);
290             break;
291         case INTERNET_STATUS_PREFETCH:
292             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_PREFETCH %p %d\n",
293                 GetCurrentThreadId(), hInternet, dwContext,
294                 lpvStatusInformation,dwStatusInformationLength);
295             break;
296         case INTERNET_STATUS_CLOSING_CONNECTION:
297             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CLOSING_CONNECTION %p %d\n",
298                 GetCurrentThreadId(), hInternet, dwContext,
299                 lpvStatusInformation,dwStatusInformationLength);
300             break;
301         case INTERNET_STATUS_CONNECTION_CLOSED:
302             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_CONNECTION_CLOSED %p %d\n",
303                 GetCurrentThreadId(), hInternet, dwContext,
304                 lpvStatusInformation,dwStatusInformationLength);
305             break;
306         case INTERNET_STATUS_HANDLE_CREATED:
307             ok(dwStatusInformationLength == sizeof(HINTERNET),
308                 "info length should be sizeof(HINTERNET) instead of %d\n",
309                 dwStatusInformationLength);
310             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CREATED %p %d\n",
311                 GetCurrentThreadId(), hInternet, dwContext,
312                 *(HINTERNET *)lpvStatusInformation,dwStatusInformationLength);
313             CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
314             SET_EXPECT(INTERNET_STATUS_DETECTING_PROXY);
315             break;
316         case INTERNET_STATUS_HANDLE_CLOSING:
317             ok(dwStatusInformationLength == sizeof(HINTERNET),
318                 "info length should be sizeof(HINTERNET) instead of %d\n",
319                 dwStatusInformationLength);
320             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CLOSING %p %d\n",
321                 GetCurrentThreadId(), hInternet, dwContext,
322                 *(HINTERNET *)lpvStatusInformation, dwStatusInformationLength);
323             if(!--close_handle_cnt)
324                 SetEvent(hCompleteEvent);
325             break;
326         case INTERNET_STATUS_REQUEST_COMPLETE:
327         {
328             INTERNET_ASYNC_RESULT *iar = (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
329             ok(dwStatusInformationLength == sizeof(INTERNET_ASYNC_RESULT),
330                 "info length should be sizeof(INTERNET_ASYNC_RESULT) instead of %d\n",
331                 dwStatusInformationLength);
332             ok(iar->dwResult == 1 || iar->dwResult == 0, "iar->dwResult = %ld\n", iar->dwResult);
333             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REQUEST_COMPLETE {%ld,%d} %d\n",
334                 GetCurrentThreadId(), hInternet, dwContext,
335                 iar->dwResult,iar->dwError,dwStatusInformationLength);
336             req_error = iar->dwError;
337             SetEvent(hCompleteEvent);
338             break;
339         }
340         case INTERNET_STATUS_REDIRECT:
341             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_REDIRECT \"%s\" %d\n",
342                 GetCurrentThreadId(), hInternet, dwContext,
343                 (LPCSTR)lpvStatusInformation, dwStatusInformationLength);
344             *(LPSTR)lpvStatusInformation = '\0';
345             CLEAR_NOTIFIED(INTERNET_STATUS_DETECTING_PROXY);
346             SET_EXPECT(INTERNET_STATUS_DETECTING_PROXY);
347             break;
348         case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
349             trace("%04x:Callback %p 0x%lx INTERNET_STATUS_INTERMEDIATE_RESPONSE %p %d\n",
350                 GetCurrentThreadId(), hInternet, dwContext,
351                 lpvStatusInformation, dwStatusInformationLength);
352             break;
353         default:
354             trace("%04x:Callback %p 0x%lx %d %p %d\n",
355                 GetCurrentThreadId(), hInternet, dwContext, dwInternetStatus,
356                 lpvStatusInformation, dwStatusInformationLength);
357     }
358 }
359
360 static void close_async_handle(HINTERNET handle, HANDLE complete_event, int handle_cnt)
361 {
362     BOOL res;
363
364     close_handle_cnt = handle_cnt;
365
366     SET_EXPECT2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
367     res = InternetCloseHandle(handle);
368     ok(res, "InternetCloseHandle failed: %u\n", GetLastError());
369     WaitForSingleObject(hCompleteEvent, INFINITE);
370     CHECK_NOTIFIED2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
371     SET_EXPECT2(INTERNET_STATUS_HANDLE_CLOSING, handle_cnt);
372 }
373
374 static void InternetReadFile_test(int flags, const test_data_t *test)
375 {
376     char *post_data = NULL;
377     BOOL res, on_async = TRUE;
378     CHAR buffer[4000];
379     DWORD length, post_len = 0;
380     DWORD out;
381     const char *types[2] = { "*", NULL };
382     HINTERNET hi, hic = 0, hor = 0;
383
384     hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
385
386     trace("Starting InternetReadFile test with flags 0x%x on url %s\n",flags,test->url);
387
388     trace("InternetOpenA <--\n");
389     hi = InternetOpenA((test->flags & TESTF_COMPRESSED) ? "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" : "",
390             INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
391     ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
392     trace("InternetOpenA -->\n");
393
394     if (hi == 0x0) goto abort;
395
396     pInternetSetStatusCallbackA(hi,&callback);
397
398     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
399
400     trace("InternetConnectA <--\n");
401     hic=InternetConnectA(hi, test->host, INTERNET_INVALID_PORT_NUMBER,
402                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
403     ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
404     trace("InternetConnectA -->\n");
405
406     if (hic == 0x0) goto abort;
407
408     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
409     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
410
411     trace("HttpOpenRequestA <--\n");
412     hor = HttpOpenRequestA(hic, test->post_data ? "POST" : "GET", test->path, NULL, NULL, types,
413                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE,
414                            0xdeadbead);
415     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
416         /*
417          * If the internet name can't be resolved we are probably behind
418          * a firewall or in some other way not directly connected to the
419          * Internet. Not enough reason to fail the test. Just ignore and
420          * abort.
421          */
422     } else  {
423         ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
424     }
425     trace("HttpOpenRequestA -->\n");
426
427     if (hor == 0x0) goto abort;
428
429     length = sizeof(buffer);
430     res = InternetQueryOptionA(hor, INTERNET_OPTION_URL, buffer, &length);
431     ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
432     ok(!strcmp(buffer, test->url), "Wrong URL %s, expected %s\n", buffer, test->url);
433
434     length = sizeof(buffer);
435     res = HttpQueryInfoA(hor, HTTP_QUERY_RAW_HEADERS, buffer, &length, 0x0);
436     ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
437     ok(length == 0, "HTTP_QUERY_RAW_HEADERS: expected length 0, but got %d\n", length);
438     ok(!strcmp(buffer, ""), "HTTP_QUERY_RAW_HEADERS: expected string \"\", but got \"%s\"\n", buffer);
439
440     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
441     CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
442     CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
443     SET_OPTIONAL2(INTERNET_STATUS_COOKIE_SENT,2);
444     SET_OPTIONAL2(INTERNET_STATUS_COOKIE_RECEIVED,2);
445     if (first_connection_to_test_url)
446     {
447         SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
448         SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
449     }
450     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
451     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
452     SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1);
453     SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1);
454     SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1);
455     SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1);
456     if(test->flags & TESTF_REDIRECT) {
457         SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
458         SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
459     }
460     SET_EXPECT(INTERNET_STATUS_REDIRECT);
461     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER);
462     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER);
463     if (flags & INTERNET_FLAG_ASYNC)
464         SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
465
466     if(test->flags & TESTF_COMPRESSED) {
467         BOOL b = TRUE;
468
469         res = InternetSetOption(hor, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b));
470         ok(res || broken(!res && GetLastError() == ERROR_INTERNET_INVALID_OPTION),
471            "InternetSetOption failed: %u\n", GetLastError());
472         if(!res)
473             goto abort;
474     }
475
476     test_status_code(hor, 0);
477
478     trace("HttpSendRequestA -->\n");
479     if(test->post_data) {
480         post_len = strlen(test->post_data);
481         post_data = HeapAlloc(GetProcessHeap(), 0, post_len);
482         memcpy(post_data, test->post_data, post_len);
483     }
484     SetLastError(0xdeadbeef);
485     res = HttpSendRequestA(hor, test->headers, -1, post_data, post_len);
486     if (flags & INTERNET_FLAG_ASYNC)
487         ok(!res && (GetLastError() == ERROR_IO_PENDING),
488             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
489     else
490         ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED),
491            "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
492     trace("HttpSendRequestA <--\n");
493
494     if (flags & INTERNET_FLAG_ASYNC) {
495         WaitForSingleObject(hCompleteEvent, INFINITE);
496         ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
497     }
498     HeapFree(GetProcessHeap(), 0, post_data);
499
500     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
501     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_RECEIVED);
502     if (first_connection_to_test_url)
503     {
504         if (! proxy_active())
505         {
506             CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
507             CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
508         }
509         else
510         {
511             CLEAR_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
512             CLEAR_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
513         }
514     }
515     else
516     {
517         CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
518         CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
519     }
520     CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, (test->flags & TESTF_REDIRECT) ? 2 : 1);
521     CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, (test->flags & TESTF_REDIRECT) ? 2 : 1);
522     CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, (test->flags & TESTF_REDIRECT) ? 2 : 1);
523     CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, (test->flags & TESTF_REDIRECT) ? 2 : 1);
524     if(test->flags & TESTF_REDIRECT)
525         CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
526     if (flags & INTERNET_FLAG_ASYNC)
527         CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
528     /* Sent on WinXP only if first_connection_to_test_url is TRUE, on Win98 always sent */
529     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
530     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
531
532     length = 4;
533     res = InternetQueryOptionA(hor,INTERNET_OPTION_REQUEST_FLAGS,&out,&length);
534     ok(res, "InternetQueryOptionA(INTERNET_OPTION_REQUEST) failed with error %d\n", GetLastError());
535
536     length = 100;
537     res = InternetQueryOptionA(hor,INTERNET_OPTION_URL,buffer,&length);
538     ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed with error %d\n", GetLastError());
539
540     length = sizeof(buffer);
541     res = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length,0x0);
542     ok(res, "HttpQueryInfoA(HTTP_QUERY_RAW_HEADERS) failed with error %d\n", GetLastError());
543     buffer[length]=0;
544
545     length = sizeof(buffer);
546     res = InternetQueryOptionA(hor, INTERNET_OPTION_URL, buffer, &length);
547     ok(res, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
548     ok(!strcmp(buffer, test->redirected_url), "Wrong URL %s\n", buffer);
549
550     length = 16;
551     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0);
552     trace("Option HTTP_QUERY_CONTENT_LENGTH -> %i  %s  (%u)\n",res,buffer,GetLastError());
553     if(test->flags & TESTF_COMPRESSED)
554         ok(!res && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND,
555            "expected ERROR_HTTP_HEADER_NOT_FOUND, got %x (%u)\n", res, GetLastError());
556
557     length = 100;
558     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
559     buffer[length]=0;
560     trace("Option HTTP_QUERY_CONTENT_TYPE -> %i  %s\n",res,buffer);
561
562     length = 100;
563     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_ENCODING,buffer,&length,0x0);
564     buffer[length]=0;
565     trace("Option HTTP_QUERY_CONTENT_ENCODING -> %i  %s\n",res,buffer);
566
567     SetLastError(0xdeadbeef);
568     res = InternetReadFile(NULL, buffer, 100, &length);
569     ok(!res, "InternetReadFile should have failed\n");
570     ok(GetLastError() == ERROR_INVALID_HANDLE,
571         "InternetReadFile should have set last error to ERROR_INVALID_HANDLE instead of %u\n",
572         GetLastError());
573
574     length = 100;
575     trace("Entering Query loop\n");
576
577     while (TRUE)
578     {
579         if (flags & INTERNET_FLAG_ASYNC)
580             SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
581         res = InternetQueryDataAvailable(hor,&length,0x0,0x0);
582         if (flags & INTERNET_FLAG_ASYNC)
583         {
584             if (res)
585             {
586                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
587             }
588             else if (GetLastError() == ERROR_IO_PENDING)
589             {
590                 trace("PENDING\n");
591                 /* on some tests, InternetQueryDataAvailable returns non-zero length and ERROR_IO_PENDING */
592                 if(!(test->flags & TESTF_CHUNKED))
593                     ok(!length, "InternetQueryDataAvailable returned ERROR_IO_PENDING and %u length\n", length);
594                 WaitForSingleObject(hCompleteEvent, INFINITE);
595                 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
596                 ok(req_error, "req_error = 0\n");
597                 continue;
598             }else {
599                 ok(0, "InternetQueryDataAvailable failed: %u\n", GetLastError());
600             }
601         }else {
602             ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
603         }
604         trace("LENGTH %d\n", length);
605         if(test->flags & TESTF_CHUNKED)
606             ok(length <= 8192, "length = %d, expected <= 8192\n", length);
607         if (length)
608         {
609             char *buffer;
610             buffer = HeapAlloc(GetProcessHeap(),0,length+1);
611
612             res = InternetReadFile(hor,buffer,length,&length);
613
614             buffer[length]=0;
615
616             trace("ReadFile -> %s %i\n",res?"TRUE":"FALSE",length);
617
618             if(test->content)
619                 ok(!strcmp(buffer, test->content), "buffer = '%s', expected '%s'\n", buffer, test->content);
620             HeapFree(GetProcessHeap(),0,buffer);
621         }else {
622             ok(!on_async, "Returned zero size in response to request complete\n");
623             break;
624         }
625         on_async = FALSE;
626     }
627     if(test->flags & TESTF_REDIRECT) {
628         CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
629         CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
630     }
631 abort:
632     trace("aborting\n");
633     close_async_handle(hi, hCompleteEvent, 2);
634     CloseHandle(hCompleteEvent);
635     first_connection_to_test_url = FALSE;
636 }
637
638 static void InternetReadFile_chunked_test(void)
639 {
640     BOOL res;
641     CHAR buffer[4000];
642     DWORD length;
643     const char *types[2] = { "*", NULL };
644     HINTERNET hi, hic = 0, hor = 0;
645
646     trace("Starting InternetReadFile chunked test\n");
647
648     trace("InternetOpenA <--\n");
649     hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
650     ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
651     trace("InternetOpenA -->\n");
652
653     if (hi == 0x0) goto abort;
654
655     trace("InternetConnectA <--\n");
656     hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER,
657                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
658     ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
659     trace("InternetConnectA -->\n");
660
661     if (hic == 0x0) goto abort;
662
663     trace("HttpOpenRequestA <--\n");
664     hor = HttpOpenRequestA(hic, "GET", "/tests/chunked", NULL, NULL, types,
665                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE,
666                            0xdeadbead);
667     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
668         /*
669          * If the internet name can't be resolved we are probably behind
670          * a firewall or in some other way not directly connected to the
671          * Internet. Not enough reason to fail the test. Just ignore and
672          * abort.
673          */
674     } else  {
675         ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
676     }
677     trace("HttpOpenRequestA -->\n");
678
679     if (hor == 0x0) goto abort;
680
681     trace("HttpSendRequestA -->\n");
682     SetLastError(0xdeadbeef);
683     res = HttpSendRequestA(hor, "", -1, NULL, 0);
684     ok(res || (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED),
685        "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
686     trace("HttpSendRequestA <--\n");
687
688     length = 100;
689     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
690     buffer[length]=0;
691     trace("Option CONTENT_TYPE -> %i  %s\n",res,buffer);
692
693     SetLastError( 0xdeadbeef );
694     length = 100;
695     res = HttpQueryInfoA(hor,HTTP_QUERY_TRANSFER_ENCODING,buffer,&length,0x0);
696     buffer[length]=0;
697     trace("Option TRANSFER_ENCODING -> %i  %s\n",res,buffer);
698     ok( res || ( proxy_active() && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND ),
699         "Failed to get TRANSFER_ENCODING option, error %u\n", GetLastError() );
700     ok( !strcmp( buffer, "chunked" ) || ( ! res && proxy_active() && GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND ),
701         "Wrong transfer encoding '%s'\n", buffer );
702
703     SetLastError( 0xdeadbeef );
704     length = 16;
705     res = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0);
706     ok( !res, "Found CONTENT_LENGTH option '%s'\n", buffer );
707     ok( GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "Wrong error %u\n", GetLastError() );
708
709     length = 100;
710     trace("Entering Query loop\n");
711
712     while (TRUE)
713     {
714         res = InternetQueryDataAvailable(hor,&length,0x0,0x0);
715         ok(!(!res && length != 0),"InternetQueryDataAvailable failed with non-zero length\n");
716         ok(res, "InternetQueryDataAvailable failed, error %d\n", GetLastError());
717         trace("got %u available\n",length);
718         if (length)
719         {
720             DWORD got;
721             char *buffer = HeapAlloc(GetProcessHeap(),0,length+1);
722
723             res = InternetReadFile(hor,buffer,length,&got);
724
725             buffer[got]=0;
726             trace("ReadFile -> %i %i\n",res,got);
727             ok( length == got, "only got %u of %u available\n", got, length );
728             ok( buffer[got-1] == '\n', "received partial line '%s'\n", buffer );
729
730             HeapFree(GetProcessHeap(),0,buffer);
731             if (!got) break;
732         }
733         if (length == 0)
734             break;
735     }
736 abort:
737     trace("aborting\n");
738     if (hor != 0x0) {
739         res = InternetCloseHandle(hor);
740         ok (res, "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n");
741     }
742     if (hi != 0x0) {
743         res = InternetCloseHandle(hi);
744         ok (res, "InternetCloseHandle of handle opened by InternetOpenA failed\n");
745     }
746 }
747
748 static void InternetReadFileExA_test(int flags)
749 {
750     DWORD rc;
751     DWORD length;
752     const char *types[2] = { "*", NULL };
753     HINTERNET hi, hic = 0, hor = 0;
754     INTERNET_BUFFERS inetbuffers;
755
756     hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
757
758     trace("Starting InternetReadFileExA test with flags 0x%x\n",flags);
759
760     trace("InternetOpenA <--\n");
761     hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
762     ok((hi != 0x0),"InternetOpen failed with error %u\n", GetLastError());
763     trace("InternetOpenA -->\n");
764
765     if (hi == 0x0) goto abort;
766
767     pInternetSetStatusCallbackA(hi,&callback);
768
769     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
770
771     trace("InternetConnectA <--\n");
772     hic=InternetConnectA(hi, "test.winehq.org", INTERNET_INVALID_PORT_NUMBER,
773                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
774     ok((hic != 0x0),"InternetConnect failed with error %u\n", GetLastError());
775     trace("InternetConnectA -->\n");
776
777     if (hic == 0x0) goto abort;
778
779     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
780     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
781
782     trace("HttpOpenRequestA <--\n");
783     hor = HttpOpenRequestA(hic, "GET", "/tests/redirect", NULL, NULL, types,
784                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE,
785                            0xdeadbead);
786     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
787         /*
788          * If the internet name can't be resolved we are probably behind
789          * a firewall or in some other way not directly connected to the
790          * Internet. Not enough reason to fail the test. Just ignore and
791          * abort.
792          */
793     } else  {
794         ok((hor != 0x0),"HttpOpenRequest failed with error %u\n", GetLastError());
795     }
796     trace("HttpOpenRequestA -->\n");
797
798     if (hor == 0x0) goto abort;
799
800     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
801     CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
802     CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
803     if (first_connection_to_test_url)
804     {
805         SET_EXPECT(INTERNET_STATUS_RESOLVING_NAME);
806         SET_EXPECT(INTERNET_STATUS_NAME_RESOLVED);
807     }
808     SET_OPTIONAL2(INTERNET_STATUS_COOKIE_SENT, 2);
809     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
810     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
811     SET_EXPECT2(INTERNET_STATUS_SENDING_REQUEST, 2);
812     SET_EXPECT2(INTERNET_STATUS_REQUEST_SENT, 2);
813     SET_EXPECT2(INTERNET_STATUS_RECEIVING_RESPONSE, 2);
814     SET_EXPECT2(INTERNET_STATUS_RESPONSE_RECEIVED, 2);
815     SET_OPTIONAL2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
816     SET_OPTIONAL2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
817     SET_EXPECT(INTERNET_STATUS_REDIRECT);
818     SET_OPTIONAL(INTERNET_STATUS_CONNECTING_TO_SERVER);
819     SET_OPTIONAL(INTERNET_STATUS_CONNECTED_TO_SERVER);
820     if (flags & INTERNET_FLAG_ASYNC)
821         SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
822     else
823         SET_WINE_ALLOW(INTERNET_STATUS_REQUEST_COMPLETE);
824
825     trace("HttpSendRequestA -->\n");
826     SetLastError(0xdeadbeef);
827     rc = HttpSendRequestA(hor, "", -1, NULL, 0);
828     if (flags & INTERNET_FLAG_ASYNC)
829         ok(((rc == 0)&&(GetLastError() == ERROR_IO_PENDING)),
830             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
831     else
832         ok((rc != 0) || GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED,
833            "Synchronous HttpSendRequest returning 0, error %u\n", GetLastError());
834     trace("HttpSendRequestA <--\n");
835
836     if (!rc && (GetLastError() == ERROR_IO_PENDING)) {
837         WaitForSingleObject(hCompleteEvent, INFINITE);
838         ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
839     }
840
841     if (first_connection_to_test_url)
842     {
843         CHECK_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
844         CHECK_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
845     }
846     else
847     {
848         CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESOLVING_NAME);
849         CHECK_NOT_NOTIFIED(INTERNET_STATUS_NAME_RESOLVED);
850     }
851     CHECK_NOTIFIED2(INTERNET_STATUS_SENDING_REQUEST, 2);
852     CHECK_NOTIFIED2(INTERNET_STATUS_REQUEST_SENT, 2);
853     CHECK_NOTIFIED2(INTERNET_STATUS_RECEIVING_RESPONSE, 2);
854     CHECK_NOTIFIED2(INTERNET_STATUS_RESPONSE_RECEIVED, 2);
855     CHECK_NOTIFIED2(INTERNET_STATUS_CLOSING_CONNECTION, 2);
856     CHECK_NOTIFIED2(INTERNET_STATUS_CONNECTION_CLOSED, 2);
857     CHECK_NOTIFIED(INTERNET_STATUS_REDIRECT);
858     if (flags & INTERNET_FLAG_ASYNC)
859         CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
860     else
861         todo_wine CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
862     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
863     /* Sent on WinXP only if first_connection_to_test_url is TRUE, on Win98 always sent */
864     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
865     CLEAR_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
866
867     /* tests invalid dwStructSize */
868     inetbuffers.dwStructSize = sizeof(INTERNET_BUFFERS)+1;
869     inetbuffers.lpcszHeader = NULL;
870     inetbuffers.dwHeadersLength = 0;
871     inetbuffers.dwBufferLength = 10;
872     inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, 10);
873     inetbuffers.dwOffsetHigh = 1234;
874     inetbuffers.dwOffsetLow = 5678;
875     rc = InternetReadFileEx(hor, &inetbuffers, 0, 0xdeadcafe);
876     ok(!rc && (GetLastError() == ERROR_INVALID_PARAMETER),
877         "InternetReadFileEx should have failed with ERROR_INVALID_PARAMETER instead of %s, %u\n",
878         rc ? "TRUE" : "FALSE", GetLastError());
879     HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
880
881     /* tests to see whether lpcszHeader is used - it isn't */
882     inetbuffers.dwStructSize = sizeof(INTERNET_BUFFERS);
883     inetbuffers.lpcszHeader = (LPCTSTR)0xdeadbeef;
884     inetbuffers.dwHeadersLength = 255;
885     inetbuffers.dwBufferLength = 0;
886     inetbuffers.lpvBuffer = NULL;
887     inetbuffers.dwOffsetHigh = 1234;
888     inetbuffers.dwOffsetLow = 5678;
889     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
890     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
891     rc = InternetReadFileEx(hor, &inetbuffers, 0, 0xdeadcafe);
892     ok(rc, "InternetReadFileEx failed with error %u\n", GetLastError());
893     trace("read %i bytes\n", inetbuffers.dwBufferLength);
894     todo_wine
895     {
896         CHECK_NOT_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
897         CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
898     }
899
900     rc = InternetReadFileEx(NULL, &inetbuffers, 0, 0xdeadcafe);
901     ok(!rc && (GetLastError() == ERROR_INVALID_HANDLE),
902         "InternetReadFileEx should have failed with ERROR_INVALID_HANDLE instead of %s, %u\n",
903         rc ? "TRUE" : "FALSE", GetLastError());
904
905     length = 0;
906     trace("Entering Query loop\n");
907
908     while (TRUE)
909     {
910         inetbuffers.dwStructSize = sizeof(INTERNET_BUFFERS);
911         inetbuffers.dwBufferLength = 1024;
912         inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, inetbuffers.dwBufferLength+1);
913         inetbuffers.dwOffsetHigh = 1234;
914         inetbuffers.dwOffsetLow = 5678;
915
916         SET_WINE_ALLOW(INTERNET_STATUS_RECEIVING_RESPONSE);
917         SET_WINE_ALLOW(INTERNET_STATUS_RESPONSE_RECEIVED);
918         SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
919         rc = InternetReadFileExA(hor, &inetbuffers, IRF_ASYNC | IRF_USE_CONTEXT, 0xcafebabe);
920         if (!rc)
921         {
922             if (GetLastError() == ERROR_IO_PENDING)
923             {
924                 trace("InternetReadFileEx -> PENDING\n");
925                 ok(flags & INTERNET_FLAG_ASYNC,
926                    "Should not get ERROR_IO_PENDING without INTERNET_FLAG_ASYNC\n");
927                 CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
928                 WaitForSingleObject(hCompleteEvent, INFINITE);
929                 CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
930                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
931                 ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
932             }
933             else
934             {
935                 trace("InternetReadFileEx -> FAILED %u\n", GetLastError());
936                 break;
937             }
938         }
939         else
940         {
941             trace("InternetReadFileEx -> SUCCEEDED\n");
942             CHECK_NOT_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
943             if (inetbuffers.dwBufferLength)
944             {
945                 todo_wine {
946                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
947                 CHECK_NOT_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
948                 }
949             }
950             else
951             {
952                 /* Win98 still sends these when 0 bytes are read, WinXP does not */
953                 CLEAR_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
954                 CLEAR_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
955             }
956         }
957
958         trace("read %i bytes\n", inetbuffers.dwBufferLength);
959         ((char *)inetbuffers.lpvBuffer)[inetbuffers.dwBufferLength] = '\0';
960
961         ok(inetbuffers.dwOffsetHigh == 1234 && inetbuffers.dwOffsetLow == 5678,
962             "InternetReadFileEx sets offsets to 0x%x%08x\n",
963             inetbuffers.dwOffsetHigh, inetbuffers.dwOffsetLow);
964
965         HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
966
967         if (!inetbuffers.dwBufferLength)
968             break;
969
970         length += inetbuffers.dwBufferLength;
971     }
972     ok(length > 0, "failed to read any of the document\n");
973     trace("Finished. Read %d bytes\n", length);
974
975 abort:
976     close_async_handle(hi, hCompleteEvent, 2);
977     CloseHandle(hCompleteEvent);
978     first_connection_to_test_url = FALSE;
979 }
980
981 static void InternetOpenUrlA_test(void)
982 {
983   HINTERNET myhinternet, myhttp;
984   char buffer[0x400];
985   DWORD size, readbytes, totalbytes=0;
986   BOOL ret;
987
988   myhinternet = InternetOpen("Winetest",0,NULL,NULL,INTERNET_FLAG_NO_CACHE_WRITE);
989   ok((myhinternet != 0), "InternetOpen failed, error %u\n",GetLastError());
990   size = 0x400;
991   ret = InternetCanonicalizeUrl(TEST_URL, buffer, &size,ICU_BROWSER_MODE);
992   ok( ret, "InternetCanonicalizeUrl failed, error %u\n",GetLastError());
993
994   SetLastError(0);
995   myhttp = InternetOpenUrl(myhinternet, TEST_URL, 0, 0,
996                            INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_TRANSFER_BINARY,0);
997   if (GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
998     return; /* WinXP returns this when not connected to the net */
999   ok((myhttp != 0),"InternetOpenUrl failed, error %u\n",GetLastError());
1000   ret = InternetReadFile(myhttp, buffer,0x400,&readbytes);
1001   ok( ret, "InternetReadFile failed, error %u\n",GetLastError());
1002   totalbytes += readbytes;
1003   while (readbytes && InternetReadFile(myhttp, buffer,0x400,&readbytes))
1004     totalbytes += readbytes;
1005   trace("read 0x%08x bytes\n",totalbytes);
1006
1007   InternetCloseHandle(myhttp);
1008   InternetCloseHandle(myhinternet);
1009 }
1010
1011 static void HttpSendRequestEx_test(void)
1012 {
1013     HINTERNET hSession;
1014     HINTERNET hConnect;
1015     HINTERNET hRequest;
1016
1017     INTERNET_BUFFERS BufferIn;
1018     DWORD dwBytesWritten, dwBytesRead, error;
1019     CHAR szBuffer[256];
1020     int i;
1021     BOOL ret;
1022
1023     static char szPostData[] = "mode=Test";
1024     static const char szContentType[] = "Content-Type: application/x-www-form-urlencoded";
1025
1026     hSession = InternetOpen("Wine Regression Test",
1027             INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1028     ok( hSession != NULL ,"Unable to open Internet session\n");
1029     hConnect = InternetConnect(hSession, "crossover.codeweavers.com",
1030             INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1031             0);
1032     ok( hConnect != NULL, "Unable to connect to http://crossover.codeweavers.com\n");
1033     hRequest = HttpOpenRequest(hConnect, "POST", "/posttest.php",
1034             NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1035     if (!hRequest && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1036     {
1037         skip( "Network unreachable, skipping test\n" );
1038         goto done;
1039     }
1040     ok( hRequest != NULL, "Failed to open request handle err %u\n", GetLastError());
1041
1042
1043     BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS);
1044     BufferIn.Next = (LPINTERNET_BUFFERS)0xdeadcab;
1045     BufferIn.lpcszHeader = szContentType;
1046     BufferIn.dwHeadersLength = sizeof(szContentType)-1;
1047     BufferIn.dwHeadersTotal = sizeof(szContentType)-1;
1048     BufferIn.lpvBuffer = szPostData;
1049     BufferIn.dwBufferLength = 3;
1050     BufferIn.dwBufferTotal = sizeof(szPostData)-1;
1051     BufferIn.dwOffsetLow = 0;
1052     BufferIn.dwOffsetHigh = 0;
1053
1054     SetLastError(0xdeadbeef);
1055     ret = HttpSendRequestEx(hRequest, &BufferIn, NULL, 0 ,0);
1056     error = GetLastError();
1057     ok(ret, "HttpSendRequestEx Failed with error %u\n", error);
1058     ok(error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", error);
1059
1060     for (i = 3; szPostData[i]; i++)
1061         ok(InternetWriteFile(hRequest, &szPostData[i], 1, &dwBytesWritten),
1062                 "InternetWriteFile failed\n");
1063
1064     ok(HttpEndRequest(hRequest, NULL, 0, 0), "HttpEndRequest Failed\n");
1065
1066     ok(InternetReadFile(hRequest, szBuffer, 255, &dwBytesRead),
1067             "Unable to read response\n");
1068     szBuffer[dwBytesRead] = 0;
1069
1070     ok(dwBytesRead == 13,"Read %u bytes instead of 13\n",dwBytesRead);
1071     ok(strncmp(szBuffer,"mode => Test\n",dwBytesRead)==0 || broken(proxy_active()),"Got string %s\n",szBuffer);
1072
1073     ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
1074 done:
1075     ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
1076     ok(InternetCloseHandle(hSession), "Close session handle failed\n");
1077 }
1078
1079 static void InternetOpenRequest_test(void)
1080 {
1081     HINTERNET session, connect, request;
1082     static const char *types[] = { "*", "", NULL };
1083     static const WCHAR slash[] = {'/', 0}, any[] = {'*', 0}, empty[] = {0};
1084     static const WCHAR *typesW[] = { any, empty, NULL };
1085     BOOL ret;
1086
1087     session = InternetOpenA("Wine Regression Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1088     ok(session != NULL ,"Unable to open Internet session\n");
1089
1090     connect = InternetConnectA(session, NULL, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1091                               INTERNET_SERVICE_HTTP, 0, 0);
1092     ok(connect == NULL, "InternetConnectA should have failed\n");
1093     ok(GetLastError() == ERROR_INVALID_PARAMETER, "InternetConnectA with NULL server named should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
1094
1095     connect = InternetConnectA(session, "", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1096                               INTERNET_SERVICE_HTTP, 0, 0);
1097     ok(connect == NULL, "InternetConnectA should have failed\n");
1098     ok(GetLastError() == ERROR_INVALID_PARAMETER, "InternetConnectA with blank server named should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
1099
1100     connect = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1101                               INTERNET_SERVICE_HTTP, 0, 0);
1102     ok(connect != NULL, "Unable to connect to http://test.winehq.org with error %d\n", GetLastError());
1103
1104     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1105     if (!request && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1106     {
1107         skip( "Network unreachable, skipping test\n" );
1108         goto done;
1109     }
1110     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1111
1112     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
1113     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1114     ok(InternetCloseHandle(request), "Close request handle failed\n");
1115
1116     request = HttpOpenRequestW(connect, NULL, slash, NULL, NULL, typesW, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1117     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1118
1119     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
1120     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1121     ok(InternetCloseHandle(request), "Close request handle failed\n");
1122
1123 done:
1124     ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1125     ok(InternetCloseHandle(session), "Close session handle failed\n");
1126 }
1127
1128 static void test_http_cache(void)
1129 {
1130     HINTERNET session, connect, request;
1131     char file_name[MAX_PATH], url[INTERNET_MAX_URL_LENGTH];
1132     DWORD size, file_size;
1133     BYTE buf[100];
1134     HANDLE file;
1135     BOOL ret;
1136
1137     static const char *types[] = { "*", "", NULL };
1138
1139     session = InternetOpenA("Wine Regression Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1140     ok(session != NULL ,"Unable to open Internet session\n");
1141
1142     connect = InternetConnectA(session, "test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
1143                               INTERNET_SERVICE_HTTP, 0, 0);
1144     ok(connect != NULL, "Unable to connect to http://test.winehq.org with error %d\n", GetLastError());
1145
1146     request = HttpOpenRequestA(connect, NULL, "/tests/hello.html", NULL, NULL, types, INTERNET_FLAG_NEED_FILE, 0);
1147     if (!request && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1148     {
1149         skip( "Network unreachable, skipping test\n" );
1150
1151         ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1152         ok(InternetCloseHandle(session), "Close session handle failed\n");
1153
1154         return;
1155     }
1156     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1157
1158     size = sizeof(url);
1159     ret = InternetQueryOptionA(request, INTERNET_OPTION_URL, url, &size);
1160     ok(ret, "InternetQueryOptionA(INTERNET_OPTION_URL) failed: %u\n", GetLastError());
1161     ok(!strcmp(url, "http://test.winehq.org/tests/hello.html"), "Wrong URL %s\n", url);
1162
1163     size = sizeof(file_name);
1164     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1165     ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1166     ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1167     ok(!size, "size = %d\n", size);
1168
1169     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
1170     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1171
1172     size = sizeof(file_name);
1173     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1174     ok(ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) failed: %u\n", GetLastError());
1175
1176     file = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1177                       FILE_ATTRIBUTE_NORMAL, NULL);
1178     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1179     file_size = GetFileSize(file, NULL);
1180     todo_wine ok(file_size == 106, "file size = %u\n", file_size);
1181
1182     size = sizeof(buf);
1183     ret = InternetReadFile(request, buf, sizeof(buf), &size);
1184     ok(ret, "InternetReadFile failed: %u\n", GetLastError());
1185     ok(size == 100, "size = %u\n", size);
1186
1187     file_size = GetFileSize(file, NULL);
1188     todo_wine ok(file_size == 106, "file size = %u\n", file_size);
1189     CloseHandle(file);
1190
1191     ok(InternetCloseHandle(request), "Close request handle failed\n");
1192
1193     file = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1194                       FILE_ATTRIBUTE_NORMAL, NULL);
1195     ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1196     CloseHandle(file);
1197
1198     /* Send the same request, requiring it to be retrieved from the cache */
1199     request = HttpOpenRequest(connect, "GET", "/tests/hello.html", NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
1200
1201     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
1202     ok(ret, "HttpSendRequest failed\n");
1203
1204     size = sizeof(buf);
1205     ret = InternetReadFile(request, buf, sizeof(buf), &size);
1206     ok(ret, "InternetReadFile failed: %u\n", GetLastError());
1207     ok(size == 100, "size = %u\n", size);
1208
1209     ok(InternetCloseHandle(request), "Close request handle failed\n");
1210
1211     request = HttpOpenRequestA(connect, NULL, "/", NULL, NULL, types, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1212     ok(request != NULL, "Failed to open request handle err %u\n", GetLastError());
1213
1214     size = sizeof(file_name);
1215     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1216     ok(!ret, "InternetQueryOptionA(INTERNET_OPTION_DATAFILE_NAME) succeeded\n");
1217     ok(GetLastError() == ERROR_INTERNET_ITEM_NOT_FOUND, "GetLastError()=%u\n", GetLastError());
1218     ok(!size, "size = %d\n", size);
1219
1220     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
1221     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
1222
1223     size = sizeof(file_name);
1224     file_name[0] = 0;
1225     ret = InternetQueryOptionA(request, INTERNET_OPTION_DATAFILE_NAME, file_name, &size);
1226     if (ret)
1227     {
1228         file = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1229                       FILE_ATTRIBUTE_NORMAL, NULL);
1230         ok(file != INVALID_HANDLE_VALUE, "Could not create file: %u\n", GetLastError());
1231         CloseHandle(file);
1232     }
1233     else
1234     {
1235         /* < IE8 */
1236         ok(file_name[0] == 0, "Didn't expect a file name\n");
1237     }
1238
1239     ok(InternetCloseHandle(request), "Close request handle failed\n");
1240     ok(InternetCloseHandle(connect), "Close connect handle failed\n");
1241     ok(InternetCloseHandle(session), "Close session handle failed\n");
1242 }
1243
1244 static void HttpHeaders_test(void)
1245 {
1246     HINTERNET hSession;
1247     HINTERNET hConnect;
1248     HINTERNET hRequest;
1249     CHAR      buffer[256];
1250     WCHAR     wbuffer[256];
1251     DWORD     len = 256;
1252     DWORD     oldlen;
1253     DWORD     index = 0;
1254
1255     hSession = InternetOpen("Wine Regression Test",
1256             INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1257     ok( hSession != NULL ,"Unable to open Internet session\n");
1258     hConnect = InternetConnect(hSession, "crossover.codeweavers.com",
1259             INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1260             0);
1261     ok( hConnect != NULL, "Unable to connect to http://crossover.codeweavers.com\n");
1262     hRequest = HttpOpenRequest(hConnect, "POST", "/posttest.php",
1263             NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1264     if (!hRequest && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED)
1265     {
1266         skip( "Network unreachable, skipping test\n" );
1267         goto done;
1268     }
1269     ok( hRequest != NULL, "Failed to open request handle\n");
1270
1271     index = 0;
1272     len = sizeof(buffer);
1273     strcpy(buffer,"Warning");
1274     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1275                buffer,&len,&index)==0,"Warning hearder reported as Existing\n");
1276
1277     ok(HttpAddRequestHeaders(hRequest,"Warning:test1",-1,HTTP_ADDREQ_FLAG_ADD),
1278             "Failed to add new header\n");
1279
1280     index = 0;
1281     len = sizeof(buffer);
1282     strcpy(buffer,"Warning");
1283     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1284                 buffer,&len,&index),"Unable to query header\n");
1285     ok(index == 1, "Index was not incremented\n");
1286     ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1287     ok(len == 5, "Invalid length (exp. 5, got %d)\n", len);
1288     ok((len < sizeof(buffer)) && (buffer[len] == 0), "Buffer not NULL-terminated\n"); /* len show only 5 characters but the buffer is NULL-terminated*/
1289     len = sizeof(buffer);
1290     strcpy(buffer,"Warning");
1291     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1292                 buffer,&len,&index)==0,"Second Index Should Not Exist\n");
1293
1294     index = 0;
1295     len = 5; /* could store the string but not the NULL terminator */
1296     strcpy(buffer,"Warning");
1297     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1298                 buffer,&len,&index) == FALSE,"Query succeeded on a too small buffer\n");
1299     ok(strcmp(buffer,"Warning")==0, "incorrect string was returned(%s)\n",buffer); /* string not touched */
1300     ok(len == 6, "Invalid length (exp. 6, got %d)\n", len); /* unlike success, the length includes the NULL-terminator */
1301
1302     /* a call with NULL will fail but will return the length */
1303     index = 0;
1304     len = sizeof(buffer);
1305     SetLastError(0xdeadbeef);
1306     ok(HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1307                 NULL,&len,&index) == FALSE,"Query worked\n");
1308     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1309     ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1310     ok(index == 0, "Index was incremented\n");
1311
1312     /* even for a len that is too small */
1313     index = 0;
1314     len = 15;
1315     SetLastError(0xdeadbeef);
1316     ok(HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1317                 NULL,&len,&index) == FALSE,"Query worked\n");
1318     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1319     ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1320     ok(index == 0, "Index was incremented\n");
1321
1322     index = 0;
1323     len = 0;
1324     SetLastError(0xdeadbeef);
1325     ok(HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1326                 NULL,&len,&index) == FALSE,"Query worked\n");
1327     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1328     ok(len > 40, "Invalid length (exp. more than 40, got %d)\n", len);
1329     ok(index == 0, "Index was incremented\n");
1330     oldlen = len;   /* bytes; at least long enough to hold buffer & nul */
1331
1332
1333     /* a working query */
1334     index = 0;
1335     len = sizeof(buffer);
1336     memset(buffer, 'x', sizeof(buffer));
1337     ok(HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1338                 buffer,&len,&index),"Unable to query header\n");
1339     ok(len + sizeof(CHAR) <= oldlen, "Result longer than advertised\n");
1340     ok((len < sizeof(buffer)-sizeof(CHAR)) && (buffer[len/sizeof(CHAR)] == 0),"No NUL at end\n");
1341     ok(len == strlen(buffer) * sizeof(CHAR), "Length wrong\n");
1342     /* what's in the middle differs between Wine and Windows so currently we check only the beginning and the end */
1343     ok(strncmp(buffer, "POST /posttest.php HTTP/1", 25)==0, "Invalid beginning of headers string\n");
1344     ok(strcmp(buffer + strlen(buffer) - 4, "\r\n\r\n")==0, "Invalid end of headers string\n");
1345     ok(index == 0, "Index was incremented\n");
1346
1347     /* Like above two tests, but for W version */
1348
1349     index = 0;
1350     len = 0;
1351     SetLastError(0xdeadbeef);
1352     ok(HttpQueryInfoW(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1353                 NULL,&len,&index) == FALSE,"Query worked\n");
1354     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected last error: %d\n", GetLastError());
1355     ok(len > 80, "Invalid length (exp. more than 80, got %d)\n", len);
1356     ok(index == 0, "Index was incremented\n");
1357     oldlen = len;   /* bytes; at least long enough to hold buffer & nul */
1358
1359     /* a working query */
1360     index = 0;
1361     len = sizeof(wbuffer);
1362     memset(wbuffer, 'x', sizeof(wbuffer));
1363     ok(HttpQueryInfoW(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1364                 wbuffer,&len,&index),"Unable to query header\n");
1365     ok(len + sizeof(WCHAR) <= oldlen, "Result longer than advertised\n");
1366     ok(len == lstrlenW(wbuffer) * sizeof(WCHAR), "Length wrong\n");
1367     ok((len < sizeof(wbuffer)-sizeof(WCHAR)) && (wbuffer[len/sizeof(WCHAR)] == 0),"No NUL at end\n");
1368     ok(index == 0, "Index was incremented\n");
1369
1370     /* end of W version tests */
1371
1372     /* Without HTTP_QUERY_FLAG_REQUEST_HEADERS */
1373     index = 0;
1374     len = sizeof(buffer);
1375     memset(buffer, 'x', sizeof(buffer));
1376     ok(HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,
1377                 buffer,&len,&index) == TRUE,"Query failed\n");
1378     ok(len == 2, "Expected 2, got %d\n", len);
1379     ok(strcmp(buffer, "\r\n") == 0, "Expected CRLF, got '%s'\n", buffer);
1380     ok(index == 0, "Index was incremented\n");
1381
1382     ok(HttpAddRequestHeaders(hRequest,"Warning:test2",-1,HTTP_ADDREQ_FLAG_ADD),
1383             "Failed to add duplicate header using HTTP_ADDREQ_FLAG_ADD\n");
1384
1385     index = 0;
1386     len = sizeof(buffer);
1387     strcpy(buffer,"Warning");
1388     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1389                 buffer,&len,&index),"Unable to query header\n");
1390     ok(index == 1, "Index was not incremented\n");
1391     ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1392     len = sizeof(buffer);
1393     strcpy(buffer,"Warning");
1394     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1395                 buffer,&len,&index),"Failed to get second header\n");
1396     ok(index == 2, "Index was not incremented\n");
1397     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1398     len = sizeof(buffer);
1399     strcpy(buffer,"Warning");
1400     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1401                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1402
1403     ok(HttpAddRequestHeaders(hRequest,"Warning:test3",-1,HTTP_ADDREQ_FLAG_REPLACE), "Failed to replace header using HTTP_ADDREQ_FLAG_REPLACE\n");
1404
1405     index = 0;
1406     len = sizeof(buffer);
1407     strcpy(buffer,"Warning");
1408     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1409                 buffer,&len,&index),"Unable to query header\n");
1410     ok(index == 1, "Index was not incremented\n");
1411     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1412     len = sizeof(buffer);
1413     strcpy(buffer,"Warning");
1414     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1415                 buffer,&len,&index),"Failed to get second header\n");
1416     ok(index == 2, "Index was not incremented\n");
1417     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1418     len = sizeof(buffer);
1419     strcpy(buffer,"Warning");
1420     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1421                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1422
1423     ok(HttpAddRequestHeaders(hRequest,"Warning:test4",-1,HTTP_ADDREQ_FLAG_ADD_IF_NEW)==0, "HTTP_ADDREQ_FLAG_ADD_IF_NEW replaced existing header\n");
1424
1425     index = 0;
1426     len = sizeof(buffer);
1427     strcpy(buffer,"Warning");
1428     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1429                 buffer,&len,&index),"Unable to query header\n");
1430     ok(index == 1, "Index was not incremented\n");
1431     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1432     len = sizeof(buffer);
1433     strcpy(buffer,"Warning");
1434     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1435                 buffer,&len,&index),"Failed to get second header\n");
1436     ok(index == 2, "Index was not incremented\n");
1437     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1438     len = sizeof(buffer);
1439     strcpy(buffer,"Warning");
1440     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1441                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1442
1443     ok(HttpAddRequestHeaders(hRequest,"Warning:test4",-1, HTTP_ADDREQ_FLAG_COALESCE), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1444
1445     index = 0;
1446     len = sizeof(buffer);
1447     strcpy(buffer,"Warning");
1448     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1449                 buffer,&len,&index),"Unable to query header\n");
1450     ok(index == 1, "Index was not incremented\n");
1451     ok(strcmp(buffer,"test2, test4")==0, "incorrect string was returned(%s)\n", buffer);
1452     len = sizeof(buffer);
1453     strcpy(buffer,"Warning");
1454     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1455     ok(index == 2, "Index was not incremented\n");
1456     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1457     len = sizeof(buffer);
1458     strcpy(buffer,"Warning");
1459     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1460
1461     ok(HttpAddRequestHeaders(hRequest,"Warning:test5",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1462
1463     index = 0;
1464     len = sizeof(buffer);
1465     strcpy(buffer,"Warning");
1466     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1467     ok(index == 1, "Index was not incremented\n");
1468     ok(strcmp(buffer,"test2, test4, test5")==0, "incorrect string was returned(%s)\n",buffer);
1469     len = sizeof(buffer);
1470     strcpy(buffer,"Warning");
1471     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1472     ok(index == 2, "Index was not incremented\n");
1473     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1474     len = sizeof(buffer);
1475     strcpy(buffer,"Warning");
1476     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1477
1478     ok(HttpAddRequestHeaders(hRequest,"Warning:test6",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1479
1480     index = 0;
1481     len = sizeof(buffer);
1482     strcpy(buffer,"Warning");
1483     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1484     ok(index == 1, "Index was not incremented\n");
1485     ok(strcmp(buffer,"test2, test4, test5; test6")==0, "incorrect string was returned(%s)\n",buffer);
1486     len = sizeof(buffer);
1487     strcpy(buffer,"Warning");
1488     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1489     ok(index == 2, "Index was not incremented\n");
1490     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1491     len = sizeof(buffer);
1492     strcpy(buffer,"Warning");
1493     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1494
1495     ok(HttpAddRequestHeaders(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");
1496
1497     index = 0;
1498     len = sizeof(buffer);
1499     strcpy(buffer,"Warning");
1500     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1501     ok(index == 1, "Index was not incremented\n");
1502     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1503     len = sizeof(buffer);
1504     strcpy(buffer,"Warning");
1505     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1506     ok(index == 2, "Index was not incremented\n");
1507     ok(strcmp(buffer,"test7")==0, "incorrect string was returned(%s)\n",buffer);
1508     len = sizeof(buffer);
1509     strcpy(buffer,"Warning");
1510     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1511
1512     /* Ensure that blank headers are ignored and don't cause a failure */
1513     ok(HttpAddRequestHeaders(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");
1514
1515     index = 0;
1516     len = sizeof(buffer);
1517     strcpy(buffer,"BlankTest");
1518     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1519     ok(index == 1, "Index was not incremented\n");
1520     ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer);
1521
1522     /* Ensure that malformed header separators are ignored and don't cause a failure */
1523     ok(HttpAddRequestHeaders(hRequest,"\r\rMalformedTest:value\n\nMalformedTestTwo: value2\rMalformedTestThree: value3\n\n\r\r\n",-1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE),
1524         "Failed to add header with malformed entries in list\n");
1525
1526     index = 0;
1527     len = sizeof(buffer);
1528     strcpy(buffer,"MalformedTest");
1529     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1530     ok(index == 1, "Index was not incremented\n");
1531     ok(strcmp(buffer,"value")==0, "incorrect string was returned(%s)\n",buffer);
1532     index = 0;
1533     len = sizeof(buffer);
1534     strcpy(buffer,"MalformedTestTwo");
1535     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1536     ok(index == 1, "Index was not incremented\n");
1537     ok(strcmp(buffer,"value2")==0, "incorrect string was returned(%s)\n",buffer);
1538     index = 0;
1539     len = sizeof(buffer);
1540     strcpy(buffer,"MalformedTestThree");
1541     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1542     ok(index == 1, "Index was not incremented\n");
1543     ok(strcmp(buffer,"value3")==0, "incorrect string was returned(%s)\n",buffer);
1544
1545     ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
1546 done:
1547     ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
1548     ok(InternetCloseHandle(hSession), "Close session handle failed\n");
1549 }
1550
1551 static const char garbagemsg[] =
1552 "Garbage: Header\r\n";
1553
1554 static const char contmsg[] =
1555 "HTTP/1.1 100 Continue\r\n";
1556
1557 static const char expandcontmsg[] =
1558 "HTTP/1.1 100 Continue\r\n"
1559 "Server: winecontinue\r\n"
1560 "Tag: something witty\r\n"
1561 "\r\n";
1562
1563 static const char okmsg[] =
1564 "HTTP/1.1 200 OK\r\n"
1565 "Server: winetest\r\n"
1566 "\r\n";
1567
1568 static const char okmsg2[] =
1569 "HTTP/1.1 200 OK\r\n"
1570 "Date: Mon, 01 Dec 2008 13:44:34 GMT\r\n"
1571 "Server: winetest\r\n"
1572 "Content-Length: 0\r\n"
1573 "Set-Cookie: one\r\n"
1574 "Set-Cookie: two\r\n"
1575 "\r\n";
1576
1577 static const char notokmsg[] =
1578 "HTTP/1.1 400 Bad Request\r\n"
1579 "Server: winetest\r\n"
1580 "\r\n";
1581
1582 static const char noauthmsg[] =
1583 "HTTP/1.1 401 Unauthorized\r\n"
1584 "Server: winetest\r\n"
1585 "Connection: close\r\n"
1586 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1587 "\r\n";
1588
1589 static const char noauthmsg2[] =
1590 "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed\r\n"
1591 "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"
1592 "\0d`0|6\n"
1593 "Server: winetest\r\n";
1594
1595 static const char proxymsg[] =
1596 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1597 "Server: winetest\r\n"
1598 "Proxy-Connection: close\r\n"
1599 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1600 "\r\n";
1601
1602 static const char page1[] =
1603 "<HTML>\r\n"
1604 "<HEAD><TITLE>wininet test page</TITLE></HEAD>\r\n"
1605 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1606 "</HTML>\r\n\r\n";
1607
1608 struct server_info {
1609     HANDLE hEvent;
1610     int port;
1611     int num_testH_retrievals;
1612 };
1613
1614 static DWORD CALLBACK server_thread(LPVOID param)
1615 {
1616     struct server_info *si = param;
1617     int r, c, i, on;
1618     SOCKET s;
1619     struct sockaddr_in sa;
1620     char buffer[0x100];
1621     WSADATA wsaData;
1622     int last_request = 0;
1623     char host_header[22];
1624     static int test_b = 0;
1625
1626     WSAStartup(MAKEWORD(1,1), &wsaData);
1627
1628     s = socket(AF_INET, SOCK_STREAM, 0);
1629     if (s == INVALID_SOCKET)
1630         return 1;
1631
1632     on = 1;
1633     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1634
1635     memset(&sa, 0, sizeof sa);
1636     sa.sin_family = AF_INET;
1637     sa.sin_port = htons(si->port);
1638     sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1639
1640     r = bind(s, (struct sockaddr*) &sa, sizeof sa);
1641     if (r<0)
1642         return 1;
1643
1644     listen(s, 0);
1645
1646     SetEvent(si->hEvent);
1647
1648     sprintf(host_header, "Host: localhost:%d", si->port);
1649
1650     do
1651     {
1652         c = accept(s, NULL, NULL);
1653
1654         memset(buffer, 0, sizeof buffer);
1655         for(i=0; i<(sizeof buffer-1); i++)
1656         {
1657             r = recv(c, &buffer[i], 1, 0);
1658             if (r != 1)
1659                 break;
1660             if (i<4) continue;
1661             if (buffer[i-2] == '\n' && buffer[i] == '\n' &&
1662                 buffer[i-3] == '\r' && buffer[i-1] == '\r')
1663                 break;
1664         }
1665         if (strstr(buffer, "GET /test1"))
1666         {
1667             if (!strstr(buffer, "Content-Length: 0"))
1668             {
1669                 send(c, okmsg, sizeof okmsg-1, 0);
1670                 send(c, page1, sizeof page1-1, 0);
1671             }
1672             else
1673                 send(c, notokmsg, sizeof notokmsg-1, 0);
1674         }
1675         if (strstr(buffer, "/test2"))
1676         {
1677             if (strstr(buffer, "Proxy-Authorization: Basic bWlrZToxMTAx"))
1678             {
1679                 send(c, okmsg, sizeof okmsg-1, 0);
1680                 send(c, page1, sizeof page1-1, 0);
1681             }
1682             else
1683                 send(c, proxymsg, sizeof proxymsg-1, 0);
1684         }
1685         if (strstr(buffer, "/test3"))
1686         {
1687             if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1688                 send(c, okmsg, sizeof okmsg-1, 0);
1689             else
1690                 send(c, noauthmsg, sizeof noauthmsg-1, 0);
1691         }
1692         if (strstr(buffer, "/test4"))
1693         {
1694             if (strstr(buffer, "Connection: Close"))
1695                 send(c, okmsg, sizeof okmsg-1, 0);
1696             else
1697                 send(c, notokmsg, sizeof notokmsg-1, 0);
1698         }
1699         if (strstr(buffer, "POST /test5") ||
1700             strstr(buffer, "RPC_IN_DATA /test5") ||
1701             strstr(buffer, "RPC_OUT_DATA /test5"))
1702         {
1703             if (strstr(buffer, "Content-Length: 0"))
1704             {
1705                 send(c, okmsg, sizeof okmsg-1, 0);
1706                 send(c, page1, sizeof page1-1, 0);
1707             }
1708             else
1709                 send(c, notokmsg, sizeof notokmsg-1, 0);
1710         }
1711         if (strstr(buffer, "GET /test6"))
1712         {
1713             send(c, contmsg, sizeof contmsg-1, 0);
1714             send(c, contmsg, sizeof contmsg-1, 0);
1715             send(c, okmsg, sizeof okmsg-1, 0);
1716             send(c, page1, sizeof page1-1, 0);
1717         }
1718         if (strstr(buffer, "POST /test7"))
1719         {
1720             if (strstr(buffer, "Content-Length: 100"))
1721             {
1722                 send(c, okmsg, sizeof okmsg-1, 0);
1723                 send(c, page1, sizeof page1-1, 0);
1724             }
1725             else
1726                 send(c, notokmsg, sizeof notokmsg-1, 0);
1727         }
1728         if (strstr(buffer, "/test8"))
1729         {
1730             if (!strstr(buffer, "Connection: Close") &&
1731                  strstr(buffer, "Connection: Keep-Alive") &&
1732                 !strstr(buffer, "Cache-Control: no-cache") &&
1733                 !strstr(buffer, "Pragma: no-cache") &&
1734                  strstr(buffer, host_header))
1735                 send(c, okmsg, sizeof okmsg-1, 0);
1736             else
1737                 send(c, notokmsg, sizeof notokmsg-1, 0);
1738         }
1739         if (strstr(buffer, "/test9"))
1740         {
1741             if (!strstr(buffer, "Connection: Close") &&
1742                 !strstr(buffer, "Connection: Keep-Alive") &&
1743                 !strstr(buffer, "Cache-Control: no-cache") &&
1744                 !strstr(buffer, "Pragma: no-cache") &&
1745                  strstr(buffer, host_header))
1746                 send(c, okmsg, sizeof okmsg-1, 0);
1747             else
1748                 send(c, notokmsg, sizeof notokmsg-1, 0);
1749         }
1750         if (strstr(buffer, "/testA"))
1751         {
1752             if (!strstr(buffer, "Connection: Close") &&
1753                 !strstr(buffer, "Connection: Keep-Alive") &&
1754                 (strstr(buffer, "Cache-Control: no-cache") ||
1755                  strstr(buffer, "Pragma: no-cache")) &&
1756                  strstr(buffer, host_header))
1757                 send(c, okmsg, sizeof okmsg-1, 0);
1758             else
1759                 send(c, notokmsg, sizeof notokmsg-1, 0);
1760         }
1761         if (!test_b && strstr(buffer, "/testB HTTP/1.1"))
1762         {
1763             test_b = 1;
1764             send(c, okmsg, sizeof okmsg-1, 0);
1765             recvfrom(c, buffer, sizeof buffer, 0, NULL, NULL);
1766             send(c, okmsg, sizeof okmsg-1, 0);
1767         }
1768         if (strstr(buffer, "/testC"))
1769         {
1770             if (strstr(buffer, "Cookie: cookie=biscuit"))
1771                 send(c, okmsg, sizeof okmsg-1, 0);
1772             else
1773                 send(c, notokmsg, sizeof notokmsg-1, 0);
1774         }
1775         if (strstr(buffer, "/testD"))
1776         {
1777             send(c, okmsg2, sizeof okmsg2-1, 0);
1778         }
1779         if (strstr(buffer, "/testE"))
1780         {
1781             send(c, noauthmsg2, sizeof noauthmsg2-1, 0);
1782         }
1783         if (strstr(buffer, "GET /quit"))
1784         {
1785             send(c, okmsg, sizeof okmsg-1, 0);
1786             send(c, page1, sizeof page1-1, 0);
1787             last_request = 1;
1788         }
1789         if (strstr(buffer, "GET /testF"))
1790         {
1791             send(c, expandcontmsg, sizeof expandcontmsg-1, 0);
1792             send(c, garbagemsg, sizeof garbagemsg-1, 0);
1793             send(c, contmsg, sizeof contmsg-1, 0);
1794             send(c, garbagemsg, sizeof garbagemsg-1, 0);
1795             send(c, okmsg, sizeof okmsg-1, 0);
1796             send(c, page1, sizeof page1-1, 0);
1797         }
1798         if (strstr(buffer, "GET /testG"))
1799         {
1800             send(c, page1, sizeof page1-1, 0);
1801         }
1802         if (strstr(buffer, "GET /testH"))
1803         {
1804             si->num_testH_retrievals++;
1805             if (!strstr(buffer, "Content-Length: 0"))
1806             {
1807                 send(c, okmsg, sizeof okmsg-1, 0);
1808                 send(c, page1, sizeof page1-1, 0);
1809             }
1810             else
1811                 send(c, notokmsg, sizeof notokmsg-1, 0);
1812         }
1813         if (strstr(buffer, "GET /test_no_content"))
1814         {
1815             static const char nocontentmsg[] = "HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n";
1816             send(c, nocontentmsg, sizeof(nocontentmsg)-1, 0);
1817         }
1818         if (strstr(buffer, "GET /test_conn_close"))
1819         {
1820             static const char conn_close_response[] = "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nsome content";
1821             send(c, conn_close_response, sizeof(conn_close_response)-1, 0);
1822             WaitForSingleObject(conn_close_event, INFINITE);
1823             trace("closing connection\n");
1824         }
1825
1826         shutdown(c, 2);
1827         closesocket(c);
1828     } while (!last_request);
1829
1830     closesocket(s);
1831
1832     return 0;
1833 }
1834
1835 static void test_basic_request(int port, const char *verb, const char *url)
1836 {
1837     HINTERNET hi, hc, hr;
1838     DWORD r, count;
1839     char buffer[0x100];
1840
1841     hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
1842     ok(hi != NULL, "open failed\n");
1843
1844     hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
1845     ok(hc != NULL, "connect failed\n");
1846
1847     hr = HttpOpenRequest(hc, verb, url, NULL, NULL, NULL, 0, 0);
1848     ok(hr != NULL, "HttpOpenRequest failed\n");
1849
1850     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
1851     ok(r, "HttpSendRequest failed\n");
1852
1853     count = 0;
1854     memset(buffer, 0, sizeof buffer);
1855     SetLastError(0xdeadbeef);
1856     r = InternetReadFile(hr, buffer, sizeof buffer, &count);
1857     ok(r, "InternetReadFile failed %u\n", GetLastError());
1858     ok(count == sizeof page1 - 1, "count was wrong\n");
1859     ok(!memcmp(buffer, page1, sizeof page1), "http data wrong, got: %s\n", buffer);
1860
1861     InternetCloseHandle(hr);
1862     InternetCloseHandle(hc);
1863     InternetCloseHandle(hi);
1864 }
1865
1866 static void test_last_error(int port)
1867 {
1868     HINTERNET hi, hc, hr;
1869     DWORD error;
1870     BOOL r;
1871
1872     hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
1873     ok(hi != NULL, "open failed\n");
1874
1875     hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
1876     ok(hc != NULL, "connect failed\n");
1877
1878     hr = HttpOpenRequest(hc, NULL, "/test1", NULL, NULL, NULL, 0, 0);
1879     ok(hr != NULL, "HttpOpenRequest failed\n");
1880
1881     SetLastError(0xdeadbeef);
1882     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
1883     error = GetLastError();
1884     ok(r, "HttpSendRequest failed\n");
1885     ok(error == ERROR_SUCCESS || broken(error != ERROR_SUCCESS), "expected ERROR_SUCCESS, got %u\n", error);
1886
1887     InternetCloseHandle(hr);
1888     InternetCloseHandle(hc);
1889     InternetCloseHandle(hi);
1890 }
1891
1892 static void test_proxy_indirect(int port)
1893 {
1894     HINTERNET hi, hc, hr;
1895     DWORD r, sz;
1896     char buffer[0x40];
1897
1898     hi = InternetOpen(NULL, 0, NULL, NULL, 0);
1899     ok(hi != NULL, "open failed\n");
1900
1901     hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
1902     ok(hc != NULL, "connect failed\n");
1903
1904     hr = HttpOpenRequest(hc, NULL, "/test2", NULL, NULL, NULL, 0, 0);
1905     ok(hr != NULL, "HttpOpenRequest failed\n");
1906
1907     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
1908     ok(r, "HttpSendRequest failed\n");
1909
1910     sz = sizeof buffer;
1911     r = HttpQueryInfo(hr, HTTP_QUERY_PROXY_AUTHENTICATE, buffer, &sz, NULL);
1912     ok(r || GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo failed: %d\n", GetLastError());
1913     if (!r)
1914     {
1915         skip("missing proxy header, not testing remaining proxy headers\n");
1916         goto out;
1917     }
1918     ok(!strcmp(buffer, "Basic realm=\"placebo\""), "proxy auth info wrong\n");
1919
1920     test_status_code(hr, 407);
1921
1922     sz = sizeof buffer;
1923     r = HttpQueryInfo(hr, HTTP_QUERY_STATUS_TEXT, buffer, &sz, NULL);
1924     ok(r, "HttpQueryInfo failed\n");
1925     ok(!strcmp(buffer, "Proxy Authentication Required"), "proxy text wrong\n");
1926
1927     sz = sizeof buffer;
1928     r = HttpQueryInfo(hr, HTTP_QUERY_VERSION, buffer, &sz, NULL);
1929     ok(r, "HttpQueryInfo failed\n");
1930     ok(!strcmp(buffer, "HTTP/1.1"), "http version wrong\n");
1931
1932     sz = sizeof buffer;
1933     r = HttpQueryInfo(hr, HTTP_QUERY_SERVER, buffer, &sz, NULL);
1934     ok(r, "HttpQueryInfo failed\n");
1935     ok(!strcmp(buffer, "winetest"), "http server wrong\n");
1936
1937     sz = sizeof buffer;
1938     r = HttpQueryInfo(hr, HTTP_QUERY_CONTENT_ENCODING, buffer, &sz, NULL);
1939     ok(GetLastError() == ERROR_HTTP_HEADER_NOT_FOUND, "HttpQueryInfo should fail\n");
1940     ok(r == FALSE, "HttpQueryInfo failed\n");
1941
1942 out:
1943     InternetCloseHandle(hr);
1944     InternetCloseHandle(hc);
1945     InternetCloseHandle(hi);
1946 }
1947
1948 static void test_proxy_direct(int port)
1949 {
1950     HINTERNET hi, hc, hr;
1951     DWORD r, sz;
1952     char buffer[0x40];
1953     static CHAR username[] = "mike",
1954                 password[] = "1101";
1955
1956     sprintf(buffer, "localhost:%d\n", port);
1957     hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0);
1958     ok(hi != NULL, "open failed\n");
1959
1960     /* try connect without authorization */
1961     hc = InternetConnect(hi, "test.winehq.org/", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
1962     ok(hc != NULL, "connect failed\n");
1963
1964     hr = HttpOpenRequest(hc, NULL, "/test2", NULL, NULL, NULL, 0, 0);
1965     ok(hr != NULL, "HttpOpenRequest failed\n");
1966
1967     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
1968     ok(r, "HttpSendRequest failed\n");
1969
1970     test_status_code(hr, 407);
1971
1972     /* set the user + password then try again */
1973     todo_wine {
1974     r = InternetSetOption(hr, INTERNET_OPTION_PROXY_USERNAME, username, 4);
1975     ok(r, "failed to set user\n");
1976
1977     r = InternetSetOption(hr, INTERNET_OPTION_PROXY_PASSWORD, password, 4);
1978     ok(r, "failed to set password\n");
1979     }
1980
1981     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
1982     ok(r, "HttpSendRequest failed\n");
1983     sz = sizeof buffer;
1984     r = HttpQueryInfo(hr, HTTP_QUERY_STATUS_CODE, buffer, &sz, NULL);
1985     ok(r, "HttpQueryInfo failed\n");
1986     todo_wine {
1987     ok(!strcmp(buffer, "200"), "proxy code wrong\n");
1988     }
1989
1990
1991     InternetCloseHandle(hr);
1992     InternetCloseHandle(hc);
1993     InternetCloseHandle(hi);
1994 }
1995
1996 static void test_header_handling_order(int port)
1997 {
1998     static char authorization[] = "Authorization: Basic dXNlcjpwd2Q=";
1999     static char connection[]    = "Connection: Close";
2000
2001     static const char *types[2] = { "*", NULL };
2002     HINTERNET session, connect, request;
2003     DWORD size, status;
2004     BOOL ret;
2005
2006     session = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2007     ok(session != NULL, "InternetOpen failed\n");
2008
2009     connect = InternetConnect(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2010     ok(connect != NULL, "InternetConnect failed\n");
2011
2012     request = HttpOpenRequest(connect, NULL, "/test3", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
2013     ok(request != NULL, "HttpOpenRequest failed\n");
2014
2015     ret = HttpAddRequestHeaders(request, authorization, ~0u, HTTP_ADDREQ_FLAG_ADD);
2016     ok(ret, "HttpAddRequestHeaders failed\n");
2017
2018     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
2019     ok(ret, "HttpSendRequest failed\n");
2020
2021     test_status_code(request, 200);
2022
2023     InternetCloseHandle(request);
2024
2025     request = HttpOpenRequest(connect, NULL, "/test4", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
2026     ok(request != NULL, "HttpOpenRequest failed\n");
2027
2028     ret = HttpSendRequest(request, connection, ~0u, NULL, 0);
2029     ok(ret, "HttpSendRequest failed\n");
2030
2031     status = 0;
2032     size = sizeof(status);
2033     ret = HttpQueryInfo( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
2034     ok(ret, "HttpQueryInfo failed\n");
2035     ok(status == 200 || status == 400 /* IE6 */, "got status %u, expected 200 or 400\n", status);
2036
2037     InternetCloseHandle(request);
2038
2039     request = HttpOpenRequest(connect, "POST", "/test7", NULL, NULL, types, INTERNET_FLAG_KEEP_CONNECTION, 0);
2040     ok(request != NULL, "HttpOpenRequest failed\n");
2041
2042     ret = HttpAddRequestHeaders(request, "Content-Length: 100\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
2043     ok(ret, "HttpAddRequestHeaders failed\n");
2044
2045     ret = HttpSendRequest(request, connection, ~0u, NULL, 0);
2046     ok(ret, "HttpSendRequest failed\n");
2047
2048     status = 0;
2049     size = sizeof(status);
2050     ret = HttpQueryInfo( request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
2051     ok(ret, "HttpQueryInfo failed\n");
2052     ok(status == 200 || status == 400 /* IE6 */, "got status %u, expected 200 or 400\n", status);
2053
2054     InternetCloseHandle(request);
2055     InternetCloseHandle(connect);
2056     InternetCloseHandle(session);
2057 }
2058
2059 static void test_connection_header(int port)
2060 {
2061     HINTERNET ses, con, req;
2062     BOOL ret;
2063
2064     ses = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2065     ok(ses != NULL, "InternetOpen failed\n");
2066
2067     con = InternetConnect(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2068     ok(con != NULL, "InternetConnect failed\n");
2069
2070     req = HttpOpenRequest(con, NULL, "/test8", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
2071     ok(req != NULL, "HttpOpenRequest failed\n");
2072
2073     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2074     ok(ret, "HttpSendRequest failed\n");
2075
2076     test_status_code(req, 200);
2077
2078     InternetCloseHandle(req);
2079
2080     req = HttpOpenRequest(con, NULL, "/test9", NULL, NULL, NULL, 0, 0);
2081     ok(req != NULL, "HttpOpenRequest failed\n");
2082
2083     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2084     ok(ret, "HttpSendRequest failed\n");
2085
2086     test_status_code(req, 200);
2087
2088     InternetCloseHandle(req);
2089
2090     req = HttpOpenRequest(con, NULL, "/test9", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
2091     ok(req != NULL, "HttpOpenRequest failed\n");
2092
2093     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2094     ok(ret, "HttpSendRequest failed\n");
2095
2096     test_status_code(req, 200);
2097
2098     InternetCloseHandle(req);
2099
2100     req = HttpOpenRequest(con, "POST", "/testA", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
2101     ok(req != NULL, "HttpOpenRequest failed\n");
2102
2103     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2104     ok(ret, "HttpSendRequest failed\n");
2105
2106     test_status_code(req, 200);
2107
2108     InternetCloseHandle(req);
2109     InternetCloseHandle(con);
2110     InternetCloseHandle(ses);
2111 }
2112
2113 static void test_http1_1(int port)
2114 {
2115     HINTERNET ses, con, req;
2116     BOOL ret;
2117
2118     ses = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2119     ok(ses != NULL, "InternetOpen failed\n");
2120
2121     con = InternetConnect(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2122     ok(con != NULL, "InternetConnect failed\n");
2123
2124     req = HttpOpenRequest(con, NULL, "/testB", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
2125     ok(req != NULL, "HttpOpenRequest failed\n");
2126
2127     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2128     if (ret)
2129     {
2130         InternetCloseHandle(req);
2131
2132         req = HttpOpenRequest(con, NULL, "/testB", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
2133         ok(req != NULL, "HttpOpenRequest failed\n");
2134
2135         ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2136         ok(ret, "HttpSendRequest failed\n");
2137     }
2138
2139     InternetCloseHandle(req);
2140     InternetCloseHandle(con);
2141     InternetCloseHandle(ses);
2142 }
2143
2144 static void test_no_content(int port)
2145 {
2146     HINTERNET session, connection, req;
2147     DWORD res;
2148
2149     trace("Testing 204 no content response...\n");
2150
2151     hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2152
2153     session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
2154     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
2155
2156     pInternetSetStatusCallbackA(session, callback);
2157
2158     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
2159     connection = InternetConnectA(session, "localhost", port,
2160             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
2161     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
2162     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
2163
2164     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
2165     req = HttpOpenRequestA(connection, "GET", "/test_no_content", NULL, NULL, NULL,
2166             INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
2167     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
2168     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
2169
2170     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
2171     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
2172     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
2173     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
2174     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
2175     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
2176     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
2177     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
2178     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
2179     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
2180
2181     res = HttpSendRequestA(req, NULL, -1, NULL, 0);
2182     ok(!res && (GetLastError() == ERROR_IO_PENDING),
2183        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
2184     WaitForSingleObject(hCompleteEvent, INFINITE);
2185     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
2186
2187     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
2188     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
2189     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
2190     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
2191     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
2192     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
2193     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
2194     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
2195     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
2196     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
2197
2198     close_async_handle(session, hCompleteEvent, 2);
2199     CloseHandle(hCompleteEvent);
2200 }
2201
2202 static void test_conn_close(int port)
2203 {
2204     HINTERNET session, connection, req;
2205     DWORD res, avail, size;
2206     BYTE buf[1024];
2207
2208     trace("Testing connection close connection...\n");
2209
2210     hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
2211     conn_close_event = CreateEvent(NULL, FALSE, FALSE, NULL);
2212
2213     session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
2214     ok(session != NULL,"InternetOpen failed with error %u\n", GetLastError());
2215
2216     pInternetSetStatusCallbackA(session, callback);
2217
2218     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
2219     connection = InternetConnectA(session, "localhost", port,
2220             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
2221     ok(connection != NULL,"InternetConnect failed with error %u\n", GetLastError());
2222     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
2223
2224     SET_EXPECT(INTERNET_STATUS_HANDLE_CREATED);
2225     req = HttpOpenRequestA(connection, "GET", "/test_conn_close", NULL, NULL, NULL,
2226             INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
2227     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
2228     CHECK_NOTIFIED(INTERNET_STATUS_HANDLE_CREATED);
2229
2230     SET_OPTIONAL(INTERNET_STATUS_COOKIE_SENT);
2231     SET_EXPECT(INTERNET_STATUS_CONNECTING_TO_SERVER);
2232     SET_EXPECT(INTERNET_STATUS_CONNECTED_TO_SERVER);
2233     SET_EXPECT(INTERNET_STATUS_SENDING_REQUEST);
2234     SET_EXPECT(INTERNET_STATUS_REQUEST_SENT);
2235     SET_EXPECT(INTERNET_STATUS_RECEIVING_RESPONSE);
2236     SET_EXPECT(INTERNET_STATUS_RESPONSE_RECEIVED);
2237     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
2238
2239     res = HttpSendRequestA(req, NULL, -1, NULL, 0);
2240     ok(!res && (GetLastError() == ERROR_IO_PENDING),
2241        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
2242     WaitForSingleObject(hCompleteEvent, INFINITE);
2243     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
2244
2245     CLEAR_NOTIFIED(INTERNET_STATUS_COOKIE_SENT);
2246     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
2247     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
2248     CHECK_NOTIFIED(INTERNET_STATUS_SENDING_REQUEST);
2249     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_SENT);
2250     CHECK_NOTIFIED(INTERNET_STATUS_RECEIVING_RESPONSE);
2251     CHECK_NOTIFIED(INTERNET_STATUS_RESPONSE_RECEIVED);
2252     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
2253
2254     avail = 0;
2255     res = InternetQueryDataAvailable(req, &avail, 0, 0);
2256     ok(res, "InternetQueryDataAvailable failed: %u\n", GetLastError());
2257     ok(avail != 0, "avail = 0\n");
2258
2259     size = 0;
2260     res = InternetReadFile(req, buf, avail, &size);
2261     ok(res, "InternetReadFile failed: %u\n", GetLastError());
2262
2263     res = InternetQueryDataAvailable(req, &avail, 0, 0);
2264     ok(!res && (GetLastError() == ERROR_IO_PENDING),
2265        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
2266     ok(!avail, "avail = %u, expected 0\n", avail);
2267
2268     SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION);
2269     SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED);
2270     SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE);
2271     SetEvent(conn_close_event);
2272     WaitForSingleObject(hCompleteEvent, INFINITE);
2273     ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error);
2274     CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
2275     CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED);
2276     CHECK_NOTIFIED(INTERNET_STATUS_REQUEST_COMPLETE);
2277
2278     close_async_handle(session, hCompleteEvent, 2);
2279     CloseHandle(hCompleteEvent);
2280 }
2281
2282 static void test_HttpSendRequestW(int port)
2283 {
2284     static const WCHAR header[] = {'U','A','-','C','P','U',':',' ','x','8','6',0};
2285     HINTERNET ses, con, req;
2286     DWORD error;
2287     BOOL ret;
2288
2289     ses = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);
2290     ok(ses != NULL, "InternetOpen failed\n");
2291
2292     con = InternetConnect(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2293     ok(con != NULL, "InternetConnect failed\n");
2294
2295     req = HttpOpenRequest(con, NULL, "/test1", NULL, NULL, NULL, 0, 0);
2296     ok(req != NULL, "HttpOpenRequest failed\n");
2297
2298     SetLastError(0xdeadbeef);
2299     ret = HttpSendRequestW(req, header, ~0u, NULL, 0);
2300     error = GetLastError();
2301     ok(!ret, "HttpSendRequestW succeeded\n");
2302     ok(error == ERROR_IO_PENDING ||
2303        broken(error == ERROR_HTTP_HEADER_NOT_FOUND) ||  /* IE6 */
2304        broken(error == ERROR_INVALID_PARAMETER),        /* IE5 */
2305        "got %u expected ERROR_IO_PENDING\n", error);
2306
2307     InternetCloseHandle(req);
2308     InternetCloseHandle(con);
2309     InternetCloseHandle(ses);
2310 }
2311
2312 static void test_cookie_header(int port)
2313 {
2314     HINTERNET ses, con, req;
2315     DWORD size, error;
2316     BOOL ret;
2317     char buffer[64];
2318
2319     ses = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2320     ok(ses != NULL, "InternetOpen failed\n");
2321
2322     con = InternetConnect(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2323     ok(con != NULL, "InternetConnect failed\n");
2324
2325     InternetSetCookie("http://localhost", "cookie", "biscuit");
2326
2327     req = HttpOpenRequest(con, NULL, "/testC", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
2328     ok(req != NULL, "HttpOpenRequest failed\n");
2329
2330     buffer[0] = 0;
2331     size = sizeof(buffer);
2332     SetLastError(0xdeadbeef);
2333     ret = HttpQueryInfo(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
2334     error = GetLastError();
2335     ok(!ret, "HttpQueryInfo succeeded\n");
2336     ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "got %u expected ERROR_HTTP_HEADER_NOT_FOUND\n", error);
2337
2338     ret = HttpAddRequestHeaders(req, "Cookie: cookie=not biscuit\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD);
2339     ok(ret, "HttpAddRequestHeaders failed: %u\n", GetLastError());
2340
2341     buffer[0] = 0;
2342     size = sizeof(buffer);
2343     ret = HttpQueryInfo(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
2344     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
2345     ok(!strcmp(buffer, "cookie=not biscuit"), "got '%s' expected \'cookie=not biscuit\'\n", buffer);
2346
2347     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2348     ok(ret, "HttpSendRequest failed: %u\n", GetLastError());
2349
2350     test_status_code(req, 200);
2351
2352     buffer[0] = 0;
2353     size = sizeof(buffer);
2354     ret = HttpQueryInfo(req, HTTP_QUERY_COOKIE | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
2355     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
2356     ok(!strcmp(buffer, "cookie=biscuit"), "got '%s' expected \'cookie=biscuit\'\n", buffer);
2357
2358     InternetCloseHandle(req);
2359     InternetCloseHandle(con);
2360     InternetCloseHandle(ses);
2361 }
2362
2363 static void test_basic_authentication(int port)
2364 {
2365     HINTERNET session, connect, request;
2366     BOOL ret;
2367
2368     session = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2369     ok(session != NULL, "InternetOpen failed\n");
2370
2371     connect = InternetConnect(session, "localhost", port, "user", "pwd", INTERNET_SERVICE_HTTP, 0, 0);
2372     ok(connect != NULL, "InternetConnect failed\n");
2373
2374     request = HttpOpenRequest(connect, NULL, "/test3", NULL, NULL, NULL, 0, 0);
2375     ok(request != NULL, "HttpOpenRequest failed\n");
2376
2377     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
2378     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
2379
2380     test_status_code(request, 200);
2381
2382     InternetCloseHandle(request);
2383     InternetCloseHandle(connect);
2384     InternetCloseHandle(session);
2385 }
2386
2387 static void test_invalid_response_headers(int port)
2388 {
2389     HINTERNET session, connect, request;
2390     DWORD size;
2391     BOOL ret;
2392     char buffer[256];
2393
2394     session = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2395     ok(session != NULL, "InternetOpen failed\n");
2396
2397     connect = InternetConnect(session, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2398     ok(connect != NULL, "InternetConnect failed\n");
2399
2400     request = HttpOpenRequest(connect, NULL, "/testE", NULL, NULL, NULL, 0, 0);
2401     ok(request != NULL, "HttpOpenRequest failed\n");
2402
2403     ret = HttpSendRequest(request, NULL, 0, NULL, 0);
2404     ok(ret, "HttpSendRequest failed %u\n", GetLastError());
2405
2406     test_status_code(request, 401);
2407
2408     buffer[0] = 0;
2409     size = sizeof(buffer);
2410     ret = HttpQueryInfo( request, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL);
2411     ok(ret, "HttpQueryInfo failed\n");
2412     ok(!strcmp(buffer, "HTTP/1.0 401 Anonymous requests or requests on unsecure channel are not allowed"),
2413        "headers wrong \"%s\"\n", buffer);
2414
2415     buffer[0] = 0;
2416     size = sizeof(buffer);
2417     ret = HttpQueryInfo( request, HTTP_QUERY_SERVER, buffer, &size, NULL);
2418     ok(ret, "HttpQueryInfo failed\n");
2419     ok(!strcmp(buffer, "winetest"), "server wrong \"%s\"\n", buffer);
2420
2421     InternetCloseHandle(request);
2422     InternetCloseHandle(connect);
2423     InternetCloseHandle(session);
2424 }
2425
2426 static void test_response_without_headers(int port)
2427 {
2428     HINTERNET hi, hc, hr;
2429     DWORD r, count, size;
2430     char buffer[1024];
2431
2432     SetLastError(0xdeadbeef);
2433     hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2434     ok(hi != NULL, "open failed %u\n", GetLastError());
2435
2436     SetLastError(0xdeadbeef);
2437     hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2438     ok(hc != NULL, "connect failed %u\n", GetLastError());
2439
2440     SetLastError(0xdeadbeef);
2441     hr = HttpOpenRequest(hc, NULL, "/testG", NULL, NULL, NULL, 0, 0);
2442     ok(hr != NULL, "HttpOpenRequest failed %u\n", GetLastError());
2443
2444     SetLastError(0xdeadbeef);
2445     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
2446     ok(r, "HttpSendRequest failed %u\n", GetLastError());
2447
2448     count = 0;
2449     memset(buffer, 0, sizeof buffer);
2450     SetLastError(0xdeadbeef);
2451     r = InternetReadFile(hr, buffer, sizeof buffer, &count);
2452     ok(r, "InternetReadFile failed %u\n", GetLastError());
2453     todo_wine ok(count == sizeof page1 - 1, "count was wrong\n");
2454     todo_wine ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2455
2456     test_status_code(hr, 200);
2457
2458     buffer[0] = 0;
2459     size = sizeof(buffer);
2460     SetLastError(0xdeadbeef);
2461     r = HttpQueryInfo(hr, HTTP_QUERY_STATUS_TEXT, buffer, &size, NULL );
2462     ok(r, "HttpQueryInfo failed %u\n", GetLastError());
2463     ok(!strcmp(buffer, "OK"), "expected OK got: \"%s\"\n", buffer);
2464
2465     buffer[0] = 0;
2466     size = sizeof(buffer);
2467     SetLastError(0xdeadbeef);
2468     r = HttpQueryInfo(hr, HTTP_QUERY_VERSION, buffer, &size, NULL);
2469     ok(r, "HttpQueryInfo failed %u\n", GetLastError());
2470     ok(!strcmp(buffer, "HTTP/1.0"), "expected HTTP/1.0 got: \"%s\"\n", buffer);
2471
2472     buffer[0] = 0;
2473     size = sizeof(buffer);
2474     SetLastError(0xdeadbeef);
2475     r = HttpQueryInfo(hr, HTTP_QUERY_RAW_HEADERS, buffer, &size, NULL);
2476     ok(r, "HttpQueryInfo failed %u\n", GetLastError());
2477     ok(!strcmp(buffer, "HTTP/1.0 200 OK"), "raw headers wrong: \"%s\"\n", buffer);
2478
2479     InternetCloseHandle(hr);
2480     InternetCloseHandle(hc);
2481     InternetCloseHandle(hi);
2482 }
2483
2484 static void test_HttpQueryInfo(int port)
2485 {
2486     HINTERNET hi, hc, hr;
2487     DWORD size, index;
2488     char buffer[1024];
2489     BOOL ret;
2490
2491     hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2492     ok(hi != NULL, "InternetOpen failed\n");
2493
2494     hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2495     ok(hc != NULL, "InternetConnect failed\n");
2496
2497     hr = HttpOpenRequest(hc, NULL, "/testD", NULL, NULL, NULL, 0, 0);
2498     ok(hr != NULL, "HttpOpenRequest failed\n");
2499
2500     ret = HttpSendRequest(hr, NULL, 0, NULL, 0);
2501     ok(ret, "HttpSendRequest failed\n");
2502
2503     index = 0;
2504     size = sizeof(buffer);
2505     ret = HttpQueryInfo(hr, HTTP_QUERY_HOST | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, &index);
2506     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2507     ok(index == 1, "expected 1 got %u\n", index);
2508
2509     index = 0;
2510     size = sizeof(buffer);
2511     ret = HttpQueryInfo(hr, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
2512     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2513     ok(index == 1, "expected 1 got %u\n", index);
2514
2515     index = 0;
2516     size = sizeof(buffer);
2517     ret = HttpQueryInfo(hr, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
2518     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2519     ok(index == 0, "expected 0 got %u\n", index);
2520
2521     size = sizeof(buffer);
2522     ret = HttpQueryInfo(hr, HTTP_QUERY_RAW_HEADERS, buffer, &size, &index);
2523     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2524     ok(index == 0, "expected 0 got %u\n", index);
2525
2526     size = sizeof(buffer);
2527     ret = HttpQueryInfo(hr, HTTP_QUERY_RAW_HEADERS_CRLF, buffer, &size, &index);
2528     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2529     ok(index == 0, "expected 0 got %u\n", index);
2530
2531     size = sizeof(buffer);
2532     ret = HttpQueryInfo(hr, HTTP_QUERY_STATUS_TEXT, buffer, &size, &index);
2533     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2534     ok(index == 0, "expected 0 got %u\n", index);
2535
2536     size = sizeof(buffer);
2537     ret = HttpQueryInfo(hr, HTTP_QUERY_VERSION, buffer, &size, &index);
2538     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2539     ok(index == 0, "expected 0 got %u\n", index);
2540
2541     test_status_code(hr, 200);
2542
2543     index = 0xdeadbeef;
2544     size = sizeof(buffer);
2545     ret = HttpQueryInfo(hr, HTTP_QUERY_FORWARDED, buffer, &size, &index);
2546     ok(!ret, "HttpQueryInfo succeeded\n");
2547     ok(index == 0xdeadbeef, "expected 0xdeadbeef got %u\n", index);
2548
2549     index = 0;
2550     size = sizeof(buffer);
2551     ret = HttpQueryInfo(hr, HTTP_QUERY_SERVER, buffer, &size, &index);
2552     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2553     ok(index == 1, "expected 1 got %u\n", index);
2554
2555     index = 0;
2556     size = sizeof(buffer);
2557     strcpy(buffer, "Server");
2558     ret = HttpQueryInfo(hr, HTTP_QUERY_CUSTOM, buffer, &size, &index);
2559     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2560     ok(index == 1, "expected 1 got %u\n", index);
2561
2562     index = 0;
2563     size = sizeof(buffer);
2564     ret = HttpQueryInfo(hr, HTTP_QUERY_SET_COOKIE, buffer, &size, &index);
2565     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2566     ok(index == 1, "expected 1 got %u\n", index);
2567
2568     size = sizeof(buffer);
2569     ret = HttpQueryInfo(hr, HTTP_QUERY_SET_COOKIE, buffer, &size, &index);
2570     ok(ret, "HttpQueryInfo failed %u\n", GetLastError());
2571     ok(index == 2, "expected 2 got %u\n", index);
2572
2573     InternetCloseHandle(hr);
2574     InternetCloseHandle(hc);
2575     InternetCloseHandle(hi);
2576 }
2577
2578 static void test_options(int port)
2579 {
2580     HINTERNET ses, con, req;
2581     DWORD size, error;
2582     DWORD_PTR ctx;
2583     BOOL ret;
2584
2585     ses = InternetOpen("winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2586     ok(ses != NULL, "InternetOpen failed\n");
2587
2588     SetLastError(0xdeadbeef);
2589     ret = InternetSetOption(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, 0);
2590     error = GetLastError();
2591     ok(!ret, "InternetSetOption succeeded\n");
2592     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2593
2594     SetLastError(0xdeadbeef);
2595     ret = InternetSetOption(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, sizeof(ctx));
2596     ok(!ret, "InternetSetOption succeeded\n");
2597     error = GetLastError();
2598     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2599
2600     SetLastError(0xdeadbeef);
2601     ret = InternetSetOption(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, 0);
2602     ok(!ret, "InternetSetOption succeeded\n");
2603     error = GetLastError();
2604     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2605
2606     ctx = 1;
2607     ret = InternetSetOption(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
2608     ok(ret, "InternetSetOption failed %u\n", GetLastError());
2609
2610     SetLastError(0xdeadbeef);
2611     ret = InternetQueryOption(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, NULL);
2612     error = GetLastError();
2613     ok(!ret, "InternetQueryOption succeeded\n");
2614     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2615
2616     SetLastError(0xdeadbeef);
2617     ret = InternetQueryOption(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, NULL);
2618     error = GetLastError();
2619     ok(!ret, "InternetQueryOption succeeded\n");
2620     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2621
2622     size = 0;
2623     SetLastError(0xdeadbeef);
2624     ret = InternetQueryOption(ses, INTERNET_OPTION_CONTEXT_VALUE, NULL, &size);
2625     error = GetLastError();
2626     ok(!ret, "InternetQueryOption succeeded\n");
2627     ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
2628
2629     size = sizeof(ctx);
2630     SetLastError(0xdeadbeef);
2631     ret = InternetQueryOption(NULL, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
2632     error = GetLastError();
2633     ok(!ret, "InternetQueryOption succeeded\n");
2634     ok(error == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %u\n", error);
2635
2636     ctx = 0xdeadbeef;
2637     size = sizeof(ctx);
2638     ret = InternetQueryOption(ses, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
2639     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
2640     ok(ctx == 1, "expected 1 got %lu\n", ctx);
2641
2642     con = InternetConnect(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2643     ok(con != NULL, "InternetConnect failed\n");
2644
2645     ctx = 0xdeadbeef;
2646     size = sizeof(ctx);
2647     ret = InternetQueryOption(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
2648     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
2649     ok(ctx == 0, "expected 0 got %lu\n", ctx);
2650
2651     ctx = 2;
2652     ret = InternetSetOption(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
2653     ok(ret, "InternetSetOption failed %u\n", GetLastError());
2654
2655     ctx = 0xdeadbeef;
2656     size = sizeof(ctx);
2657     ret = InternetQueryOption(con, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
2658     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
2659     ok(ctx == 2, "expected 2 got %lu\n", ctx);
2660
2661     req = HttpOpenRequest(con, NULL, "/test1", NULL, NULL, NULL, 0, 0);
2662     ok(req != NULL, "HttpOpenRequest failed\n");
2663
2664     ctx = 0xdeadbeef;
2665     size = sizeof(ctx);
2666     ret = InternetQueryOption(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
2667     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
2668     ok(ctx == 0, "expected 0 got %lu\n", ctx);
2669
2670     ctx = 3;
2671     ret = InternetSetOption(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, sizeof(ctx));
2672     ok(ret, "InternetSetOption failed %u\n", GetLastError());
2673
2674     ctx = 0xdeadbeef;
2675     size = sizeof(ctx);
2676     ret = InternetQueryOption(req, INTERNET_OPTION_CONTEXT_VALUE, &ctx, &size);
2677     ok(ret, "InternetQueryOption failed %u\n", GetLastError());
2678     ok(ctx == 3, "expected 3 got %lu\n", ctx);
2679
2680     /* INTERNET_OPTION_PROXY */
2681     SetLastError(0xdeadbeef);
2682     ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, NULL, NULL);
2683     error = GetLastError();
2684     ok(!ret, "InternetQueryOption succeeded\n");
2685     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2686
2687     SetLastError(0xdeadbeef);
2688     ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, &ctx, NULL);
2689     error = GetLastError();
2690     ok(!ret, "InternetQueryOption succeeded\n");
2691     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2692
2693     size = 0;
2694     SetLastError(0xdeadbeef);
2695     ret = InternetQueryOptionA(ses, INTERNET_OPTION_PROXY, NULL, &size);
2696     error = GetLastError();
2697     ok(!ret, "InternetQueryOption succeeded\n");
2698     ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
2699     ok(size >= sizeof(INTERNET_PROXY_INFOA), "expected size to be greater or equal to the struct size\n");
2700
2701     InternetCloseHandle(req);
2702     InternetCloseHandle(con);
2703     InternetCloseHandle(ses);
2704 }
2705
2706 static void test_url_caching(int port, int *num_retrievals)
2707 {
2708     HINTERNET hi, hc, hr;
2709     DWORD r, count;
2710     char buffer[0x100];
2711
2712     ok(*num_retrievals == 0, "expected 0 retrievals prior to test\n");
2713
2714     hi = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
2715     ok(hi != NULL, "open failed\n");
2716
2717     hc = InternetConnect(hi, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
2718     ok(hc != NULL, "connect failed\n");
2719
2720     /* Pre-load the cache: */
2721     hr = HttpOpenRequest(hc, "GET", "/testH", NULL, NULL, NULL, 0, 0);
2722     ok(hr != NULL, "HttpOpenRequest failed\n");
2723
2724     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
2725     ok(r, "HttpSendRequest failed\n");
2726
2727     ok(*num_retrievals == 1, "expected 1 retrievals, got %d\n", *num_retrievals);
2728
2729     count = 0;
2730     memset(buffer, 0, sizeof buffer);
2731     SetLastError(0xdeadbeef);
2732     r = InternetReadFile(hr, buffer, sizeof buffer, &count);
2733     ok(r, "InternetReadFile failed %u\n", GetLastError());
2734     ok(count == sizeof page1 - 1, "count was wrong\n");
2735     ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2736
2737     InternetCloseHandle(hr);
2738
2739     /* Send the same request, requiring it to be retrieved from the cache */
2740     hr = HttpOpenRequest(hc, "GET", "/testH", NULL, NULL, NULL, INTERNET_FLAG_FROM_CACHE, 0);
2741     ok(hr != NULL, "HttpOpenRequest failed\n");
2742
2743     r = HttpSendRequest(hr, NULL, 0, NULL, 0);
2744     /* Older Windows versions succeed with this request, newer ones fail with
2745      * ERROR_FILE_NOT_FOUND.  Accept either, as the older version allows us
2746      * to verify that the server isn't contacted.
2747      */
2748     if (!r)
2749         ok(GetLastError() == ERROR_FILE_NOT_FOUND,
2750            "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
2751     else
2752     {
2753         /* The server shouldn't be contacted for this request. */
2754         todo_wine
2755         ok(*num_retrievals == 1, "expected 1 retrievals\n");
2756
2757         count = 0;
2758         memset(buffer, 0, sizeof buffer);
2759         SetLastError(0xdeadbeef);
2760         r = InternetReadFile(hr, buffer, sizeof buffer, &count);
2761         ok(r, "InternetReadFile failed %u\n", GetLastError());
2762         ok(count == sizeof page1 - 1, "count was wrong\n");
2763         ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
2764     }
2765
2766     InternetCloseHandle(hc);
2767     InternetCloseHandle(hi);
2768 }
2769
2770 static void test_http_connection(void)
2771 {
2772     struct server_info si;
2773     HANDLE hThread;
2774     DWORD id = 0, r;
2775
2776     si.hEvent = CreateEvent(NULL, 0, 0, NULL);
2777     si.port = 7531;
2778     si.num_testH_retrievals = 0;
2779
2780     hThread = CreateThread(NULL, 0, server_thread, (LPVOID) &si, 0, &id);
2781     ok( hThread != NULL, "create thread failed\n");
2782
2783     r = WaitForSingleObject(si.hEvent, 10000);
2784     ok (r == WAIT_OBJECT_0, "failed to start wininet test server\n");
2785     if (r != WAIT_OBJECT_0)
2786         return;
2787
2788     test_basic_request(si.port, "GET", "/test1");
2789     test_proxy_indirect(si.port);
2790     test_proxy_direct(si.port);
2791     test_header_handling_order(si.port);
2792     test_basic_request(si.port, "POST", "/test5");
2793     test_basic_request(si.port, "RPC_IN_DATA", "/test5");
2794     test_basic_request(si.port, "RPC_OUT_DATA", "/test5");
2795     test_basic_request(si.port, "GET", "/test6");
2796     test_basic_request(si.port, "GET", "/testF");
2797     test_connection_header(si.port);
2798     test_http1_1(si.port);
2799     test_cookie_header(si.port);
2800     test_basic_authentication(si.port);
2801     test_invalid_response_headers(si.port);
2802     test_response_without_headers(si.port);
2803     test_HttpQueryInfo(si.port);
2804     test_HttpSendRequestW(si.port);
2805     test_last_error(si.port);
2806     test_options(si.port);
2807     test_url_caching(si.port, &si.num_testH_retrievals);
2808     test_no_content(si.port);
2809     test_conn_close(si.port);
2810
2811     /* send the basic request again to shutdown the server thread */
2812     test_basic_request(si.port, "GET", "/quit");
2813
2814     r = WaitForSingleObject(hThread, 3000);
2815     ok( r == WAIT_OBJECT_0, "thread wait failed\n");
2816     CloseHandle(hThread);
2817 }
2818
2819 static void release_cert_info(INTERNET_CERTIFICATE_INFOA *info)
2820 {
2821     LocalFree(info->lpszSubjectInfo);
2822     LocalFree(info->lpszIssuerInfo);
2823     LocalFree(info->lpszProtocolName);
2824     LocalFree(info->lpszSignatureAlgName);
2825     LocalFree(info->lpszEncryptionAlgName);
2826 }
2827
2828 static void test_secure_connection(void)
2829 {
2830     static const WCHAR gizmo5[] = {'G','i','z','m','o','5',0};
2831     static const WCHAR testbot[] = {'t','e','s','t','b','o','t','.','w','i','n','e','h','q','.','o','r','g',0};
2832     static const WCHAR get[] = {'G','E','T',0};
2833     static const WCHAR slash[] = {'/',0};
2834     HINTERNET ses, con, req;
2835     DWORD size, flags;
2836     INTERNET_CERTIFICATE_INFOA *certificate_structA = NULL;
2837     INTERNET_CERTIFICATE_INFOW *certificate_structW = NULL;
2838     BOOL ret;
2839
2840     ses = InternetOpen("Gizmo5", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
2841     ok(ses != NULL, "InternetOpen failed\n");
2842
2843     con = InternetConnect(ses, "testbot.winehq.org",
2844                           INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL,
2845                           INTERNET_SERVICE_HTTP, 0, 0);
2846     ok(con != NULL, "InternetConnect failed\n");
2847
2848     req = HttpOpenRequest(con, "GET", "/", NULL, NULL, NULL,
2849                           INTERNET_FLAG_SECURE, 0);
2850     ok(req != NULL, "HttpOpenRequest failed\n");
2851
2852     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2853     ok(ret, "HttpSendRequest failed: %d\n", GetLastError());
2854
2855     size = sizeof(flags);
2856     ret = InternetQueryOption(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
2857     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
2858     ok(flags & SECURITY_FLAG_SECURE, "expected secure flag to be set\n");
2859
2860     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2861                                NULL, &size);
2862     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
2863     ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %d\n", size);
2864     certificate_structA = HeapAlloc(GetProcessHeap(), 0, size);
2865     ret = InternetQueryOption(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2866                               certificate_structA, &size);
2867     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
2868     if (ret)
2869     {
2870         ok(certificate_structA->lpszSubjectInfo &&
2871            strlen(certificate_structA->lpszSubjectInfo) > 1,
2872            "expected a non-empty subject name\n");
2873         ok(certificate_structA->lpszIssuerInfo &&
2874            strlen(certificate_structA->lpszIssuerInfo) > 1,
2875            "expected a non-empty issuer name\n");
2876         ok(!certificate_structA->lpszSignatureAlgName,
2877            "unexpected signature algorithm name\n");
2878         ok(!certificate_structA->lpszEncryptionAlgName,
2879            "unexpected encryption algorithm name\n");
2880         ok(!certificate_structA->lpszProtocolName,
2881            "unexpected protocol name\n");
2882         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
2883         release_cert_info(certificate_structA);
2884     }
2885     HeapFree(GetProcessHeap(), 0, certificate_structA);
2886
2887     /* Querying the same option through InternetQueryOptionW still results in
2888      * ASCII strings being returned.
2889      */
2890     size = 0;
2891     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2892                                NULL, &size);
2893     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
2894     ok(size == sizeof(INTERNET_CERTIFICATE_INFOW), "size = %d\n", size);
2895     certificate_structW = HeapAlloc(GetProcessHeap(), 0, size);
2896     ret = InternetQueryOption(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2897                               certificate_structW, &size);
2898     certificate_structA = (INTERNET_CERTIFICATE_INFOA *)certificate_structW;
2899     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
2900     if (ret)
2901     {
2902         ok(certificate_structA->lpszSubjectInfo &&
2903            strlen(certificate_structA->lpszSubjectInfo) > 1,
2904            "expected a non-empty subject name\n");
2905         ok(certificate_structA->lpszIssuerInfo &&
2906            strlen(certificate_structA->lpszIssuerInfo) > 1,
2907            "expected a non-empty issuer name\n");
2908         ok(!certificate_structA->lpszSignatureAlgName,
2909            "unexpected signature algorithm name\n");
2910         ok(!certificate_structA->lpszEncryptionAlgName,
2911            "unexpected encryption algorithm name\n");
2912         ok(!certificate_structA->lpszProtocolName,
2913            "unexpected protocol name\n");
2914         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
2915         release_cert_info(certificate_structA);
2916     }
2917     HeapFree(GetProcessHeap(), 0, certificate_structW);
2918
2919     InternetCloseHandle(req);
2920     InternetCloseHandle(con);
2921     InternetCloseHandle(ses);
2922
2923     /* Repeating the tests with the W functions has the same result: */
2924     ses = InternetOpenW(gizmo5, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
2925     ok(ses != NULL, "InternetOpen failed\n");
2926
2927     con = InternetConnectW(ses, testbot,
2928                           INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL,
2929                           INTERNET_SERVICE_HTTP, 0, 0);
2930     ok(con != NULL, "InternetConnect failed\n");
2931
2932     req = HttpOpenRequestW(con, get, slash, NULL, NULL, NULL,
2933                           INTERNET_FLAG_SECURE, 0);
2934     ok(req != NULL, "HttpOpenRequest failed\n");
2935
2936     ret = HttpSendRequest(req, NULL, 0, NULL, 0);
2937     ok(ret, "HttpSendRequest failed: %d\n", GetLastError());
2938
2939     size = sizeof(flags);
2940     ret = InternetQueryOption(req, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size);
2941     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
2942     ok(flags & SECURITY_FLAG_SECURE, "expected secure flag to be set\n");
2943
2944     ret = InternetQueryOptionA(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2945                                NULL, &size);
2946     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
2947     ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %d\n", size);
2948     certificate_structA = HeapAlloc(GetProcessHeap(), 0, size);
2949     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2950                                certificate_structA, &size);
2951     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
2952     if (ret)
2953     {
2954         ok(certificate_structA->lpszSubjectInfo &&
2955            strlen(certificate_structA->lpszSubjectInfo) > 1,
2956            "expected a non-empty subject name\n");
2957         ok(certificate_structA->lpszIssuerInfo &&
2958            strlen(certificate_structA->lpszIssuerInfo) > 1,
2959            "expected a non-empty issuer name\n");
2960         ok(!certificate_structA->lpszSignatureAlgName,
2961            "unexpected signature algorithm name\n");
2962         ok(!certificate_structA->lpszEncryptionAlgName,
2963            "unexpected encryption algorithm name\n");
2964         ok(!certificate_structA->lpszProtocolName,
2965            "unexpected protocol name\n");
2966         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
2967         release_cert_info(certificate_structA);
2968     }
2969     HeapFree(GetProcessHeap(), 0, certificate_structA);
2970
2971     /* Again, querying the same option through InternetQueryOptionW still
2972      * results in ASCII strings being returned.
2973      */
2974     size = 0;
2975     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2976                                NULL, &size);
2977     ok(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
2978     ok(size == sizeof(INTERNET_CERTIFICATE_INFOW), "size = %d\n", size);
2979     certificate_structW = HeapAlloc(GetProcessHeap(), 0, size);
2980     ret = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
2981                                certificate_structW, &size);
2982     certificate_structA = (INTERNET_CERTIFICATE_INFOA *)certificate_structW;
2983     ok(ret, "InternetQueryOption failed: %d\n", GetLastError());
2984     if (ret)
2985     {
2986         ok(certificate_structA->lpszSubjectInfo &&
2987            strlen(certificate_structA->lpszSubjectInfo) > 1,
2988            "expected a non-empty subject name\n");
2989         ok(certificate_structA->lpszIssuerInfo &&
2990            strlen(certificate_structA->lpszIssuerInfo) > 1,
2991            "expected a non-empty issuer name\n");
2992         ok(!certificate_structA->lpszSignatureAlgName,
2993            "unexpected signature algorithm name\n");
2994         ok(!certificate_structA->lpszEncryptionAlgName,
2995            "unexpected encryption algorithm name\n");
2996         ok(!certificate_structA->lpszProtocolName,
2997            "unexpected protocol name\n");
2998         ok(certificate_structA->dwKeySize, "expected a non-zero key size\n");
2999         release_cert_info(certificate_structA);
3000     }
3001     HeapFree(GetProcessHeap(), 0, certificate_structW);
3002
3003     InternetCloseHandle(req);
3004     InternetCloseHandle(con);
3005     InternetCloseHandle(ses);
3006 }
3007
3008 static void test_user_agent_header(void)
3009 {
3010     HINTERNET ses, con, req;
3011     DWORD size, err;
3012     char buffer[64];
3013     BOOL ret;
3014
3015     ses = InternetOpen("Gizmo5", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
3016     ok(ses != NULL, "InternetOpen failed\n");
3017
3018     con = InternetConnect(ses, "test.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3019     ok(con != NULL, "InternetConnect failed\n");
3020
3021     req = HttpOpenRequest(con, "GET", "/tests/hello.html", "HTTP/1.0", NULL, NULL, 0, 0);
3022     ok(req != NULL, "HttpOpenRequest failed\n");
3023
3024     size = sizeof(buffer);
3025     ret = HttpQueryInfo(req, HTTP_QUERY_USER_AGENT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
3026     err = GetLastError();
3027     ok(!ret, "HttpQueryInfo succeeded\n");
3028     ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
3029
3030     ret = HttpAddRequestHeaders(req, "User-Agent: Gizmo Project\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
3031     ok(ret, "HttpAddRequestHeaders succeeded\n");
3032
3033     size = sizeof(buffer);
3034     ret = HttpQueryInfo(req, HTTP_QUERY_USER_AGENT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
3035     err = GetLastError();
3036     ok(ret, "HttpQueryInfo failed\n");
3037     ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
3038
3039     InternetCloseHandle(req);
3040
3041     req = HttpOpenRequest(con, "GET", "/", "HTTP/1.0", NULL, NULL, 0, 0);
3042     ok(req != NULL, "HttpOpenRequest failed\n");
3043
3044     size = sizeof(buffer);
3045     ret = HttpQueryInfo(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
3046     err = GetLastError();
3047     ok(!ret, "HttpQueryInfo succeeded\n");
3048     ok(err == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", err);
3049
3050     ret = HttpAddRequestHeaders(req, "Accept: audio/*, image/*, text/*\r\nUser-Agent: Gizmo Project\r\n", ~0u, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
3051     ok(ret, "HttpAddRequestHeaders failed\n");
3052
3053     buffer[0] = 0;
3054     size = sizeof(buffer);
3055     ret = HttpQueryInfo(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
3056     ok(ret, "HttpQueryInfo failed: %u\n", GetLastError());
3057     ok(!strcmp(buffer, "audio/*, image/*, text/*"), "got '%s' expected 'audio/*, image/*, text/*'\n", buffer);
3058
3059     InternetCloseHandle(req);
3060     InternetCloseHandle(con);
3061     InternetCloseHandle(ses);
3062 }
3063
3064 static void test_bogus_accept_types_array(void)
3065 {
3066     HINTERNET ses, con, req;
3067     static const char *types[] = { (const char *)6240, "*/*", "%p", "", (const char *)0xffffffff, "*/*", NULL };
3068     DWORD size, error;
3069     char buffer[32];
3070     BOOL ret;
3071
3072     ses = InternetOpen("MERONG(0.9/;p)", INTERNET_OPEN_TYPE_DIRECT, "", "", 0);
3073     con = InternetConnect(ses, "www.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
3074     req = HttpOpenRequest(con, "POST", "/post/post_action.php", "HTTP/1.0", "", types, INTERNET_FLAG_FORMS_SUBMIT, 0);
3075
3076     ok(req != NULL, "HttpOpenRequest failed: %u\n", GetLastError());
3077
3078     buffer[0] = 0;
3079     size = sizeof(buffer);
3080     SetLastError(0xdeadbeef);
3081     ret = HttpQueryInfo(req, HTTP_QUERY_ACCEPT | HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer, &size, NULL);
3082     error = GetLastError();
3083     ok(!ret || broken(ret), "HttpQueryInfo succeeded\n");
3084     if (!ret) ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND, got %u\n", error);
3085     ok(broken(!strcmp(buffer, ", */*, %p, , , */*")) /* IE6 */ ||
3086        broken(!strcmp(buffer, "*/*, %p, */*")) /* IE7/8 */ ||
3087        !strcmp(buffer, ""), "got '%s' expected ''\n", buffer);
3088
3089     InternetCloseHandle(req);
3090     InternetCloseHandle(con);
3091     InternetCloseHandle(ses);
3092 }
3093
3094 struct context
3095 {
3096     HANDLE event;
3097     HINTERNET req;
3098 };
3099
3100 static void WINAPI cb(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID info, DWORD size)
3101 {
3102     INTERNET_ASYNC_RESULT *result = info;
3103     struct context *ctx = (struct context *)context;
3104
3105     trace("%p 0x%08lx %u %p 0x%08x\n", handle, context, status, info, size);
3106
3107     if (status == INTERNET_STATUS_REQUEST_COMPLETE)
3108     {
3109         trace("request handle: 0x%08lx\n", result->dwResult);
3110         ctx->req = (HINTERNET)result->dwResult;
3111         SetEvent(ctx->event);
3112     }
3113     if (status == INTERNET_STATUS_HANDLE_CLOSING)
3114     {
3115         DWORD type = INTERNET_HANDLE_TYPE_CONNECT_HTTP, size = sizeof(type);
3116
3117         if (InternetQueryOption(handle, INTERNET_OPTION_HANDLE_TYPE, &type, &size))
3118             ok(type != INTERNET_HANDLE_TYPE_CONNECT_HTTP, "unexpected callback\n");
3119         SetEvent(ctx->event);
3120     }
3121 }
3122
3123 static void test_open_url_async(void)
3124 {
3125     BOOL ret;
3126     HINTERNET ses, req;
3127     DWORD size, error;
3128     struct context ctx;
3129     ULONG type;
3130
3131     ctx.req = NULL;
3132     ctx.event = CreateEvent(NULL, TRUE, FALSE, "Z:_home_hans_jaman-installer.exe_ev1");
3133
3134     ses = InternetOpen("AdvancedInstaller", 0, NULL, NULL, INTERNET_FLAG_ASYNC);
3135     ok(ses != NULL, "InternetOpen failed\n");
3136
3137     SetLastError(0xdeadbeef);
3138     ret = InternetSetOptionA(NULL, INTERNET_OPTION_CALLBACK, &cb, sizeof(DWORD_PTR));
3139     error = GetLastError();
3140     ok(!ret, "InternetSetOptionA succeeded\n");
3141     ok(error == ERROR_INTERNET_INCORRECT_HANDLE_TYPE, "got %u expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE\n", error);
3142
3143     ret = InternetSetOptionA(ses, INTERNET_OPTION_CALLBACK, &cb, sizeof(DWORD_PTR));
3144     error = GetLastError();
3145     ok(!ret, "InternetSetOptionA failed\n");
3146     ok(error == ERROR_INTERNET_OPTION_NOT_SETTABLE, "got %u expected ERROR_INTERNET_OPTION_NOT_SETTABLE\n", error);
3147
3148     pInternetSetStatusCallbackA(ses, cb);
3149     ResetEvent(ctx.event);
3150
3151     req = InternetOpenUrl(ses, "http://test.winehq.org", NULL, 0, 0, (DWORD_PTR)&ctx);
3152     ok(!req && GetLastError() == ERROR_IO_PENDING, "InternetOpenUrl failed\n");
3153
3154     WaitForSingleObject(ctx.event, INFINITE);
3155
3156     type = 0;
3157     size = sizeof(type);
3158     ret = InternetQueryOption(ctx.req, INTERNET_OPTION_HANDLE_TYPE, &type, &size);
3159     ok(ret, "InternetQueryOption failed: %u\n", GetLastError());
3160     ok(type == INTERNET_HANDLE_TYPE_HTTP_REQUEST,
3161        "expected INTERNET_HANDLE_TYPE_HTTP_REQUEST, got %u\n", type);
3162
3163     size = 0;
3164     ret = HttpQueryInfo(ctx.req, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &size, NULL);
3165     ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "HttpQueryInfo failed\n");
3166     ok(size > 0, "expected size > 0\n");
3167
3168     ResetEvent(ctx.event);
3169     InternetCloseHandle(ctx.req);
3170     WaitForSingleObject(ctx.event, INFINITE);
3171
3172     InternetCloseHandle(ses);
3173     CloseHandle(ctx.event);
3174 }
3175
3176 enum api
3177 {
3178     internet_connect = 1,
3179     http_open_request,
3180     http_send_request_ex,
3181     internet_writefile,
3182     http_end_request,
3183     internet_close_handle
3184 };
3185
3186 struct notification
3187 {
3188     enum api     function; /* api responsible for notification */
3189     unsigned int status;   /* status received */
3190     int          async;    /* delivered from another thread? */
3191     int          todo;
3192     int          optional;
3193 };
3194
3195 struct info
3196 {
3197     enum api     function;
3198     const struct notification *test;
3199     unsigned int count;
3200     unsigned int index;
3201     HANDLE       wait;
3202     DWORD        thread;
3203     unsigned int line;
3204     DWORD        expect_result;
3205     BOOL         is_aborted;
3206 };
3207
3208 static CRITICAL_SECTION notification_cs;
3209
3210 static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD buflen )
3211 {
3212     BOOL status_ok, function_ok;
3213     struct info *info = (struct info *)context;
3214     unsigned int i;
3215
3216     EnterCriticalSection( &notification_cs );
3217
3218     if(info->is_aborted) {
3219         LeaveCriticalSection(&notification_cs);
3220         return;
3221     }
3222
3223     if (status == INTERNET_STATUS_HANDLE_CREATED)
3224     {
3225         DWORD size = sizeof(struct info *);
3226         HttpQueryInfoA( handle, INTERNET_OPTION_CONTEXT_VALUE, &info, &size, 0 );
3227     }else if(status == INTERNET_STATUS_REQUEST_COMPLETE) {
3228         INTERNET_ASYNC_RESULT *ar = (INTERNET_ASYNC_RESULT*)buffer;
3229
3230         ok(buflen == sizeof(*ar), "unexpected buflen = %d\n", buflen);
3231         if(info->expect_result == ERROR_SUCCESS) {
3232             ok(ar->dwResult == 1, "ar->dwResult = %ld, expected 1\n", ar->dwResult);
3233         }else {
3234             ok(!ar->dwResult, "ar->dwResult = %ld, expected 1\n", ar->dwResult);
3235             ok(ar->dwError == info->expect_result, "ar->dwError = %d, expected %d\n", ar->dwError, info->expect_result);
3236         }
3237     }
3238
3239     i = info->index;
3240     if (i >= info->count)
3241     {
3242         LeaveCriticalSection( &notification_cs );
3243         return;
3244     }
3245
3246     while (info->test[i].status != status &&
3247         (info->test[i].optional || info->test[i].todo) &&
3248         i < info->count - 1 &&
3249         info->test[i].function == info->test[i + 1].function)
3250     {
3251         i++;
3252     }
3253
3254     status_ok   = (info->test[i].status == status);
3255     function_ok = (info->test[i].function == info->function);
3256
3257     if (!info->test[i].todo)
3258     {
3259         ok( status_ok, "%u: expected status %u got %u\n", info->line, info->test[i].status, status );
3260         ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function );
3261
3262         if (info->test[i].async)
3263             ok(info->thread != GetCurrentThreadId(), "%u: expected thread %u got %u\n",
3264                info->line, info->thread, GetCurrentThreadId());
3265     }
3266     else
3267     {
3268         todo_wine ok( status_ok, "%u: expected status %u got %u\n", info->line, info->test[i].status, status );
3269         if (status_ok)
3270             todo_wine ok( function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function );
3271     }
3272     if (i == info->count - 1 || info->test[i].function != info->test[i + 1].function) SetEvent( info->wait );
3273     info->index = i+1;
3274
3275     LeaveCriticalSection( &notification_cs );
3276 }
3277
3278 static void setup_test( struct info *info, enum api function, unsigned int line, DWORD expect_result )
3279 {
3280     info->function = function;
3281     info->line = line;
3282     info->expect_result = expect_result;
3283 }
3284
3285 struct notification_data
3286 {
3287     const struct notification *test;
3288     const unsigned int count;
3289     const char *method;
3290     const char *host;
3291     const char *path;
3292     const char *data;
3293     BOOL expect_conn_failure;
3294 };
3295
3296 static const struct notification async_send_request_ex_test[] =
3297 {
3298     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED, 0 },
3299     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED, 0 },
3300     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, 1, 0, 1 },
3301     { http_send_request_ex,  INTERNET_STATUS_COOKIE_SENT, 1, 0, 1 },
3302     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, 1, 0, 1 },
3303     { http_send_request_ex,  INTERNET_STATUS_NAME_RESOLVED, 1, 0, 1 },
3304     { http_send_request_ex,  INTERNET_STATUS_CONNECTING_TO_SERVER, 1 },
3305     { http_send_request_ex,  INTERNET_STATUS_CONNECTED_TO_SERVER, 1 },
3306     { http_send_request_ex,  INTERNET_STATUS_SENDING_REQUEST, 1 },
3307     { http_send_request_ex,  INTERNET_STATUS_REQUEST_SENT, 1 },
3308     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, 1 },
3309     { internet_writefile,    INTERNET_STATUS_SENDING_REQUEST, 0 },
3310     { internet_writefile,    INTERNET_STATUS_REQUEST_SENT, 0 },
3311     { http_end_request,      INTERNET_STATUS_RECEIVING_RESPONSE, 1 },
3312     { http_end_request,      INTERNET_STATUS_RESPONSE_RECEIVED, 1 },
3313     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, 1 },
3314     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, 0, 0, 1 },
3315     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, 0, 0, 1 },
3316     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, 0, },
3317     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, 0, }
3318 };
3319
3320 static const struct notification async_send_request_ex_test2[] =
3321 {
3322     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED, 0 },
3323     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED, 0 },
3324     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, 1, 0, 1 },
3325     { http_send_request_ex,  INTERNET_STATUS_COOKIE_SENT, 1, 0, 1 },
3326     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, 1, 0, 1 },
3327     { http_send_request_ex,  INTERNET_STATUS_NAME_RESOLVED, 1, 0, 1 },
3328     { http_send_request_ex,  INTERNET_STATUS_CONNECTING_TO_SERVER, 1, 1 },
3329     { http_send_request_ex,  INTERNET_STATUS_CONNECTED_TO_SERVER, 1, 1 },
3330     { http_send_request_ex,  INTERNET_STATUS_SENDING_REQUEST, 1 },
3331     { http_send_request_ex,  INTERNET_STATUS_REQUEST_SENT, 1 },
3332     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, 1 },
3333     { http_end_request,      INTERNET_STATUS_RECEIVING_RESPONSE, 1 },
3334     { http_end_request,      INTERNET_STATUS_RESPONSE_RECEIVED, 1 },
3335     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, 1 },
3336     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, 0, 0, 1 },
3337     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, 0, 0, 1 },
3338     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, 0, },
3339     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, 0, }
3340 };
3341
3342 static const struct notification async_send_request_ex_resolve_failure_test[] =
3343 {
3344     { internet_connect,      INTERNET_STATUS_HANDLE_CREATED, 0 },
3345     { http_open_request,     INTERNET_STATUS_HANDLE_CREATED, 0 },
3346     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, 1, 0, 1 },
3347     { http_send_request_ex,  INTERNET_STATUS_RESOLVING_NAME, 1 },
3348     { http_send_request_ex,  INTERNET_STATUS_DETECTING_PROXY, 1, 0, 1 },
3349     { http_send_request_ex,  INTERNET_STATUS_REQUEST_COMPLETE, 1 },
3350     { http_end_request,      INTERNET_STATUS_REQUEST_COMPLETE, 1 },
3351     { internet_close_handle, INTERNET_STATUS_CLOSING_CONNECTION, 0, 0, 1 },
3352     { internet_close_handle, INTERNET_STATUS_CONNECTION_CLOSED, 0, 0, 1 },
3353     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, 0, },
3354     { internet_close_handle, INTERNET_STATUS_HANDLE_CLOSING, 0, }
3355 };
3356
3357 static const struct notification_data notification_data[] = {
3358     {
3359         async_send_request_ex_test,
3360         sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
3361         "POST",
3362         "test.winehq.org",
3363         "tests/posttest.php",
3364         "Public ID=codeweavers"
3365     },
3366     {
3367         async_send_request_ex_test2,
3368         sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
3369         "POST",
3370         "test.winehq.org",
3371         "tests/posttest.php"
3372     },
3373     {
3374         async_send_request_ex_resolve_failure_test,
3375         sizeof(async_send_request_ex_resolve_failure_test)/sizeof(async_send_request_ex_resolve_failure_test[0]),
3376         "GET",
3377         "brokenhost",
3378         "index.html",
3379         NULL,
3380         TRUE
3381     }
3382 };
3383
3384 static void test_async_HttpSendRequestEx(const struct notification_data *nd)
3385 {
3386     BOOL ret;
3387     HINTERNET ses, req, con;
3388     struct info info;
3389     DWORD size, written, error;
3390     INTERNET_BUFFERSA b;
3391     static const char *accept[2] = {"*/*", NULL};
3392     char buffer[32];
3393
3394     trace("Async HttpSendRequestEx test (%s %s)\n", nd->method, nd->host);
3395
3396     InitializeCriticalSection( &notification_cs );
3397
3398     info.test  = nd->test;
3399     info.count = nd->count;
3400     info.index = 0;
3401     info.wait = CreateEvent( NULL, FALSE, FALSE, NULL );
3402     info.thread = GetCurrentThreadId();
3403     info.is_aborted = FALSE;
3404
3405     ses = InternetOpen( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC );
3406     ok( ses != NULL, "InternetOpen failed\n" );
3407
3408     pInternetSetStatusCallbackA( ses, check_notification );
3409
3410     setup_test( &info, internet_connect, __LINE__, ERROR_SUCCESS );
3411     con = InternetConnect( ses, nd->host, 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)&info );
3412     ok( con != NULL, "InternetConnect failed %u\n", GetLastError() );
3413
3414     WaitForSingleObject( info.wait, 10000 );
3415
3416     setup_test( &info, http_open_request, __LINE__, ERROR_SUCCESS );
3417     req = HttpOpenRequest( con, nd->method, nd->path, NULL, NULL, accept, 0, (DWORD_PTR)&info );
3418     ok( req != NULL, "HttpOpenRequest failed %u\n", GetLastError() );
3419
3420     WaitForSingleObject( info.wait, 10000 );
3421
3422     if(nd->data) {
3423         memset( &b, 0, sizeof(INTERNET_BUFFERSA) );
3424         b.dwStructSize = sizeof(INTERNET_BUFFERSA);
3425         b.lpcszHeader = "Content-Type: application/x-www-form-urlencoded";
3426         b.dwHeadersLength = strlen( b.lpcszHeader );
3427         b.dwBufferTotal = nd->data ? strlen( nd->data ) : 0;
3428     }
3429
3430     setup_test( &info, http_send_request_ex, __LINE__,
3431             nd->expect_conn_failure ? ERROR_INTERNET_NAME_NOT_RESOLVED : ERROR_SUCCESS );
3432     ret = HttpSendRequestExA( req, nd->data ? &b : NULL, NULL, 0x28, 0 );
3433     ok( !ret && GetLastError() == ERROR_IO_PENDING, "HttpSendRequestExA failed %d %u\n", ret, GetLastError() );
3434
3435     error = WaitForSingleObject( info.wait, 10000 );
3436     if(error != WAIT_OBJECT_0) {
3437         skip("WaitForSingleObject returned %d, assuming DNS problem\n", error);
3438         info.is_aborted = TRUE;
3439         goto abort;
3440     }
3441
3442     size = sizeof(buffer);
3443     SetLastError( 0xdeadbeef );
3444     ret = HttpQueryInfoA( req, HTTP_QUERY_CONTENT_ENCODING, buffer, &size, 0 );
3445     error = GetLastError();
3446     ok( !ret, "HttpQueryInfoA failed %u\n", GetLastError() );
3447     if(nd->expect_conn_failure) {
3448         ok(error == ERROR_HTTP_HEADER_NOT_FOUND, "expected ERROR_HTTP_HEADER_NOT_FOUND got %u\n", error );
3449     }else {
3450         todo_wine
3451         ok(error == ERROR_INTERNET_INCORRECT_HANDLE_STATE,
3452             "expected ERROR_INTERNET_INCORRECT_HANDLE_STATE got %u\n", error );
3453     }
3454
3455     if (nd->data)
3456     {
3457         written = 0;
3458         size = strlen( nd->data );
3459         setup_test( &info, internet_writefile, __LINE__, ERROR_SUCCESS );
3460         ret = InternetWriteFile( req, nd->data, size, &written );
3461         ok( ret, "InternetWriteFile failed %u\n", GetLastError() );
3462         ok( written == size, "expected %u got %u\n", written, size );
3463
3464         WaitForSingleObject( info.wait, 10000 );
3465
3466         SetLastError( 0xdeadbeef );
3467         ret = HttpEndRequestA( req, (void *)nd->data, 0x28, 0 );
3468         error = GetLastError();
3469         ok( !ret, "HttpEndRequestA succeeded\n" );
3470         ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error );
3471     }
3472
3473     SetLastError( 0xdeadbeef );
3474     setup_test( &info, http_end_request, __LINE__,
3475             nd->expect_conn_failure ? ERROR_INTERNET_OPERATION_CANCELLED : ERROR_SUCCESS);
3476     ret = HttpEndRequestA( req, NULL, 0x28, 0 );
3477     error = GetLastError();
3478     ok( !ret, "HttpEndRequestA succeeded\n" );
3479     ok( error == ERROR_IO_PENDING, "expected ERROR_IO_PENDING got %u\n", error );
3480
3481     WaitForSingleObject( info.wait, 10000 );
3482
3483     setup_test( &info, internet_close_handle, __LINE__, ERROR_SUCCESS );
3484  abort:
3485     InternetCloseHandle( req );
3486     InternetCloseHandle( con );
3487     InternetCloseHandle( ses );
3488
3489     WaitForSingleObject( info.wait, 10000 );
3490     Sleep(100);
3491     CloseHandle( info.wait );
3492 }
3493
3494 static HINTERNET closetest_session, closetest_req, closetest_conn;
3495 static BOOL closetest_closed;
3496
3497 static void WINAPI closetest_callback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
3498      LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
3499 {
3500     DWORD len, type;
3501     BOOL res;
3502
3503     trace("closetest_callback %p: %d\n", hInternet, dwInternetStatus);
3504
3505     ok(hInternet == closetest_session || hInternet == closetest_conn || hInternet == closetest_req,
3506        "Unexpected hInternet %p\n", hInternet);
3507     if(!closetest_closed)
3508         return;
3509
3510     len = sizeof(type);
3511     res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_HANDLE_TYPE, &type, &len);
3512     ok(!res && GetLastError() == ERROR_INVALID_HANDLE,
3513        "InternetQueryOptionA(%p INTERNET_OPTION_HANDLE_TYPE) failed: %x %u, expected TRUE ERROR_INVALID_HANDLE\n",
3514        closetest_req, res, GetLastError());
3515 }
3516
3517 static void test_InternetCloseHandle(void)
3518 {
3519     DWORD len, flags;
3520     BOOL res;
3521
3522     closetest_session = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
3523     ok(closetest_session != NULL,"InternetOpen failed with error %u\n", GetLastError());
3524
3525     pInternetSetStatusCallbackA(closetest_session, closetest_callback);
3526
3527     closetest_conn = InternetConnectA(closetest_session, "source.winehq.org", INTERNET_INVALID_PORT_NUMBER,
3528             NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
3529     ok(closetest_conn != NULL,"InternetConnect failed with error %u\n", GetLastError());
3530
3531     closetest_req = HttpOpenRequestA(closetest_conn, "GET", "winegecko.php", NULL, NULL, NULL,
3532             INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE, 0xdeadbead);
3533
3534     res = HttpSendRequestA(closetest_req, NULL, -1, NULL, 0);
3535     ok(!res && (GetLastError() == ERROR_IO_PENDING),
3536        "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
3537
3538     len = sizeof(flags);
3539     res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_REQUEST_FLAGS, &flags, &len);
3540     ok(res, "InternetQueryOptionA(%p INTERNET_OPTION_URL) failed: %u\n", closetest_req, GetLastError());
3541
3542     res = InternetCloseHandle(closetest_session);
3543     ok(res, "InternetCloseHandle failed: %u\n", GetLastError());
3544     closetest_closed = TRUE;
3545     trace("Closed session handle\n");
3546
3547     res = InternetCloseHandle(closetest_conn);
3548     ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "InternetCloseConnection(conn) failed: %x %u\n",
3549        res, GetLastError());
3550
3551     res = InternetCloseHandle(closetest_req);
3552     ok(!res && GetLastError() == ERROR_INVALID_HANDLE, "InternetCloseConnection(req) failed: %x %u\n",
3553        res, GetLastError());
3554
3555     len = sizeof(flags);
3556     res = InternetQueryOptionA(closetest_req, INTERNET_OPTION_REQUEST_FLAGS, &flags, &len);
3557     ok(!res && GetLastError() == ERROR_INVALID_HANDLE,
3558        "InternetQueryOptionA(%p INTERNET_OPTION_URL) failed: %x %u, expected TRUE ERROR_INVALID_HANDLE\n",
3559        closetest_req, res, GetLastError());
3560 }
3561
3562 static void init_status_tests(void)
3563 {
3564     memset(expect, 0, sizeof(expect));
3565     memset(optional, 0, sizeof(optional));
3566     memset(wine_allow, 0, sizeof(wine_allow));
3567     memset(notified, 0, sizeof(notified));
3568     memset(status_string, 0, sizeof(status_string));
3569
3570 #define STATUS_STRING(status) status_string[status] = #status
3571     STATUS_STRING(INTERNET_STATUS_RESOLVING_NAME);
3572     STATUS_STRING(INTERNET_STATUS_NAME_RESOLVED);
3573     STATUS_STRING(INTERNET_STATUS_CONNECTING_TO_SERVER);
3574     STATUS_STRING(INTERNET_STATUS_CONNECTED_TO_SERVER);
3575     STATUS_STRING(INTERNET_STATUS_SENDING_REQUEST);
3576     STATUS_STRING(INTERNET_STATUS_REQUEST_SENT);
3577     STATUS_STRING(INTERNET_STATUS_RECEIVING_RESPONSE);
3578     STATUS_STRING(INTERNET_STATUS_RESPONSE_RECEIVED);
3579     STATUS_STRING(INTERNET_STATUS_CTL_RESPONSE_RECEIVED);
3580     STATUS_STRING(INTERNET_STATUS_PREFETCH);
3581     STATUS_STRING(INTERNET_STATUS_CLOSING_CONNECTION);
3582     STATUS_STRING(INTERNET_STATUS_CONNECTION_CLOSED);
3583     STATUS_STRING(INTERNET_STATUS_HANDLE_CREATED);
3584     STATUS_STRING(INTERNET_STATUS_HANDLE_CLOSING);
3585     STATUS_STRING(INTERNET_STATUS_DETECTING_PROXY);
3586     STATUS_STRING(INTERNET_STATUS_REQUEST_COMPLETE);
3587     STATUS_STRING(INTERNET_STATUS_REDIRECT);
3588     STATUS_STRING(INTERNET_STATUS_INTERMEDIATE_RESPONSE);
3589     STATUS_STRING(INTERNET_STATUS_USER_INPUT_REQUIRED);
3590     STATUS_STRING(INTERNET_STATUS_STATE_CHANGE);
3591     STATUS_STRING(INTERNET_STATUS_COOKIE_SENT);
3592     STATUS_STRING(INTERNET_STATUS_COOKIE_RECEIVED);
3593     STATUS_STRING(INTERNET_STATUS_PRIVACY_IMPACTED);
3594     STATUS_STRING(INTERNET_STATUS_P3P_HEADER);
3595     STATUS_STRING(INTERNET_STATUS_P3P_POLICYREF);
3596     STATUS_STRING(INTERNET_STATUS_COOKIE_HISTORY);
3597 #undef STATUS_STRING
3598 }
3599
3600 START_TEST(http)
3601 {
3602     HMODULE hdll;
3603     hdll = GetModuleHandleA("wininet.dll");
3604
3605     if(!GetProcAddress(hdll, "InternetGetCookieExW")) {
3606         win_skip("Too old IE (older than 6.0)\n");
3607         return;
3608     }
3609
3610     pInternetSetStatusCallbackA = (void*)GetProcAddress(hdll, "InternetSetStatusCallbackA");
3611
3612     init_status_tests();
3613     test_InternetCloseHandle();
3614     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[0]);
3615     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[1]);
3616     InternetReadFile_test(0, &test_data[1]);
3617     first_connection_to_test_url = TRUE;
3618     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[2]);
3619     InternetReadFile_test(0, &test_data[2]);
3620     InternetReadFileExA_test(INTERNET_FLAG_ASYNC);
3621     test_open_url_async();
3622     test_async_HttpSendRequestEx(&notification_data[0]);
3623     test_async_HttpSendRequestEx(&notification_data[1]);
3624     test_async_HttpSendRequestEx(&notification_data[2]);
3625     InternetOpenRequest_test();
3626     test_http_cache();
3627     InternetOpenUrlA_test();
3628     HttpHeaders_test();
3629     test_http_connection();
3630     test_secure_connection();
3631     test_user_agent_header();
3632     test_bogus_accept_types_array();
3633     InternetReadFile_chunked_test();
3634     HttpSendRequestEx_test();
3635     InternetReadFile_test(INTERNET_FLAG_ASYNC, &test_data[3]);
3636 }