Fix for subprotocols for server
This commit is contained in:
parent
7e6b82306c
commit
253f8f7ddc
@ -41,7 +41,9 @@ namespace Example2
|
|||||||
|
|
||||||
wssv.AddWebSocketService<Echo> ("/Echo");
|
wssv.AddWebSocketService<Echo> ("/Echo");
|
||||||
wssv.AddWebSocketService<Chat> ("/Chat");
|
wssv.AddWebSocketService<Chat> ("/Chat");
|
||||||
//wssv.AddWebSocketService<Chat> ("/Chat", () => new Chat ("Anon#"));
|
//wssv.AddWebSocketService<Chat> (
|
||||||
|
// "/Chat",
|
||||||
|
// () => new Chat ("Anon#") { Protocol = "chat" });
|
||||||
|
|
||||||
wssv.Start ();
|
wssv.Start ();
|
||||||
if (wssv.IsListening) {
|
if (wssv.IsListening) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The MIT License
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -241,7 +241,7 @@ namespace WebSocketSharp.Net.WebSockets
|
|||||||
/// WebSocket connection request.
|
/// WebSocket connection request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This property represents the subprotocols of the WebSocket connection.
|
/// This property represents the subprotocols requested from the client.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// An IEnumerable<string> that contains the values of the
|
/// An IEnumerable<string> that contains the values of the
|
||||||
@ -249,7 +249,10 @@ namespace WebSocketSharp.Net.WebSockets
|
|||||||
/// </value>
|
/// </value>
|
||||||
public override IEnumerable<string> SecWebSocketProtocols {
|
public override IEnumerable<string> SecWebSocketProtocols {
|
||||||
get {
|
get {
|
||||||
return _context.Request.Headers.GetValues ("Sec-WebSocket-Protocol");
|
var protocols = _context.Request.Headers ["Sec-WebSocket-Protocol"];
|
||||||
|
if (protocols != null)
|
||||||
|
foreach (var protocol in protocols.Split (','))
|
||||||
|
yield return protocol.Trim ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ namespace WebSocketSharp.Net.WebSockets
|
|||||||
/// WebSocket connection request.
|
/// WebSocket connection request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This property represents the subprotocols of the WebSocket connection.
|
/// This property represents the subprotocols requested from the client.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// An IEnumerable<string> that contains the values of the
|
/// An IEnumerable<string> that contains the values of the
|
||||||
@ -259,7 +259,10 @@ namespace WebSocketSharp.Net.WebSockets
|
|||||||
/// </value>
|
/// </value>
|
||||||
public override IEnumerable<string> SecWebSocketProtocols {
|
public override IEnumerable<string> SecWebSocketProtocols {
|
||||||
get {
|
get {
|
||||||
return _request.Headers.GetValues ("Sec-WebSocket-Protocol");
|
var protocols = _request.Headers ["Sec-WebSocket-Protocol"];
|
||||||
|
if (protocols != null)
|
||||||
|
foreach (var protocol in protocols.Split (','))
|
||||||
|
yield return protocol.Trim ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* The MIT License
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -173,7 +173,7 @@ namespace WebSocketSharp.Net.WebSockets
|
|||||||
/// WebSocket connection request.
|
/// WebSocket connection request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This property represents the subprotocols of the WebSocket connection.
|
/// This property represents the subprotocols requested from the client.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// An IEnumerable<string> that contains the values of the
|
/// An IEnumerable<string> that contains the values of the
|
||||||
|
@ -44,10 +44,11 @@ namespace WebSocketSharp.Server
|
|||||||
{
|
{
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private WebSocket _websocket;
|
|
||||||
private WebSocketContext _context;
|
private WebSocketContext _context;
|
||||||
|
private string _protocol;
|
||||||
private WebSocketSessionManager _sessions;
|
private WebSocketSessionManager _sessions;
|
||||||
private DateTime _start;
|
private DateTime _start;
|
||||||
|
private WebSocket _websocket;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -129,6 +130,38 @@ namespace WebSocketSharp.Server
|
|||||||
get; private set;
|
get; private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the subprotocol used on the WebSocket connection.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Set operation of this property is available before the connection has
|
||||||
|
/// been established.
|
||||||
|
/// </remarks>
|
||||||
|
/// <value>
|
||||||
|
/// <para>
|
||||||
|
/// A <see cref="string"/> that represents the subprotocol if any.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// The value to set must be a token defined in
|
||||||
|
/// <see href="http://tools.ietf.org/html/rfc2616#section-2.2">RFC 2616</see>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// The default value is <see cref="String.Empty"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </value>
|
||||||
|
public string Protocol {
|
||||||
|
get {
|
||||||
|
return _websocket != null
|
||||||
|
? _websocket.Protocol
|
||||||
|
: _protocol ?? String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
if (State == WebSocketState.CONNECTING && value.IsToken ())
|
||||||
|
_protocol = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time that the current <see cref="WebSocketService"/> instance
|
/// Gets the time that the current <see cref="WebSocketService"/> instance
|
||||||
/// has been started.
|
/// has been started.
|
||||||
@ -203,11 +236,14 @@ namespace WebSocketSharp.Server
|
|||||||
_sessions = sessions;
|
_sessions = sessions;
|
||||||
|
|
||||||
_websocket = context.WebSocket;
|
_websocket = context.WebSocket;
|
||||||
|
_websocket.Protocol = _protocol;
|
||||||
_websocket.CookiesValidation = ValidateCookies;
|
_websocket.CookiesValidation = ValidateCookies;
|
||||||
|
|
||||||
_websocket.OnOpen += onOpen;
|
_websocket.OnOpen += onOpen;
|
||||||
_websocket.OnMessage += onMessage;
|
_websocket.OnMessage += onMessage;
|
||||||
_websocket.OnError += onError;
|
_websocket.OnError += onError;
|
||||||
_websocket.OnClose += onClose;
|
_websocket.OnClose += onClose;
|
||||||
|
|
||||||
_websocket.ConnectAsServer ();
|
_websocket.ConnectAsServer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +392,11 @@ namespace WebSocketSharp
|
|||||||
/// </value>
|
/// </value>
|
||||||
public string Protocol {
|
public string Protocol {
|
||||||
get {
|
get {
|
||||||
return _protocol;
|
return _protocol ?? String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal set {
|
||||||
|
_protocol = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,9 +597,9 @@ namespace WebSocketSharp
|
|||||||
_context.UserEndPoint,
|
_context.UserEndPoint,
|
||||||
_context));
|
_context));
|
||||||
|
|
||||||
var err = checkIfValidHandshakeRequest (_context);
|
var msg = checkIfValidHandshakeRequest (_context);
|
||||||
if (err != null) {
|
if (msg != null) {
|
||||||
_logger.Error (err);
|
_logger.Error (msg);
|
||||||
|
|
||||||
error ("An error has occurred while connecting.");
|
error ("An error has occurred while connecting.");
|
||||||
Close (HttpStatusCode.BadRequest);
|
Close (HttpStatusCode.BadRequest);
|
||||||
@ -603,11 +607,10 @@ namespace WebSocketSharp
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_base64Key = _context.SecWebSocketKey;
|
if (_protocol != null &&
|
||||||
|
!_context.SecWebSocketProtocols.Contains (
|
||||||
if (_protocol.Length > 0 &&
|
protocol => protocol == _protocol))
|
||||||
!_context.Headers.Contains ("Sec-WebSocket-Protocol", _protocol))
|
_protocol = null;
|
||||||
_protocol = String.Empty;
|
|
||||||
|
|
||||||
var extensions = _context.Headers ["Sec-WebSocket-Extensions"];
|
var extensions = _context.Headers ["Sec-WebSocket-Extensions"];
|
||||||
if (extensions != null && extensions.Length > 0)
|
if (extensions != null && extensions.Length > 0)
|
||||||
@ -672,15 +675,15 @@ namespace WebSocketSharp
|
|||||||
// As server
|
// As server
|
||||||
private string checkIfValidHandshakeRequest (WebSocketContext context)
|
private string checkIfValidHandshakeRequest (WebSocketContext context)
|
||||||
{
|
{
|
||||||
string key, version;
|
var headers = context.Headers;
|
||||||
return !context.IsWebSocketRequest
|
return !context.IsWebSocketRequest
|
||||||
? "Not WebSocket connection request."
|
? "Not WebSocket connection request."
|
||||||
: !validateHostHeader (context.Host)
|
: !validateHostHeader (headers ["Host"])
|
||||||
? "Invalid Host header."
|
? "Invalid Host header."
|
||||||
: (key = context.SecWebSocketKey) == null || key.Length == 0
|
: !validateSecWebSocketKeyHeader (headers ["Sec-WebSocket-Key"])
|
||||||
? "Invalid Sec-WebSocket-Key header."
|
? "Invalid Sec-WebSocket-Key header."
|
||||||
: (version = context.SecWebSocketVersion) == null ||
|
: !validateSecWebSocketVersionClientHeader (
|
||||||
version != _version
|
headers ["Sec-WebSocket-Version"])
|
||||||
? "Invalid Sec-WebSocket-Version header."
|
? "Invalid Sec-WebSocket-Version header."
|
||||||
: !validateCookies (context.CookieCollection, _cookies)
|
: !validateCookies (context.CookieCollection, _cookies)
|
||||||
? "Invalid Cookies."
|
? "Invalid Cookies."
|
||||||
@ -703,7 +706,7 @@ namespace WebSocketSharp
|
|||||||
: !validateSecWebSocketProtocolHeader (
|
: !validateSecWebSocketProtocolHeader (
|
||||||
headers ["Sec-WebSocket-Protocol"])
|
headers ["Sec-WebSocket-Protocol"])
|
||||||
? "Invalid Sec-WebSocket-Protocol header."
|
? "Invalid Sec-WebSocket-Protocol header."
|
||||||
: !validateSecWebSocketVersionHeader (
|
: !validateSecWebSocketVersionServerHeader (
|
||||||
headers ["Sec-WebSocket-Version"])
|
headers ["Sec-WebSocket-Version"])
|
||||||
? "Invalid Sec-WebSocket-Version header."
|
? "Invalid Sec-WebSocket-Version header."
|
||||||
: null;
|
: null;
|
||||||
@ -944,7 +947,7 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
headers ["Sec-WebSocket-Accept"] = CreateResponseKey (_base64Key);
|
headers ["Sec-WebSocket-Accept"] = CreateResponseKey (_base64Key);
|
||||||
|
|
||||||
if (_protocol.Length > 0)
|
if (_protocol != null)
|
||||||
headers ["Sec-WebSocket-Protocol"] = _protocol;
|
headers ["Sec-WebSocket-Protocol"] = _protocol;
|
||||||
|
|
||||||
if (_extensions.Length > 0)
|
if (_extensions.Length > 0)
|
||||||
@ -1002,7 +1005,6 @@ namespace WebSocketSharp
|
|||||||
_extensions = String.Empty;
|
_extensions = String.Empty;
|
||||||
_forConn = new object ();
|
_forConn = new object ();
|
||||||
_forSend = new object ();
|
_forSend = new object ();
|
||||||
_protocol = String.Empty;
|
|
||||||
_readyState = WebSocketState.CONNECTING;
|
_readyState = WebSocketState.CONNECTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1381,6 +1383,16 @@ namespace WebSocketSharp
|
|||||||
return value != null && value == CreateResponseKey (_base64Key);
|
return value != null && value == CreateResponseKey (_base64Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As server
|
||||||
|
private bool validateSecWebSocketKeyHeader (string value)
|
||||||
|
{
|
||||||
|
if (value == null || value.Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_base64Key = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private bool validateSecWebSocketProtocolHeader (string value)
|
private bool validateSecWebSocketProtocolHeader (string value)
|
||||||
{
|
{
|
||||||
@ -1395,8 +1407,14 @@ namespace WebSocketSharp
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As server
|
||||||
|
private bool validateSecWebSocketVersionClientHeader (string value)
|
||||||
|
{
|
||||||
|
return value != null && value == _version;
|
||||||
|
}
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private bool validateSecWebSocketVersionHeader (string value)
|
private bool validateSecWebSocketVersionServerHeader (string value)
|
||||||
{
|
{
|
||||||
return value == null || value == _version;
|
return value == null || value == _version;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user