Modified connecting
This commit is contained in:
parent
809e5ab58c
commit
0407486041
@ -69,7 +69,7 @@ namespace WebSocketSharp
|
|||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private AuthenticationChallenge _authChallenge;
|
private AuthenticationChallenge _authChallenge;
|
||||||
private string _base64key;
|
private string _base64Key;
|
||||||
private RemoteCertificateValidationCallback
|
private RemoteCertificateValidationCallback
|
||||||
_certValidationCallback;
|
_certValidationCallback;
|
||||||
private bool _client;
|
private bool _client;
|
||||||
@ -168,7 +168,7 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
_protocols = protocols.ToString (", ");
|
_protocols = protocols.ToString (", ");
|
||||||
|
|
||||||
_base64key = createBase64Key ();
|
_base64Key = CreateBase64Key ();
|
||||||
_client = true;
|
_client = true;
|
||||||
_logger = new Logger ();
|
_logger = new Logger ();
|
||||||
_secure = _uri.Scheme == "wss";
|
_secure = _uri.Scheme == "wss";
|
||||||
@ -487,22 +487,26 @@ namespace WebSocketSharp
|
|||||||
// As server
|
// As server
|
||||||
private bool acceptHandshake ()
|
private bool acceptHandshake ()
|
||||||
{
|
{
|
||||||
_logger.Debug (String.Format (
|
_logger.Debug (
|
||||||
"A WebSocket connection request from {0}:\n{1}", _context.UserEndPoint, _context));
|
String.Format (
|
||||||
|
"A WebSocket connection request from {0}:\n{1}",
|
||||||
|
_context.UserEndPoint,
|
||||||
|
_context));
|
||||||
|
|
||||||
if (!validateConnectionRequest (_context))
|
var err = checkIfValidHandshakeRequest (_context);
|
||||||
{
|
if (err != null) {
|
||||||
_logger.Error ("An invalid WebSocket connection request.");
|
_logger.Error (err);
|
||||||
|
|
||||||
error ("An error has occurred while handshaking.");
|
error ("An error has occurred while connecting.");
|
||||||
Close (HttpStatusCode.BadRequest);
|
Close (HttpStatusCode.BadRequest);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_base64key = _context.SecWebSocketKey;
|
_base64Key = _context.SecWebSocketKey;
|
||||||
|
|
||||||
if (_protocol.Length > 0 && !_context.Headers.Contains ("Sec-WebSocket-Protocol", _protocol))
|
if (_protocol.Length > 0 &&
|
||||||
|
!_context.Headers.Contains ("Sec-WebSocket-Protocol", _protocol))
|
||||||
_protocol = String.Empty;
|
_protocol = String.Empty;
|
||||||
|
|
||||||
var extensions = _context.Headers ["Sec-WebSocket-Extensions"];
|
var extensions = _context.Headers ["Sec-WebSocket-Extensions"];
|
||||||
@ -512,6 +516,45 @@ namespace WebSocketSharp
|
|||||||
return send (createHandshakeResponse ());
|
return send (createHandshakeResponse ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As server
|
||||||
|
private string checkIfValidHandshakeRequest (WebSocketContext context)
|
||||||
|
{
|
||||||
|
string key, version;
|
||||||
|
return !context.IsWebSocketRequest
|
||||||
|
? "Not WebSocket connection request."
|
||||||
|
: !validateHostHeader (context.Host)
|
||||||
|
? "Invalid Host header."
|
||||||
|
: (key = context.SecWebSocketKey) == null || key.Length == 0
|
||||||
|
? "Invalid Sec-WebSocket-Key header."
|
||||||
|
: (version = context.SecWebSocketVersion) == null ||
|
||||||
|
version != _version
|
||||||
|
? "Invalid Sec-WebSocket-Version header."
|
||||||
|
: !validateCookies (context.CookieCollection, _cookies)
|
||||||
|
? "Invalid Cookies."
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As client
|
||||||
|
private string checkIfValidHandshakeResponse (HandshakeResponse response)
|
||||||
|
{
|
||||||
|
var headers = response.Headers;
|
||||||
|
|
||||||
|
string accept, version;
|
||||||
|
return response.IsUnauthorized
|
||||||
|
? String.Format (
|
||||||
|
"An HTTP {0} authorization is required.",
|
||||||
|
response.AuthChallenge.Scheme)
|
||||||
|
: !response.IsWebSocketResponse
|
||||||
|
? "Not WebSocket connection response to the connection request."
|
||||||
|
: (accept = headers ["Sec-WebSocket-Accept"]) == null ||
|
||||||
|
accept != CreateResponseKey (_base64Key)
|
||||||
|
? "Invalid Sec-WebSocket-Accept header."
|
||||||
|
: (version = headers ["Sec-WebSocket-Version"]) != null &&
|
||||||
|
version != _version
|
||||||
|
? "Invalid Sec-WebSocket-Version header."
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
private void close (CloseStatusCode code, string reason, bool wait)
|
private void close (CloseStatusCode code, string reason, bool wait)
|
||||||
{
|
{
|
||||||
close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait);
|
close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait);
|
||||||
@ -649,7 +692,7 @@ namespace WebSocketSharp
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connect ()
|
private bool connect ()
|
||||||
{
|
{
|
||||||
lock (_forConnect) {
|
lock (_forConnect) {
|
||||||
if (IsOpened) {
|
if (IsOpened) {
|
||||||
@ -657,30 +700,24 @@ namespace WebSocketSharp
|
|||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (_client ? doHandshake () : acceptHandshake ())
|
if (_client ? doHandshake () : acceptHandshake ()) {
|
||||||
open ();
|
_readyState = WebSocketState.OPEN;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
processException (
|
processException (
|
||||||
ex, "An exception has occurred while connecting or opening.");
|
ex, "An exception has occurred while connecting.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
|
||||||
private static string createBase64Key ()
|
|
||||||
{
|
|
||||||
var src = new byte [16];
|
|
||||||
var rand = new Random ();
|
|
||||||
rand.NextBytes (src);
|
|
||||||
|
|
||||||
return Convert.ToBase64String (src);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private string createExtensionsRequest ()
|
private string createExtensionsRequest ()
|
||||||
{
|
{
|
||||||
@ -709,7 +746,7 @@ namespace WebSocketSharp
|
|||||||
if (!_origin.IsNullOrEmpty ())
|
if (!_origin.IsNullOrEmpty ())
|
||||||
headers ["Origin"] = _origin;
|
headers ["Origin"] = _origin;
|
||||||
|
|
||||||
headers ["Sec-WebSocket-Key"] = _base64key;
|
headers ["Sec-WebSocket-Key"] = _base64Key;
|
||||||
|
|
||||||
if (!_protocols.IsNullOrEmpty ())
|
if (!_protocols.IsNullOrEmpty ())
|
||||||
headers ["Sec-WebSocket-Protocol"] = _protocols;
|
headers ["Sec-WebSocket-Protocol"] = _protocols;
|
||||||
@ -744,7 +781,7 @@ namespace WebSocketSharp
|
|||||||
var res = new HandshakeResponse (HttpStatusCode.SwitchingProtocols);
|
var res = new HandshakeResponse (HttpStatusCode.SwitchingProtocols);
|
||||||
var headers = res.Headers;
|
var headers = res.Headers;
|
||||||
|
|
||||||
headers ["Sec-WebSocket-Accept"] = createResponseKey ();
|
headers ["Sec-WebSocket-Accept"] = CreateResponseKey (_base64Key);
|
||||||
|
|
||||||
if (_protocol.Length > 0)
|
if (_protocol.Length > 0)
|
||||||
headers ["Sec-WebSocket-Protocol"] = _protocol;
|
headers ["Sec-WebSocket-Protocol"] = _protocol;
|
||||||
@ -767,32 +804,16 @@ namespace WebSocketSharp
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string createResponseKey ()
|
|
||||||
{
|
|
||||||
var buffer = new StringBuilder (_base64key, 64);
|
|
||||||
buffer.Append (_guid);
|
|
||||||
SHA1 sha1 = new SHA1CryptoServiceProvider ();
|
|
||||||
var src = sha1.ComputeHash (Encoding.UTF8.GetBytes (buffer.ToString ()));
|
|
||||||
|
|
||||||
return Convert.ToBase64String (src);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private bool doHandshake ()
|
private bool doHandshake ()
|
||||||
{
|
{
|
||||||
setClientStream ();
|
setClientStream ();
|
||||||
var res = sendHandshakeRequest ();
|
var res = sendHandshakeRequest ();
|
||||||
var err = res.IsUnauthorized
|
var err = checkIfValidHandshakeResponse (res);
|
||||||
? String.Format ("An HTTP {0} authorization is required.", res.AuthChallenge.Scheme)
|
if (err != null) {
|
||||||
: !validateConnectionResponse (res)
|
|
||||||
? "An invalid response to this WebSocket connection request."
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (err != null)
|
|
||||||
{
|
|
||||||
_logger.Error (err);
|
_logger.Error (err);
|
||||||
|
|
||||||
var msg = "An error has occurred while handshaking.";
|
var msg = "An error has occurred while connecting.";
|
||||||
error (msg);
|
error (msg);
|
||||||
close (CloseStatusCode.ABNORMAL, msg, false);
|
close (CloseStatusCode.ABNORMAL, msg, false);
|
||||||
|
|
||||||
@ -831,10 +852,14 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
private void open ()
|
private void open ()
|
||||||
{
|
{
|
||||||
_readyState = WebSocketState.OPEN;
|
try {
|
||||||
|
OnOpen.Emit (this, EventArgs.Empty);
|
||||||
OnOpen.Emit (this, EventArgs.Empty);
|
startReceiving ();
|
||||||
startReceiving ();
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
processException (
|
||||||
|
ex, "An exception has occurred while opening.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool processCloseFrame (WsFrame frame)
|
private bool processCloseFrame (WsFrame frame)
|
||||||
@ -1270,13 +1295,15 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
private void startReceiving ()
|
private void startReceiving ()
|
||||||
{
|
{
|
||||||
|
if (_readyState != WebSocketState.OPEN)
|
||||||
|
return;
|
||||||
|
|
||||||
_exitReceiving = new AutoResetEvent (false);
|
_exitReceiving = new AutoResetEvent (false);
|
||||||
_receivePong = new AutoResetEvent (false);
|
_receivePong = new AutoResetEvent (false);
|
||||||
|
|
||||||
Action receive = null;
|
Action receive = null;
|
||||||
receive = () => _stream.ReadFrameAsync (
|
receive = () => _stream.ReadFrameAsync (
|
||||||
frame =>
|
frame => {
|
||||||
{
|
|
||||||
if (processFrame (frame))
|
if (processFrame (frame))
|
||||||
receive ();
|
receive ();
|
||||||
else
|
else
|
||||||
@ -1288,26 +1315,6 @@ namespace WebSocketSharp
|
|||||||
receive ();
|
receive ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// As server
|
|
||||||
private bool validateConnectionRequest (WebSocketContext context)
|
|
||||||
{
|
|
||||||
string version;
|
|
||||||
return context.IsWebSocketRequest &&
|
|
||||||
validateHostHeader (context.Host) &&
|
|
||||||
!context.SecWebSocketKey.IsNullOrEmpty () &&
|
|
||||||
((version = context.SecWebSocketVersion) != null && version == _version) &&
|
|
||||||
validateCookies (context.CookieCollection, _cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As client
|
|
||||||
private bool validateConnectionResponse (HandshakeResponse response)
|
|
||||||
{
|
|
||||||
string accept, version;
|
|
||||||
return response.IsWebSocketResponse &&
|
|
||||||
((accept = response.Headers ["Sec-WebSocket-Accept"]) != null && accept == createResponseKey ()) &&
|
|
||||||
((version = response.Headers ["Sec-WebSocket-Version"]) == null || version == _version);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As server
|
// As server
|
||||||
private bool validateCookies (CookieCollection request, CookieCollection response)
|
private bool validateCookies (CookieCollection request, CookieCollection response)
|
||||||
{
|
{
|
||||||
@ -1377,15 +1384,37 @@ namespace WebSocketSharp
|
|||||||
internal void ConnectAsServer ()
|
internal void ConnectAsServer ()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (acceptHandshake ())
|
if (acceptHandshake ()) {
|
||||||
|
_readyState = WebSocketState.OPEN;
|
||||||
open ();
|
open ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
processException (
|
processException (
|
||||||
ex, "An exception has occurred while connecting or opening.");
|
ex, "An exception has occurred while connecting.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As client
|
||||||
|
internal static string CreateBase64Key ()
|
||||||
|
{
|
||||||
|
var src = new byte [16];
|
||||||
|
var rand = new Random ();
|
||||||
|
rand.NextBytes (src);
|
||||||
|
|
||||||
|
return Convert.ToBase64String (src);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string CreateResponseKey (string base64Key)
|
||||||
|
{
|
||||||
|
var buffer = new StringBuilder (base64Key, 64);
|
||||||
|
buffer.Append (_guid);
|
||||||
|
SHA1 sha1 = new SHA1CryptoServiceProvider ();
|
||||||
|
var src = sha1.ComputeHash (Encoding.UTF8.GetBytes (buffer.ToString ()));
|
||||||
|
|
||||||
|
return Convert.ToBase64String (src);
|
||||||
|
}
|
||||||
|
|
||||||
internal bool Ping (byte [] frameAsBytes, int timeOut)
|
internal bool Ping (byte [] frameAsBytes, int timeOut)
|
||||||
{
|
{
|
||||||
return send (frameAsBytes) &&
|
return send (frameAsBytes) &&
|
||||||
@ -1571,7 +1600,8 @@ namespace WebSocketSharp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect ();
|
if (connect ())
|
||||||
|
open ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1590,8 +1620,13 @@ namespace WebSocketSharp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Action connector = connect;
|
Func<bool> connector = connect;
|
||||||
connector.BeginInvoke (ar => connector.EndInvoke (ar), null);
|
connector.BeginInvoke (
|
||||||
|
ar => {
|
||||||
|
if (connector.EndInvoke (ar))
|
||||||
|
open ();
|
||||||
|
},
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user