Fix for subprotocols for server

This commit is contained in:
sta 2014-02-07 16:47:59 +09:00
parent 7e6b82306c
commit 253f8f7ddc
6 changed files with 89 additions and 27 deletions

View File

@ -41,7 +41,9 @@ namespace Example2
wssv.AddWebSocketService<Echo> ("/Echo");
wssv.AddWebSocketService<Chat> ("/Chat");
//wssv.AddWebSocketService<Chat> ("/Chat", () => new Chat ("Anon#"));
//wssv.AddWebSocketService<Chat> (
// "/Chat",
// () => new Chat ("Anon#") { Protocol = "chat" });
wssv.Start ();
if (wssv.IsListening) {

View File

@ -4,7 +4,7 @@
*
* 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
@ -241,7 +241,7 @@ namespace WebSocketSharp.Net.WebSockets
/// WebSocket connection request.
/// </summary>
/// <remarks>
/// This property represents the subprotocols of the WebSocket connection.
/// This property represents the subprotocols requested from the client.
/// </remarks>
/// <value>
/// An IEnumerable&lt;string&gt; that contains the values of the
@ -249,7 +249,10 @@ namespace WebSocketSharp.Net.WebSockets
/// </value>
public override IEnumerable<string> SecWebSocketProtocols {
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 ();
}
}

View File

@ -251,7 +251,7 @@ namespace WebSocketSharp.Net.WebSockets
/// WebSocket connection request.
/// </summary>
/// <remarks>
/// This property represents the subprotocols of the WebSocket connection.
/// This property represents the subprotocols requested from the client.
/// </remarks>
/// <value>
/// An IEnumerable&lt;string&gt; that contains the values of the
@ -259,7 +259,10 @@ namespace WebSocketSharp.Net.WebSockets
/// </value>
public override IEnumerable<string> SecWebSocketProtocols {
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 ();
}
}

View File

@ -4,7 +4,7 @@
*
* 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
@ -173,7 +173,7 @@ namespace WebSocketSharp.Net.WebSockets
/// WebSocket connection request.
/// </summary>
/// <remarks>
/// This property represents the subprotocols of the WebSocket connection.
/// This property represents the subprotocols requested from the client.
/// </remarks>
/// <value>
/// An IEnumerable&lt;string&gt; that contains the values of the

View File

@ -44,10 +44,11 @@ namespace WebSocketSharp.Server
{
#region Private Fields
private WebSocket _websocket;
private WebSocketContext _context;
private string _protocol;
private WebSocketSessionManager _sessions;
private DateTime _start;
private WebSocket _websocket;
#endregion
@ -129,6 +130,38 @@ namespace WebSocketSharp.Server
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>
/// Gets the time that the current <see cref="WebSocketService"/> instance
/// has been started.
@ -203,11 +236,14 @@ namespace WebSocketSharp.Server
_sessions = sessions;
_websocket = context.WebSocket;
_websocket.Protocol = _protocol;
_websocket.CookiesValidation = ValidateCookies;
_websocket.OnOpen += onOpen;
_websocket.OnMessage += onMessage;
_websocket.OnError += onError;
_websocket.OnClose += onClose;
_websocket.ConnectAsServer ();
}

View File

@ -392,7 +392,11 @@ namespace WebSocketSharp
/// </value>
public string Protocol {
get {
return _protocol;
return _protocol ?? String.Empty;
}
internal set {
_protocol = value;
}
}
@ -593,9 +597,9 @@ namespace WebSocketSharp
_context.UserEndPoint,
_context));
var err = checkIfValidHandshakeRequest (_context);
if (err != null) {
_logger.Error (err);
var msg = checkIfValidHandshakeRequest (_context);
if (msg != null) {
_logger.Error (msg);
error ("An error has occurred while connecting.");
Close (HttpStatusCode.BadRequest);
@ -603,11 +607,10 @@ namespace WebSocketSharp
return false;
}
_base64Key = _context.SecWebSocketKey;
if (_protocol.Length > 0 &&
!_context.Headers.Contains ("Sec-WebSocket-Protocol", _protocol))
_protocol = String.Empty;
if (_protocol != null &&
!_context.SecWebSocketProtocols.Contains (
protocol => protocol == _protocol))
_protocol = null;
var extensions = _context.Headers ["Sec-WebSocket-Extensions"];
if (extensions != null && extensions.Length > 0)
@ -672,15 +675,15 @@ namespace WebSocketSharp
// As server
private string checkIfValidHandshakeRequest (WebSocketContext context)
{
string key, version;
var headers = context.Headers;
return !context.IsWebSocketRequest
? "Not WebSocket connection request."
: !validateHostHeader (context.Host)
: !validateHostHeader (headers ["Host"])
? "Invalid Host header."
: (key = context.SecWebSocketKey) == null || key.Length == 0
: !validateSecWebSocketKeyHeader (headers ["Sec-WebSocket-Key"])
? "Invalid Sec-WebSocket-Key header."
: (version = context.SecWebSocketVersion) == null ||
version != _version
: !validateSecWebSocketVersionClientHeader (
headers ["Sec-WebSocket-Version"])
? "Invalid Sec-WebSocket-Version header."
: !validateCookies (context.CookieCollection, _cookies)
? "Invalid Cookies."
@ -703,7 +706,7 @@ namespace WebSocketSharp
: !validateSecWebSocketProtocolHeader (
headers ["Sec-WebSocket-Protocol"])
? "Invalid Sec-WebSocket-Protocol header."
: !validateSecWebSocketVersionHeader (
: !validateSecWebSocketVersionServerHeader (
headers ["Sec-WebSocket-Version"])
? "Invalid Sec-WebSocket-Version header."
: null;
@ -944,7 +947,7 @@ namespace WebSocketSharp
headers ["Sec-WebSocket-Accept"] = CreateResponseKey (_base64Key);
if (_protocol.Length > 0)
if (_protocol != null)
headers ["Sec-WebSocket-Protocol"] = _protocol;
if (_extensions.Length > 0)
@ -1002,7 +1005,6 @@ namespace WebSocketSharp
_extensions = String.Empty;
_forConn = new object ();
_forSend = new object ();
_protocol = String.Empty;
_readyState = WebSocketState.CONNECTING;
}
@ -1381,6 +1383,16 @@ namespace WebSocketSharp
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
private bool validateSecWebSocketProtocolHeader (string value)
{
@ -1395,8 +1407,14 @@ namespace WebSocketSharp
return true;
}
// As server
private bool validateSecWebSocketVersionClientHeader (string value)
{
return value != null && value == _version;
}
// As client
private bool validateSecWebSocketVersionHeader (string value)
private bool validateSecWebSocketVersionServerHeader (string value)
{
return value == null || value == _version;
}