Reverse the order for deleting the items in resetcontent to correctly
[wine] / dlls / wininet / tests / http.c
1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include "windef.h"
6 #include "winbase.h"
7 #include "wininet.h"
8
9 #include "wine/test.h"
10
11 #define TEST_URL "http://www.winehq.org/site/about"
12 #define TEST_URL_PATH "/site/about"
13
14 int goon = 0;
15
16 VOID WINAPI callback(
17      HINTERNET hInternet,
18      DWORD dwContext,
19      DWORD dwInternetStatus,
20      LPVOID lpvStatusInformation,
21      DWORD dwStatusInformationLength
22 )
23 {
24     char name[124];
25
26     switch (dwInternetStatus)
27     {
28         case INTERNET_STATUS_RESOLVING_NAME:
29             strcpy(name,"INTERNET_STATUS_RESOLVING_NAME");
30             break;
31         case INTERNET_STATUS_NAME_RESOLVED:
32             strcpy(name,"INTERNET_STATUS_NAME_RESOLVED");
33             break;
34         case INTERNET_STATUS_CONNECTING_TO_SERVER:
35             strcpy(name,"INTERNET_STATUS_CONNECTING_TO_SERVER");
36             break;
37         case INTERNET_STATUS_CONNECTED_TO_SERVER:
38             strcpy(name,"INTERNET_STATUS_CONNECTED_TO_SERVER");
39             break;
40         case INTERNET_STATUS_SENDING_REQUEST:
41             strcpy(name,"INTERNET_STATUS_SENDING_REQUEST");
42             break;
43         case INTERNET_STATUS_REQUEST_SENT:
44             strcpy(name,"INTERNET_STATUS_REQUEST_SENT");
45             break;
46         case INTERNET_STATUS_RECEIVING_RESPONSE:
47             strcpy(name,"INTERNET_STATUS_RECEIVING_RESPONSE");
48             break;
49         case INTERNET_STATUS_RESPONSE_RECEIVED:
50             strcpy(name,"INTERNET_STATUS_RESPONSE_RECEIVED");
51             break;
52         case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
53             strcpy(name,"INTERNET_STATUS_CTL_RESPONSE_RECEIVED");
54             break;
55         case INTERNET_STATUS_PREFETCH:
56             strcpy(name,"INTERNET_STATUS_PREFETCH");
57             break;
58         case INTERNET_STATUS_CLOSING_CONNECTION:
59             strcpy(name,"INTERNET_STATUS_CLOSING_CONNECTION");
60             break;
61         case INTERNET_STATUS_CONNECTION_CLOSED:
62             strcpy(name,"INTERNET_STATUS_CONNECTION_CLOSED");
63             break;
64         case INTERNET_STATUS_HANDLE_CREATED:
65             strcpy(name,"INTERNET_STATUS_HANDLE_CREATED");
66             break;
67         case INTERNET_STATUS_HANDLE_CLOSING:
68             strcpy(name,"INTERNET_STATUS_HANDLE_CLOSING");
69             break;
70         case INTERNET_STATUS_REQUEST_COMPLETE:
71             strcpy(name,"INTERNET_STATUS_REQUEST_COMPLETE");
72             goon = 1;
73             break;
74         case INTERNET_STATUS_REDIRECT:
75             strcpy(name,"INTERNET_STATUS_REDIRECT");
76             break;
77         case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
78             strcpy(name,"INTERNET_STATUS_INTERMEDIATE_RESPONSE");
79             break;
80     }
81
82     trace("Callback %p 0x%lx %s(%li) %p %ld\n",hInternet,dwContext,name,dwInternetStatus,lpvStatusInformation,dwStatusInformationLength);
83 }
84
85 void winapi_test(int flags)
86 {
87     DWORD rc;
88     CHAR buffer[4000];
89     DWORD length;
90     DWORD out;
91     const char *types[2] = { "*", NULL };
92     HINTERNET hi, hic = 0, hor = 0;
93
94     trace("Starting with flags 0x%x\n",flags);
95
96     trace("InternetOpenA <--\n");
97     hi = InternetOpenA("",0x0,0x0,0x0,flags);
98     ok((hi != 0x0),"InternetOpen Failed\n");
99     trace("InternetOpenA -->\n");
100
101     if (hi == 0x0) goto abort;
102
103     InternetSetStatusCallback(hi,&callback);
104
105     trace("InternetConnectA <--\n");
106     hic=InternetConnectA(hi,"www.winehq.org",0x0,0x0,0x0,0x3,0x0,0xdeadbeef);
107     ok((hic != 0x0),"InternetConnect Failed\n");
108     trace("InternetConnectA -->\n");
109
110     if (hic == 0x0) goto abort;
111
112     trace("HttpOpenRequestA <--\n");
113     hor = HttpOpenRequestA(hic, "GET",
114                           "/about/",
115                           0x0,0x0,types,0x00400800,0xdeadbead);
116     if (hor == 0x0 && GetLastError() == 12007 /* ERROR_INTERNET_NAME_NOT_RESOLVED */) {
117         /*
118          * If the internet name can't be resolved we are probably behind
119          * a firewall or in some other way not directly connected to the
120          * Internet. Not enough reason to fail the test. Just ignore and
121          * abort.
122          */
123     } else  {
124         ok((hor != 0x0),"HttpOpenRequest Failed\n");
125     }
126     trace("HttpOpenRequestA -->\n");
127
128     if (hor == 0x0) goto abort;
129
130     trace("HttpSendRequestA -->\n");
131     SetLastError(0);
132     rc = HttpSendRequestA(hor, "", 0xffffffff,0x0,0x0);
133     if (flags)
134         ok(((rc == 0)&&(GetLastError()==997)),
135             "Asynchronous HttpSendRequest NOT returning 0 with error 997\n");
136     else
137         ok((rc != 0) || GetLastError() == 12007, /* 12007 == XP */
138            "Synchronous HttpSendRequest returning 0, error %ld\n", GetLastError());
139     trace("HttpSendRequestA <--\n");
140
141     while ((flags)&&(!goon))
142         Sleep(100);
143
144     length = 4;
145     rc = InternetQueryOptionA(hor,0x17,&out,&length);
146     trace("Option 0x17 -> %li  %li\n",rc,out);
147
148     length = 100;
149     rc = InternetQueryOptionA(hor,0x22,buffer,&length);
150     trace("Option 0x22 -> %li  %s\n",rc,buffer);
151
152     length = 4000;
153     rc = HttpQueryInfoA(hor,0x16,buffer,&length,0x0);
154     buffer[length]=0;
155     trace("Option 0x16 -> %li  %s\n",rc,buffer);
156
157     length = 4000;
158     rc = InternetQueryOptionA(hor,0x22,buffer,&length);
159     buffer[length]=0;
160     trace("Option 0x22 -> %li  %s\n",rc,buffer);
161
162     length = 16;
163     rc = HttpQueryInfoA(hor,0x5,&buffer,&length,0x0);
164     trace("Option 0x5 -> %li  %s  (%li)\n",rc,buffer,GetLastError());
165
166     length = 100;
167     rc = HttpQueryInfoA(hor,0x1,buffer,&length,0x0);
168     buffer[length]=0;
169     trace("Option 0x1 -> %li  %s\n",rc,buffer);
170
171     length = 100;
172     trace("Entering Query loop\n");
173
174     while (length)
175     {
176
177         rc = InternetQueryDataAvailable(hor,&length,0x0,0x0);
178         ok(!(rc == 0 && length != 0),"InternetQueryDataAvailable failed\n");
179
180         if (length)
181         {
182             char *buffer;
183             buffer = (char*)HeapAlloc(GetProcessHeap(),0,length+1);
184
185             rc = InternetReadFile(hor,buffer,length,&length);
186
187             buffer[length]=0;
188
189             trace("ReadFile -> %li %li\n",rc,length);
190
191             HeapFree(GetProcessHeap(),0,buffer);
192         }
193     }
194 abort:
195     if (hor != 0x0) {
196         rc = InternetCloseHandle(hor);
197         ok ((rc != 0), "InternetCloseHandle of handle opened by HttpOpenRequestA failed\n");
198         rc = InternetCloseHandle(hor);
199         ok ((rc == 0), "Double close of handle opened by HttpOpenRequestA succeeded\n");
200     }
201     if (hic != 0x0) {
202         rc = InternetCloseHandle(hic);
203         ok ((rc != 0), "InternetCloseHandle of handle opened by InternetConnectA failed\n");
204     }
205     if (hi != 0x0) {
206       rc = InternetCloseHandle(hi);
207       ok ((rc != 0), "InternetCloseHandle of handle opened by InternetOpenA failed\n");
208       if (flags)
209           Sleep(100);
210     }
211 }
212
213 void InternetOpenUrlA_test(void)
214 {
215   HINTERNET myhinternet, myhttp;
216   char buffer[0x400];
217   URL_COMPONENTSA urlComponents;
218   char protocol[32], hostName[1024], userName[1024];
219   char password[1024], extra[1024], path[1024];
220   DWORD size, readbytes, totalbytes=0;
221   BOOL ret;
222   
223   myhinternet = InternetOpen("Winetest",0,NULL,NULL,INTERNET_FLAG_NO_CACHE_WRITE);
224   ok((myhinternet != 0), "InternetOpen failed, error %lx\n",GetLastError());
225   size = 0x400;
226   ret = InternetCanonicalizeUrl(TEST_URL, buffer, &size,ICU_BROWSER_MODE);
227   ok( ret, "InternetCanonicalizeUrl failed, error %lx\n",GetLastError());
228   
229   urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
230   urlComponents.lpszScheme = protocol;
231   urlComponents.dwSchemeLength = 32;
232   urlComponents.lpszHostName = hostName;
233   urlComponents.dwHostNameLength = 1024;
234   urlComponents.lpszUserName = userName;
235   urlComponents.dwUserNameLength = 1024;
236   urlComponents.lpszPassword = password;
237   urlComponents.dwPasswordLength = 1024;
238   urlComponents.lpszUrlPath = path;
239   urlComponents.dwUrlPathLength = 2048;
240   urlComponents.lpszExtraInfo = extra;
241   urlComponents.dwExtraInfoLength = 1024;
242   ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents);
243   ok( ret, "InternetCrackUrl failed, error %lx\n",GetLastError());
244   SetLastError(0);
245   myhttp = InternetOpenUrl(myhinternet, TEST_URL, 0, 0,
246                            INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_TRANSFER_BINARY,0);
247   if (GetLastError() == 12007)
248     return; /* WinXP returns this when not connected to the net */
249   ok((myhttp != 0),"InternetOpenUrl failed, error %lx\n",GetLastError());
250   ret = InternetReadFile(myhttp, buffer,0x400,&readbytes);
251   ok( ret, "InternetReadFile failed, error %lx\n",GetLastError());
252   totalbytes += readbytes;
253   while (readbytes && InternetReadFile(myhttp, buffer,0x400,&readbytes))
254     totalbytes += readbytes;
255   trace("read 0x%08lx bytes\n",totalbytes);
256 }
257   
258 void InternetCrackUrl_test(void)
259 {
260   URL_COMPONENTSA urlComponents;
261   char protocol[32], hostName[1024], userName[1024];
262   char password[1024], extra[1024], path[1024];
263   BOOL ret;
264
265   urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
266   urlComponents.lpszScheme = protocol;
267   urlComponents.dwSchemeLength = 32;
268   urlComponents.lpszHostName = hostName;
269   urlComponents.dwHostNameLength = 1024;
270   urlComponents.lpszUserName = userName;
271   urlComponents.dwUserNameLength = 1024;
272   urlComponents.lpszPassword = password;
273   urlComponents.dwPasswordLength = 1024;
274   urlComponents.lpszUrlPath = path;
275   urlComponents.dwUrlPathLength = 2048;
276   urlComponents.lpszExtraInfo = extra;
277   urlComponents.dwExtraInfoLength = 1024;
278   ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents);
279   ok( ret, "InternetCrackUrl failed, error %lx\n",GetLastError());
280   ok((strcmp(TEST_URL_PATH,path) == 0),"path cracked wrong\n");
281 }
282
283 void InternetCrackUrlW_test(void)
284 {
285     WCHAR url[] = {
286         'h','t','t','p',':','/','/','1','9','2','.','1','6','8','.','0','.','2','2','/',
287         'C','F','I','D','E','/','m','a','i','n','.','c','f','m','?','C','F','S','V','R',
288         '=','I','D','E','&','A','C','T','I','O','N','=','I','D','E','_','D','E','F','A',
289         'U','L','T', 0 };
290     URL_COMPONENTSW comp;
291     WCHAR scheme[20], host[20], user[20], pwd[20], urlpart[50], extra[50];
292     BOOL r;
293
294     urlpart[0]=0;
295     scheme[0]=0;
296     extra[0]=0;
297     host[0]=0;
298     user[0]=0;
299     pwd[0]=0;
300     memset(&comp, 0, sizeof comp);
301     comp.dwStructSize = sizeof comp;
302     comp.lpszScheme = scheme;
303     comp.dwSchemeLength = sizeof scheme;
304     comp.lpszHostName = host;
305     comp.dwHostNameLength = sizeof host;
306     comp.lpszUserName = user;
307     comp.dwUserNameLength = sizeof user;
308     comp.lpszPassword = pwd;
309     comp.dwPasswordLength = sizeof pwd;
310     comp.lpszUrlPath = urlpart;
311     comp.dwUrlPathLength = sizeof urlpart;
312     comp.lpszExtraInfo = extra;
313     comp.dwExtraInfoLength = sizeof extra;
314
315     r = InternetCrackUrlW(url, 0, 0, &comp );
316     ok( r, "failed to crack url\n");
317     ok( comp.dwSchemeLength == 4, "scheme length wrong\n");
318     ok( comp.dwHostNameLength == 12, "host length wrong\n");
319     ok( comp.dwUserNameLength == 0, "user length wrong\n");
320     ok( comp.dwPasswordLength == 0, "password length wrong\n");
321     ok( comp.dwUrlPathLength == 15, "url length wrong\n");
322     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
323  
324     urlpart[0]=0;
325     scheme[0]=0;
326     extra[0]=0;
327     host[0]=0;
328     user[0]=0;
329     pwd[0]=0;
330     memset(&comp, 0, sizeof comp);
331     comp.dwStructSize = sizeof comp;
332     comp.lpszHostName = host;
333     comp.dwHostNameLength = sizeof host;
334     comp.lpszUrlPath = urlpart;
335     comp.dwUrlPathLength = sizeof urlpart;
336
337     r = InternetCrackUrlW(url, 0, 0, &comp );
338     ok( r, "failed to crack url\n");
339     ok( comp.dwSchemeLength == 0, "scheme length wrong\n");
340     ok( comp.dwHostNameLength == 12, "host length wrong\n");
341     ok( comp.dwUserNameLength == 0, "user length wrong\n");
342     ok( comp.dwPasswordLength == 0, "password length wrong\n");
343     ok( comp.dwUrlPathLength == 44, "url length wrong\n");
344     ok( comp.dwExtraInfoLength == 0, "extra length wrong\n");
345
346     urlpart[0]=0;
347     scheme[0]=0;
348     extra[0]=0;
349     host[0]=0;
350     user[0]=0;
351     pwd[0]=0;
352     memset(&comp, 0, sizeof comp);
353     comp.dwStructSize = sizeof comp;
354     comp.lpszHostName = host;
355     comp.dwHostNameLength = sizeof host;
356     comp.lpszUrlPath = urlpart;
357     comp.dwUrlPathLength = sizeof urlpart;
358     comp.lpszExtraInfo = NULL;
359     comp.dwExtraInfoLength = sizeof extra;
360
361     r = InternetCrackUrlW(url, 0, 0, &comp );
362     ok( r, "failed to crack url\n");
363     ok( comp.dwSchemeLength == 0, "scheme length wrong\n");
364     ok( comp.dwHostNameLength == 12, "host length wrong\n");
365     ok( comp.dwUserNameLength == 0, "user length wrong\n");
366     ok( comp.dwPasswordLength == 0, "password length wrong\n");
367     ok( comp.dwUrlPathLength == 15, "url length wrong\n");
368     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
369 }
370
371 static void InternetTimeFromSystemTimeA_test()
372 {
373     BOOL ret;
374     static const SYSTEMTIME time = { 2005, 1, 5, 7, 12, 6, 35, 0 };
375     char string[INTERNET_RFC1123_BUFSIZE];
376     static const char expect[] = "Fri, 07 Jan 2005 12:06:35 GMT";
377
378     ret = InternetTimeFromSystemTimeA( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string) );
379     ok( ret, "InternetTimeFromSystemTimeA failed (%ld)\n", GetLastError() );
380
381     ok( !memcmp( string, expect, sizeof(expect) ),
382         "InternetTimeFromSystemTimeA failed (%ld)\n", GetLastError() );
383 }
384
385 static void InternetTimeFromSystemTimeW_test()
386 {
387     BOOL ret;
388     static const SYSTEMTIME time = { 2005, 1, 5, 7, 12, 6, 35, 0 };
389     WCHAR string[INTERNET_RFC1123_BUFSIZE + 1];
390     static const WCHAR expect[] = { 'F','r','i',',',' ','0','7',' ','J','a','n',' ','2','0','0','5',' ',
391                                     '1','2',':','0','6',':','3','5',' ','G','M','T',0 };
392
393     ret = InternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string) );
394     ok( ret, "InternetTimeFromSystemTimeW failed (%ld)\n", GetLastError() );
395
396     ok( !memcmp( string, expect, sizeof(expect) ),
397         "InternetTimeFromSystemTimeW failed (%ld)\n", GetLastError() );
398 }
399
400 static void InternetTimeToSystemTimeA_test()
401 {
402     BOOL ret;
403     SYSTEMTIME time;
404     static const SYSTEMTIME expect = { 2005, 1, 5, 7, 12, 6, 35, 0 };
405     static const char string[] = "Fri, 07 Jan 2005 12:06:35 GMT";
406     static const char string2[] = " fri 7 jan 2005 12 06 35";
407
408     ret = InternetTimeToSystemTimeA( string, &time, 0 );
409     ok( ret, "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
410     ok( !memcmp( &time, &expect, sizeof(expect) ),
411         "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
412
413     ret = InternetTimeToSystemTimeA( string2, &time, 0 );
414     ok( ret, "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
415     ok( !memcmp( &time, &expect, sizeof(expect) ),
416         "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
417 }
418
419 static void InternetTimeToSystemTimeW_test()
420 {
421     BOOL ret;
422     SYSTEMTIME time;
423     static const SYSTEMTIME expect = { 2005, 1, 5, 7, 12, 6, 35, 0 };
424     static const WCHAR string[] = { 'F','r','i',',',' ','0','7',' ','J','a','n',' ','2','0','0','5',' ',
425                                     '1','2',':','0','6',':','3','5',' ','G','M','T',0 };
426     static const WCHAR string2[] = { ' ','f','r','i',' ','7',' ','j','a','n',' ','2','0','0','5',' ',
427                                      '1','2',' ','0','6',' ','3','5',0 };
428     static const WCHAR string3[] = { 'F','r',0 };
429
430     ret = InternetTimeToSystemTimeW( string, &time, 0 );
431     ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
432     ok( !memcmp( &time, &expect, sizeof(expect) ),
433         "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
434
435     ret = InternetTimeToSystemTimeW( string2, &time, 0 );
436     ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
437     ok( !memcmp( &time, &expect, sizeof(expect) ),
438         "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
439
440     ret = InternetTimeToSystemTimeW( string3, &time, 0 );
441     ok( !ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
442 }
443
444 START_TEST(http)
445 {
446     winapi_test(0x10000000);
447     winapi_test(0x00000000);
448     InternetCrackUrl_test();
449     InternetOpenUrlA_test();
450     InternetCrackUrlW_test();
451     InternetTimeFromSystemTimeA_test();
452     InternetTimeFromSystemTimeW_test();
453     InternetTimeToSystemTimeA_test();
454     InternetTimeToSystemTimeW_test();
455 }