New tests.
[mono.git] / mcs / class / System / System.Net / WebHeaderCollection.cs
index 8f2f39d28e743f0d8bb074b5200afbcbc50678fd..16f77533a40dfc0c95c8c2420a44d110c8f28723 100644 (file)
@@ -33,6 +33,7 @@
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
@@ -42,12 +43,16 @@ using System.Text;
     
 namespace System.Net 
 {
+#if MOONLIGHT
+       internal class WebHeaderCollection : NameValueCollection, ISerializable {
+#else
        [Serializable]
        [ComVisible(true)]
-       public class WebHeaderCollection : NameValueCollection, ISerializable
-       {
+       public class WebHeaderCollection : NameValueCollection, ISerializable {
+#endif
                private static readonly Hashtable restricted;
                private static readonly Hashtable multiValue;
+               static readonly Dictionary<string, bool> restricted_response;
                private bool internallyCreated = false;
                
                // Static Initializer
@@ -71,7 +76,14 @@ namespace System.Net
                        restricted.Add ("referer", true);
                        restricted.Add ("transfer-encoding", true);
                        restricted.Add ("user-agent", true);                    
-                       
+                       restricted.Add ("proxy-connection", true);                      
+
+                       //
+                       restricted_response = new Dictionary<string, bool> (StringComparer.InvariantCultureIgnoreCase);
+                       restricted_response.Add ("Content-Length", true);
+                       restricted_response.Add ("Transfer-Encoding", true);
+                       restricted_response.Add ("WWW-Authenticate", true);
+
                        // see par 14 of RFC 2068 to see which header names
                        // accept multiple values each separated by a comma
                        multiValue = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
@@ -187,6 +199,16 @@ namespace System.Net
                        return values;
                }
 
+               public override string[] GetValues (int index)
+               {
+                       string[] values = base.GetValues (index);
+                       if (values == null || values.Length == 0) {
+                               return(null);
+                       }
+                       
+                       return(values);
+               }
+
                /* Now i wonder why this is here...
                static string [] GetMultipleValues (string [] values)
                {
@@ -233,16 +255,25 @@ namespace System.Net
                        if (headerName == "") // MS throw nullexception here!
                                throw new ArgumentException ("empty string", "headerName");
 
+                       if (!IsHeaderName (headerName))
+                               throw new ArgumentException ("Invalid character in header");
+
                        return restricted.ContainsKey (headerName);
                }
 
-#if NET_2_0
-               [MonoNotSupported("")]
                public static bool IsRestricted (string headerName, bool response)
                {
-                       throw new NotImplementedException ();
+                       if (String.IsNullOrEmpty (headerName))
+                               throw new ArgumentNullException ("headerName");
+
+                       if (!IsHeaderName (headerName))
+                               throw new ArgumentException ("Invalid character in header");
+
+
+                       if (response)
+                               return restricted_response.ContainsKey (headerName);
+                       return restricted.ContainsKey (headerName);
                }
-#endif
 
                public override void OnDeserialization (object sender)
                {
@@ -292,9 +323,14 @@ namespace System.Net
                                  
                        return sb.Append("\r\n").ToString();
                }
-
+#if !TARGET_JVM
                void ISerializable.GetObjectData (SerializationInfo serializationInfo,
                                                  StreamingContext streamingContext)
+               {
+                       GetObjectData (serializationInfo, streamingContext);
+               }
+#endif
+               public override void GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
                {
                        int count = base.Count;
                        serializationInfo.AddValue ("Count", count);
@@ -304,7 +340,42 @@ namespace System.Net
                        }
                }
 
-#if NET_2_0
+               public override string[] AllKeys
+               {
+                       get {
+                               return(base.AllKeys);
+                       }
+               }
+               
+               public override int Count 
+               {
+                       get {
+                               return(base.Count);
+                       }
+               }
+
+               public override KeysCollection Keys
+               {
+                       get {
+                               return(base.Keys);
+                       }
+               }
+
+               public override string Get (int index)
+               {
+                       return(base.Get (index));
+               }
+               
+               public override string Get (string name)
+               {
+                       return(base.Get (name));
+               }
+               
+               public override string GetKey (int index)
+               {
+                       return(base.GetKey (index));
+               }
+
                public void Add (HttpRequestHeader header, string value)
                {
                        Add (RequestHeaderToString (header), value);
@@ -339,92 +410,93 @@ namespace System.Net
                {
                        switch (value){
                        case HttpRequestHeader.CacheControl:
-                               return "cache-control";
+                               return "Cache-Control";
                        case HttpRequestHeader.Connection:
-                               return "connection";
+                               return "Connection";
                        case HttpRequestHeader.Date:
-                               return "date";
+                               return "Date";
                        case HttpRequestHeader.KeepAlive:
-                               return "keep-alive";
+                               return "Keep-Alive";
                        case HttpRequestHeader.Pragma:
-                               return "pragma";
+                               return "Pragma";
                        case HttpRequestHeader.Trailer:
-                               return "trailer";
+                               return "Trailer";
                        case HttpRequestHeader.TransferEncoding:
-                               return "transfer-encoding";
+                               return "Transfer-Encoding";
                        case HttpRequestHeader.Upgrade:
-                               return "upgrade";
+                               return "Upgrade";
                        case HttpRequestHeader.Via:
-                               return "via";
+                               return "Via";
                        case HttpRequestHeader.Warning:
-                               return "warning";
+                               return "Warning";
                        case HttpRequestHeader.Allow:
-                               return "allow";
+                               return "Allow";
                        case HttpRequestHeader.ContentLength:
-                               return "content-length";
+                               return "Content-Length";
                        case HttpRequestHeader.ContentType:
-                               return "content-type";
+                               return "Content-Type";
                        case HttpRequestHeader.ContentEncoding:
-                               return "content-encoding";
+                               return "Content-Encoding";
                        case HttpRequestHeader.ContentLanguage:
-                               return "content-language";
+                               return "Content-Language";
                        case HttpRequestHeader.ContentLocation:
-                               return "content-location";
+                               return "Content-Location";
                        case HttpRequestHeader.ContentMd5:
-                               return "content-md5";
+                               return "Content-MD5";
                        case HttpRequestHeader.ContentRange:
-                               return "content-range";
+                               return "Content-Range";
                        case HttpRequestHeader.Expires:
-                               return "expires";
+                               return "Expires";
                        case HttpRequestHeader.LastModified:
-                               return "last-modified";
+                               return "Last-Modified";
                        case HttpRequestHeader.Accept:
-                               return "accept";
+                               return "Accept";
                        case HttpRequestHeader.AcceptCharset:
-                               return "accept-charset";
+                               return "Accept-Charset";
                        case HttpRequestHeader.AcceptEncoding:
-                               return "accept-encoding";
+                               return "Accept-Encoding";
                        case HttpRequestHeader.AcceptLanguage:
                                return "accept-language";
                        case HttpRequestHeader.Authorization:
-                               return "authorization";
+                               return "Authorization";
                        case HttpRequestHeader.Cookie:
-                               return "cookie";
+                               return "Cookie";
                        case HttpRequestHeader.Expect:
-                               return "expect";
+                               return "Expect";
                        case HttpRequestHeader.From:
-                               return "from";
+                               return "From";
                        case HttpRequestHeader.Host:
-                               return "host";
+                               return "Host";
                        case HttpRequestHeader.IfMatch:
-                               return "if-match";
+                               return "If-Match";
                        case HttpRequestHeader.IfModifiedSince:
-                               return "if-modified-since";
+                               return "If-Modified-Since";
                        case HttpRequestHeader.IfNoneMatch:
-                               return "if-none-match";
+                               return "If-None-Match";
                        case HttpRequestHeader.IfRange:
-                               return "if-range";
+                               return "If-Range";
                        case HttpRequestHeader.IfUnmodifiedSince:
-                               return "if-unmodified-since";
+                               return "If-Unmodified-Since";
                        case HttpRequestHeader.MaxForwards:
-                               return "max-forwards";
+                               return "Max-Forwards";
                        case HttpRequestHeader.ProxyAuthorization:
-                               return "proxy-authorization";
+                               return "Proxy-Authorization";
                        case HttpRequestHeader.Referer:
-                               return "referer";
+                               return "Referer";
                        case HttpRequestHeader.Range:
-                               return "range";
+                               return "Range";
                        case HttpRequestHeader.Te:
-                               return "te";
+                               return "TE";
                        case HttpRequestHeader.Translate:
-                               return "translate";
+                               return "Translate";
                        case HttpRequestHeader.UserAgent:
-                               return "user-agent";
+                               return "User-Agent";
                        default:
                                throw new InvalidOperationException ();
                        }
                }
                
+               
                public string this[HttpRequestHeader hrh]
                {
                        get {
@@ -440,65 +512,65 @@ namespace System.Net
                {
                        switch (value){
                        case HttpResponseHeader.CacheControl:
-                               return "cache-control";
+                               return "Cache-Control";
                        case HttpResponseHeader.Connection:
-                               return "connection";
+                               return "Connection";
                        case HttpResponseHeader.Date:
-                               return "date";
+                               return "Date";
                        case HttpResponseHeader.KeepAlive:
-                               return "keep-alive";
+                               return "Keep-Alive";
                        case HttpResponseHeader.Pragma:
-                               return "pragma";
+                               return "Pragma";
                        case HttpResponseHeader.Trailer:
-                               return "trailer";
+                               return "Trailer";
                        case HttpResponseHeader.TransferEncoding:
-                               return "transfer-encoding";
+                               return "Transfer-Encoding";
                        case HttpResponseHeader.Upgrade:
-                               return "upgrade";
+                               return "Upgrade";
                        case HttpResponseHeader.Via:
-                               return "via";
+                               return "Via";
                        case HttpResponseHeader.Warning:
-                               return "warning";
+                               return "Warning";
                        case HttpResponseHeader.Allow:
-                               return "allow";
+                               return "Allow";
                        case HttpResponseHeader.ContentLength:
-                               return "content-length";
+                               return "Content-Length";
                        case HttpResponseHeader.ContentType:
-                               return "content-type";
+                               return "Content-Type";
                        case HttpResponseHeader.ContentEncoding:
-                               return "content-encoding";
+                               return "Content-Encoding";
                        case HttpResponseHeader.ContentLanguage:
-                               return "content-language";
+                               return "Content-Language";
                        case HttpResponseHeader.ContentLocation:
-                               return "content-location";
+                               return "Content-Location";
                        case HttpResponseHeader.ContentMd5:
-                               return "content-md5";
+                               return "Content-MD5";
                        case HttpResponseHeader.ContentRange:
-                               return "content-range";
+                               return "Content-Range";
                        case HttpResponseHeader.Expires:
-                               return "expires";
+                               return "Expires";
                        case HttpResponseHeader.LastModified:
-                               return "last-modified";
+                               return "Last-Modified";
                        case HttpResponseHeader.AcceptRanges:
-                               return "accept-ranges";
+                               return "Accept-Ranges";
                        case HttpResponseHeader.Age:
-                               return "age";
+                               return "Age";
                        case HttpResponseHeader.ETag:
-                               return "etag";
+                               return "ETag";
                        case HttpResponseHeader.Location:
-                               return "location";
+                               return "Location";
                        case HttpResponseHeader.ProxyAuthenticate:
-                               return "proxy-authenticate";
+                               return "Proxy-Authenticate";
                        case HttpResponseHeader.RetryAfter:
-                               return "RetryAfter";
+                               return "Retry-After";
                        case HttpResponseHeader.Server:
-                               return "server";
+                               return "Server";
                        case HttpResponseHeader.SetCookie:
-                               return "set-cookie";
+                               return "Set-Cookie";
                        case HttpResponseHeader.Vary:
-                               return "vary";
+                               return "Vary";
                        case HttpResponseHeader.WwwAuthenticate:
-                               return "www-authenticate";
+                               return "WWW-Authenticate";
                        default:
                                throw new InvalidOperationException ();
                        }
@@ -515,7 +587,17 @@ namespace System.Net
                                Add (ResponseHeaderToString (hrh), value);
                        }
                }
-#endif
+
+               public override void Clear ()
+               {
+                       base.Clear ();
+               }
+
+
+               public override IEnumerator GetEnumerator ()
+               {
+                       return(base.GetEnumerator ());
+               }
 
                // Internal Methods
                
@@ -600,31 +682,30 @@ namespace System.Net
                
                internal static bool IsHeaderName (string name)
                {
-                       // token          = 1*<any CHAR except CTLs or tspecials>
-                       // tspecials      = "(" | ")" | "<" | ">" | "@"
-                       //                | "," | ";" | ":" | "\" | <">
-                       //                | "/" | "[" | "]" | "?" | "="
-                       //                | "{" | "}" | SP | HT
-                       
                        if (name == null || name.Length == 0)
                                return false;
 
                        int len = name.Length;
                        for (int i = 0; i < len; i++) {                 
                                char c = name [i];
-                               if (c < 0x20 || c >= 0x7f)
+                               if (c > 126 || !allowed_chars [(int) c])
                                        return false;
                        }
                        
-                       return name.IndexOfAny (tspecials) == -1;
+                       return true;
                }
 
-               private static char [] tspecials = 
-                               new char [] {'(', ')', '<', '>', '@',
-                                            ',', ';', ':', '\\', '"',
-                                            '/', '[', ']', '?', '=',
-                                            '{', '}', ' ', '\t'};
-                                                       
+               static bool [] allowed_chars = new bool [126] {
+                       false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+                       false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+                       false, false, false, false, false, true, false, true, true, true, true, false, false, false, true,
+                       true, false, true, true, false, true, true, true, true, true, true, true, true, true, true, false,
+                       false, false, false, false, false, false, true, true, true, true, true, true, true, true, true,
+                       true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+                       false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
+                       true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+                       false, true, false
+                       };
        }
 }