diff --git a/websocket-sharp/WebSocketException.cs b/websocket-sharp/WebSocketException.cs
index 6e762dd0..d237792a 100644
--- a/websocket-sharp/WebSocketException.cs
+++ b/websocket-sharp/WebSocketException.cs
@@ -4,8 +4,8 @@
*
* The MIT License
*
- * Copyright (c) 2012-2013 sta.blockhead
- *
+ * Copyright (c) 2012-2014 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
@@ -15,7 +15,7 @@
*
* 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
@@ -31,30 +31,41 @@ using System;
namespace WebSocketSharp
{
///
- /// Represents the exception that occurred when attempting to perform an operation
- /// on the WebSocket connection.
+ /// Represents the exception that occurred when attempting to perform an
+ /// operation on the WebSocket connection.
///
public class WebSocketException : Exception
{
#region Internal Constructors
internal WebSocketException ()
- : this (CloseStatusCode.ABNORMAL)
+ : this (CloseStatusCode.ABNORMAL, null, null)
{
}
internal WebSocketException (CloseStatusCode code)
- : this (code, null)
+ : this (code, null, null)
{
}
internal WebSocketException (string reason)
- : this (CloseStatusCode.ABNORMAL, reason)
+ : this (CloseStatusCode.ABNORMAL, reason, null)
+ {
+ }
+
+ internal WebSocketException (string reason, Exception innerException)
+ : this (CloseStatusCode.ABNORMAL, reason, innerException)
{
}
internal WebSocketException (CloseStatusCode code, string reason)
- : base (reason ?? code.GetMessage ())
+ : this (code, reason, null)
+ {
+ }
+
+ internal WebSocketException (
+ CloseStatusCode code, string reason, Exception innerException)
+ : base (reason ?? code.GetMessage (), innerException)
{
Code = code;
}
@@ -64,10 +75,12 @@ namespace WebSocketSharp
#region Public Properties
///
- /// Gets the associated with the .
+ /// Gets the associated with the
+ /// .
///
///
- /// One of the values, indicates the causes of the .
+ /// One of the values, indicates the cause of
+ /// the .
///
public CloseStatusCode Code {
get; private set;
diff --git a/websocket-sharp/WsStream.cs b/websocket-sharp/WsStream.cs
index f72e8527..60d2dde6 100644
--- a/websocket-sharp/WsStream.cs
+++ b/websocket-sharp/WsStream.cs
@@ -42,7 +42,7 @@ namespace WebSocketSharp
{
#region Private Const Fields
- private const int _handshakeLimitLen = 8192;
+ private const int _handshakeHeadersLimitLen = 8192;
private const int _handshakeTimeout = 90000;
#endregion
@@ -100,61 +100,33 @@ namespace WebSocketSharp
#region Private Methods
- private byte [] readHandshakeEntityBody (string length)
+ private static byte [] readHandshakeEntityBody (Stream stream, string length)
{
var len = Int64.Parse (length);
return len > 1024
- ? _innerStream.ReadBytes (len, 1024)
- : _innerStream.ReadBytes ((int) len);
+ ? stream.ReadBytes (len, 1024)
+ : stream.ReadBytes ((int) len);
}
- private string [] readHandshakeHeaders ()
+ private static string [] readHandshakeHeaders (Stream stream)
{
- var read = false;
- var exception = false;
-
var buffer = new List ();
Action add = i => buffer.Add ((byte) i);
- var timeout = false;
- var timer = new Timer (
- state => {
- timeout = true;
- _innerStream.Close ();
- },
- null,
- _handshakeTimeout,
- -1);
-
- try {
- while (buffer.Count < _handshakeLimitLen) {
- if (_innerStream.ReadByte ().EqualsWith ('\r', add) &&
- _innerStream.ReadByte ().EqualsWith ('\n', add) &&
- _innerStream.ReadByte ().EqualsWith ('\r', add) &&
- _innerStream.ReadByte ().EqualsWith ('\n', add)) {
- read = true;
- break;
- }
+ var read = false;
+ while (buffer.Count < _handshakeHeadersLimitLen) {
+ if (stream.ReadByte ().EqualsWith ('\r', add) &&
+ stream.ReadByte ().EqualsWith ('\n', add) &&
+ stream.ReadByte ().EqualsWith ('\r', add) &&
+ stream.ReadByte ().EqualsWith ('\n', add)) {
+ read = true;
+ break;
}
}
- catch {
- exception = true;
- }
- finally {
- timer.Change (-1, -1);
- timer.Dispose ();
- }
- var reason = timeout
- ? "A timeout has occurred while receiving a handshake."
- : exception
- ? "An exception has occurred while receiving a handshake."
- : !read
- ? "A handshake length is greater than the limit length."
- : null;
-
- if (reason != null)
- throw new WebSocketException (reason);
+ if (!read)
+ throw new WebSocketException (
+ "The header part of a handshake is greater than the limit length.");
return Encoding.UTF8.GetString (buffer.ToArray ())
.Replace ("\r\n", "\n")
@@ -208,6 +180,48 @@ namespace WebSocketSharp
return new WsStream (conn.Stream, conn.IsSecure);
}
+ internal T ReadHandshake (Func parser)
+ where T : HandshakeBase
+ {
+ var timeout = false;
+ var timer = new Timer (
+ state => {
+ timeout = true;
+ _innerStream.Close ();
+ },
+ null,
+ _handshakeTimeout,
+ -1);
+
+ T handshake = null;
+ Exception exception = null;
+ try {
+ handshake = parser (readHandshakeHeaders (_innerStream));
+ var contentLen = handshake.Headers ["Content-Length"];
+ if (contentLen != null && contentLen.Length > 0)
+ handshake.EntityBodyData = readHandshakeEntityBody (
+ _innerStream, contentLen);
+ }
+ catch (Exception ex) {
+ exception = ex;
+ }
+ finally {
+ timer.Change (-1, -1);
+ timer.Dispose ();
+ }
+
+ var reason = timeout
+ ? "A timeout has occurred while receiving a handshake."
+ : exception != null
+ ? "An exception has occurred while receiving a handshake."
+ : null;
+
+ if (reason != null)
+ throw new WebSocketException (reason, exception);
+
+ return handshake;
+ }
+
internal bool Write (byte [] data)
{
lock (_forWrite) {
@@ -240,29 +254,20 @@ namespace WebSocketSharp
return WsFrame.Parse (_innerStream, true);
}
- public void ReadFrameAsync (Action completed, Action error)
+ public void ReadFrameAsync (
+ Action completed, Action error)
{
WsFrame.ParseAsync (_innerStream, true, completed, error);
}
public HandshakeRequest ReadHandshakeRequest ()
{
- var req = HandshakeRequest.Parse (readHandshakeHeaders ());
- var contentLen = req.Headers ["Content-Length"];
- if (contentLen != null && contentLen.Length > 0)
- req.EntityBodyData = readHandshakeEntityBody (contentLen);
-
- return req;
+ return ReadHandshake (HandshakeRequest.Parse);
}
public HandshakeResponse ReadHandshakeResponse ()
{
- var res = HandshakeResponse.Parse (readHandshakeHeaders ());
- var contentLen = res.Headers ["Content-Length"];
- if (contentLen != null && contentLen.Length > 0)
- res.EntityBodyData = readHandshakeEntityBody (contentLen);
-
- return res;
+ return ReadHandshake (HandshakeResponse.Parse);
}
public bool WriteFrame (WsFrame frame)