2010-01-20 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / System.Net / System.Net / WebHeaderCollection_2_1.cs
1 //
2 // System.Net.WebHeaderCollection (for 2.1 profile)
3 //
4 // Authors:
5 //      Jb Evain  <jbevain@novell.com>
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (c) 2007, 2009 Novell, Inc. (http://www.novell.com)
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 #if NET_2_1
33
34 using System;
35 using System.Collections;
36 using System.Collections.Generic;
37
38 namespace System.Net {
39
40         public sealed class WebHeaderCollection : IEnumerable {
41
42                 internal Dictionary<string, string> headers;
43                 bool validate;
44
45                 public WebHeaderCollection ()
46                         : this (false)
47                 {
48                 }
49
50                 internal WebHeaderCollection (bool restrict)
51                 {
52                         validate = restrict;
53                         headers = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
54                 }
55
56                 public int Count {
57                         get { return headers.Count; }
58                 }
59
60                 public string [] AllKeys {
61                         get {
62                                 var keys = new string [headers.Count];
63                                 headers.Keys.CopyTo (keys, 0);
64                                 return keys;
65                         }
66                 }
67
68                 public string this [string header] {
69                         get {
70                                 if (header == null)
71                                         throw new ArgumentNullException ("header");
72
73                                 string value = null;
74                                 headers.TryGetValue (header, out value);
75                                 return value;
76                         }
77                         set {
78                                 if (header == null)
79                                         throw new ArgumentNullException ("header");
80                                 if (header.Length == 0)
81                                         throw new ArgumentException ("header");
82
83                                 if (validate)
84                                         ValidateHeader (header);
85                                 headers [header] = value;
86                         }
87                 }
88
89                 public string this [HttpRequestHeader header] {
90                         get { return this [HttpRequestHeaderToString (header)]; }
91                         set {
92                                 string h = HttpRequestHeaderToString (header);
93                                 if (validate)
94                                         ValidateHeader (h);
95                                 headers [h] = value;
96                         }
97                 }
98
99                 // some headers cannot be set using the "this" property but by using
100                 // the right property of the Web[Request|Response]. However the value 
101                 // does end up in the collection (and can be read safely from there)
102                 internal void SetHeader (string header, string value)
103                 {
104                         if (String.IsNullOrEmpty (value))
105                                 headers.Remove (header);
106                         else
107                                 headers [header] = value;
108                 }
109
110                 IEnumerator IEnumerable.GetEnumerator ()
111                 {
112                         return headers.GetEnumerator ();
113                 }
114
115                 static string HttpResponseHeaderToString (HttpResponseHeader header)
116                 {
117                         switch (header) {
118                         case HttpResponseHeader.CacheControl:           return "Cache-Control";
119                         case HttpResponseHeader.Connection:             return "Connection";
120                         case HttpResponseHeader.Date:                   return "Date";
121                         case HttpResponseHeader.KeepAlive:              return "Keep-Alive";
122                         case HttpResponseHeader.Pragma:                 return "Pragma";
123                         case HttpResponseHeader.Trailer:                return "Trailer";
124                         case HttpResponseHeader.TransferEncoding:       return "Transfer-Encoding";
125                         case HttpResponseHeader.Upgrade:                return "Upgrade";
126                         case HttpResponseHeader.Via:                    return "Via";
127                         case HttpResponseHeader.Warning:                return "Warning";
128                         case HttpResponseHeader.Allow:                  return "Allow";
129                         case HttpResponseHeader.ContentLength:          return "Content-Length";
130                         case HttpResponseHeader.ContentType:            return "Content-Type";
131                         case HttpResponseHeader.ContentEncoding:        return "Content-Encoding";
132                         case HttpResponseHeader.ContentLanguage:        return "Content-Language";
133                         case HttpResponseHeader.ContentLocation:        return "Content-Location";
134                         case HttpResponseHeader.ContentMd5:             return "Content-MD5";
135                         case HttpResponseHeader.ContentRange:           return "Content-Range";
136                         case HttpResponseHeader.Expires:                return "Expires";
137                         case HttpResponseHeader.LastModified:           return "Last-Modified";
138                         case HttpResponseHeader.AcceptRanges:           return "Accept-Ranges";
139                         case HttpResponseHeader.Age:                    return "Age";
140                         case HttpResponseHeader.ETag:                   return "ETag";
141                         case HttpResponseHeader.Location:               return "Location";
142                         case HttpResponseHeader.ProxyAuthenticate:      return "Proxy-Authenticate";
143                         case HttpResponseHeader.RetryAfter:             return "Retry-After";
144                         case HttpResponseHeader.Server:                 return "Server";
145                         case HttpResponseHeader.SetCookie:              return "Set-Cookie";
146                         case HttpResponseHeader.Vary:                   return "Vary";
147                         case HttpResponseHeader.WwwAuthenticate:        return "WWW-Authenticate";
148                         default:
149                                 throw new IndexOutOfRangeException ();
150                         }
151                 }
152
153                 static string HttpRequestHeaderToString (HttpRequestHeader header)
154                 {
155                         switch (header) {
156                         case HttpRequestHeader.CacheControl:            return "Cache-Control";
157                         case HttpRequestHeader.Connection:              return "Connection";
158                         case HttpRequestHeader.Date:                    return "Date";
159                         case HttpRequestHeader.KeepAlive:               return "Keep-Alive";
160                         case HttpRequestHeader.Pragma:                  return "Pragma";
161                         case HttpRequestHeader.Trailer:                 return "Trailer";
162                         case HttpRequestHeader.TransferEncoding:        return "Transfer-Encoding";
163                         case HttpRequestHeader.Upgrade:                 return "Upgrade";
164                         case HttpRequestHeader.Via:                     return "Via";
165                         case HttpRequestHeader.Warning:                 return "Warning";
166                         case HttpRequestHeader.Allow:                   return "Allow";
167                         case HttpRequestHeader.ContentLength:           return "Content-Length";
168                         case HttpRequestHeader.ContentType:             return "Content-Type";
169                         case HttpRequestHeader.ContentEncoding:         return "Content-Encoding";
170                         case HttpRequestHeader.ContentLanguage:         return "Content-Language";
171                         case HttpRequestHeader.ContentLocation:         return "Content-Location";
172                         case HttpRequestHeader.ContentMd5:              return "Content-MD5";
173                         case HttpRequestHeader.ContentRange:            return "Content-Range";
174                         case HttpRequestHeader.Expires:                 return "Expires";
175                         case HttpRequestHeader.LastModified:            return "Last-Modified";
176                         case HttpRequestHeader.Accept:                  return "Accept";
177                         case HttpRequestHeader.AcceptCharset:           return "Accept-Charset";
178                         case HttpRequestHeader.AcceptEncoding:          return "Accept-Encoding";
179                         case HttpRequestHeader.AcceptLanguage:          return "Accept-Language";
180                         case HttpRequestHeader.Authorization:           return "Authorization";
181                         case HttpRequestHeader.Cookie:                  return "Cookie";
182                         case HttpRequestHeader.Expect:                  return "Expect";
183                         case HttpRequestHeader.From:                    return "From";
184                         case HttpRequestHeader.Host:                    return "Host";
185                         case HttpRequestHeader.IfMatch:                 return "If-Match";
186                         case HttpRequestHeader.IfModifiedSince:         return "If-Modified-Since";
187                         case HttpRequestHeader.IfNoneMatch:             return "If-None-Match";
188                         case HttpRequestHeader.IfRange:                 return "If-Range";
189                         case HttpRequestHeader.IfUnmodifiedSince:       return "If-Unmodified-Since";
190                         case HttpRequestHeader.MaxForwards:             return "Max-Forwards";
191                         case HttpRequestHeader.ProxyAuthorization:      return "Proxy-Authorization";
192                         case HttpRequestHeader.Referer:                 return "Referer";
193                         case HttpRequestHeader.Range:                   return "Range";
194                         case HttpRequestHeader.Te:                      return "TE";
195                         case HttpRequestHeader.Translate:               return "Translate";
196                         case HttpRequestHeader.UserAgent:               return "User-Agent";
197                         default:
198                                 throw new IndexOutOfRangeException ();
199                         }
200                 }
201
202                 internal static void ValidateHeader (string header)
203                 {
204                         switch (header.ToLowerInvariant ()) {
205                         case "connection":
206                         case "date":
207                         case "keep-alive":
208                         case "trailer":
209                         case "transfer-encoding":
210                         case "upgrade":
211                         case "via":
212                         case "warning":
213                         case "allow":
214                         case "content-length":
215                         case "content-type":
216                         case "content-location":
217                         case "content-range":
218                         case "last-modified":
219                         case "accept":
220                         case "accept-charset":
221                         case "accept-encoding":
222                         case "accept-language":
223                         case "authorization":
224                         case "cookie":
225                         case "expect":
226                         case "host":
227                         case "if-modified-since":
228                         case "max-forwards":
229                         case "proxy-authorization":
230                         case "referer":
231                         case "range":
232                         case "te":
233                         case "user-agent":
234                         // extra (not HttpRequestHeader defined) headers that are not accepted by SL2
235                         // note: the HttpResponseHeader enum is not available in SL2
236                         case "accept-ranges":
237                         case "age":
238                         case "allowed":
239                         case "connect":
240                         case "content-transfer-encoding":
241                         case "delete":
242                         case "etag":
243                         case "get":
244                         case "head":
245                         case "location":
246                         case "options":
247                         case "post":
248                         case "proxy-authenticate":
249                         case "proxy-connection":
250                         case "public":
251                         case "put":
252                         case "request-range":
253                         case "retry-after":
254                         case "server":
255                         case "sec-headertest":
256                         case "sec-":
257                         case "trace":
258                         case "uri":
259                         case "vary":
260                         case "www-authenticate":
261                         case "x-flash-version":
262                                 throw new ArgumentException ("header");
263                         default:
264                                 return;
265                         }
266                 }
267         }
268 }
269
270 #endif