kernel32: FindFirstChangeNotification needs a static IO_STATUS_BLOCK.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
31 #include "wine/test.h"
32
33 #define TEST_URL "http://www.winehq.org/site/about"
34 #define TEST_URL_PATH "/site/about"
35 #define TEST_URL2 "http://www.myserver.com/myscript.php?arg=1"
36 #define TEST_URL2_SERVER "www.myserver.com"
37 #define TEST_URL2_PATH "/myscript.php"
38 #define TEST_URL2_PATHEXTRA "/myscript.php?arg=1"
39 #define TEST_URL2_EXTRA "?arg=1"
40 #define TEST_URL3 "file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml"
41
42 #define CREATE_URL1 "http://username:password@www.winehq.org/site/about"
43 #define CREATE_URL2 "http://username@www.winehq.org/site/about"
44 #define CREATE_URL3 "http://username:"
45 #define CREATE_URL4 "http://www.winehq.org/site/about"
46 #define CREATE_URL5 "http://"
47 #define CREATE_URL6 "nhtt://username:password@www.winehq.org:80/site/about"
48 #define CREATE_URL7 "http://username:password@www.winehq.org:42/site/about"
49
50 static HANDLE hCompleteEvent;
51
52 static VOID WINAPI callback(
53      HINTERNET hInternet,
54      DWORD dwContext,
55      DWORD dwInternetStatus,
56      LPVOID lpvStatusInformation,
57      DWORD dwStatusInformationLength
58 )
59 {
60     switch (dwInternetStatus)
61     {
62         case INTERNET_STATUS_RESOLVING_NAME:
63             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_RESOLVING_NAME \"%s\" %ld\n",
64                 GetCurrentThreadId(), hInternet, dwContext,
65                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
66             break;
67         case INTERNET_STATUS_NAME_RESOLVED:
68             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_NAME_RESOLVED \"%s\" %ld\n",
69                 GetCurrentThreadId(), hInternet, dwContext,
70                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
71             break;
72         case INTERNET_STATUS_CONNECTING_TO_SERVER:
73             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_CONNECTING_TO_SERVER \"%s\" %ld\n",
74                 GetCurrentThreadId(), hInternet, dwContext,
75                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
76             break;
77         case INTERNET_STATUS_CONNECTED_TO_SERVER:
78             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_CONNECTED_TO_SERVER \"%s\" %ld\n",
79                 GetCurrentThreadId(), hInternet, dwContext,
80                 (LPCSTR)lpvStatusInformation,dwStatusInformationLength);
81             break;
82         case INTERNET_STATUS_SENDING_REQUEST:
83             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_SENDING_REQUEST %p %ld\n",
84                 GetCurrentThreadId(), hInternet, dwContext,
85                 lpvStatusInformation,dwStatusInformationLength);
86             break;
87         case INTERNET_STATUS_REQUEST_SENT:
88             ok(dwStatusInformationLength == sizeof(DWORD),
89                 "info length should be sizeof(DWORD) instead of %ld\n",
90                 dwStatusInformationLength);
91             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_REQUEST_SENT 0x%lx %ld\n",
92                 GetCurrentThreadId(), hInternet, dwContext,
93                 *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
94             break;
95         case INTERNET_STATUS_RECEIVING_RESPONSE:
96             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_RECEIVING_RESPONSE %p %ld\n",
97                 GetCurrentThreadId(), hInternet, dwContext,
98                 lpvStatusInformation,dwStatusInformationLength);
99             break;
100         case INTERNET_STATUS_RESPONSE_RECEIVED:
101             ok(dwStatusInformationLength == sizeof(DWORD),
102                 "info length should be sizeof(DWORD) instead of %ld\n",
103                 dwStatusInformationLength);
104             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_RESPONSE_RECEIVED 0x%lx %ld\n",
105                 GetCurrentThreadId(), hInternet, dwContext,
106                 *(DWORD *)lpvStatusInformation,dwStatusInformationLength);
107             break;
108         case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
109             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_CTL_RESPONSE_RECEIVED %p %ld\n",
110                 GetCurrentThreadId(), hInternet,dwContext,
111                 lpvStatusInformation,dwStatusInformationLength);
112             break;
113         case INTERNET_STATUS_PREFETCH:
114             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_PREFETCH %p %ld\n",
115                 GetCurrentThreadId(), hInternet, dwContext,
116                 lpvStatusInformation,dwStatusInformationLength);
117             break;
118         case INTERNET_STATUS_CLOSING_CONNECTION:
119             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_CLOSING_CONNECTION %p %ld\n",
120                 GetCurrentThreadId(), hInternet, dwContext,
121                 lpvStatusInformation,dwStatusInformationLength);
122             break;
123         case INTERNET_STATUS_CONNECTION_CLOSED:
124             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_CONNECTION_CLOSED %p %ld\n",
125                 GetCurrentThreadId(), hInternet, dwContext,
126                 lpvStatusInformation,dwStatusInformationLength);
127             break;
128         case INTERNET_STATUS_HANDLE_CREATED:
129             ok(dwStatusInformationLength == sizeof(HINTERNET),
130                 "info length should be sizeof(HINTERNET) instead of %ld\n",
131                 dwStatusInformationLength);
132             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CREATED %p %ld\n",
133                 GetCurrentThreadId(), hInternet, dwContext,
134                 *(HINTERNET *)lpvStatusInformation,dwStatusInformationLength);
135             break;
136         case INTERNET_STATUS_HANDLE_CLOSING:
137             ok(dwStatusInformationLength == sizeof(HINTERNET),
138                 "info length should be sizeof(HINTERNET) instead of %ld\n",
139                 dwStatusInformationLength);
140             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_HANDLE_CLOSING %p %ld\n",
141                 GetCurrentThreadId(), hInternet, dwContext,
142                 *(HINTERNET *)lpvStatusInformation, dwStatusInformationLength);
143             break;
144         case INTERNET_STATUS_REQUEST_COMPLETE:
145         {
146             INTERNET_ASYNC_RESULT *iar = (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
147             ok(dwStatusInformationLength == sizeof(INTERNET_ASYNC_RESULT),
148                 "info length should be sizeof(INTERNET_ASYNC_RESULT) instead of %ld\n",
149                 dwStatusInformationLength);
150             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_REQUEST_COMPLETE {%ld,%ld} %ld\n",
151                 GetCurrentThreadId(), hInternet, dwContext,
152                 iar->dwResult,iar->dwError,dwStatusInformationLength);
153             SetEvent(hCompleteEvent);
154             break;
155         }
156         case INTERNET_STATUS_REDIRECT:
157             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_REDIRECT \"%s\" %ld\n",
158                 GetCurrentThreadId(), hInternet, dwContext,
159                 (LPCSTR)lpvStatusInformation, dwStatusInformationLength);
160             break;
161         case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
162             trace("%04lx:Callback %p 0x%lx INTERNET_STATUS_INTERMEDIATE_RESPONSE %p %ld\n",
163                 GetCurrentThreadId(), hInternet, dwContext,
164                 lpvStatusInformation, dwStatusInformationLength);
165             break;
166         default:
167             trace("%04lx:Callback %p 0x%lx %ld %p %ld\n",
168                 GetCurrentThreadId(), hInternet, dwContext, dwInternetStatus,
169                 lpvStatusInformation, dwStatusInformationLength);
170     }
171 }
172
173 static void InternetReadFile_test(int flags)
174 {
175     DWORD rc;
176     CHAR buffer[4000];
177     DWORD length;
178     DWORD out;
179     const char *types[2] = { "*", NULL };
180     HINTERNET hi, hic = 0, hor = 0;
181
182     hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
183
184     trace("Starting InternetReadFile test with flags 0x%x\n",flags);
185
186     trace("InternetOpenA <--\n");
187     hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
188     ok((hi != 0x0),"InternetOpen failed with error %ld\n", GetLastError());
189     trace("InternetOpenA -->\n");
190
191     if (hi == 0x0) goto abort;
192
193     InternetSetStatusCallback(hi,&callback);
194
195     trace("InternetConnectA <--\n");
196     hic=InternetConnectA(hi, "www.winehq.org", INTERNET_INVALID_PORT_NUMBER,
197                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
198     ok((hic != 0x0),"InternetConnect failed with error %ld\n", GetLastError());
199     trace("InternetConnectA -->\n");
200
201     if (hic == 0x0) goto abort;
202
203     trace("HttpOpenRequestA <--\n");
204     hor = HttpOpenRequestA(hic, "GET", "/about/", NULL, NULL, types,
205                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE,
206                            0xdeadbead);
207     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
208         /*
209          * If the internet name can't be resolved we are probably behind
210          * a firewall or in some other way not directly connected to the
211          * Internet. Not enough reason to fail the test. Just ignore and
212          * abort.
213          */
214     } else  {
215         ok((hor != 0x0),"HttpOpenRequest failed with error %ld\n", GetLastError());
216     }
217     trace("HttpOpenRequestA -->\n");
218
219     if (hor == 0x0) goto abort;
220
221     trace("HttpSendRequestA -->\n");
222     SetLastError(0xdeadbeef);
223     rc = HttpSendRequestA(hor, "", -1, NULL, 0);
224     if (flags & INTERNET_FLAG_ASYNC)
225         ok(((rc == 0)&&(GetLastError() == ERROR_IO_PENDING)),
226             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
227     else
228         ok((rc != 0) || GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED,
229            "Synchronous HttpSendRequest returning 0, error %ld\n", GetLastError());
230     trace("HttpSendRequestA <--\n");
231
232     if (flags & INTERNET_FLAG_ASYNC)
233         WaitForSingleObject(hCompleteEvent, INFINITE);
234
235     length = 4;
236     rc = InternetQueryOptionA(hor,INTERNET_OPTION_REQUEST_FLAGS,&out,&length);
237     trace("Option 0x17 -> %li  %li\n",rc,out);
238
239     length = 100;
240     rc = InternetQueryOptionA(hor,INTERNET_OPTION_URL,buffer,&length);
241     trace("Option 0x22 -> %li  %s\n",rc,buffer);
242
243     length = 4000;
244     rc = HttpQueryInfoA(hor,HTTP_QUERY_RAW_HEADERS,buffer,&length,0x0);
245     buffer[length]=0;
246     trace("Option 0x16 -> %li  %s\n",rc,buffer);
247
248     length = 4000;
249     rc = InternetQueryOptionA(hor,INTERNET_OPTION_URL,buffer,&length);
250     buffer[length]=0;
251     trace("Option 0x22 -> %li  %s\n",rc,buffer);
252
253     length = 16;
254     rc = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_LENGTH,&buffer,&length,0x0);
255     trace("Option 0x5 -> %li  %s  (%li)\n",rc,buffer,GetLastError());
256
257     length = 100;
258     rc = HttpQueryInfoA(hor,HTTP_QUERY_CONTENT_TYPE,buffer,&length,0x0);
259     buffer[length]=0;
260     trace("Option 0x1 -> %li  %s\n",rc,buffer);
261
262     SetLastError(0xdeadbeef);
263     rc = InternetReadFile(NULL, buffer, 100, &length);
264     ok(!rc, "InternetReadFile should have failed\n");
265     ok(GetLastError() == ERROR_INVALID_HANDLE,
266         "InternetReadFile should have set last error to ERROR_INVALID_HANDLE instead of %ld\n",
267         GetLastError());
268
269     length = 100;
270     trace("Entering Query loop\n");
271
272     while (length)
273     {
274         rc = InternetQueryDataAvailable(hor,&length,0x0,0x0);
275         ok(!(rc == 0 && length != 0),"InternetQueryDataAvailable failed\n");
276
277         if (length)
278         {
279             char *buffer;
280             buffer = HeapAlloc(GetProcessHeap(),0,length+1);
281
282             rc = InternetReadFile(hor,buffer,length,&length);
283
284             buffer[length]=0;
285
286             trace("ReadFile -> %li %li\n",rc,length);
287
288             HeapFree(GetProcessHeap(),0,buffer);
289         }
290     }
291 abort:
292     if (hor != 0x0) {
293         SetLastError(0xdeadbeef);
294         rc = InternetCloseHandle(hor);
295         ok ((rc != 0), "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n");
296         SetLastError(0xdeadbeef);
297         rc = InternetCloseHandle(hor);
298         ok ((rc == 0), "Double close of handle opened by HttpOpenRequestA succeeded\n");
299         ok (GetLastError() == ERROR_INVALID_HANDLE,
300             "Double close of handle should have set ERROR_INVALID_HANDLE instead of %ld\n",
301             GetLastError());
302     }
303     if (hic != 0x0) {
304         rc = InternetCloseHandle(hic);
305         ok ((rc != 0), "InternetCloseHandle of handle opened by InternetConnectA failed\n");
306     }
307     if (hi != 0x0) {
308       rc = InternetCloseHandle(hi);
309       ok ((rc != 0), "InternetCloseHandle of handle opened by InternetOpenA failed\n");
310       if (flags & INTERNET_FLAG_ASYNC)
311           Sleep(100);
312     }
313     CloseHandle(hCompleteEvent);
314 }
315
316 static void InternetReadFileExA_test(int flags)
317 {
318     DWORD rc;
319     DWORD length;
320     const char *types[2] = { "*", NULL };
321     HINTERNET hi, hic = 0, hor = 0;
322     INTERNET_BUFFERS inetbuffers;
323
324     hCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
325
326     trace("Starting InternetReadFileExA test with flags 0x%x\n",flags);
327
328     trace("InternetOpenA <--\n");
329     hi = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, flags);
330     ok((hi != 0x0),"InternetOpen failed with error %ld\n", GetLastError());
331     trace("InternetOpenA -->\n");
332
333     if (hi == 0x0) goto abort;
334
335     InternetSetStatusCallback(hi,&callback);
336
337     trace("InternetConnectA <--\n");
338     hic=InternetConnectA(hi, "www.winehq.org", INTERNET_INVALID_PORT_NUMBER,
339                          NULL, NULL, INTERNET_SERVICE_HTTP, 0x0, 0xdeadbeef);
340     ok((hic != 0x0),"InternetConnect failed with error %ld\n", GetLastError());
341     trace("InternetConnectA -->\n");
342
343     if (hic == 0x0) goto abort;
344
345     trace("HttpOpenRequestA <--\n");
346     hor = HttpOpenRequestA(hic, "GET", "/about/", NULL, NULL, types,
347                            INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_RESYNCHRONIZE,
348                            0xdeadbead);
349     if (hor == 0x0 && GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED) {
350         /*
351          * If the internet name can't be resolved we are probably behind
352          * a firewall or in some other way not directly connected to the
353          * Internet. Not enough reason to fail the test. Just ignore and
354          * abort.
355          */
356     } else  {
357         ok((hor != 0x0),"HttpOpenRequest failed with error %ld\n", GetLastError());
358     }
359     trace("HttpOpenRequestA -->\n");
360
361     if (hor == 0x0) goto abort;
362
363     trace("HttpSendRequestA -->\n");
364     SetLastError(0xdeadbeef);
365     rc = HttpSendRequestA(hor, "", -1, NULL, 0);
366     if (flags & INTERNET_FLAG_ASYNC)
367         ok(((rc == 0)&&(GetLastError() == ERROR_IO_PENDING)),
368             "Asynchronous HttpSendRequest NOT returning 0 with error ERROR_IO_PENDING\n");
369     else
370         ok((rc != 0) || GetLastError() == ERROR_INTERNET_NAME_NOT_RESOLVED,
371            "Synchronous HttpSendRequest returning 0, error %ld\n", GetLastError());
372     trace("HttpSendRequestA <--\n");
373
374     if (!rc && (GetLastError() == ERROR_IO_PENDING))
375         WaitForSingleObject(hCompleteEvent, INFINITE);
376
377     /* tests invalid dwStructSize */
378     inetbuffers.dwStructSize = sizeof(INTERNET_BUFFERS)+1;
379     inetbuffers.lpcszHeader = NULL;
380     inetbuffers.dwHeadersLength = 0;
381     inetbuffers.dwBufferLength = 10;
382     inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, 10);
383     inetbuffers.dwOffsetHigh = 1234;
384     inetbuffers.dwOffsetLow = 5678;
385     rc = InternetReadFileEx(hor, &inetbuffers, 0, 0xdeadcafe);
386     ok(!rc && (GetLastError() == ERROR_INVALID_PARAMETER),
387         "InternetReadFileEx should have failed with ERROR_INVALID_PARAMETER instead of %s, %ld\n",
388         rc ? "TRUE" : "FALSE", GetLastError());
389     HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
390
391     /* tests to see whether lpcszHeader is used - it isn't */
392     inetbuffers.dwStructSize = sizeof(INTERNET_BUFFERS);
393     inetbuffers.lpcszHeader = (LPCTSTR)0xdeadbeef;
394     inetbuffers.dwHeadersLength = 255;
395     inetbuffers.dwBufferLength = 0;
396     inetbuffers.lpvBuffer = NULL;
397     inetbuffers.dwOffsetHigh = 1234;
398     inetbuffers.dwOffsetLow = 5678;
399     rc = InternetReadFileEx(hor, &inetbuffers, 0, 0xdeadcafe);
400     ok(rc, "InternetReadFileEx failed with error %ld\n", GetLastError());
401
402     rc = InternetReadFileEx(NULL, &inetbuffers, 0, 0xdeadcafe);
403     ok(!rc && (GetLastError() == ERROR_INVALID_HANDLE),
404         "InternetReadFileEx should have failed with ERROR_INVALID_HANDLE instead of %s, %ld\n",
405         rc ? "TRUE" : "FALSE", GetLastError());
406
407     length = 0;
408     trace("Entering Query loop\n");
409
410     while (TRUE)
411     {
412         inetbuffers.dwStructSize = sizeof(INTERNET_BUFFERS);
413         inetbuffers.dwBufferLength = 1024;
414         inetbuffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, inetbuffers.dwBufferLength+1);
415         inetbuffers.dwOffsetHigh = 1234;
416         inetbuffers.dwOffsetLow = 5678;
417
418         rc = InternetReadFileExA(hor, &inetbuffers, IRF_ASYNC | IRF_USE_CONTEXT, 0xcafebabe);
419         if (!rc)
420         {
421             if (GetLastError() == ERROR_IO_PENDING)
422             {
423                 trace("InternetReadFileEx -> PENDING\n");
424                 WaitForSingleObject(hCompleteEvent, INFINITE);
425             }
426             else
427             {
428                 trace("InternetReadFileEx -> FAILED %ld\n", GetLastError());
429                 break;
430             }
431         }
432         else
433             trace("InternetReadFileEx -> SUCCEEDED\n");
434
435         trace("read %li bytes\n", inetbuffers.dwBufferLength);
436         ((char *)inetbuffers.lpvBuffer)[inetbuffers.dwBufferLength] = '\0';
437
438         ok(inetbuffers.dwOffsetHigh == 1234 && inetbuffers.dwOffsetLow == 5678,
439             "InternetReadFileEx sets offsets to 0x%lx%08lx\n",
440             inetbuffers.dwOffsetHigh, inetbuffers.dwOffsetLow);
441
442         HeapFree(GetProcessHeap(), 0, inetbuffers.lpvBuffer);
443
444         if (!inetbuffers.dwBufferLength)
445             break;
446
447         length += inetbuffers.dwBufferLength;
448     }
449     trace("Finished. Read %ld bytes\n", length);
450
451 abort:
452     if (hor) {
453         rc = InternetCloseHandle(hor);
454         ok ((rc != 0), "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n");
455         rc = InternetCloseHandle(hor);
456         ok ((rc == 0), "Double close of handle opened by HttpOpenRequestA succeeded\n");
457     }
458     if (hic) {
459         rc = InternetCloseHandle(hic);
460         ok ((rc != 0), "InternetCloseHandle of handle opened by InternetConnectA failed\n");
461     }
462     if (hi) {
463       rc = InternetCloseHandle(hi);
464       ok ((rc != 0), "InternetCloseHandle of handle opened by InternetOpenA failed\n");
465       if (flags & INTERNET_FLAG_ASYNC)
466           Sleep(100);
467     }
468     CloseHandle(hCompleteEvent);
469 }
470
471 static void InternetOpenUrlA_test(void)
472 {
473   HINTERNET myhinternet, myhttp;
474   char buffer[0x400];
475   URL_COMPONENTSA urlComponents;
476   char protocol[32], hostName[1024], userName[1024];
477   char password[1024], extra[1024], path[1024];
478   DWORD size, readbytes, totalbytes=0;
479   BOOL ret;
480   
481   myhinternet = InternetOpen("Winetest",0,NULL,NULL,INTERNET_FLAG_NO_CACHE_WRITE);
482   ok((myhinternet != 0), "InternetOpen failed, error %lx\n",GetLastError());
483   size = 0x400;
484   ret = InternetCanonicalizeUrl(TEST_URL, buffer, &size,ICU_BROWSER_MODE);
485   ok( ret, "InternetCanonicalizeUrl failed, error %lx\n",GetLastError());
486   
487   urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
488   urlComponents.lpszScheme = protocol;
489   urlComponents.dwSchemeLength = 32;
490   urlComponents.lpszHostName = hostName;
491   urlComponents.dwHostNameLength = 1024;
492   urlComponents.lpszUserName = userName;
493   urlComponents.dwUserNameLength = 1024;
494   urlComponents.lpszPassword = password;
495   urlComponents.dwPasswordLength = 1024;
496   urlComponents.lpszUrlPath = path;
497   urlComponents.dwUrlPathLength = 2048;
498   urlComponents.lpszExtraInfo = extra;
499   urlComponents.dwExtraInfoLength = 1024;
500   ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents);
501   ok( ret, "InternetCrackUrl failed, error %lx\n",GetLastError());
502   SetLastError(0);
503   myhttp = InternetOpenUrl(myhinternet, TEST_URL, 0, 0,
504                            INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_TRANSFER_BINARY,0);
505   if (GetLastError() == 12007)
506     return; /* WinXP returns this when not connected to the net */
507   ok((myhttp != 0),"InternetOpenUrl failed, error %lx\n",GetLastError());
508   ret = InternetReadFile(myhttp, buffer,0x400,&readbytes);
509   ok( ret, "InternetReadFile failed, error %lx\n",GetLastError());
510   totalbytes += readbytes;
511   while (readbytes && InternetReadFile(myhttp, buffer,0x400,&readbytes))
512     totalbytes += readbytes;
513   trace("read 0x%08lx bytes\n",totalbytes);
514 }
515   
516 static inline void copy_compsA(
517     URL_COMPONENTSA *src, 
518     URL_COMPONENTSA *dst, 
519     DWORD scheLen,
520     DWORD hostLen,
521     DWORD userLen,
522     DWORD passLen,
523     DWORD pathLen,
524     DWORD extrLen )
525 {
526     *dst = *src;
527     dst->dwSchemeLength    = scheLen;
528     dst->dwHostNameLength  = hostLen;
529     dst->dwUserNameLength  = userLen;
530     dst->dwPasswordLength  = passLen;
531     dst->dwUrlPathLength   = pathLen;
532     dst->dwExtraInfoLength = extrLen;
533     SetLastError(0xfaceabad);
534 }
535   
536 static inline void zero_compsA(
537     URL_COMPONENTSA *dst, 
538     DWORD scheLen,
539     DWORD hostLen,
540     DWORD userLen,
541     DWORD passLen,
542     DWORD pathLen,
543     DWORD extrLen )
544 {
545     ZeroMemory(dst, sizeof(URL_COMPONENTSA));
546     dst->dwStructSize = sizeof(URL_COMPONENTSA);
547     dst->dwSchemeLength    = scheLen;
548     dst->dwHostNameLength  = hostLen;
549     dst->dwUserNameLength  = userLen;
550     dst->dwPasswordLength  = passLen;
551     dst->dwUrlPathLength   = pathLen;
552     dst->dwExtraInfoLength = extrLen;
553     SetLastError(0xfaceabad);
554 }
555   
556 static void InternetCrackUrl_test(void)
557 {
558   URL_COMPONENTSA urlSrc, urlComponents;
559   char protocol[32], hostName[1024], userName[1024];
560   char password[1024], extra[1024], path[1024];
561   BOOL ret;
562   DWORD GLE;
563
564   ZeroMemory(&urlSrc, sizeof(urlSrc));
565   urlSrc.dwStructSize = sizeof(urlSrc);
566   urlSrc.lpszScheme = protocol;
567   urlSrc.lpszHostName = hostName;
568   urlSrc.lpszUserName = userName;
569   urlSrc.lpszPassword = password;
570   urlSrc.lpszUrlPath = path;
571   urlSrc.lpszExtraInfo = extra;
572
573   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
574   ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents);
575   ok( ret, "InternetCrackUrl failed, error %lx\n",GetLastError());
576   ok((strcmp(TEST_URL_PATH,path) == 0),"path cracked wrong\n");
577
578   /* Bug 1805: Confirm the returned lengths are correct:                     */
579   /* 1. When extra info split out explicitly */
580   zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 1);
581   ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed, error 0x%lx\n", GetLastError());
582   ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATH),".dwUrlPathLength should be %ld, but is %ld\n", (DWORD)strlen(TEST_URL2_PATH), urlComponents.dwUrlPathLength);
583   ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATH,strlen(TEST_URL2_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATH, urlComponents.lpszUrlPath);
584   ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %ld, but is %ld\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength);
585   ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName);
586   ok(urlComponents.dwExtraInfoLength == strlen(TEST_URL2_EXTRA),".dwExtraInfoLength should be %ld, but is %ld\n", (DWORD)strlen(TEST_URL2_EXTRA), urlComponents.dwExtraInfoLength);
587   ok(!strncmp(urlComponents.lpszExtraInfo,TEST_URL2_EXTRA,strlen(TEST_URL2_EXTRA)),"lpszExtraInfo should be %s but is %s\n", TEST_URL2_EXTRA, urlComponents.lpszHostName);
588
589   /* 2. When extra info is not split out explicitly and is in url path */
590   zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 0);
591   ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed with GLE 0x%lx\n",GetLastError());
592   ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATHEXTRA),".dwUrlPathLength should be %ld, but is %ld\n", (DWORD)strlen(TEST_URL2_PATHEXTRA), urlComponents.dwUrlPathLength);
593   ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATHEXTRA,strlen(TEST_URL2_PATHEXTRA)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATHEXTRA, urlComponents.lpszUrlPath);
594   ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %ld, but is %ld\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength);
595   ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName);
596
597   /*3. Check for %20 */
598   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
599   ok(InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents),"InternetCrackUrl failed with GLE 0x%lx\n",GetLastError());
600
601
602   /* Tests for lpsz* members pointing to real strings while 
603    * some corresponding length members are set to zero */
604   copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
605   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
606   ok(ret==1, "InternetCrackUrl returned %d with GLE=%ld (expected to return 1)\n",
607     ret, GetLastError());
608
609   copy_compsA(&urlSrc, &urlComponents, 32, 0, 1024, 1024, 2048, 1024);
610   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
611   ok(ret==1, "InternetCrackUrl returned %d with GLE=%ld (expected to return 1)\n",
612     ret, GetLastError());
613
614   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 0, 1024, 2048, 1024);
615   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
616   ok(ret==1, "InternetCrackUrl returned %d with GLE=%ld (expected to return 1)\n",
617     ret, GetLastError());
618
619   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 0, 2048, 1024);
620   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
621   ok(ret==1, "InternetCrackUrl returned %d with GLE=%ld (expected to return 1)\n",
622     ret, GetLastError());
623
624   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 0, 1024);
625   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
626   GLE = GetLastError();
627   todo_wine
628   ok(ret==0 && (GLE==ERROR_INVALID_HANDLE || GLE==ERROR_INSUFFICIENT_BUFFER),
629      "InternetCrackUrl returned %d with GLE=%ld (expected to return 0 and ERROR_INVALID_HANDLE or ERROR_INSUFFICIENT_BUFFER)\n",
630     ret, GLE);
631
632   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 0);
633   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
634   GLE = GetLastError();
635   todo_wine
636   ok(ret==0 && (GLE==ERROR_INVALID_HANDLE || GLE==ERROR_INSUFFICIENT_BUFFER),
637      "InternetCrackUrl returned %d with GLE=%ld (expected to return 0 and ERROR_INVALID_HANDLE or ERROR_INSUFFICIENT_BUFFER)\n",
638     ret, GLE);
639
640   copy_compsA(&urlSrc, &urlComponents, 0, 0, 0, 0, 0, 0);
641   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
642   GLE = GetLastError();
643   todo_wine
644   ok(ret==0 && GLE==ERROR_INVALID_PARAMETER,
645      "InternetCrackUrl returned %d with GLE=%ld (expected to return 0 and ERROR_INVALID_PARAMETER)\n",
646     ret, GLE);
647 }
648
649 static void InternetCrackUrlW_test(void)
650 {
651     WCHAR url[] = {
652         'h','t','t','p',':','/','/','1','9','2','.','1','6','8','.','0','.','2','2','/',
653         'C','F','I','D','E','/','m','a','i','n','.','c','f','m','?','C','F','S','V','R',
654         '=','I','D','E','&','A','C','T','I','O','N','=','I','D','E','_','D','E','F','A',
655         'U','L','T', 0 };
656     URL_COMPONENTSW comp;
657     WCHAR scheme[20], host[20], user[20], pwd[20], urlpart[50], extra[50];
658     BOOL r;
659
660     urlpart[0]=0;
661     scheme[0]=0;
662     extra[0]=0;
663     host[0]=0;
664     user[0]=0;
665     pwd[0]=0;
666     memset(&comp, 0, sizeof comp);
667     comp.dwStructSize = sizeof comp;
668     comp.lpszScheme = scheme;
669     comp.dwSchemeLength = sizeof scheme;
670     comp.lpszHostName = host;
671     comp.dwHostNameLength = sizeof host;
672     comp.lpszUserName = user;
673     comp.dwUserNameLength = sizeof user;
674     comp.lpszPassword = pwd;
675     comp.dwPasswordLength = sizeof pwd;
676     comp.lpszUrlPath = urlpart;
677     comp.dwUrlPathLength = sizeof urlpart;
678     comp.lpszExtraInfo = extra;
679     comp.dwExtraInfoLength = sizeof extra;
680
681     r = InternetCrackUrlW(url, 0, 0, &comp );
682     ok( r, "failed to crack url\n");
683     ok( comp.dwSchemeLength == 4, "scheme length wrong\n");
684     ok( comp.dwHostNameLength == 12, "host length wrong\n");
685     ok( comp.dwUserNameLength == 0, "user length wrong\n");
686     ok( comp.dwPasswordLength == 0, "password length wrong\n");
687     ok( comp.dwUrlPathLength == 15, "url length wrong\n");
688     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
689  
690     urlpart[0]=0;
691     scheme[0]=0;
692     extra[0]=0;
693     host[0]=0;
694     user[0]=0;
695     pwd[0]=0;
696     memset(&comp, 0, sizeof comp);
697     comp.dwStructSize = sizeof comp;
698     comp.lpszHostName = host;
699     comp.dwHostNameLength = sizeof host;
700     comp.lpszUrlPath = urlpart;
701     comp.dwUrlPathLength = sizeof urlpart;
702
703     r = InternetCrackUrlW(url, 0, 0, &comp );
704     ok( r, "failed to crack url\n");
705     ok( comp.dwSchemeLength == 0, "scheme length wrong\n");
706     ok( comp.dwHostNameLength == 12, "host length wrong\n");
707     ok( comp.dwUserNameLength == 0, "user length wrong\n");
708     ok( comp.dwPasswordLength == 0, "password length wrong\n");
709     ok( comp.dwUrlPathLength == 44, "url length wrong\n");
710     ok( comp.dwExtraInfoLength == 0, "extra length wrong\n");
711
712     urlpart[0]=0;
713     scheme[0]=0;
714     extra[0]=0;
715     host[0]=0;
716     user[0]=0;
717     pwd[0]=0;
718     memset(&comp, 0, sizeof comp);
719     comp.dwStructSize = sizeof comp;
720     comp.lpszHostName = host;
721     comp.dwHostNameLength = sizeof host;
722     comp.lpszUrlPath = urlpart;
723     comp.dwUrlPathLength = sizeof urlpart;
724     comp.lpszExtraInfo = NULL;
725     comp.dwExtraInfoLength = sizeof extra;
726
727     r = InternetCrackUrlW(url, 0, 0, &comp );
728     ok( r, "failed to crack url\n");
729     ok( comp.dwSchemeLength == 0, "scheme length wrong\n");
730     ok( comp.dwHostNameLength == 12, "host length wrong\n");
731     ok( comp.dwUserNameLength == 0, "user length wrong\n");
732     ok( comp.dwPasswordLength == 0, "password length wrong\n");
733     ok( comp.dwUrlPathLength == 15, "url length wrong\n");
734     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
735 }
736
737 static void InternetTimeFromSystemTimeA_test(void)
738 {
739     BOOL ret;
740     static const SYSTEMTIME time = { 2005, 1, 5, 7, 12, 6, 35, 0 };
741     char string[INTERNET_RFC1123_BUFSIZE];
742     static const char expect[] = "Fri, 07 Jan 2005 12:06:35 GMT";
743
744     ret = InternetTimeFromSystemTimeA( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string) );
745     ok( ret, "InternetTimeFromSystemTimeA failed (%ld)\n", GetLastError() );
746
747     ok( !memcmp( string, expect, sizeof(expect) ),
748         "InternetTimeFromSystemTimeA failed (%ld)\n", GetLastError() );
749 }
750
751 static void InternetTimeFromSystemTimeW_test(void)
752 {
753     BOOL ret;
754     static const SYSTEMTIME time = { 2005, 1, 5, 7, 12, 6, 35, 0 };
755     WCHAR string[INTERNET_RFC1123_BUFSIZE + 1];
756     static const WCHAR expect[] = { 'F','r','i',',',' ','0','7',' ','J','a','n',' ','2','0','0','5',' ',
757                                     '1','2',':','0','6',':','3','5',' ','G','M','T',0 };
758
759     ret = InternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string) );
760     ok( ret, "InternetTimeFromSystemTimeW failed (%ld)\n", GetLastError() );
761
762     ok( !memcmp( string, expect, sizeof(expect) ),
763         "InternetTimeFromSystemTimeW failed (%ld)\n", GetLastError() );
764 }
765
766 static void InternetTimeToSystemTimeA_test(void)
767 {
768     BOOL ret;
769     SYSTEMTIME time;
770     static const SYSTEMTIME expect = { 2005, 1, 5, 7, 12, 6, 35, 0 };
771     static const char string[] = "Fri, 07 Jan 2005 12:06:35 GMT";
772     static const char string2[] = " fri 7 jan 2005 12 06 35";
773
774     ret = InternetTimeToSystemTimeA( string, &time, 0 );
775     ok( ret, "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
776     ok( !memcmp( &time, &expect, sizeof(expect) ),
777         "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
778
779     ret = InternetTimeToSystemTimeA( string2, &time, 0 );
780     ok( ret, "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
781     ok( !memcmp( &time, &expect, sizeof(expect) ),
782         "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
783 }
784
785 static void InternetTimeToSystemTimeW_test(void)
786 {
787     BOOL ret;
788     SYSTEMTIME time;
789     static const SYSTEMTIME expect = { 2005, 1, 5, 7, 12, 6, 35, 0 };
790     static const WCHAR string[] = { 'F','r','i',',',' ','0','7',' ','J','a','n',' ','2','0','0','5',' ',
791                                     '1','2',':','0','6',':','3','5',' ','G','M','T',0 };
792     static const WCHAR string2[] = { ' ','f','r','i',' ','7',' ','j','a','n',' ','2','0','0','5',' ',
793                                      '1','2',' ','0','6',' ','3','5',0 };
794     static const WCHAR string3[] = { 'F','r',0 };
795
796     ret = InternetTimeToSystemTimeW( NULL, NULL, 0 );
797     ok( !ret, "InternetTimeToSystemTimeW succeeded (%ld)\n", GetLastError() );
798
799     ret = InternetTimeToSystemTimeW( NULL, &time, 0 );
800     ok( !ret, "InternetTimeToSystemTimeW succeeded (%ld)\n", GetLastError() );
801
802     ret = InternetTimeToSystemTimeW( string, NULL, 0 );
803     ok( !ret, "InternetTimeToSystemTimeW succeeded (%ld)\n", GetLastError() );
804
805     ret = InternetTimeToSystemTimeW( string, &time, 1 );
806     ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
807
808     ret = InternetTimeToSystemTimeW( string, &time, 0 );
809     ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
810     ok( !memcmp( &time, &expect, sizeof(expect) ),
811         "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
812
813     ret = InternetTimeToSystemTimeW( string2, &time, 0 );
814     ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
815     ok( !memcmp( &time, &expect, sizeof(expect) ),
816         "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
817
818     ret = InternetTimeToSystemTimeW( string3, &time, 0 );
819     ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
820 }
821
822 static void fill_url_components(LPURL_COMPONENTS lpUrlComponents)
823 {
824         lpUrlComponents->dwStructSize = sizeof(URL_COMPONENTS);
825         lpUrlComponents->lpszScheme = "http";
826         lpUrlComponents->dwSchemeLength = strlen(lpUrlComponents->lpszScheme);
827         lpUrlComponents->nScheme = INTERNET_SCHEME_HTTP;
828         lpUrlComponents->lpszHostName = "www.winehq.org";
829         lpUrlComponents->dwHostNameLength = strlen(lpUrlComponents->lpszHostName);
830         lpUrlComponents->nPort = 80;
831         lpUrlComponents->lpszUserName = "username";
832         lpUrlComponents->dwUserNameLength = strlen(lpUrlComponents->lpszUserName);
833         lpUrlComponents->lpszPassword = "password";
834         lpUrlComponents->dwPasswordLength = strlen(lpUrlComponents->lpszPassword);
835         lpUrlComponents->lpszUrlPath = "/site/about";
836         lpUrlComponents->dwUrlPathLength = strlen(lpUrlComponents->lpszUrlPath);
837         lpUrlComponents->lpszExtraInfo = "";
838         lpUrlComponents->dwExtraInfoLength = strlen(lpUrlComponents->lpszExtraInfo);
839 }
840
841 static void InternetCreateUrlA_test()
842 {
843         URL_COMPONENTS urlComp;
844         LPSTR szUrl;
845         DWORD len = -1;
846         BOOL ret;
847
848         /* test NULL lpUrlComponents */
849         ret = InternetCreateUrlA(NULL, 0, NULL, &len);
850         SetLastError(0xdeadbeef);
851         ok(!ret, "Expected failure\n");
852         ok(GetLastError() == 0xdeadbeef,
853                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
854         ok(len == -1, "Expected len -1, got %ld\n", len);
855
856         /* test garbage lpUrlComponets */
857         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
858         SetLastError(0xdeadbeef);
859         ok(!ret, "Expected failure\n");
860         ok(GetLastError() == 0xdeadbeef,
861                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
862         ok(len == -1, "Expected len -1, got %ld\n", len);
863
864         /* test zero'ed lpUrlComponents */
865         ZeroMemory(&urlComp, sizeof(URL_COMPONENTS));
866         SetLastError(0xdeadbeef);
867         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
868         ok(!ret, "Expected failure\n");
869         ok(GetLastError() == ERROR_INVALID_PARAMETER,
870                 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
871         ok(len == -1, "Expected len -1, got %ld\n", len);
872
873         /* test valid lpUrlComponets, NULL lpdwUrlLength */
874         fill_url_components(&urlComp);
875         SetLastError(0xdeadbeef);
876         ret = InternetCreateUrlA(&urlComp, 0, NULL, NULL);
877         ok(!ret, "Expected failure\n");
878         ok(GetLastError() == ERROR_INVALID_PARAMETER,
879                 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
880         ok(len == -1, "Expected len -1, got %ld\n", len);
881
882         /* test valid lpUrlComponets, emptry szUrl
883          * lpdwUrlLength is size of buffer required on exit, including
884          * the terminating null when GLE == ERROR_INSUFFICIENT_BUFFER
885          */
886         SetLastError(0xdeadbeef);
887         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
888         ok(!ret, "Expected failure\n");
889         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
890                 "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
891         ok(len == 51, "Expected len 51, got %ld\n", len);
892
893         /* test correct size, NULL szUrl */
894         fill_url_components(&urlComp);
895         SetLastError(0xdeadbeef);
896         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
897         ok(!ret, "Expected failure\n");
898         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
899                 "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
900         ok(len == 51, "Expected len 51, got %ld\n", len);
901
902         /* test valid lpUrlComponets, alloced szUrl, small size */
903         SetLastError(0xdeadbeef);
904         szUrl = HeapAlloc(GetProcessHeap(), 0, len);
905         len -= 2;
906         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
907         ok(!ret, "Expected failure\n");
908         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
909                 "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
910         ok(len == 51, "Expected len 51, got %ld\n", len);
911
912         /* alloced szUrl, NULL lpszScheme
913      * shows that it uses dwXLength instead of strlen(lpszX)
914          */
915         SetLastError(0xdeadbeef);
916         urlComp.lpszScheme = NULL;
917         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
918         ok(ret, "Expected success\n");
919         ok(GetLastError() == 0xdeadbeef,
920                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
921         ok(len == 50, "Expected len 50, got %ld\n", len);
922
923         /* alloced szUrl, invalid nScheme
924          * any nScheme out of range seems ignored
925          */
926         fill_url_components(&urlComp);
927         SetLastError(0xdeadbeef);
928         urlComp.nScheme = -3;
929         len++;
930         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
931         ok(ret, "Expected success\n");
932         ok(GetLastError() == 0xdeadbeef,
933                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
934         ok(len == 50, "Expected len 50, got %ld\n", len);
935
936         /* test valid lpUrlComponets, alloced szUrl */
937         fill_url_components(&urlComp);
938         SetLastError(0xdeadbeef);
939         len = 51;
940         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
941         ok(ret, "Expected success\n");
942         ok(GetLastError() == 0xdeadbeef,
943                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
944         ok(len == 50, "Expected len 50, got %ld\n", len);
945         ok(strstr(szUrl, "80") == NULL, "Didn't expect to find 80 in szUrl\n");
946         ok(!strcmp(szUrl, CREATE_URL1), "Expected %s, got %s\n", CREATE_URL1, szUrl);
947
948         /* valid username, NULL password */
949         fill_url_components(&urlComp);
950         SetLastError(0xdeadbeef);
951         urlComp.lpszPassword = NULL;
952         len = 42;
953         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
954         ok(ret, "Expected success\n");
955         ok(GetLastError() == 0xdeadbeef,
956                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
957         ok(len == 41, "Expected len 41, got %ld\n", len);
958         ok(!strcmp(szUrl, CREATE_URL2), "Expected %s, got %s\n", CREATE_URL2, szUrl);
959
960         /* valid username, empty password */
961         fill_url_components(&urlComp);
962         SetLastError(0xdeadbeef);
963         urlComp.lpszPassword = "";
964         len = 51;
965         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
966         ok(ret, "Expected success\n");
967         ok(GetLastError() == 0xdeadbeef,
968                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
969         ok(len == 50, "Expected len 50, got %ld\n", len);
970         ok(!strcmp(szUrl, CREATE_URL3), "Expected %s, got %s\n", CREATE_URL2, szUrl);
971
972         /* valid password, NULL username
973          * if password is provided, username has to exist
974          */
975         fill_url_components(&urlComp);
976         SetLastError(0xdeadbeef);
977         urlComp.lpszUserName = NULL;
978         len = 42;
979         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
980         ok(!ret, "Expected failure\n");
981         ok(GetLastError() == ERROR_INVALID_PARAMETER,
982                 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
983         ok(len == 42, "Expected len 42, got %ld\n", len);
984         ok(!strcmp(szUrl, CREATE_URL3), "Expected %s, got %s\n", CREATE_URL2, szUrl);
985
986         /* valid password, empty username
987          * if password is provided, username has to exist
988          */
989         fill_url_components(&urlComp);
990         SetLastError(0xdeadbeef);
991         urlComp.lpszUserName = "";
992         len = 51;
993         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
994         ok(ret, "Expected success\n");
995         ok(GetLastError() == 0xdeadbeef,
996                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
997         ok(len == 50, "Expected len 50, got %ld\n", len);
998         ok(!strcmp(szUrl, CREATE_URL5), "Expected %s, got %s\n", CREATE_URL4, szUrl);
999
1000         /* NULL username, NULL password */
1001         fill_url_components(&urlComp);
1002         SetLastError(0xdeadbeef);
1003         urlComp.lpszUserName = NULL;
1004         urlComp.lpszPassword = NULL;
1005         len = 42;
1006         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
1007         ok(ret, "Expected success\n");
1008         ok(GetLastError() == 0xdeadbeef,
1009                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
1010         ok(len == 32, "Expected len 32, got %ld\n", len);
1011         ok(!strcmp(szUrl, CREATE_URL4), "Expected %s, got %s\n", CREATE_URL3, szUrl);
1012
1013         /* empty username, empty password */
1014         fill_url_components(&urlComp);
1015         SetLastError(0xdeadbeef);
1016         urlComp.lpszUserName = "";
1017         urlComp.lpszPassword = "";
1018         len = 51;
1019         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
1020         ok(ret, "Expected success\n");
1021         ok(GetLastError() == 0xdeadbeef,
1022                 "Expected 0xdeadbeef, got %ld\n", GetLastError());
1023         ok(len == 50, "Expected len 50, got %ld\n", len);
1024         ok(!strcmp(szUrl, CREATE_URL5), "Expected %s, got %s\n", CREATE_URL4, szUrl);
1025
1026         /* if lpszScheme != "http" or nPort != 80, display nPort.
1027          * depending on nScheme, displays only first x characters
1028          * of lpszScheme:
1029          *  HTTP: x=4
1030          *  FTP: x=3 etc
1031          */
1032         fill_url_components(&urlComp);
1033         HeapFree(GetProcessHeap(), 0, szUrl);
1034         urlComp.lpszScheme = "nhttp";
1035         len = 54;
1036         szUrl = HeapAlloc(GetProcessHeap(), 0, len);
1037         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
1038         ok(ret, "Expected success\n");
1039         ok(len == 53, "Expected len 51, got %ld\n", len);
1040         ok(strstr(szUrl, "80") != NULL, "Expected to find 80 in szUrl\n");
1041         ok(!strncmp(szUrl, "nhtt://", 7), "Expected 'nhtt://'\n");
1042         ok(!strcmp(szUrl, CREATE_URL6), "Expected %s, got %s\n", CREATE_URL5, szUrl);
1043
1044         /* if lpszScheme != "http" or nPort != 80, display nPort */
1045         HeapFree(GetProcessHeap(), 0, szUrl);
1046         urlComp.lpszScheme = "http";
1047         urlComp.nPort = 42;
1048         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
1049         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
1050         ok(ret, "Expected success\n");
1051         ok(len == 53, "Expected len 53, got %ld\n", len);
1052         ok(strstr(szUrl, "42") != NULL, "Expected to find 42 in szUrl\n");
1053         ok(!strcmp(szUrl, CREATE_URL7), "Expected %s, got %s\n", CREATE_URL6, szUrl);
1054
1055         HeapFree(GetProcessHeap(), 0, szUrl);
1056 }
1057
1058 static void HttpSendRequestEx_test(void)
1059 {
1060     HINTERNET hSession;
1061     HINTERNET hConnect;
1062     HINTERNET hRequest;
1063
1064     INTERNET_BUFFERS BufferIn;
1065     DWORD dwBytesWritten;
1066     DWORD dwBytesRead;
1067     CHAR szBuffer[256];
1068     int i;
1069     BOOL ret;
1070
1071     static const char szPostData[] = "mode=Test";
1072     static const char szContentType[] = "Content-Type: application/x-www-form-urlencoded";
1073     
1074     hSession = InternetOpen("Wine Regression Test",
1075             INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1076     ok( hSession != NULL ,"Unable to open Internet session\n");
1077     hConnect = InternetConnect(hSession, "crossover.codeweavers.com",
1078             INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1079             0);
1080     ok( hConnect != NULL, "Unable to connect to http://crossover.codeweavers.com\n");
1081     hRequest = HttpOpenRequest(hConnect, "POST", "/posttest.php",
1082             NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1083     ok( hRequest != NULL, "Failed to open request handle\n");
1084
1085
1086     BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS);
1087     BufferIn.Next = (LPINTERNET_BUFFERS)0xdeadcab;
1088     BufferIn.lpcszHeader = szContentType;
1089     BufferIn.dwHeadersLength = sizeof(szContentType);
1090     BufferIn.dwHeadersTotal = sizeof(szContentType);
1091     BufferIn.lpvBuffer = (LPVOID)szPostData;
1092     BufferIn.dwBufferLength = 3;
1093     BufferIn.dwBufferTotal = sizeof(szPostData)-1;
1094     BufferIn.dwOffsetLow = 0;
1095     BufferIn.dwOffsetHigh = 0;
1096
1097     ret = HttpSendRequestEx(hRequest, &BufferIn, NULL, 0 ,0);
1098     ok(ret, "HttpSendRequestEx Failed with error %ld\n", GetLastError());
1099
1100     for (i = 3; szPostData[i]; i++)
1101         ok(InternetWriteFile(hRequest, &szPostData[i], 1, &dwBytesWritten),
1102                 "InternetWriteFile failed\n");
1103
1104     ok(HttpEndRequest(hRequest, NULL, 0, 0), "HttpEndRequest Failed\n");
1105
1106     ok(InternetReadFile(hRequest, szBuffer, 255, &dwBytesRead),
1107             "Unable to read response\n");
1108     szBuffer[dwBytesRead] = 0;
1109
1110     ok(dwBytesRead == 13,"Read %lu bytes instead of 13\n",dwBytesRead);
1111     ok(strncmp(szBuffer,"mode => Test\n",dwBytesRead)==0,"Got string %s\n",szBuffer);
1112
1113     ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
1114     ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
1115     ok(InternetCloseHandle(hSession), "Close session handle failed\n");
1116 }
1117
1118 static void HttpHeaders_test(void)
1119 {
1120     HINTERNET hSession;
1121     HINTERNET hConnect;
1122     HINTERNET hRequest;
1123     CHAR      buffer[256];
1124     DWORD     len = 256;
1125     DWORD     index = 0;
1126
1127     hSession = InternetOpen("Wine Regression Test",
1128             INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
1129     ok( hSession != NULL ,"Unable to open Internet session\n");
1130     hConnect = InternetConnect(hSession, "crossover.codeweavers.com",
1131             INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0,
1132             0);
1133     ok( hConnect != NULL, "Unable to connect to http://crossover.codeweavers.com\n");
1134     hRequest = HttpOpenRequest(hConnect, "POST", "/posttest.php",
1135             NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
1136     ok( hRequest != NULL, "Failed to open request handle\n");
1137
1138     index = 0;
1139     len = sizeof(buffer);
1140     strcpy(buffer,"Warning");
1141     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1142                buffer,&len,&index)==0,"Warning hearder reported as Existing\n");
1143     
1144     ok(HttpAddRequestHeaders(hRequest,"Warning:test1",-1,HTTP_ADDREQ_FLAG_ADD),
1145             "Failed to add new header\n");
1146
1147     index = 0;
1148     len = sizeof(buffer);
1149     strcpy(buffer,"Warning");
1150     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1151                 buffer,&len,&index),"Unable to query header\n");
1152     ok(index == 1, "Index was not incremented\n");
1153     ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1154     len = sizeof(buffer);
1155     strcpy(buffer,"Warning");
1156     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1157                 buffer,&len,&index)==0,"Second Index Should Not Exist\n");
1158
1159     ok(HttpAddRequestHeaders(hRequest,"Warning:test2",-1,HTTP_ADDREQ_FLAG_ADD),
1160             "Failed to add duplicate header using HTTP_ADDREQ_FLAG_ADD\n");
1161
1162     index = 0;
1163     len = sizeof(buffer);
1164     strcpy(buffer,"Warning");
1165     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1166                 buffer,&len,&index),"Unable to query header\n");
1167     ok(index == 1, "Index was not incremented\n");
1168     ok(strcmp(buffer,"test1")==0, "incorrect string was returned(%s)\n",buffer);
1169     len = sizeof(buffer);
1170     strcpy(buffer,"Warning");
1171     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1172                 buffer,&len,&index),"Failed to get second header\n");
1173     ok(index == 2, "Index was not incremented\n");
1174     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1175     len = sizeof(buffer);
1176     strcpy(buffer,"Warning");
1177     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1178                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1179
1180     ok(HttpAddRequestHeaders(hRequest,"Warning:test3",-1,HTTP_ADDREQ_FLAG_REPLACE), "Failed to replace header using HTTP_ADDREQ_FLAG_REPLACE\n");
1181
1182     index = 0;
1183     len = sizeof(buffer);
1184     strcpy(buffer,"Warning");
1185     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1186                 buffer,&len,&index),"Unable to query header\n");
1187     ok(index == 1, "Index was not incremented\n");
1188     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1189     len = sizeof(buffer);
1190     strcpy(buffer,"Warning");
1191     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1192                 buffer,&len,&index),"Failed to get second header\n");
1193     ok(index == 2, "Index was not incremented\n");
1194     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1195     len = sizeof(buffer);
1196     strcpy(buffer,"Warning");
1197     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1198                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1199     
1200     ok(HttpAddRequestHeaders(hRequest,"Warning:test4",-1,HTTP_ADDREQ_FLAG_ADD_IF_NEW)==0, "HTTP_ADDREQ_FLAG_ADD_IF_NEW replaced existing header\n");
1201
1202     index = 0;
1203     len = sizeof(buffer);
1204     strcpy(buffer,"Warning");
1205     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1206                 buffer,&len,&index),"Unable to query header\n");
1207     ok(index == 1, "Index was not incremented\n");
1208     ok(strcmp(buffer,"test2")==0, "incorrect string was returned(%s)\n",buffer);
1209     len = sizeof(buffer);
1210     strcpy(buffer,"Warning");
1211     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1212                 buffer,&len,&index),"Failed to get second header\n");
1213     ok(index == 2, "Index was not incremented\n");
1214     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1215     len = sizeof(buffer);
1216     strcpy(buffer,"Warning");
1217     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1218                 buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1219
1220     ok(HttpAddRequestHeaders(hRequest,"Warning:test4",-1, HTTP_ADDREQ_FLAG_COALESCE), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1221
1222     index = 0;
1223     len = sizeof(buffer);
1224     strcpy(buffer,"Warning");
1225     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS,
1226                 buffer,&len,&index),"Unable to query header\n");
1227     ok(index == 1, "Index was not incremented\n");
1228     ok(strcmp(buffer,"test2, test4")==0, "incorrect string was returned(%s)\n", buffer);
1229     len = sizeof(buffer);
1230     strcpy(buffer,"Warning");
1231     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1232     ok(index == 2, "Index was not incremented\n");
1233     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1234     len = sizeof(buffer);
1235     strcpy(buffer,"Warning");
1236     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1237
1238     ok(HttpAddRequestHeaders(hRequest,"Warning:test5",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1239
1240     index = 0;
1241     len = sizeof(buffer);
1242     strcpy(buffer,"Warning");
1243     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1244     ok(index == 1, "Index was not incremented\n");
1245     ok(strcmp(buffer,"test2, test4, test5")==0, "incorrect string was returned(%s)\n",buffer);
1246     len = sizeof(buffer);
1247     strcpy(buffer,"Warning");
1248     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1249     ok(index == 2, "Index was not incremented\n");
1250     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1251     len = sizeof(buffer);
1252     strcpy(buffer,"Warning");
1253     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1254
1255     ok(HttpAddRequestHeaders(hRequest,"Warning:test6",-1, HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON), "HTTP_ADDREQ_FLAG_COALESCE Did not work\n");
1256
1257     index = 0;
1258     len = sizeof(buffer);
1259     strcpy(buffer,"Warning");
1260     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1261     ok(index == 1, "Index was not incremented\n");
1262     ok(strcmp(buffer,"test2, test4, test5; test6")==0, "incorrect string was returned(%s)\n",buffer);
1263     len = sizeof(buffer);
1264     strcpy(buffer,"Warning");
1265     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1266     ok(index == 2, "Index was not incremented\n");
1267     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1268     len = sizeof(buffer);
1269     strcpy(buffer,"Warning");
1270     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1271
1272     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");
1273
1274     index = 0;
1275     len = sizeof(buffer);
1276     strcpy(buffer,"Warning");
1277     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Unable to query header\n");
1278     ok(index == 1, "Index was not incremented\n");
1279     ok(strcmp(buffer,"test3")==0, "incorrect string was returned(%s)\n",buffer);
1280     len = sizeof(buffer);
1281     strcpy(buffer,"Warning");
1282     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index),"Failed to get second header\n");
1283     ok(index == 2, "Index was not incremented\n");
1284     ok(strcmp(buffer,"test7")==0, "incorrect string was returned(%s)\n",buffer);
1285     len = sizeof(buffer);
1286     strcpy(buffer,"Warning");
1287     ok(HttpQueryInfo(hRequest,HTTP_QUERY_CUSTOM|HTTP_QUERY_FLAG_REQUEST_HEADERS, buffer,&len,&index)==0,"Third Header Should Not Exist\n");
1288
1289     
1290     ok(InternetCloseHandle(hRequest), "Close request handle failed\n");
1291     ok(InternetCloseHandle(hConnect), "Close connect handle failed\n");
1292     ok(InternetCloseHandle(hSession), "Close session handle failed\n");
1293 }
1294
1295
1296
1297 START_TEST(http)
1298 {
1299     InternetReadFile_test(INTERNET_FLAG_ASYNC);
1300     InternetReadFile_test(0);
1301     InternetReadFileExA_test(INTERNET_FLAG_ASYNC);
1302     InternetCrackUrl_test();
1303     InternetOpenUrlA_test();
1304     InternetCrackUrlW_test();
1305     InternetTimeFromSystemTimeA_test();
1306     InternetTimeFromSystemTimeW_test();
1307     InternetTimeToSystemTimeA_test();
1308     InternetTimeToSystemTimeW_test();
1309     InternetCreateUrlA_test();
1310     HttpSendRequestEx_test();
1311     HttpHeaders_test();
1312 }