Modified ReadHandshake method

This commit is contained in:
sta 2013-06-16 16:09:02 +09:00
parent 37c317f254
commit efabc511b3
3 changed files with 75 additions and 86 deletions

View File

@ -224,6 +224,35 @@ namespace WebSocketSharp {
: stream.ToByteArray();
}
// <summary>
// Determines whether the specified <see cref="int"/> equals the specified <see cref="char"/>,
// and invokes the specified Action&lt;int&gt; delegate at the same time.
// </summary>
// <returns>
// <c>true</c> if <paramref name="value"/> equals <paramref name="c"/>; otherwise, <c>false</c>.
// </returns>
// <param name="value">
// An <see cref="int"/> to compare.
// </param>
// <param name="c">
// A <see cref="char"/> to compare.
// </param>
// <param name="action">
// An Action&lt;int&gt; delegate that references the method(s) called at the same time as when comparing.
// An <see cref="int"/> parameter to pass to the method(s) is <paramref name="value"/>.
// </param>
// <exception cref="ArgumentOutOfRangeException">
// <paramref name="value"/> is less than 0, or greater than 255.
// </exception>
internal static bool EqualsWith(this int value, char c, Action<int> action)
{
if (value < 0 || value > 255)
throw new ArgumentOutOfRangeException("value");
action(value);
return value == c - 0;
}
internal static string GetNameInternal(this string nameAndValue, string separator)
{
int i = nameAndValue.IndexOf(separator);
@ -272,27 +301,27 @@ namespace WebSocketSharp {
}
// <summary>
// Determines whether the specified object is <see langword="null"/>.
// And invokes the specified <see cref="Action"/> delegate if the specified object is <see langword="null"/>.
// Determines whether the specified object is <see langword="null"/>,
// and invokes the specified <see cref="Action"/> delegate if the object is <see langword="null"/>.
// </summary>
// <returns>
// <c>true</c> if the <paramref name="obj"/> parameter is <see langword="null"/>; otherwise, <c>false</c>.
// <c>true</c> if <paramref name="obj"/> is <see langword="null"/>; otherwise, <c>false</c>.
// </returns>
// <param name="obj">
// A <b>class</b> to test.
// </param>
// <param name="act">
// An <see cref="Action"/> delegate that contains the method(s) called if the <paramref name="obj"/> is <see langword="null"/>.
// <param name="action">
// An <see cref="Action"/> delegate that references the method(s) called if <paramref name="obj"/> is <see langword="null"/>.
// </param>
// <typeparam name="T">
// The type of the <paramref name="obj"/> parameter.
// The type of <paramref name="obj"/>.
// </typeparam>
internal static bool IsNullDo<T>(this T obj, Action act)
internal static bool IsNullDo<T>(this T obj, Action action)
where T : class
{
if (obj == null)
{
act();
action();
return true;
}
@ -662,36 +691,6 @@ namespace WebSocketSharp {
eventHandler(sender, e);
}
/// <summary>
/// Determines whether the specified <see cref="int"/> equals the specified <see cref="char"/> as <see cref="byte"/>.
/// And save this specified <see cref="int"/> as <see cref="byte"/> to the specified <strong>List&lt;byte&gt;</strong>.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="value"/> parameter equals the <paramref name="c"/> parameter as <see cref="byte"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="value">
/// An <see cref="int"/> to compare.
/// </param>
/// <param name="c">
/// A <see cref="char"/> to compare.
/// </param>
/// <param name="dest">
/// A <strong>List&lt;byte&gt;</strong> to save the <paramref name="value"/> as <see cref="byte"/>.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// Is thrown when the <paramref name="value"/> parameter passed to a method is invalid because it is outside the allowable range of values as <see cref="byte"/>.
/// </exception>
public static bool EqualsAndSaveTo(this int value, char c, List<byte> dest)
{
if (value < 0 || value > 255)
throw new ArgumentOutOfRangeException("value");
var b = (byte)value;
dest.Add(b);
return b == Convert.ToByte(c);
}
/// <summary>
/// Gets the absolute path from the specified <see cref="Uri"/>.
/// </summary>

View File

@ -47,6 +47,11 @@ namespace WebSocketSharp {
{
}
internal WebSocketException(string message)
: this(CloseStatusCode.NO_STATUS_CODE, message)
{
}
internal WebSocketException(CloseStatusCode code, string message)
: base(message)
{

View File

@ -40,6 +40,12 @@ namespace WebSocketSharp {
internal class WsStream : IDisposable
{
#region Private Const Fields
private const int _handshakeLimitLen = 8192;
#endregion
#region Private Fields
private Stream _innerStream;
@ -53,7 +59,7 @@ namespace WebSocketSharp {
private WsStream()
{
_forRead = new object();
_forRead = new object();
_forWrite = new object();
}
@ -64,21 +70,21 @@ namespace WebSocketSharp {
public WsStream(NetworkStream innerStream)
: this()
{
if (innerStream.IsNull())
if (innerStream == null)
throw new ArgumentNullException("innerStream");
_innerStream = innerStream;
_isSecure = false;
_isSecure = false;
}
public WsStream(SslStream innerStream)
: this()
{
if (innerStream.IsNull())
if (innerStream == null)
throw new ArgumentNullException("innerStream");
_innerStream = innerStream;
_isSecure = true;
_isSecure = true;
}
#endregion
@ -103,40 +109,6 @@ namespace WebSocketSharp {
#region Private Methods
private int read(byte[] buffer, int offset, int size)
{
var readLen = _innerStream.Read(buffer, offset, size);
if (readLen < size)
{
var msg = String.Format("Data can not be read from {0}.", _innerStream.GetType().Name);
throw new IOException(msg);
}
return readLen;
}
private int readByte()
{
return _innerStream.ReadByte();
}
private string[] readHandshake()
{
var buffer = new List<byte>();
while (true)
{
if (readByte().EqualsAndSaveTo('\r', buffer) &&
readByte().EqualsAndSaveTo('\n', buffer) &&
readByte().EqualsAndSaveTo('\r', buffer) &&
readByte().EqualsAndSaveTo('\n', buffer))
break;
}
return Encoding.UTF8.GetString(buffer.ToArray())
.Replace("\r\n", "\n").Replace("\n\n", "\n").TrimEnd('\n')
.Split('\n');
}
private bool write(byte[] data)
{
lock (_forWrite)
@ -181,7 +153,7 @@ namespace WebSocketSharp {
if (secure)
{
var sslStream = new SslStream(netStream, false);
var certPath = ConfigurationManager.AppSettings["ServerCertPath"];
var certPath = ConfigurationManager.AppSettings["ServerCertPath"];
sslStream.AuthenticateAsServer(new X509Certificate2(certPath));
return new WsStream(sslStream);
@ -192,7 +164,7 @@ namespace WebSocketSharp {
internal static WsStream CreateServerStream(WebSocketSharp.Net.HttpListenerContext context)
{
var conn = context.Connection;
var conn = context.Connection;
var stream = conn.Stream;
return conn.IsSecure
@ -236,17 +208,30 @@ namespace WebSocketSharp {
public string[] ReadHandshake()
{
lock (_forRead)
var read = false;
var buffer = new List<byte>();
Action<int> add = i => buffer.Add((byte)i);
while (buffer.Count < _handshakeLimitLen)
{
try
if (_innerStream.ReadByte().EqualsWith('\r', add) &&
_innerStream.ReadByte().EqualsWith('\n', add) &&
_innerStream.ReadByte().EqualsWith('\r', add) &&
_innerStream.ReadByte().EqualsWith('\n', add))
{
return readHandshake();
}
catch
{
return null;
read = true;
break;
}
}
if (!read)
throw new WebSocketException("The length of the handshake is greater than the limit length.");
return Encoding.UTF8.GetString(buffer.ToArray())
.Replace("\r\n", "\n")
.Replace("\n ", " ")
.Replace("\n\t", " ")
.Replace("\n\n", "")
.Split('\n');
}
public bool Write(WsFrame frame)