diff --git a/Example2/Program.cs b/Example2/Program.cs index 0795cb3b..fa387677 100644 --- a/Example2/Program.cs +++ b/Example2/Program.cs @@ -41,7 +41,9 @@ namespace Example2 wssv.AddWebSocketService ("/Echo"); wssv.AddWebSocketService ("/Chat"); - //wssv.AddWebSocketService ("/Chat", () => new Chat ("Anon#")); + //wssv.AddWebSocketService ( + // "/Chat", + // () => new Chat ("Anon#") { Protocol = "chat" }); wssv.Start (); if (wssv.IsListening) { diff --git a/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs index 09a19458..6be645c2 100644 --- a/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs +++ b/websocket-sharp/Net/WebSockets/HttpListenerWebSocketContext.cs @@ -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. /// /// - /// This property represents the subprotocols of the WebSocket connection. + /// This property represents the subprotocols requested from the client. /// /// /// An IEnumerable<string> that contains the values of the @@ -249,7 +249,10 @@ namespace WebSocketSharp.Net.WebSockets /// public override IEnumerable 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 (); } } diff --git a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs index 428f1c40..6fb29092 100644 --- a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs +++ b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs @@ -251,7 +251,7 @@ namespace WebSocketSharp.Net.WebSockets /// WebSocket connection request. /// /// - /// This property represents the subprotocols of the WebSocket connection. + /// This property represents the subprotocols requested from the client. /// /// /// An IEnumerable<string> that contains the values of the @@ -259,7 +259,10 @@ namespace WebSocketSharp.Net.WebSockets /// public override IEnumerable 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 (); } } diff --git a/websocket-sharp/Net/WebSockets/WebSocketContext.cs b/websocket-sharp/Net/WebSockets/WebSocketContext.cs index 0067429d..34901cff 100644 --- a/websocket-sharp/Net/WebSockets/WebSocketContext.cs +++ b/websocket-sharp/Net/WebSockets/WebSocketContext.cs @@ -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. /// /// - /// This property represents the subprotocols of the WebSocket connection. + /// This property represents the subprotocols requested from the client. /// /// /// An IEnumerable<string> that contains the values of the diff --git a/websocket-sharp/Server/WebSocketService.cs b/websocket-sharp/Server/WebSocketService.cs index 906283e3..41c3c076 100644 --- a/websocket-sharp/Server/WebSocketService.cs +++ b/websocket-sharp/Server/WebSocketService.cs @@ -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; } + /// + /// Gets or sets the subprotocol used on the WebSocket connection. + /// + /// + /// Set operation of this property is available before the connection has + /// been established. + /// + /// + /// + /// A that represents the subprotocol if any. + /// + /// + /// The value to set must be a token defined in + /// RFC 2616. + /// + /// + /// The default value is . + /// + /// + public string Protocol { + get { + return _websocket != null + ? _websocket.Protocol + : _protocol ?? String.Empty; + } + + set { + if (State == WebSocketState.CONNECTING && value.IsToken ()) + _protocol = value; + } + } + /// /// Gets the time that the current 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 (); } diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 4bf27827..5aa144ba 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -392,7 +392,11 @@ namespace WebSocketSharp /// 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; }