Add some 4.5 api
[mono.git] / mcs / class / System / System.Net / CookieParser.cs
1 //
2 // System.Net.CookieParser
3 //
4 // Authors:
5 //      Lawrence Pit (loz@cable.a2000.nl)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //      Daniel Nauck    (dna(at)mono-project(dot)de)
8 //
9 // (c) 2002 Lawrence Pit
10 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
11 // (c) 2008 Daniel Nauck
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Collections;
37 using System.Globalization;
38
39 namespace System.Net {
40
41         class CookieParser {
42                 string header;
43                 int pos;
44                 int length;
45
46                 public CookieParser (string header) : this (header, 0)
47                 {
48                 }
49
50                 public CookieParser (string header, int position)
51                 {
52                         this.header = header;
53                         this.pos = position;
54                         this.length = header.Length;
55                 }
56
57                 public bool GetNextNameValue (out string name, out string val)
58                 {
59                         name = null;
60                         val = null;
61
62                         if (pos >= length)
63                                 return false;
64
65                         name = GetCookieName ();
66                         if (pos < header.Length && header [pos] == '=') {
67                                 pos++;
68                                 val = GetCookieValue ();
69                         }
70
71                         if (pos < length && header [pos] == ';')
72                                 pos++;
73
74                         return true;
75                 }
76
77                 string GetCookieName ()
78                 {
79                         int k = pos;
80                         while (k < length && Char.IsWhiteSpace (header [k]))
81                                 k++;
82
83                         int begin = k;
84                         while (k < length && header [k] != ';' &&  header [k] != '=')
85                                 k++;
86
87                         pos = k;
88                         return header.Substring (begin, k - begin).Trim ();
89                 }
90
91                 string GetCookieValue ()
92                 {
93                         if (pos >= length)
94                                 return null;
95
96                         int k = pos;
97                         while (k < length && Char.IsWhiteSpace (header [k]))
98                                 k++;
99
100                         int begin;
101                         if (header [k] == '"'){
102                                 int j;
103                                 begin = ++k;
104
105                                 while (k < length && header [k] != '"')
106                                         k++;
107
108                                 for (j = k; j < length && header [j] != ';'; j++)
109                                         ;
110                                 pos = j;
111                         } else {
112                                 begin = k;
113                                 while (k < length && header [k] != ';')
114                                         k++;
115                                 pos = k;
116                         }
117                                 
118                         return header.Substring (begin, k - begin).Trim ();
119                 }
120
121                 static string[] cookieExpiresFormats =
122                         new string[] { "r",
123                                         "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'",
124                                         "ddd, dd'-'MMM'-'yy HH':'mm':'ss 'GMT'" };
125
126                 static public DateTime TryParseCookieExpires (string value)
127                 {
128                         if (String.IsNullOrEmpty (value))
129                                 return DateTime.MinValue;
130
131                         for (int i = 0; i < cookieExpiresFormats.Length; i++) {
132                                 try {
133                                         DateTime cookieExpiresUtc = DateTime.ParseExact (value, cookieExpiresFormats [i], CultureInfo.InvariantCulture);
134
135                                         //convert UTC/GMT time to local time
136                                         cookieExpiresUtc = DateTime.SpecifyKind (cookieExpiresUtc, DateTimeKind.Utc);
137                                         return TimeZone.CurrentTimeZone.ToLocalTime (cookieExpiresUtc);
138                                 } catch {}
139                         }
140
141                         //If we can't parse Expires, use cookie as session cookie (expires is DateTime.MinValue)
142                         return DateTime.MinValue;
143                 }
144         }
145 }
146