[system.net.http] Accept header with multiple values. Fixes #27352
[mono.git] / mcs / class / System.Net.Http / System.Net.Http.Headers / HttpRequestHeaders.cs
index c16acbac2ef5974d021b2b929c8e66df25bfdc7e..4f6ceeef8e96102c57d94a4f3714ec3ea9fd6b3c 100644 (file)
@@ -32,31 +32,34 @@ namespace System.Net.Http.Headers
 {
        public sealed class HttpRequestHeaders : HttpHeaders
        {
+               bool? expectContinue;
+
                internal HttpRequestHeaders ()
+                       : base (HttpHeaderKind.Request)
                {
                }
 
                public HttpHeaderValueCollection<MediaTypeWithQualityHeaderValue> Accept {
                        get {
-                               return GetValue<HttpHeaderValueCollection<MediaTypeWithQualityHeaderValue>> ("Accept");
+                               return GetValues<MediaTypeWithQualityHeaderValue> ("Accept");
                        }
                }
 
                public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptCharset {
                        get {
-                               return GetValue<HttpHeaderValueCollection<StringWithQualityHeaderValue>> ("Accept-Charset");
+                               return GetValues<StringWithQualityHeaderValue> ("Accept-Charset");
                        }
                }
 
                public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptEncoding {
                        get {
-                               return GetValue<HttpHeaderValueCollection<StringWithQualityHeaderValue>> ("Accept-Encoding");
+                               return GetValues<StringWithQualityHeaderValue> ("Accept-Encoding");
                        }
                }
 
                public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptLanguage {
                        get {
-                               return GetValue<HttpHeaderValueCollection<StringWithQualityHeaderValue>> ("Accept-Language");
+                               return GetValues<StringWithQualityHeaderValue> ("Accept-Language");
                        }
                }
 
@@ -65,7 +68,7 @@ namespace System.Net.Http.Headers
                                return GetValue<AuthenticationHeaderValue> ("Authorization");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("Authorization", value);
                        }
                }
 
@@ -74,23 +77,38 @@ namespace System.Net.Http.Headers
                                return GetValue<CacheControlHeaderValue> ("Cache-Control");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("Cache-Control", value);
                        }
                }
 
                public HttpHeaderValueCollection<string> Connection {
                        get {
-                               return GetValue<HttpHeaderValueCollection<string>> ("Connection");
+                               return GetValues<string> ("Connection");
                        }
                }
 
                public bool? ConnectionClose {
                        get {
-                               throw new NotImplementedException ();
-                               //return Connection.GetValue<bool?> ("close");
+                               if (connectionclose == true || Connection.Find (l => string.Equals (l, "close", StringComparison.OrdinalIgnoreCase)) != null)
+                                       return true;
+
+                               return connectionclose;
                        }
                        set {
-                               // TODO: return Connection.SetValue ("Connection", "close", value);
+                               if (connectionclose == value)
+                                       return;
+
+                               Connection.Remove ("close");
+                               if (value == true)
+                                       Connection.Add ("close");
+
+                               connectionclose = value;
+                       }
+               }
+
+               internal bool ConnectionKeepAlive {
+                       get {
+                               return Connection.Find (l => string.Equals (l, "Keep-Alive", StringComparison.OrdinalIgnoreCase)) != null;
                        }
                }
 
@@ -99,22 +117,34 @@ namespace System.Net.Http.Headers
                                return GetValue<DateTimeOffset?> ("Date");
                        }
                        set {
-                               SetValue ("Date", value);
+                               AddOrRemove ("Date", value, Parser.DateTime.ToString);
                        }
                }
 
                public HttpHeaderValueCollection<NameValueWithParametersHeaderValue> Expect {
                        get {
-                               return GetValue<HttpHeaderValueCollection<NameValueWithParametersHeaderValue>> ("Expect");
+                               return GetValues<NameValueWithParametersHeaderValue> ("Expect");
                        }
                }
 
                public bool? ExpectContinue { 
                        get {
-                               throw new NotImplementedException ();
+                               if (expectContinue.HasValue)
+                                       return expectContinue;
+
+                               var found = TransferEncoding.Find (l => string.Equals (l.Value, "100-continue", StringComparison.OrdinalIgnoreCase));
+                               return found != null ? true : (bool?) null;
                        }
                        set {
-                               // TODO:
+                               if (expectContinue == value)
+                                       return;
+
+                               Expect.Remove (l => l.Name == "100-continue");
+
+                               if (value == true)
+                                       Expect.Add (new NameValueWithParametersHeaderValue ("100-continue"));
+
+                               expectContinue = value;
                        }
                }
 
@@ -123,7 +153,10 @@ namespace System.Net.Http.Headers
                                return GetValue<string> ("From");
                        }
                        set {
-                               // TODO: error checks
+                               if (!string.IsNullOrEmpty (value) && !Parser.EmailAddress.TryParse (value, out value))
+                                       throw new FormatException ();
+
+                               AddOrRemove ("From", value);
                        }
                }
 
@@ -132,13 +165,13 @@ namespace System.Net.Http.Headers
                                return GetValue<string> ("Host");
                        }
                        set {
-                               // TODO: error checks
+                               AddOrRemove ("Host", value);
                        }
                }
 
                public HttpHeaderValueCollection<EntityTagHeaderValue> IfMatch {
                        get {
-                               return GetValue<HttpHeaderValueCollection<EntityTagHeaderValue>> ("If-Match");
+                               return GetValues<EntityTagHeaderValue> ("If-Match");
                        }
                }
 
@@ -147,23 +180,22 @@ namespace System.Net.Http.Headers
                                return GetValue<DateTimeOffset?> ("If-Modified-Since");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("If-Modified-Since", value, Parser.DateTime.ToString);
                        }
                }
 
                public HttpHeaderValueCollection<EntityTagHeaderValue> IfNoneMatch {
                        get {
-                               return GetValue<HttpHeaderValueCollection<EntityTagHeaderValue>> ("If-None-Match");
+                               return GetValues<EntityTagHeaderValue> ("If-None-Match");
                        }
                }
 
                public RangeConditionHeaderValue IfRange {
-                       get
-                       {
+                       get {
                                return GetValue<RangeConditionHeaderValue> ("If-Range");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("If-Range", value);
                        }
                }
 
@@ -172,7 +204,7 @@ namespace System.Net.Http.Headers
                                return GetValue<DateTimeOffset?> ("If-Unmodified-Since");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("If-Unmodified-Since", value, Parser.DateTime.ToString);
                        }
                }
 
@@ -181,13 +213,13 @@ namespace System.Net.Http.Headers
                                return GetValue<int?> ("Max-Forwards");
                        }
                        set {
-                               SetValue ("Max-Forwards", value);
+                               AddOrRemove ("Max-Forwards", value);
                        }
                }
 
                public HttpHeaderValueCollection<NameValueHeaderValue> Pragma {
                        get {
-                               return GetValue<HttpHeaderValueCollection<NameValueHeaderValue>> ("Pragma");
+                               return GetValues<NameValueHeaderValue> ("Pragma");
                        }
                }
 
@@ -196,7 +228,7 @@ namespace System.Net.Http.Headers
                                return GetValue<AuthenticationHeaderValue> ("Proxy-Authorization");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("Proxy-Authorization", value);
                        }
                }
 
@@ -205,7 +237,7 @@ namespace System.Net.Http.Headers
                                return GetValue<RangeHeaderValue> ("Range");
                        }
                        set {
-                               // TODO:
+                               AddOrRemove ("Range", value);
                        }
                }
 
@@ -214,59 +246,76 @@ namespace System.Net.Http.Headers
                                return GetValue<Uri> ("Referer");
                        }
                        set {
-                               SetValue ("Referer", value);
+                               AddOrRemove ("Referer", value);
                        }
                }
 
                public HttpHeaderValueCollection<TransferCodingWithQualityHeaderValue> TE {
                    get {
-                       return GetValue<HttpHeaderValueCollection<TransferCodingWithQualityHeaderValue>> ("TE");
+                       return GetValues<TransferCodingWithQualityHeaderValue> ("TE");
                    }
                }
 
                public HttpHeaderValueCollection<string> Trailer {
                        get {
-                               return GetValue<HttpHeaderValueCollection<string>> ("Trailer");
+                               return GetValues<string> ("Trailer");
                        }
                }
 
                public HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncoding {
                        get {
-                               return GetValue<HttpHeaderValueCollection<TransferCodingHeaderValue>> ("Transfer-Encoding");
+                               return GetValues<TransferCodingHeaderValue> ("Transfer-Encoding");
                        }
                }
 
                public bool? TransferEncodingChunked {
                        get {
-                               throw new NotImplementedException ();
-                       }
+                               if (transferEncodingChunked.HasValue)
+                                       return transferEncodingChunked;
 
+                               var found = TransferEncoding.Find (l => string.Equals (l.Value, "chunked", StringComparison.OrdinalIgnoreCase));
+                               return found != null ? true : (bool?) null;
+                       }
                        set {
-                               // TODO:
+                               if (value == transferEncodingChunked)
+                                       return;
+
+                               TransferEncoding.Remove (l => l.Value == "chunked");
+                               if (value == true)
+                                       TransferEncoding.Add (new TransferCodingHeaderValue ("chunked"));
+
+                               transferEncodingChunked = value;
                        }
                }
 
                public HttpHeaderValueCollection<ProductHeaderValue> Upgrade {
                        get {
-                               return GetValue<HttpHeaderValueCollection<ProductHeaderValue>> ("Upgrade");
+                               return GetValues<ProductHeaderValue> ("Upgrade");
                        }
                }
 
                public HttpHeaderValueCollection<ProductInfoHeaderValue> UserAgent {
                        get {
-                               return GetValue<HttpHeaderValueCollection<ProductInfoHeaderValue>> ("User-Agent");
+                               return GetValues<ProductInfoHeaderValue> ("User-Agent");
                        }
                }
 
                public HttpHeaderValueCollection<ViaHeaderValue> Via {
                        get {
-                               return GetValue<HttpHeaderValueCollection<ViaHeaderValue>> ("Via");
+                               return GetValues<ViaHeaderValue> ("Via");
                        }
                }
 
                public HttpHeaderValueCollection<WarningHeaderValue> Warning {
                        get {
-                               return GetValue<HttpHeaderValueCollection<WarningHeaderValue>> ("Warning");
+                               return GetValues<WarningHeaderValue> ("Warning");
+                       }
+               }
+
+               internal void AddHeaders (HttpRequestHeaders headers)
+               {
+                       foreach (var header in headers) {
+                               TryAddWithoutValidation (header.Key, header.Value);
                        }
                }
        }