Fix the retry-on-broken-connection codepath for SoupRequest
[platform/upstream/libsoup.git] / tests / date.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2005 Novell, Inc.
4  */
5
6 #include "test-utils.h"
7
8 static gboolean check_ok (const char *strdate, SoupDate *date);
9
10 static SoupDate *
11 make_date (const char *strdate)
12 {
13         char *dup;
14         SoupDate *date;
15
16         /* We do it this way so that if soup_date_new_from_string()
17          * reads off the end of the string, it will trigger an error
18          * when valgrinding, rather than just reading the start of the
19          * next const string.
20          */
21         dup = g_strdup (strdate);
22         date = soup_date_new_from_string (dup);
23         g_free (dup);
24         return date;
25 }
26
27 static const struct {
28         SoupDateFormat format;
29         const char *date;
30 } good_dates[] = {
31         { SOUP_DATE_HTTP,            "Sat, 06 Nov 2004 08:09:07 GMT" },
32         { SOUP_DATE_COOKIE,          "Sat, 06-Nov-2004 08:09:07 GMT" },
33         { SOUP_DATE_RFC2822,         "Sat, 6 Nov 2004 08:09:07 -0430" },
34         { SOUP_DATE_ISO8601_COMPACT, "20041106T080907" },
35         { SOUP_DATE_ISO8601_FULL,    "2004-11-06T08:09:07" },
36         { SOUP_DATE_ISO8601_XMLRPC,  "20041106T08:09:07" }
37 };
38
39 static void
40 check_good (SoupDateFormat format, const char *strdate)
41 {
42         SoupDate *date;
43         char *strdate2;
44
45         date = make_date (strdate);
46         g_assert (date);
47         strdate2 = soup_date_to_string (date, format);
48         if (!check_ok (strdate, date))
49                 return;
50
51         if (strcmp (strdate, strdate2) != 0) {
52                 debug_printf (1, "  restringification failed: '%s' -> '%s'\n",
53                               strdate, strdate2);
54                 errors++;
55         }
56         g_free (strdate2);
57 }
58
59 static const char *ok_dates[] = {
60         /* rfc1123-date, and broken variants */
61         "Sat, 06 Nov 2004 08:09:07 GMT",
62         "Sat, 6 Nov 2004 08:09:07 GMT",
63         "Sat,  6 Nov 2004 08:09:07 GMT",
64         "Sat, 06 Nov 2004 08:09:07",
65         "06 Nov 2004 08:09:07 GMT",
66         "SAT, 06 NOV 2004 08:09:07 +1000",
67
68         /* rfc850-date, and broken variants */
69         "Saturday, 06-Nov-04 08:09:07 GMT",
70         "Saturday, 6-Nov-04 08:09:07 GMT",
71         "Saturday,  6-Nov-04 08:09:07 GMT",
72         "Saturday, 06-Nov-104 08:09:07 GMT",
73         "Saturday, 06-Nov-04 08:09:07",
74         "06-Nov-04 08:09:07 GMT",
75
76         /* asctime-date, and broken variants */
77         "Sat Nov  6 08:09:07 2004",
78         "Sat Nov 06 08:09:07 2004",
79         "Sat Nov 6 08:09:07 2004",
80         "Sat Nov  6 08:09:07 2004 GMT",
81
82         /* ISO 8601 */
83         "2004-11-06T08:09:07Z",
84         "20041106T08:09:07Z",
85         "20041106T08:09:07+00:00",
86         "20041106T080907+00:00",
87
88         /* Netscape cookie spec date, and broken variants */
89         "Sat, 06-Nov-2004 08:09:07 GMT",
90         "Sat, 6-Nov-2004 08:09:07 GMT",
91         "Sat,  6-Nov-2004 08:09:07 GMT",
92         "Sat, 06-Nov-2004 08:09:07",
93
94         /* Original version of Netscape cookie spec, and broken variants */
95         "Sat, 06-Nov-04 08:09:07 GMT",
96         "Sat, 6-Nov-04 08:09:07 GMT",
97         "Sat,  6-Nov-04 08:09:07 GMT",
98         "Sat, 06-Nov-104 08:09:07 GMT",
99         "Sat, 06-Nov-04 08:09:07",
100
101         /* Netscape cookie spec example syntax, and broken variants */
102         "Saturday, 06-Nov-04 08:09:07 GMT",
103         "Saturday, 6-Nov-04 08:09:07 GMT",
104         "Saturday,  6-Nov-04 08:09:07 GMT",
105         "Saturday, 06-Nov-104 08:09:07 GMT",
106         "Saturday, 06-Nov-2004 08:09:07 GMT",
107         "Saturday, 6-Nov-2004 08:09:07 GMT",
108         "Saturday,  6-Nov-2004 08:09:07 GMT",
109         "Saturday, 06-Nov-04 08:09:07",
110
111         /* Miscellaneous broken formats seen on the web */
112         "Sat 06-Nov-2004  08:9:07",
113         "Saturday, 06-Nov-04 8:9:07 GMT",
114         "Sat, 06 Nov 2004 08:09:7 GMT"
115 };
116
117 #define TIME_T 1099728547L
118 #define TIME_T_STRING "1099728547"
119
120 static gboolean
121 check_ok (const char *strdate, SoupDate *date)
122 {
123         debug_printf (2, "%s\n", strdate);
124
125         if (date &&
126             date->year == 2004 && date->month == 11 && date->day == 6 &&
127             date->hour == 8 && date->minute == 9 && date->second == 7) {
128                 soup_date_free (date);
129                 return TRUE;
130         }
131
132         debug_printf (1, "  date parsing failed for '%s'.\n", strdate);
133         if (date) {
134                 debug_printf (1, "    got: %d %d %d - %d %d %d\n\n",
135                               date->year, date->month, date->day,
136                               date->hour, date->minute, date->second);
137                 soup_date_free (date);
138         }
139         errors++;
140         return FALSE;
141 }
142
143 static const char *bad_dates[] = {
144         /* broken rfc1123-date */
145         ", 06 Nov 2004 08:09:07 GMT",
146         "Sat, Nov 2004 08:09:07 GMT",
147         "Sat, 06 2004 08:09:07 GMT",
148         "Sat, 06 Nov 08:09:07 GMT",
149         "Sat, 06 Nov 2004 :09:07 GMT",
150         "Sat, 06 Nov 2004 09:07 GMT",
151         "Sat, 06 Nov 2004 08::07 GMT",
152         "Sat, 06 Nov 2004 08:09: GMT",
153
154         /* broken rfc850-date */
155         ", 06-Nov-04 08:09:07 GMT",
156         "Saturday, -Nov-04 08:09:07 GMT",
157         "Saturday, Nov-04 08:09:07 GMT",
158         "Saturday, 06-04 08:09:07 GMT",
159         "Saturday, 06--04 08:09:07 GMT",
160         "Saturday, 06-Nov- 08:09:07 GMT",
161         "Saturday, 06-Nov 08:09:07 GMT",
162         "Saturday, 06-Nov-04 :09:07 GMT",
163         "Saturday, 06-Nov-04 09:07 GMT",
164         "Saturday, 06-Nov-04 08::07 GMT",
165         "Saturday, 06-Nov-04 08:09: GMT",
166
167         /* broken asctime-date */
168         "Nov  6 08:09:07 2004",
169         "Sat  6 08:09:07 2004",
170         "Sat Nov 08:09:07 2004",
171         "Sat Nov  6 :09:07 2004",
172         "Sat Nov  6 09:07 2004",
173         "Sat Nov  6 08::07 2004",
174         "Sat Nov  6 08:09: 2004",
175         "Sat Nov  6 08:09:07",
176         "Sat Nov  6 08:09:07 GMT 2004"
177 };
178
179 static void
180 check_bad (const char *strdate, SoupDate *date)
181 {
182         debug_printf (2, "%s\n", strdate);
183
184         if (!date)
185                 return;
186         errors++;
187
188         debug_printf (1, "  date parsing succeeded for '%s'!\n", strdate);
189         debug_printf (1, "    got: %d %d %d - %d %d %d\n\n",
190                       date->year, date->month, date->day,
191                       date->hour, date->minute, date->second);
192         soup_date_free (date);
193 }
194
195 static const struct conversion {
196         const char *source;
197         const char *http, *cookie, *rfc2822, *compact, *full, *xmlrpc;
198 } conversions[] = {
199         /* SOUP_DATE_HTTP */
200         { "Sat, 06 Nov 2004 08:09:07 GMT",
201
202           "Sat, 06 Nov 2004 08:09:07 GMT",
203           "Sat, 06-Nov-2004 08:09:07 GMT",
204           "Sat, 6 Nov 2004 08:09:07 +0000",
205           "20041106T080907Z",
206           "2004-11-06T08:09:07Z",
207           "20041106T08:09:07" },
208
209         /* RFC2822 GMT */
210         { "Sat, 6 Nov 2004 08:09:07 +0000",
211
212           "Sat, 06 Nov 2004 08:09:07 GMT",
213           "Sat, 06-Nov-2004 08:09:07 GMT",
214           "Sat, 6 Nov 2004 08:09:07 +0000",
215           "20041106T080907Z",
216           "2004-11-06T08:09:07Z",
217           "20041106T08:09:07" },
218
219         /* RFC2822 with positive offset */
220         { "Sat, 6 Nov 2004 08:09:07 +0430",
221
222           "Sat, 06 Nov 2004 04:39:07 GMT",
223           "Sat, 06-Nov-2004 04:39:07 GMT",
224           "Sat, 6 Nov 2004 08:09:07 +0430",
225           "20041106T080907+0430",
226           "2004-11-06T08:09:07+04:30",
227           "20041106T08:09:07" },
228
229         /* RFC2822 with negative offset */
230         { "Sat, 6 Nov 2004 08:09:07 -0430",
231
232           "Sat, 06 Nov 2004 12:39:07 GMT",
233           "Sat, 06-Nov-2004 12:39:07 GMT",
234           "Sat, 6 Nov 2004 08:09:07 -0430",
235           "20041106T080907-0430",
236           "2004-11-06T08:09:07-04:30",
237           "20041106T08:09:07" },
238
239         /* RFC2822 floating */
240         { "Sat, 6 Nov 2004 08:09:07 -0000",
241
242           "Sat, 06 Nov 2004 08:09:07 GMT",
243           "Sat, 06-Nov-2004 08:09:07 GMT",
244           "Sat, 6 Nov 2004 08:09:07 -0000",
245           "20041106T080907",
246           "2004-11-06T08:09:07",
247           "20041106T08:09:07" },
248
249         /* ISO GMT */
250         { "2004-11-06T08:09:07Z",
251
252           "Sat, 06 Nov 2004 08:09:07 GMT",
253           "Sat, 06-Nov-2004 08:09:07 GMT",
254           "Sat, 6 Nov 2004 08:09:07 +0000",
255           "20041106T080907Z",
256           "2004-11-06T08:09:07Z",
257           "20041106T08:09:07" },
258
259         /* ISO with positive offset */
260         { "2004-11-06T08:09:07+04:30",
261
262           "Sat, 06 Nov 2004 04:39:07 GMT",
263           "Sat, 06-Nov-2004 04:39:07 GMT",
264           "Sat, 6 Nov 2004 08:09:07 +0430",
265           "20041106T080907+0430",
266           "2004-11-06T08:09:07+04:30",
267           "20041106T08:09:07" },
268
269         /* ISO with negative offset */
270         { "2004-11-06T08:09:07-04:30",
271
272           "Sat, 06 Nov 2004 12:39:07 GMT",
273           "Sat, 06-Nov-2004 12:39:07 GMT",
274           "Sat, 6 Nov 2004 08:09:07 -0430",
275           "20041106T080907-0430",
276           "2004-11-06T08:09:07-04:30",
277           "20041106T08:09:07" },
278
279         /* ISO floating */
280         { "2004-11-06T08:09:07",
281
282           "Sat, 06 Nov 2004 08:09:07 GMT",
283           "Sat, 06-Nov-2004 08:09:07 GMT",
284           "Sat, 6 Nov 2004 08:09:07 -0000",
285           "20041106T080907",
286           "2004-11-06T08:09:07",
287           "20041106T08:09:07" }
288 };
289
290 static void
291 check_conversion (const struct conversion *conv)
292 {
293         SoupDate *date;
294         char *str;
295
296         debug_printf (2, "%s\n", conv->source);
297         date = make_date (conv->source);
298         if (!date) {
299                 debug_printf (1, "  date parsing failed for '%s'.\n", conv->source);
300                 errors++;
301                 return;
302         }
303
304         str = soup_date_to_string (date, SOUP_DATE_HTTP);
305         if (!str || strcmp (str, conv->http) != 0) {
306                 debug_printf (1, "  conversion of '%s' to HTTP failed:\n"
307                               "    wanted: %s\n    got:    %s\n",
308                               conv->source, conv->http, str ? str : "(null)");
309                 errors++;
310         }
311         g_free (str);
312
313         str = soup_date_to_string (date, SOUP_DATE_COOKIE);
314         if (!str || strcmp (str, conv->cookie) != 0) {
315                 debug_printf (1, "  conversion of '%s' to COOKIE failed:\n"
316                               "    wanted: %s\n    got:    %s\n",
317                               conv->source, conv->cookie, str ? str : "(null)");
318                 errors++;
319         }
320         g_free (str);
321
322         str = soup_date_to_string (date, SOUP_DATE_RFC2822);
323         if (!str || strcmp (str, conv->rfc2822) != 0) {
324                 debug_printf (1, "  conversion of '%s' to RFC2822 failed:\n"
325                               "    wanted: %s\n    got:    %s\n",
326                               conv->source, conv->rfc2822, str ? str : "(null)");
327                 errors++;
328         }
329         g_free (str);
330
331         str = soup_date_to_string (date, SOUP_DATE_ISO8601_COMPACT);
332         if (!str || strcmp (str, conv->compact) != 0) {
333                 debug_printf (1, "  conversion of '%s' to COMPACT failed:\n"
334                               "    wanted: %s\n    got:    %s\n",
335                               conv->source, conv->compact, str ? str : "(null)");
336                 errors++;
337         }
338         g_free (str);
339
340         str = soup_date_to_string (date, SOUP_DATE_ISO8601_FULL);
341         if (!str || strcmp (str, conv->full) != 0) {
342                 debug_printf (1, "  conversion of '%s' to FULL failed:\n"
343                               "    wanted: %s\n    got:    %s\n",
344                               conv->source, conv->full, str ? str : "(null)");
345                 errors++;
346         }
347         g_free (str);
348
349         str = soup_date_to_string (date, SOUP_DATE_ISO8601_XMLRPC);
350         if (!str || strcmp (str, conv->xmlrpc) != 0) {
351                 debug_printf (1, "  conversion of '%s' to XMLRPC failed:\n"
352                               "    wanted: %s\n    got:    %s\n",
353                               conv->source, conv->xmlrpc, str ? str : "(null)");
354                 errors++;
355         }
356         g_free (str);
357
358         soup_date_free (date);
359 }
360
361 int
362 main (int argc, char **argv)
363 {
364         int i;
365
366         test_init (argc, argv, NULL);
367
368         debug_printf (1, "Good dates:\n");
369         for (i = 0; i < G_N_ELEMENTS (good_dates); i++)
370                 check_good (good_dates[i].format, good_dates[i].date);
371
372         debug_printf (1, "\nOK dates:\n");
373         for (i = 0; i < G_N_ELEMENTS (ok_dates); i++)
374                 check_ok (ok_dates[i], make_date (ok_dates[i]));
375         check_ok (TIME_T_STRING, soup_date_new_from_time_t (TIME_T));
376
377         debug_printf (1, "\nBad dates:\n");
378         for (i = 0; i < G_N_ELEMENTS (bad_dates); i++)
379                 check_bad (bad_dates[i], make_date (bad_dates[i]));
380
381         debug_printf (1, "\nConversions:\n");
382         for (i = 0; i < G_N_ELEMENTS (conversions); i++)
383                 check_conversion (&conversions[i] );
384
385         test_cleanup ();
386         return errors != 0;
387 }