diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs
index bc0eb04b..d5a25717 100644
--- a/websocket-sharp/Ext.cs
+++ b/websocket-sharp/Ext.cs
@@ -367,11 +367,11 @@ namespace WebSocketSharp
/// A to compare.
///
///
- /// An Action<int> delegate that references the method(s) called at the same time as when comparing.
+ /// An Action<int> delegate that references the method(s) called at the same time as comparing.
/// An parameter to pass to the method(s) is .
///
///
- /// is less than 0, or greater than 255.
+ /// is not between 0 and 255.
///
internal static bool EqualsWith (this int value, char c, Action action)
{
@@ -407,15 +407,27 @@ namespace WebSocketSharp
: original;
}
- internal static string GetErrorMessage (this CloseStatusCode code)
+ internal static string GetMessage (this CloseStatusCode code)
{
- return code == CloseStatusCode.INCORRECT_DATA
- ? "An incorrect data has been received."
- : code == CloseStatusCode.INCONSISTENT_DATA
- ? "An inconsistent data has been received."
- : code == CloseStatusCode.TOO_BIG
- ? "A too big data has been received."
- : "A WebSocket exception has occured.";
+ return code == CloseStatusCode.PROTOCOL_ERROR
+ ? "A WebSocket protocol error has occurred."
+ : code == CloseStatusCode.INCORRECT_DATA
+ ? "An incorrect data has been received."
+ : code == CloseStatusCode.ABNORMAL
+ ? "An exception has occurred."
+ : code == CloseStatusCode.INCONSISTENT_DATA
+ ? "An inconsistent data has been received."
+ : code == CloseStatusCode.POLICY_VIOLATION
+ ? "A policy violation data has been received."
+ : code == CloseStatusCode.TOO_BIG
+ ? "A too big data has been received."
+ : code == CloseStatusCode.IGNORE_EXTENSION
+ ? "WebSocket client did not receive expected extension(s)."
+ : code == CloseStatusCode.SERVER_ERROR
+ ? "WebSocket server got an internal error."
+ : code == CloseStatusCode.TLS_HANDSHAKE_FAILURE
+ ? "An error has occurred while handshaking."
+ : String.Empty;
}
internal static string GetNameInternal (this string nameAndValue, string separator)
@@ -426,17 +438,6 @@ namespace WebSocketSharp
: null;
}
- internal static string GetReason (this CloseStatusCode code)
- {
- return code == CloseStatusCode.ABNORMAL
- ? "A WebSocket exception has occured."
- : code == CloseStatusCode.TOO_BIG
- ? String.Format (
- "The payload data length is greater than the allowable length ({0} bytes).",
- PayloadData.MaxLength)
- : String.Empty;
- }
-
internal static string GetValueInternal (this string nameAndValue, string separator)
{
int i = nameAndValue.IndexOf (separator);
@@ -791,9 +792,9 @@ namespace WebSocketSharp
internal static void WriteBytes (this Stream stream, byte [] value)
{
- using (var input = new MemoryStream (value))
+ using (var src = new MemoryStream (value))
{
- input.CopyTo (stream);
+ src.CopyTo (stream);
}
}
diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs
index 05387de7..534a981c 100644
--- a/websocket-sharp/WebSocket.cs
+++ b/websocket-sharp/WebSocket.cs
@@ -505,14 +505,14 @@ namespace WebSocketSharp
// As server
private bool acceptHandshake ()
{
- _logger.Debug (String.Format ("A WebSocket connection request from {0}:\n{1}",
- _context.UserEndPoint, _context));
+ _logger.Debug (String.Format (
+ "A WebSocket connection request from {0}:\n{1}", _context.UserEndPoint, _context));
if (!validateConnectionRequest (_context))
{
- var msg = "Invalid WebSocket connection request.";
- _logger.Error (msg);
- error (msg);
+ _logger.Error ("An invalid WebSocket connection request.");
+
+ error ("An error has occurred while handshaking.");
Close (HttpStatusCode.BadRequest);
return false;
@@ -542,11 +542,11 @@ namespace WebSocketSharp
if (_readyState == WebSocketState.CLOSING || _readyState == WebSocketState.CLOSED)
return;
- _logger.Trace ("Start closing handshake.");
-
_readyState = WebSocketState.CLOSING;
}
+ _logger.Trace ("Start closing handshake.");
+
var args = new CloseEventArgs (payload);
args.WasClean = _client
? close (
@@ -559,9 +559,9 @@ namespace WebSocketSharp
closeServerResources);
_readyState = WebSocketState.CLOSED;
+ OnClose.Emit (this, args);
_logger.Trace ("End closing handshake.");
- OnClose.Emit (this, args);
}
private bool close (byte [] frameAsBytes, int timeOut, Func release)
@@ -596,7 +596,7 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
return false;
}
@@ -616,13 +616,13 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
return false;
}
}
- private bool concatenateFragments (Stream dest)
+ private bool concatenateFragmentsInto (Stream dest)
{
while (true)
{
@@ -661,7 +661,7 @@ namespace WebSocketSharp
return processCloseFrame (frame);
// ?
- return processIncorrectFrame (frame, null);
+ return processUnsupportedFrame (frame, CloseStatusCode.INCORRECT_DATA, null);
}
return true;
@@ -772,23 +772,25 @@ namespace WebSocketSharp
{
setClientStream ();
var res = sendHandshakeRequest ();
- var msg = res.IsUnauthorized
+ var err = res.IsUnauthorized
? String.Format ("An HTTP {0} authorization is required.", res.AuthChallenge.Scheme)
: !validateConnectionResponse (res)
- ? "Invalid response to this WebSocket connection request."
- : String.Empty;
+ ? "An invalid response to this WebSocket connection request."
+ : null;
- if (msg.Length > 0)
+ if (err != null)
{
- _logger.Error (msg);
+ _logger.Error (err);
+
+ var msg = "An error has occurred while handshaking.";
error (msg);
- Close (CloseStatusCode.ABNORMAL);
+ close (CloseStatusCode.ABNORMAL, msg, false);
return false;
}
var protocol = res.Headers ["Sec-WebSocket-Protocol"];
- if (protocol != null && protocol.Length > 0)
+ if (!protocol.IsNullOrEmpty ())
_protocol = protocol;
processRespondedExtensions (res.Headers ["Sec-WebSocket-Extensions"]);
@@ -841,23 +843,34 @@ namespace WebSocketSharp
return true;
}
- private void processException (Exception exception)
+ private void processException (Exception exception, string reason)
{
- _logger.Fatal (exception.ToString ());
-
var code = CloseStatusCode.ABNORMAL;
- var reason = "An exception has occured.";
- var msg = reason;
+ var msg = reason ?? code.GetMessage ();
+
if (exception.GetType () == typeof (WebSocketException))
{
var wsex = (WebSocketException) exception;
code = wsex.Code;
reason = wsex.Message;
- msg = code.GetErrorMessage ();
+ }
+
+ if (code == CloseStatusCode.ABNORMAL)
+ {
+ _logger.Fatal (exception.ToString ());
+ reason = msg;
+ }
+ else
+ {
+ _logger.Error (reason);
+ msg = code.GetMessage ();
}
error (msg);
- close (code, reason, false);
+ if (_readyState == WebSocketState.CONNECTING && !_client)
+ Close (HttpStatusCode.BadRequest);
+ else
+ close (code, reason, false);
}
private bool processFragmentedFrame (WsFrame frame)
@@ -872,7 +885,7 @@ namespace WebSocketSharp
using (var concatenated = new MemoryStream ())
{
concatenated.WriteBytes (first.PayloadData.ApplicationData);
- if (!concatenateFragments (concatenated))
+ if (!concatenateFragmentsInto (concatenated))
return false;
byte [] data;
@@ -894,7 +907,10 @@ namespace WebSocketSharp
private bool processFrame (WsFrame frame)
{
return frame.IsCompressed && _compression == CompressionMethod.NONE
- ? processIncorrectFrame (frame, "A compressed frame without available decompression method.")
+ ? processUnsupportedFrame (
+ frame,
+ CloseStatusCode.INCORRECT_DATA,
+ "A compressed data has been received without available decompression method.")
: frame.IsFragmented
? processFragmentedFrame (frame)
: frame.IsData
@@ -905,16 +921,7 @@ namespace WebSocketSharp
? processPongFrame ()
: frame.IsClose
? processCloseFrame (frame)
- : processIncorrectFrame (frame, null);
- }
-
- private bool processIncorrectFrame (WsFrame frame, string reason)
- {
- _logger.Debug ("Incorrect frame:\n" + frame.PrintToString (false));
- processException (new WebSocketException (
- CloseStatusCode.INCORRECT_DATA, reason ?? String.Empty));
-
- return false;
+ : processUnsupportedFrame (frame, CloseStatusCode.POLICY_VIOLATION, null);
}
private bool processPingFrame (WsFrame frame)
@@ -979,6 +986,14 @@ namespace WebSocketSharp
_compression = CompressionMethod.NONE;
}
+ private bool processUnsupportedFrame (WsFrame frame, CloseStatusCode code, string reason)
+ {
+ _logger.Debug ("Unsupported frame:\n" + frame.PrintToString (false));
+ processException (new WebSocketException (code, reason), null);
+
+ return false;
+ }
+
// As client
private HandshakeResponse receiveHandshakeResponse ()
{
@@ -1049,7 +1064,7 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
}
return sent;
@@ -1075,7 +1090,7 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
}
finally {
if (compressed)
@@ -1101,7 +1116,7 @@ namespace WebSocketSharp
catch (Exception ex)
{
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
}
};
@@ -1121,7 +1136,7 @@ namespace WebSocketSharp
catch (Exception ex)
{
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
}
};
@@ -1244,7 +1259,8 @@ namespace WebSocketSharp
else
_exitReceiving.Set ();
},
- processException);
+ ex => processException (
+ ex, "An exception has occurred while receiving a message."));
receive ();
}
@@ -1357,7 +1373,7 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
}
}
}
@@ -1381,7 +1397,7 @@ namespace WebSocketSharp
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
}
}
}
@@ -1519,12 +1535,7 @@ namespace WebSocketSharp
open ();
}
catch (Exception ex) {
- _logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
- if (_client)
- Close (CloseStatusCode.ABNORMAL);
- else
- Close (HttpStatusCode.BadRequest);
+ processException (ex, "An exception has occurred while connecting or opening.");
}
}
@@ -1808,7 +1819,7 @@ namespace WebSocketSharp
ex =>
{
_logger.Fatal (ex.ToString ());
- error ("An exception has occured.");
+ error ("An exception has occurred.");
});
}
diff --git a/websocket-sharp/WebSocketException.cs b/websocket-sharp/WebSocketException.cs
index bd7394f5..aa07c74d 100644
--- a/websocket-sharp/WebSocketException.cs
+++ b/websocket-sharp/WebSocketException.cs
@@ -44,7 +44,7 @@ namespace WebSocketSharp
}
internal WebSocketException (CloseStatusCode code)
- : this (code, code.GetReason ())
+ : this (code, code.GetMessage ())
{
}
@@ -54,7 +54,7 @@ namespace WebSocketSharp
}
internal WebSocketException (CloseStatusCode code, string reason)
- : base (reason)
+ : base (reason ?? code.GetMessage ())
{
Code = code;
}
diff --git a/websocket-sharp/WsFrame.cs b/websocket-sharp/WsFrame.cs
index 7a83ddef..e21bd3ee 100644
--- a/websocket-sharp/WsFrame.cs
+++ b/websocket-sharp/WsFrame.cs
@@ -459,7 +459,8 @@ namespace WebSocketSharp
{
// Check if allowable payload data length.
if (payloadLen > 126 && dataLen > PayloadData.MaxLength)
- throw new WebSocketException (CloseStatusCode.TOO_BIG);
+ throw new WebSocketException (
+ CloseStatusCode.TOO_BIG, "The 'Payload Data' length is greater than the allowable length.");
data = payloadLen > 126
? stream.ReadBytes ((long) dataLen, 1024)
diff --git a/websocket-sharp/WsStream.cs b/websocket-sharp/WsStream.cs
index 6642ec74..da33859f 100644
--- a/websocket-sharp/WsStream.cs
+++ b/websocket-sharp/WsStream.cs
@@ -32,6 +32,7 @@ using System.IO;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
+using System.Threading;
using WebSocketSharp.Net;
using WebSocketSharp.Net.Security;
@@ -42,6 +43,7 @@ namespace WebSocketSharp
#region Private Const Fields
private const int _handshakeLimitLen = 8192;
+ private const int _handshakeTimeout = 90000;
#endregion
@@ -181,22 +183,53 @@ namespace WebSocketSharp
public string [] ReadHandshake ()
{
var read = false;
+ var exception = false;
+
var buffer = new List ();
Action add = i => buffer.Add ((byte) i);
- 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))
+
+ var timeout = false;
+ var timer = new Timer (
+ state =>
{
- read = true;
- break;
+ 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;
+ }
}
}
+ catch {
+ exception = true;
+ }
+ finally {
+ timer.Change (-1, -1);
+ timer.Dispose ();
+ }
- if (!read)
- throw new WebSocketException ("The length of the handshake is greater than the limit length.");
+ 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);
return Encoding.UTF8.GetString (buffer.ToArray ())
.Replace ("\r\n", "\n")