// // WebHeaderCollection.cs // Copied from System.Net.WebHeaderCollection.cs // // Authors: // Lawrence Pit (loz@cable.a2000.nl) // Gonzalo Paniagua Javier (gonzalo@ximian.com) // Miguel de Icaza (miguel@novell.com) // sta (sta.blockhead@gmail.com) // // Copyright (c) 2003 Ximian, Inc. (http://www.ximian.com) // Copyright (c) 2007 Novell, Inc. (http://www.novell.com) // Copyright (c) 2012-2013 sta.blockhead // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security.Permissions; using System.Text; namespace WebSocketSharp.Net { /// /// Provides a collection of the HTTP headers associated with a request or response. /// [Serializable] [ComVisible (true)] public class WebHeaderCollection : NameValueCollection, ISerializable { #region Fields static readonly Dictionary headers; bool internallyCreated; HttpHeaderType state; #endregion #region Constructors static WebHeaderCollection () { headers = new Dictionary (StringComparer.InvariantCultureIgnoreCase) { { "Accept", new HttpHeaderInfo () { Name = "Accept", Type = HttpHeaderType.Request | HttpHeaderType.Restricted | HttpHeaderType.MultiValue } }, { "AcceptCharset", new HttpHeaderInfo () { Name = "Accept-Charset", Type = HttpHeaderType.Request | HttpHeaderType.MultiValue } }, { "AcceptEncoding", new HttpHeaderInfo () { Name = "Accept-Encoding", Type = HttpHeaderType.Request | HttpHeaderType.MultiValue } }, { "AcceptLanguage", new HttpHeaderInfo () { Name = "Accept-language", Type = HttpHeaderType.Request | HttpHeaderType.MultiValue } }, { "AcceptRanges", new HttpHeaderInfo () { Name = "Accept-Ranges", Type = HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Age", new HttpHeaderInfo () { Name = "Age", Type = HttpHeaderType.Response } }, { "Allow", new HttpHeaderInfo () { Name = "Allow", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Authorization", new HttpHeaderInfo () { Name = "Authorization", Type = HttpHeaderType.Request | HttpHeaderType.MultiValue } }, { "CacheControl", new HttpHeaderInfo () { Name = "Cache-Control", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Connection", new HttpHeaderInfo () { Name = "Connection", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted | HttpHeaderType.MultiValue } }, { "ContentEncoding", new HttpHeaderInfo () { Name = "Content-Encoding", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "ContentLanguage", new HttpHeaderInfo () { Name = "Content-Language", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "ContentLength", new HttpHeaderInfo () { Name = "Content-Length", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted } }, { "ContentLocation", new HttpHeaderInfo () { Name = "Content-Location", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "ContentMd5", new HttpHeaderInfo () { Name = "Content-MD5", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "ContentRange", new HttpHeaderInfo () { Name = "Content-Range", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "ContentType", new HttpHeaderInfo () { Name = "Content-Type", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted } }, { "Cookie", new HttpHeaderInfo () { Name = "Cookie", Type = HttpHeaderType.Request } }, { "Cookie2", new HttpHeaderInfo () { Name = "Cookie2", Type = HttpHeaderType.Request } }, { "Date", new HttpHeaderInfo () { Name = "Date", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted } }, { "Expect", new HttpHeaderInfo () { Name = "Expect", Type = HttpHeaderType.Request | HttpHeaderType.Restricted | HttpHeaderType.MultiValue } }, { "Expires", new HttpHeaderInfo () { Name = "Expires", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "ETag", new HttpHeaderInfo () { Name = "ETag", Type = HttpHeaderType.Response } }, { "From", new HttpHeaderInfo () { Name = "From", Type = HttpHeaderType.Request } }, { "Host", new HttpHeaderInfo () { Name = "Host", Type = HttpHeaderType.Request | HttpHeaderType.Restricted } }, { "IfMatch", new HttpHeaderInfo () { Name = "If-Match", Type = HttpHeaderType.Request | HttpHeaderType.MultiValue } }, { "IfModifiedSince", new HttpHeaderInfo () { Name = "If-Modified-Since", Type = HttpHeaderType.Request | HttpHeaderType.Restricted } }, { "IfNoneMatch", new HttpHeaderInfo () { Name = "If-None-Match", Type = HttpHeaderType.Request | HttpHeaderType.MultiValue } }, { "IfRange", new HttpHeaderInfo () { Name = "If-Range", Type = HttpHeaderType.Request } }, { "IfUnmodifiedSince", new HttpHeaderInfo () { Name = "If-Unmodified-Since", Type = HttpHeaderType.Request } }, { "KeepAlive", new HttpHeaderInfo () { Name = "Keep-Alive", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "LastModified", new HttpHeaderInfo () { Name = "Last-Modified", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "Location", new HttpHeaderInfo () { Name = "Location", Type = HttpHeaderType.Response } }, { "MaxForwards", new HttpHeaderInfo () { Name = "Max-Forwards", Type = HttpHeaderType.Request } }, { "Pragma", new HttpHeaderInfo () { Name = "Pragma", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "ProxyConnection", new HttpHeaderInfo () { Name = "Proxy-Connection", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted } }, { "ProxyAuthenticate", new HttpHeaderInfo () { Name = "Proxy-Authenticate", Type = HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "ProxyAuthorization", new HttpHeaderInfo () { Name = "Proxy-Authorization", Type = HttpHeaderType.Request } }, { "Public", new HttpHeaderInfo () { Name = "Public", Type = HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Range", new HttpHeaderInfo () { Name = "Range", Type = HttpHeaderType.Request | HttpHeaderType.Restricted | HttpHeaderType.MultiValue } }, { "Referer", new HttpHeaderInfo () { Name = "Referer", Type = HttpHeaderType.Request | HttpHeaderType.Restricted } }, { "RetryAfter", new HttpHeaderInfo () { Name = "Retry-After", Type = HttpHeaderType.Response } }, { "SecWebSocketAccept", new HttpHeaderInfo () { Name = "Sec-WebSocket-Accept", Type = HttpHeaderType.Response | HttpHeaderType.Restricted } }, { "SecWebSocketExtensions", new HttpHeaderInfo () { Name = "Sec-WebSocket-Extensions", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted | HttpHeaderType.MultiValueInRequest } }, { "SecWebSocketKey", new HttpHeaderInfo () { Name = "Sec-WebSocket-Key", Type = HttpHeaderType.Request | HttpHeaderType.Restricted } }, { "SecWebSocketProtocol", new HttpHeaderInfo () { Name = "Sec-WebSocket-Protocol", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValueInRequest } }, { "SecWebSocketVersion", new HttpHeaderInfo () { Name = "Sec-WebSocket-Version", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted | HttpHeaderType.MultiValueInResponse } }, { "Server", new HttpHeaderInfo () { Name = "Server", Type = HttpHeaderType.Response } }, { "SetCookie", new HttpHeaderInfo () { Name = "Set-Cookie", Type = HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "SetCookie2", new HttpHeaderInfo () { Name = "Set-Cookie2", Type = HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Te", new HttpHeaderInfo () { Name = "TE", Type = HttpHeaderType.Request } }, { "Trailer", new HttpHeaderInfo () { Name = "Trailer", Type = HttpHeaderType.Request | HttpHeaderType.Response } }, { "TransferEncoding", new HttpHeaderInfo () { Name = "Transfer-Encoding", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.Restricted | HttpHeaderType.MultiValue } }, { "Translate", new HttpHeaderInfo () { Name = "Translate", Type = HttpHeaderType.Request } }, { "Upgrade", new HttpHeaderInfo () { Name = "Upgrade", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "UserAgent", new HttpHeaderInfo () { Name = "User-Agent", Type = HttpHeaderType.Request | HttpHeaderType.Restricted } }, { "Vary", new HttpHeaderInfo () { Name = "Vary", Type = HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Via", new HttpHeaderInfo () { Name = "Via", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "Warning", new HttpHeaderInfo () { Name = "Warning", Type = HttpHeaderType.Request | HttpHeaderType.Response | HttpHeaderType.MultiValue } }, { "WwwAuthenticate", new HttpHeaderInfo () { Name = "WWW-Authenticate", Type = HttpHeaderType.Response | HttpHeaderType.Restricted | HttpHeaderType.MultiValue } } }; } internal WebHeaderCollection (bool internallyCreated) { this.internallyCreated = internallyCreated; state = HttpHeaderType.Unspecified; } /// /// Initializes a new instance of the class /// with the specified and . /// /// /// A that contains the data to need to serialize the object. /// /// /// A that contains the source of the serialized stream associated with the new . /// /// /// is . /// /// /// An element with the specified name is not found in . /// protected WebHeaderCollection ( SerializationInfo serializationInfo, StreamingContext streamingContext) { if (serializationInfo == null) throw new ArgumentNullException ("serializationInfo"); try { internallyCreated = serializationInfo.GetBoolean ("InternallyCreated"); state = (HttpHeaderType) serializationInfo.GetInt32 ("State"); int count = serializationInfo.GetInt32 ("Count"); for (int i = 0; i < count; i++) { base.Add ( serializationInfo.GetString (i.ToString ()), serializationInfo.GetString ((count + i).ToString ())); } } catch (SerializationException ex) { throw new ArgumentException (ex.Message, "serializationInfo", ex); } } /// /// Initializes a new instance of the class. /// public WebHeaderCollection () { internallyCreated = false; state = HttpHeaderType.Unspecified; } #endregion #region Properties /// /// Gets all header names in the collection. /// /// /// An array of that contains all header names in the collection. /// public override string [] AllKeys { get { return base.AllKeys; } } /// /// Gets the number of headers in the collection. /// /// /// An that indicates the number of headers in the collection. /// public override int Count { get { return base.Count; } } /// /// Gets or sets the specified request in the collection. /// /// /// A that contains the value of the specified request . /// /// /// A that indicates a request header. /// /// /// The current instance does not allow any of values. /// /// /// /// is a restricted header. /// /// /// -or- /// /// /// contains invalid characters. /// /// /// /// The length of is greater than 65535. /// public string this [HttpRequestHeader header] { get { return Get (Convert (header)); } set { Add (header, value); } } /// /// Gets or sets the specified response in the collection. /// /// /// A that contains the value of the specified response . /// /// /// A that indicates a response header. /// /// /// The current instance does not allow any of values. /// /// /// /// is a restricted header. /// /// /// -or- /// /// /// contains invalid characters. /// /// /// /// The length of is greater than 65535. /// public string this [HttpResponseHeader header] { get { return Get (Convert (header)); } set { Add (header, value); } } /// /// Gets a collection of header names in the collection. /// /// /// A that contains a collection /// of header names in the collection. /// public override KeysCollection Keys { get { return base.Keys; } } #endregion #region Private Methods void Add (string name, string value, bool ignoreRestricted) { Action add; if (ignoreRestricted) add = AddWithoutCheckingNameAndRestricted; else add = AddWithoutCheckingName; DoWithCheckingState (add, CheckName (name), value, true); } void AddWithoutCheckingName (string name, string value) { DoWithoutCheckingName (base.Add, name, value); } void AddWithoutCheckingNameAndRestricted (string name, string value) { base.Add (name, CheckValue (value)); } static int CheckColonSeparated (string header) { int i = header.IndexOf (':'); if (i == -1) throw new ArgumentException ("No colon found.", "header"); return i; } static HttpHeaderType CheckHeaderType (string name) { HttpHeaderInfo info; return !TryGetHeaderInfo (name, out info) ? HttpHeaderType.Unspecified : info.IsRequest && !info.IsResponse ? HttpHeaderType.Request : !info.IsRequest && info.IsResponse ? HttpHeaderType.Response : HttpHeaderType.Unspecified; } static string CheckName (string name) { if (name.IsNullOrEmpty ()) throw new ArgumentNullException ("name"); name = name.Trim (); if (!IsHeaderName (name)) throw new ArgumentException ("Contains invalid characters.", "name"); return name; } void CheckRestricted (string name) { if (!internallyCreated && ContainsInRestricted (name, true)) throw new ArgumentException ("This header must be modified with the appropiate property."); } void CheckState (bool response) { if (state == HttpHeaderType.Unspecified) return; if (response && state == HttpHeaderType.Request) throw new InvalidOperationException ("This collection has already been used to store the request headers."); if (!response && state == HttpHeaderType.Response) throw new InvalidOperationException ("This collection has already been used to store the response headers."); } static string CheckValue (string value) { if (value.IsNullOrEmpty ()) return String.Empty; value = value.Trim (); if (value.Length > 65535) throw new ArgumentOutOfRangeException ("value", "The length must not be greater than 65535."); if (!IsHeaderValue (value)) throw new ArgumentException ("Contains invalid characters.", "value"); return value; } static string Convert (string key) { HttpHeaderInfo info; return headers.TryGetValue (key, out info) ? info.Name : String.Empty; } static bool ContainsInRestricted (string name, bool response) { HttpHeaderInfo info; return TryGetHeaderInfo (name, out info) ? info.IsRestricted (response) : false; } void DoWithCheckingState ( Action act, string name, string value, bool setState) { var type = CheckHeaderType (name); if (type == HttpHeaderType.Request) DoWithCheckingState (act, name, value, false, setState); else if (type == HttpHeaderType.Response) DoWithCheckingState (act, name, value, true, setState); else act (name, value); } void DoWithCheckingState ( Action act, string name, string value, bool response, bool setState) { CheckState (response); act (name, value); if (setState) SetState (response); } void DoWithoutCheckingName (Action act, string name, string value) { CheckRestricted (name); act (name, CheckValue (value)); } static HttpHeaderInfo GetHeaderInfo (string name) { return (from HttpHeaderInfo info in headers.Values where info.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase) select info).FirstOrDefault (); } void RemoveWithoutCheckingName (string name, string unuse) { CheckRestricted (name); base.Remove (name); } void SetState (bool response) { if (state == HttpHeaderType.Unspecified) state = response ? HttpHeaderType.Response : HttpHeaderType.Request; } void SetWithoutCheckingName (string name, string value) { DoWithoutCheckingName (base.Set, name, value); } static bool TryGetHeaderInfo (string name, out HttpHeaderInfo info) { info = GetHeaderInfo (name); return info != null; } #endregion #region Internal Methods internal static string Convert (HttpRequestHeader header) { return Convert (header.ToString ()); } internal static string Convert (HttpResponseHeader header) { return Convert (header.ToString ()); } internal static bool IsHeaderName (string name) { return name.IsNullOrEmpty () ? false : name.IsToken (); } internal static bool IsHeaderValue (string value) { return value.IsText (); } internal static bool IsMultiValue (string headerName, bool response) { if (headerName.IsNullOrEmpty ()) return false; HttpHeaderInfo info; return TryGetHeaderInfo (headerName, out info) ? info.IsMultiValue (response) : false; } internal void RemoveInternal (string name) { base.Remove (name); } internal void SetInternal (string header, bool response) { int pos = CheckColonSeparated (header); SetInternal (header.Substring (0, pos), header.Substring (pos + 1), response); } internal void SetInternal (string name, string value, bool response) { value = CheckValue (value); if (IsMultiValue (name, response)) base.Add (name, value); else base.Set (name, value); } internal string ToStringMultiValue (bool response) { var sb = new StringBuilder (); Count.Times (i => { string key = GetKey (i); if (IsMultiValue (key, response)) { foreach (string value in GetValues (i)) sb.AppendFormat ("{0}: {1}\r\n", key, value); } else { sb.AppendFormat ("{0}: {1}\r\n", key, Get (i)); } }); return sb.Append ("\r\n").ToString (); } #endregion #region Explicit Interface Implementation /// /// Populates the specified with the data to need to /// serialize the object. /// /// /// A that holds the data to need to serialize the object. /// /// /// A that specifies the destination for the serialization. /// /// /// is . /// [SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter, SerializationFormatter = true)] void ISerializable.GetObjectData ( SerializationInfo serializationInfo, StreamingContext streamingContext) { GetObjectData (serializationInfo, streamingContext); } #endregion #region Protected Methods /// /// Adds a header to the collection without checking whether the header is on the restricted header list. /// /// /// A that contains the name of the header to add. /// /// /// A that contains the value of the header to add. /// /// /// is or . /// /// /// or contains invalid characters. /// /// /// The length of is greater than 65535. /// /// /// The current instance does not allow the . /// protected void AddWithoutValidate (string headerName, string headerValue) { Add (headerName, headerValue, true); } #endregion #region Public Methods /// /// Adds the specified to the collection. /// /// /// A that contains a header with the name and value separated by a colon (:). /// /// /// is , , or /// the name part of is . /// /// /// /// does not contain a colon. /// /// /// -or- /// /// /// is a restricted header. /// /// /// -or- /// /// /// The name or value part of contains invalid characters. /// /// /// /// The length of the value part of is greater than 65535. /// /// /// The current instance does not allow the . /// public void Add (string header) { if (header.IsNullOrEmpty ()) throw new ArgumentNullException ("header"); int pos = CheckColonSeparated (header); Add (header.Substring (0, pos), header.Substring (pos + 1)); } /// /// Adds the specified request with the specified to the collection. /// /// /// A is a request header to add. /// /// /// A that contains the value of the header to add. /// /// /// The current instance does not allow any of values. /// /// /// /// is a restricted header. /// /// /// -or- /// /// /// contains invalid characters. /// /// /// /// The length of is greater than 65535. /// public void Add (HttpRequestHeader header, string value) { DoWithCheckingState (AddWithoutCheckingName, Convert (header), value, false, true); } /// /// Adds the specified response with the specified to the collection. /// /// /// A is a response header to add. /// /// /// A that contains the value of the header to add. /// /// /// The current instance does not allow any of values. /// /// /// /// is a restricted header. /// /// /// -or- /// /// /// contains invalid characters. /// /// /// /// The length of is greater than 65535. /// public void Add (HttpResponseHeader header, string value) { DoWithCheckingState (AddWithoutCheckingName, Convert (header), value, true, true); } /// /// Adds a header with the specified and to the collection. /// /// /// A that contains the name of the header to add. /// /// /// A that contains the value of the header to add. /// /// /// is or . /// /// /// /// or contains invalid characters. /// /// /// -or- /// /// /// is a restricted header name. /// /// /// /// The length of is greater than 65535. /// /// /// The current instance does not allow the header . /// public override void Add (string name, string value) { Add (name, value, false); } /// /// Removes all headers from the collection. /// public override void Clear () { base.Clear (); state = HttpHeaderType.Unspecified; } /// /// Get the value of the header with the specified in the collection. /// /// /// A that receives the value of the header. /// /// /// An that is the zero-based index of the header to get. /// public override string Get (int index) { return base.Get (index); } /// /// Get the value of the header with the specified in the collection. /// /// /// A that receives the value of the header. /// if there is no header with in the collection. /// /// /// A that contains the name of the header to get. /// public override string Get (string name) { return base.Get (name); } /// /// Gets the enumerator to use to iterate through the . /// /// /// An instance of an implementation of the interface /// to use to iterate through the . /// public override IEnumerator GetEnumerator () { return base.GetEnumerator (); } /// /// Get the header name at the specified position in the collection. /// /// /// A that receives the header name. /// /// /// An is the zero-based index of the key to get from the collection. /// public override string GetKey (int index) { return base.GetKey (index); } /// /// Gets an array of header values stored in the specified name. /// /// /// An array of that receives the header values. /// /// /// A that contains a header name. /// public override string [] GetValues (string header) { string [] values = base.GetValues (header); return values == null || values.Length == 0 ? null : values; } /// /// Gets an array of header values stored in the specified position of the header collection. /// /// /// An array of that receives the header values. /// /// /// An is the zero-based index of the header in the collection. /// public override string [] GetValues (int index) { string [] values = base.GetValues (index); return values == null || values.Length == 0 ? null : values; } /// /// Populates the specified with the data to need to /// serialize the object. /// /// /// A that holds the data to need to serialize the object. /// /// /// A that specifies the destination for the serialization. /// /// /// is . /// [SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] public override void GetObjectData ( SerializationInfo serializationInfo, StreamingContext streamingContext) { if (serializationInfo == null) throw new ArgumentNullException ("serializationInfo"); serializationInfo.AddValue ("InternallyCreated", internallyCreated); serializationInfo.AddValue ("State", (int) state); int count = Count; serializationInfo.AddValue ("Count", count); count.Times (i => { serializationInfo.AddValue (i.ToString (), GetKey (i)); serializationInfo.AddValue ((count + i).ToString (), Get (i)); }); } /// /// Determines whether the specified header can be set for the request. /// /// /// true if the header is restricted; otherwise, false. /// /// /// A that contains the name of the header to test. /// /// /// is or . /// /// /// contains invalid characters. /// public static bool IsRestricted (string headerName) { return IsRestricted (headerName, false); } /// /// Determines whether the specified header can be set for the request or the response. /// /// /// true if the header is restricted; otherwise, false. /// /// /// A that contains the name of the header to test. /// /// /// true if does the test for the response; for the request, false. /// /// /// is or . /// /// /// contains invalid characters. /// public static bool IsRestricted (string headerName, bool response) { return ContainsInRestricted (CheckName (headerName), response); } /// /// Implements the interface and raises the deserialization event /// when the deserialization is complete. /// /// /// An that contains the source of the deserialization event. /// public override void OnDeserialization (object sender) { } /// /// Removes the specified header from the collection. /// /// /// A to remove from the collection. /// /// /// The current instance does not allow any of values. /// /// /// is a restricted header. /// public void Remove (HttpRequestHeader header) { DoWithCheckingState (RemoveWithoutCheckingName, Convert (header), null, false, false); } /// /// Removes the specified header from the collection. /// /// /// A to remove from the collection. /// /// /// The current instance does not allow any of values. /// /// /// is a restricted header. /// public void Remove (HttpResponseHeader header) { DoWithCheckingState (RemoveWithoutCheckingName, Convert (header), null, true, false); } /// /// Removes the specified header from the collection. /// /// /// A that contains the name of the header to remove from the collection. /// /// /// is or . /// /// /// /// contains invalid characters. /// /// /// -or- /// /// /// is a restricted header name. /// /// /// /// The current instance does not allow the header . /// public override void Remove (string name) { DoWithCheckingState (RemoveWithoutCheckingName, CheckName (name), null, false); } /// /// Sets the specified header to the specified value. /// /// /// A to set. /// /// /// A that contains the value of the header to set. /// /// /// The current instance does not allow any of values. /// /// /// /// is a restricted header. /// /// /// -or- /// /// /// contains invalid characters. /// /// /// /// The length of is greater than 65535. /// public void Set (HttpRequestHeader header, string value) { DoWithCheckingState (SetWithoutCheckingName, Convert (header), value, false, true); } /// /// Sets the specified header to the specified value. /// /// /// A to set. /// /// /// A that contains the value of the header to set. /// /// /// The current instance does not allow any of values. /// /// /// /// is a restricted header. /// /// /// -or- /// /// /// contains invalid characters. /// /// /// /// The length of is greater than 65535. /// public void Set (HttpResponseHeader header, string value) { DoWithCheckingState (SetWithoutCheckingName, Convert (header), value, true, true); } /// /// Sets the specified header to the specified value. /// /// /// A that contains the name of the header to set. /// /// /// A that contains the value of the header to set. /// /// /// is or . /// /// /// /// or contain invalid characters. /// /// /// -or- /// /// /// is a restricted header name. /// /// /// /// The length of is greater than 65535. /// /// /// The current instance does not allow the header . /// public override void Set (string name, string value) { DoWithCheckingState (SetWithoutCheckingName, CheckName (name), value, true); } /// /// Converts the current to an array of . /// /// /// An array of that receives the converted current . /// public byte [] ToByteArray () { return Encoding.UTF8.GetBytes (ToString ()); } /// /// Returns a that represents the current . /// /// /// A that represents the current . /// public override string ToString () { var sb = new StringBuilder(); Count.Times (i => { sb.AppendFormat ("{0}: {1}\r\n", GetKey (i), Get (i)); }); return sb.Append ("\r\n").ToString (); } #endregion } }