Refactored WebHeaderCollection.cs

This commit is contained in:
sta 2014-04-19 17:35:49 +09:00
parent a413cddab8
commit 117aa1089a

View File

@ -44,13 +44,12 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq;
using System.Net; using System.Net;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Security.Permissions; using System.Security.Permissions;
using System.Text; using System.Text;
namespace WebSocketSharp.Net namespace WebSocketSharp.Net
{ {
/// <summary> /// <summary>
@ -615,16 +614,12 @@ namespace WebSocketSharp.Net
/// Gets or sets the specified request <paramref name="header"/> in the collection. /// Gets or sets the specified request <paramref name="header"/> in the collection.
/// </summary> /// </summary>
/// <value> /// <value>
/// A <see cref="string"/> that represents the value of the specified request /// A <see cref="string"/> that represents the value of the request <paramref name="header"/>.
/// <paramref name="header"/>.
/// </value> /// </value>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpRequestHeader"/> that represents the request header. /// One of the <see cref="HttpRequestHeader"/> enum values, represents the request header
/// to get or set.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpRequestHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <para> /// <para>
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
@ -639,6 +634,10 @@ namespace WebSocketSharp.Net
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// The length of <paramref name="value"/> is greater than 65535. /// The length of <paramref name="value"/> is greater than 65535.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the request
/// <paramref name="header"/>.
/// </exception>
public string this [HttpRequestHeader header] { public string this [HttpRequestHeader header] {
get { get {
return Get (Convert (header)); return Get (Convert (header));
@ -653,16 +652,12 @@ namespace WebSocketSharp.Net
/// Gets or sets the specified response <paramref name="header"/> in the collection. /// Gets or sets the specified response <paramref name="header"/> in the collection.
/// </summary> /// </summary>
/// <value> /// <value>
/// A <see cref="string"/> that represents the value of the specified response /// A <see cref="string"/> that represents the value of the response <paramref name="header"/>.
/// <paramref name="header"/>.
/// </value> /// </value>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpResponseHeader"/> that represents the response header. /// One of the <see cref="HttpResponseHeader"/> enum values, represents the response header
/// to get or set.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpResponseHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <para> /// <para>
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
@ -677,6 +672,10 @@ namespace WebSocketSharp.Net
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// The length of <paramref name="value"/> is greater than 65535. /// The length of <paramref name="value"/> is greater than 65535.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the response
/// <paramref name="header"/>.
/// </exception>
public string this [HttpResponseHeader header] { public string this [HttpResponseHeader header] {
get { get {
return Get (Convert (header)); return Get (Convert (header));
@ -735,8 +734,8 @@ namespace WebSocketSharp.Net
private static HttpHeaderType checkHeaderType (string name) private static HttpHeaderType checkHeaderType (string name)
{ {
HttpHeaderInfo info; var info = getHeaderInfo (name);
return !tryGetHeaderInfo (name, out info) return info == null
? HttpHeaderType.Unspecified ? HttpHeaderType.Unspecified
: info.IsRequest && !info.IsResponse : info.IsRequest && !info.IsResponse
? HttpHeaderType.Request ? HttpHeaderType.Request
@ -747,7 +746,7 @@ namespace WebSocketSharp.Net
private static string checkName (string name) private static string checkName (string name)
{ {
if (name.IsNullOrEmpty ()) if (name == null || name.Length == 0)
throw new ArgumentNullException ("name"); throw new ArgumentNullException ("name");
name = name.Trim (); name = name.Trim ();
@ -779,7 +778,7 @@ namespace WebSocketSharp.Net
private static string checkValue (string value) private static string checkValue (string value)
{ {
if (value.IsNullOrEmpty ()) if (value == null || value.Length == 0)
return String.Empty; return String.Empty;
value = value.Trim (); value = value.Trim ();
@ -818,8 +817,8 @@ namespace WebSocketSharp.Net
{ {
checkState (response); checkState (response);
action (name, value); action (name, value);
if (setState) if (setState && _state == HttpHeaderType.Unspecified)
setDefaultState (response); _state = response ? HttpHeaderType.Response : HttpHeaderType.Request;
} }
private void doWithoutCheckingName (Action <string, string> action, string name, string value) private void doWithoutCheckingName (Action <string, string> action, string name, string value)
@ -830,15 +829,17 @@ namespace WebSocketSharp.Net
private static HttpHeaderInfo getHeaderInfo (string name) private static HttpHeaderInfo getHeaderInfo (string name)
{ {
return (from HttpHeaderInfo info in _headers.Values foreach (var info in _headers.Values)
where info.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase) if (info.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase))
select info).FirstOrDefault (); return info;
return null;
} }
private static bool isRestricted (string name, bool response) private static bool isRestricted (string name, bool response)
{ {
HttpHeaderInfo info; var info = getHeaderInfo (name);
return tryGetHeaderInfo (name, out info) && info.IsRestricted (response); return info != null && info.IsRestricted (response);
} }
private void removeWithoutCheckingName (string name, string unuse) private void removeWithoutCheckingName (string name, string unuse)
@ -847,23 +848,11 @@ namespace WebSocketSharp.Net
base.Remove (name); base.Remove (name);
} }
private void setDefaultState (bool response)
{
if (_state == HttpHeaderType.Unspecified)
_state = response ? HttpHeaderType.Response : HttpHeaderType.Request;
}
private void setWithoutCheckingName (string name, string value) private void setWithoutCheckingName (string name, string value)
{ {
doWithoutCheckingName (base.Set, name, value); doWithoutCheckingName (base.Set, name, value);
} }
private static bool tryGetHeaderInfo (string name, out HttpHeaderInfo info)
{
info = getHeaderInfo (name);
return info != null;
}
#endregion #endregion
#region Internal Methods #region Internal Methods
@ -880,7 +869,7 @@ namespace WebSocketSharp.Net
internal static bool IsHeaderName (string name) internal static bool IsHeaderName (string name)
{ {
return !name.IsNullOrEmpty () && name.IsToken (); return name != null && name.Length > 0 && name.IsToken ();
} }
internal static bool IsHeaderValue (string value) internal static bool IsHeaderValue (string value)
@ -890,11 +879,11 @@ namespace WebSocketSharp.Net
internal static bool IsMultiValue (string headerName, bool response) internal static bool IsMultiValue (string headerName, bool response)
{ {
if (headerName.IsNullOrEmpty ()) if (headerName == null || headerName.Length == 0)
return false; return false;
HttpHeaderInfo info; var info = getHeaderInfo (headerName);
return tryGetHeaderInfo (headerName, out info) && info.IsMultiValue (response); return info != null && info.IsMultiValue (response);
} }
internal void RemoveInternal (string name) internal void RemoveInternal (string name)
@ -1018,15 +1007,12 @@ namespace WebSocketSharp.Net
/// <paramref name="value"/> to the collection. /// <paramref name="value"/> to the collection.
/// </summary> /// </summary>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpRequestHeader"/> that represents the request header to add. /// One of the <see cref="HttpRequestHeader"/> enum values, represents the request header
/// to add.
/// </param> /// </param>
/// <param name="value"> /// <param name="value">
/// A <see cref="string"/> that represents the value of the header to add. /// A <see cref="string"/> that represents the value of the header to add.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpRequestHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <para> /// <para>
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
@ -1041,6 +1027,10 @@ namespace WebSocketSharp.Net
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// The length of <paramref name="value"/> is greater than 65535. /// The length of <paramref name="value"/> is greater than 65535.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the request
/// <paramref name="header"/>.
/// </exception>
public void Add (HttpRequestHeader header, string value) public void Add (HttpRequestHeader header, string value)
{ {
doWithCheckingState (addWithoutCheckingName, Convert (header), value, false, true); doWithCheckingState (addWithoutCheckingName, Convert (header), value, false, true);
@ -1051,15 +1041,12 @@ namespace WebSocketSharp.Net
/// <paramref name="value"/> to the collection. /// <paramref name="value"/> to the collection.
/// </summary> /// </summary>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpResponseHeader"/> that represents the response header to add. /// One of the <see cref="HttpResponseHeader"/> enum values, represents the response header
/// to add.
/// </param> /// </param>
/// <param name="value"> /// <param name="value">
/// A <see cref="string"/> that represents the value of the header to add. /// A <see cref="string"/> that represents the value of the header to add.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpResponseHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <para> /// <para>
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
@ -1074,14 +1061,18 @@ namespace WebSocketSharp.Net
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// The length of <paramref name="value"/> is greater than 65535. /// The length of <paramref name="value"/> is greater than 65535.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the response
/// <paramref name="header"/>.
/// </exception>
public void Add (HttpResponseHeader header, string value) public void Add (HttpResponseHeader header, string value)
{ {
doWithCheckingState (addWithoutCheckingName, Convert (header), value, true, true); doWithCheckingState (addWithoutCheckingName, Convert (header), value, true, true);
} }
/// <summary> /// <summary>
/// Adds a header with the specified <paramref name="name"/> and <paramref name="value"/> to /// Adds a header with the specified <paramref name="name"/> and <paramref name="value"/>
/// the collection. /// to the collection.
/// </summary> /// </summary>
/// <param name="name"> /// <param name="name">
/// A <see cref="string"/> that represents the name of the header to add. /// A <see cref="string"/> that represents the name of the header to add.
@ -1125,13 +1116,13 @@ namespace WebSocketSharp.Net
} }
/// <summary> /// <summary>
/// Get the value of the header with the specified <paramref name="index"/> in the collection. /// Get the value of the header at the specified <paramref name="index"/> in the collection.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// A <see cref="string"/> that receives the value of the header. /// A <see cref="string"/> that receives the value of the header.
/// </returns> /// </returns>
/// <param name="index"> /// <param name="index">
/// An <see cref="int"/> that is the zero-based index of the header to get. /// An <see cref="int"/> that represents the zero-based index of the header to find.
/// </param> /// </param>
public override string Get (int index) public override string Get (int index)
{ {
@ -1142,11 +1133,11 @@ namespace WebSocketSharp.Net
/// Get the value of the header with the specified <paramref name="name"/> in the collection. /// Get the value of the header with the specified <paramref name="name"/> in the collection.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// A <see cref="string"/> that receives the value of the header. /// A <see cref="string"/> that receives the value of the header. <see langword="null"/> if
/// <see langword="null"/> if there is no header with <paramref name="name"/> in the collection. /// there is no header with <paramref name="name"/> in the collection.
/// </returns> /// </returns>
/// <param name="name"> /// <param name="name">
/// A <see cref="string"/> that represents the name of the header to get. /// A <see cref="string"/> that represents the name of the header to find.
/// </param> /// </param>
public override string Get (string name) public override string Get (string name)
{ {
@ -1166,36 +1157,19 @@ namespace WebSocketSharp.Net
} }
/// <summary> /// <summary>
/// Get the header name at the specified <paramref name="index"/> position in the collection. /// Get the name of the header at the specified <paramref name="index"/> in the collection.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// A <see cref="string"/> that receives the header name. /// A <see cref="string"/> that receives the header name.
/// </returns> /// </returns>
/// <param name="index"> /// <param name="index">
/// An <see cref="int"/> is the zero-based index of the key to get from the collection. /// An <see cref="int"/> that represents the zero-based index of the header to find.
/// </param> /// </param>
public override string GetKey (int index) public override string GetKey (int index)
{ {
return base.GetKey (index); return base.GetKey (index);
} }
/// <summary>
/// Gets an array of header values stored in the specified <paramref name="header"/>.
/// </summary>
/// <returns>
/// An array of <see cref="string"/> that receives the header values.
/// </returns>
/// <param name="header">
/// A <see cref="string"/> that represents the name of the header.
/// </param>
public override string [] GetValues (string header)
{
var values = base.GetValues (header);
return values != null && values.Length > 0
? values
: null;
}
/// <summary> /// <summary>
/// Gets an array of header values stored in the specified <paramref name="index"/> position of /// Gets an array of header values stored in the specified <paramref name="index"/> position of
/// the collection. /// the collection.
@ -1204,7 +1178,7 @@ namespace WebSocketSharp.Net
/// An array of <see cref="string"/> that receives the header values. /// An array of <see cref="string"/> that receives the header values.
/// </returns> /// </returns>
/// <param name="index"> /// <param name="index">
/// An <see cref="int"/> is the zero-based index of the header in the collection. /// An <see cref="int"/> that represents the zero-based index of the header to find.
/// </param> /// </param>
public override string [] GetValues (int index) public override string [] GetValues (int index)
{ {
@ -1214,6 +1188,23 @@ namespace WebSocketSharp.Net
: null; : null;
} }
/// <summary>
/// Gets an array of header values stored in the specified <paramref name="header"/>.
/// </summary>
/// <returns>
/// An array of <see cref="string"/> that receives the header values.
/// </returns>
/// <param name="header">
/// A <see cref="string"/> that represents the name of the header to find.
/// </param>
public override string [] GetValues (string header)
{
var values = base.GetValues (header);
return values != null && values.Length > 0
? values
: null;
}
/// <summary> /// <summary>
/// Populates the specified <see cref="SerializationInfo"/> with the data needed to serialize /// Populates the specified <see cref="SerializationInfo"/> with the data needed to serialize
/// the <see cref="WebHeaderCollection"/>. /// the <see cref="WebHeaderCollection"/>.
@ -1302,38 +1293,38 @@ namespace WebSocketSharp.Net
} }
/// <summary> /// <summary>
/// Removes the specified request header from the collection. /// Removes the specified request <paramref name="header"/> from the collection.
/// </summary> /// </summary>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpRequestHeader"/> that represents the request header to remove from /// One of the <see cref="HttpRequestHeader"/> enum values, represents the request header
/// the collection. /// to remove.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpRequestHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the request
/// <paramref name="header"/>.
/// </exception>
public void Remove (HttpRequestHeader header) public void Remove (HttpRequestHeader header)
{ {
doWithCheckingState (removeWithoutCheckingName, Convert (header), null, false, false); doWithCheckingState (removeWithoutCheckingName, Convert (header), null, false, false);
} }
/// <summary> /// <summary>
/// Removes the specified response header from the collection. /// Removes the specified response <paramref name="header"/> from the collection.
/// </summary> /// </summary>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpResponseHeader"/> that represents the response header to remove from /// One of the <see cref="HttpResponseHeader"/> enum values, represents the response header
/// the collection. /// to remove.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpResponseHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the response
/// <paramref name="header"/>.
/// </exception>
public void Remove (HttpResponseHeader header) public void Remove (HttpResponseHeader header)
{ {
doWithCheckingState (removeWithoutCheckingName, Convert (header), null, true, false); doWithCheckingState (removeWithoutCheckingName, Convert (header), null, true, false);
@ -1343,7 +1334,7 @@ namespace WebSocketSharp.Net
/// Removes the specified header from the collection. /// Removes the specified header from the collection.
/// </summary> /// </summary>
/// <param name="name"> /// <param name="name">
/// A <see cref="string"/> that represents the name of the header to remove from the collection. /// A <see cref="string"/> that represents the name of the header to remove.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// <paramref name="name"/> is <see langword="null"/> or empty. /// <paramref name="name"/> is <see langword="null"/> or empty.
@ -1369,18 +1360,15 @@ namespace WebSocketSharp.Net
} }
/// <summary> /// <summary>
/// Sets the specified request header to the specified value. /// Sets the specified request <paramref name="header"/> to the specified value.
/// </summary> /// </summary>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpRequestHeader"/> that represents the request header to set. /// One of the <see cref="HttpRequestHeader"/> enum values, represents the request header
/// to set.
/// </param> /// </param>
/// <param name="value"> /// <param name="value">
/// A <see cref="string"/> that represents the value of the request header to set. /// A <see cref="string"/> that represents the value of the request header to set.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpRequestHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <para> /// <para>
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
@ -1395,24 +1383,25 @@ namespace WebSocketSharp.Net
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// The length of <paramref name="value"/> is greater than 65535. /// The length of <paramref name="value"/> is greater than 65535.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the request
/// <paramref name="header"/>.
/// </exception>
public void Set (HttpRequestHeader header, string value) public void Set (HttpRequestHeader header, string value)
{ {
doWithCheckingState (setWithoutCheckingName, Convert (header), value, false, true); doWithCheckingState (setWithoutCheckingName, Convert (header), value, false, true);
} }
/// <summary> /// <summary>
/// Sets the specified response header to the specified value. /// Sets the specified response <paramref name="header"/> to the specified value.
/// </summary> /// </summary>
/// <param name="header"> /// <param name="header">
/// A <see cref="HttpResponseHeader"/> that represents the response header to set. /// One of the <see cref="HttpResponseHeader"/> enum values, represents the response header
/// to set.
/// </param> /// </param>
/// <param name="value"> /// <param name="value">
/// A <see cref="string"/> that represents the value of the response header to set. /// A <see cref="string"/> that represents the value of the response header to set.
/// </param> /// </param>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow any of
/// <see cref="HttpResponseHeader"/> enum values.
/// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <para> /// <para>
/// <paramref name="header"/> is a restricted header. /// <paramref name="header"/> is a restricted header.
@ -1427,6 +1416,10 @@ namespace WebSocketSharp.Net
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// The length of <paramref name="value"/> is greater than 65535. /// The length of <paramref name="value"/> is greater than 65535.
/// </exception> /// </exception>
/// <exception cref="InvalidOperationException">
/// The current <see cref="WebHeaderCollection"/> instance doesn't allow the response
/// <paramref name="header"/>.
/// </exception>
public void Set (HttpResponseHeader header, string value) public void Set (HttpResponseHeader header, string value)
{ {
doWithCheckingState (setWithoutCheckingName, Convert (header), value, true, true); doWithCheckingState (setWithoutCheckingName, Convert (header), value, true, true);