diff --git a/Example2/Echo.cs b/Example2/Echo.cs index 130a934d..e3fa6ba6 100644 --- a/Example2/Echo.cs +++ b/Example2/Echo.cs @@ -3,24 +3,24 @@ using WebSocketSharp; using WebSocketSharp.Net; using WebSocketSharp.Server; -namespace Example2 { - +namespace Example2 +{ public class Echo : WebSocketService { - protected override void OnMessage(MessageEventArgs e) + protected override void OnMessage (MessageEventArgs e) { - var msg = QueryString.Contains("name") - ? String.Format("'{0}' returns to {1}", e.Data, QueryString["name"]) + var msg = QueryString.Contains ("name") + ? String.Format ("Returns '{0}' to {1}", e.Data, QueryString ["name"]) : e.Data; - Send(msg); + Send (msg); } - protected override bool ProcessCookies(CookieCollection request, CookieCollection response) + protected override bool ValidateCookies (CookieCollection request, CookieCollection response) { foreach (Cookie cookie in request) { cookie.Expired = true; - response.Add(cookie); + response.Add (cookie); } return true; diff --git a/websocket-sharp/Server/WebSocketService.cs b/websocket-sharp/Server/WebSocketService.cs index 5371e494..e55d2b60 100644 --- a/websocket-sharp/Server/WebSocketService.cs +++ b/websocket-sharp/Server/WebSocketService.cs @@ -33,16 +33,16 @@ using System.Threading; using WebSocketSharp.Net; using WebSocketSharp.Net.WebSockets; -namespace WebSocketSharp.Server { - +namespace WebSocketSharp.Server +{ /// /// Provides the basic functions of the WebSocket service. /// /// /// The WebSocketService class is an abstract class. /// - public abstract class WebSocketService { - + public abstract class WebSocketService + { #region Private Fields private WebSocketContext _context; @@ -56,7 +56,7 @@ namespace WebSocketSharp.Server { /// /// Initializes a new instance of the class. /// - public WebSocketService() + public WebSocketService () { ID = String.Empty; IsBound = false; @@ -80,7 +80,7 @@ namespace WebSocketSharp.Server { /// Gets or sets the logging functions. /// /// - /// If you wanted to change the current logger to the service own logger, you would set this property + /// If you want to change the current logger to the service own logger, you set this property /// to a new instance that you created. /// /// @@ -102,7 +102,7 @@ namespace WebSocketSharp.Server { } /// - /// Gets the collection of query string variables used in the WebSocket opening handshake. + /// Gets the collection of query string variables used in the WebSocket connection request. /// /// /// A that contains the collection of query string variables. @@ -116,10 +116,11 @@ namespace WebSocketSharp.Server { } /// - /// Gets the sessions to the . + /// Gets the sessions to the instances. /// /// - /// A that contains the sessions to the the . + /// A that contains the sessions to + /// the instances. /// protected WebSocketServiceManager Sessions { get { @@ -134,82 +135,82 @@ namespace WebSocketSharp.Server { #region Public Properties /// - /// Gets the ID of the instance. + /// Gets the ID of the current instance. /// /// /// A that contains an ID. /// - public string ID { get; private set; } + public string ID { + get; private set; + } /// - /// Gets a value indicating whether the instance is bound to a . + /// Gets a value indicating whether the current instance + /// has been bound to a . /// /// - /// true if the instance is bound to a ; otherwise, false. + /// true if the current instance has been bound to + /// a ; otherwise, false. /// - public bool IsBound { get; private set; } + public bool IsBound { + get; private set; + } #endregion #region Private Methods - private void onClose(object sender, CloseEventArgs e) + private void onClose (object sender, CloseEventArgs e) { - _sessions.Remove(ID); - OnClose(e); + _sessions.Remove (ID); + OnClose (e); } - private void onError(object sender, ErrorEventArgs e) + private void onError (object sender, ErrorEventArgs e) { - OnError(e); + OnError (e); } - private void onMessage(object sender, MessageEventArgs e) + private void onMessage (object sender, MessageEventArgs e) { - OnMessage(e); + OnMessage (e); } - private void onOpen(object sender, EventArgs e) + private void onOpen (object sender, EventArgs e) { - ID = _sessions.Add(this); - OnOpen(); + ID = _sessions.Add (this); + OnOpen (); } #endregion #region Internal Methods - internal void Bind(WebSocketContext context, WebSocketServiceManager sessions) + internal void Bind (WebSocketContext context, WebSocketServiceManager sessions) { if (IsBound) return; - if (!ProcessCookies(context.CookieCollection, context.WebSocket.CookieCollection)) - { - context.WebSocket.Close(HttpStatusCode.BadRequest); - return; - } - _context = context; _sessions = sessions; _websocket = context.WebSocket; - - _websocket.OnOpen += onOpen; + _websocket.CookiesValidation = ValidateCookies; + _websocket.OnOpen += onOpen; _websocket.OnMessage += onMessage; - _websocket.OnError += onError; - _websocket.OnClose += onClose; + _websocket.OnError += onError; + _websocket.OnClose += onClose; IsBound = true; } - internal void SendAsync(byte[] data, Action completed) + internal void SendAsync (byte [] data, Action completed) { - _websocket.SendAsync(data, completed); + _websocket.SendAsync (data, completed); } - internal void SendAsync(string data, Action completed) + internal void SendAsync (string data, Action completed) { - _websocket.SendAsync(data, completed); + _websocket.SendAsync (data, completed); } #endregion @@ -217,55 +218,64 @@ namespace WebSocketSharp.Server { #region Protected Methods /// - /// Occurs when the inner receives a Close frame or the Stop method is called. + /// Is called when the WebSocket connection has been closed. /// /// - /// A that contains the event data associated with a event. + /// A that contains an event data associated with + /// an inner event. /// - protected virtual void OnClose(CloseEventArgs e) + protected virtual void OnClose (CloseEventArgs e) { } /// - /// Occurs when the inner gets an error. + /// Is called when the inner gets an error. /// /// - /// An that contains the event data associated with a event. + /// An that contains an event data associated with + /// an inner event. /// - protected virtual void OnError(ErrorEventArgs e) + protected virtual void OnError (ErrorEventArgs e) { } /// - /// Occurs when the inner receives a data frame. + /// Is called when the inner receives a data frame. /// /// - /// A that contains the event data associated with a event. + /// A that contains an event data associated with + /// an inner event. /// - protected virtual void OnMessage(MessageEventArgs e) + protected virtual void OnMessage (MessageEventArgs e) { } /// - /// Occurs when the WebSocket connection has been established. + /// Is called when the WebSocket connection has been established. /// - protected virtual void OnOpen() + protected virtual void OnOpen () { } /// - /// Processes the cookies used in the WebSocket opening handshake. + /// Validates the cookies used in the WebSocket connection request. /// + /// + /// This method is called when the inner validates + /// the WebSocket connection request. + /// /// - /// true if processing the cookies is successfully; otherwise, false. + /// true if the cookies is valid; otherwise, false. + /// The default returns true. /// /// - /// A that contains a collection of the HTTP Cookies received from the client. + /// A that contains a collection of the HTTP Cookies + /// to validate. /// /// - /// A that contains a collection of the HTTP Cookies to send to the client. + /// A that receives the HTTP Cookies to send to the client. /// - protected virtual bool ProcessCookies(CookieCollection request, CookieCollection response) + protected virtual bool ValidateCookies (CookieCollection request, CookieCollection response) { return true; } @@ -275,150 +285,155 @@ namespace WebSocketSharp.Server { #region Public Methods /// - /// Broadcasts the specified array of to the clients of every instances - /// in the . + /// Broadcasts the specified array of to the clients of + /// every instances in the . /// /// /// An array of to broadcast. /// - public void Broadcast(byte[] data) + public void Broadcast (byte [] data) { if (IsBound) - _sessions.Broadcast(data); + _sessions.Broadcast (data); } /// - /// Broadcasts the specified to the clients of every instances - /// in the . + /// Broadcasts the specified to the clients of + /// every instances in the . /// /// /// A to broadcast. /// - public void Broadcast(string data) + public void Broadcast (string data) { if (IsBound) - _sessions.Broadcast(data); + _sessions.Broadcast (data); } /// - /// Pings to the clients of every instances + /// Sends Pings to the clients of every instances /// in the . /// /// /// A Dictionary<string, bool> that contains the collection of IDs and values - /// indicating whether each instances received a Pong in a time. + /// indicating whether the each instances received a Pong in a time. /// - public Dictionary Broadping() + public Dictionary Broadping () { - return Broadping(String.Empty); + return Broadping (String.Empty); } /// - /// Pings with the specified to the clients of every instances - /// in the . + /// Sends Pings with the specified to the clients of + /// every instances in the . /// /// /// A Dictionary<string, bool> that contains the collection of IDs and values - /// indicating whether each instances received a Pong in a time. + /// indicating whether the each instances received a Pong in a time. /// /// - /// A that contains a message. + /// A that contains a message to send. /// - public Dictionary Broadping(string message) + public Dictionary Broadping (string message) { return IsBound - ? _sessions.Broadping(message) + ? _sessions.Broadping (message) : null; } /// - /// Pings to the client of the instance. + /// Sends a Ping to the client of the current instance. /// /// - /// true if the instance receives a Pong in a time; otherwise, false. + /// true if the current instance receives a Pong in a time; + /// otherwise, false. /// - public bool Ping() + public bool Ping () { - return Ping(String.Empty); + return Ping (String.Empty); } /// - /// Pings with the specified to the client of the instance. + /// Sends a Ping with the specified to the client of + /// the current instance. /// /// - /// true if the instance receives a Pong in a time; otherwise, false. + /// true if the current instance receives a Pong in a time; + /// otherwise, false. /// /// - /// A that contains a message. + /// A that contains a message to send. /// - public bool Ping(string message) + public bool Ping (string message) { return IsBound - ? _websocket.Ping(message) + ? _websocket.Ping (message) : false; } /// - /// Pings to the client of the instance + /// Sends a Ping to the client of the instance /// associated with the specified . /// /// - /// true if the instance receives a Pong in a time; otherwise, false. + /// true if the instance receives a Pong in a time; + /// otherwise, false. /// /// /// A that contains an ID that represents the destination for the Ping. /// - public bool PingTo(string id) + public bool PingTo (string id) { - return PingTo(id, String.Empty); + return PingTo (id, String.Empty); } /// - /// Pings with the specified to the client of the instance - /// associated with the specified . + /// Sends a Ping with the specified to the client of + /// the instance associated with the specified . /// /// - /// true if the instance receives a Pong in a time; otherwise, false. + /// true if the instance receives a Pong in a time; + /// otherwise, false. /// /// /// A that contains an ID that represents the destination for the Ping. /// /// - /// A that contains a message. + /// A that contains a message to send. /// - public bool PingTo(string id, string message) + public bool PingTo (string id, string message) { if (!IsBound) return false; WebSocketService service; - return _sessions.TryGetWebSocketService(id, out service) - ? service.Ping(message) + return _sessions.TryGetWebSocketService (id, out service) + ? service.Ping (message) : false; } /// - /// Sends a binary data to the client of the instance. + /// Sends a binary data to the client of the current instance. /// /// /// An array of that contains a binary data to send. /// - public void Send(byte[] data) + public void Send (byte [] data) { if (IsBound) - _websocket.Send(data); + _websocket.Send (data); } /// - /// Sends a text data to the client of the instance. + /// Sends a text data to the client of the current instance. /// /// /// A that contains a text data to send. /// - public void Send(string data) + public void Send (string data) { if (IsBound) - _websocket.Send(data); + _websocket.Send (data); } /// @@ -431,14 +446,14 @@ namespace WebSocketSharp.Server { /// /// An array of that contains a binary data to send. /// - public void SendTo(string id, byte[] data) + public void SendTo (string id, byte [] data) { if (!IsBound) return; WebSocketService service; - if (_sessions.TryGetWebSocketService(id, out service)) - service.Send(data); + if (_sessions.TryGetWebSocketService (id, out service)) + service.Send (data); } /// @@ -451,65 +466,68 @@ namespace WebSocketSharp.Server { /// /// A that contains a text data to send. /// - public void SendTo(string id, string data) + public void SendTo (string id, string data) { if (!IsBound) return; WebSocketService service; - if (_sessions.TryGetWebSocketService(id, out service)) - service.Send(data); + if (_sessions.TryGetWebSocketService (id, out service)) + service.Send (data); } /// - /// Starts the instance. + /// Starts a instance. /// - public void Start() + public void Start () { if (IsBound) - _websocket.Connect(); + _websocket.Connect (); } /// - /// Stops the instance. + /// Stops the current instance. /// - public void Stop() + public void Stop () { if (!IsBound) return; - _websocket.Close(); + _websocket.Close (); } /// - /// Stops the instance with the specified and . + /// Stops the current instance with the specified + /// and . /// /// /// A that contains a status code indicating the reason for stop. /// /// - /// A that contains a reason for stop. + /// A that contains the reason for stop. /// - public void Stop(ushort code, string reason) + public void Stop (ushort code, string reason) { if (!IsBound) return; - _websocket.Close(code, reason); + _websocket.Close (code, reason); } /// - /// Stops the instance with the specified and . + /// Stops the current instance with the specified + /// and . /// /// - /// One of the values that contains a status code indicating the reason for stop. + /// One of the values that indicates a status code + /// indicating the reason for stop. /// /// - /// A that contains a reason for stop. + /// A that contains the reason for stop. /// - public void Stop(CloseStatusCode code, string reason) + public void Stop (CloseStatusCode code, string reason) { - Stop((ushort)code, reason); + Stop ((ushort) code, reason); } #endregion diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index f91e1520..604c59e3 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -71,9 +71,11 @@ namespace WebSocketSharp _certValidationCallback; private bool _client; private Action _closeContext; - private CookieCollection _cookies; private CompressionMethod _compression; private WebSocketContext _context; + private CookieCollection _cookies; + private Func + _cookiesValidation; private WsCredential _credentials; private string _extensions; private AutoResetEvent _exitReceiving; @@ -222,9 +224,13 @@ namespace WebSocketSharp #region Internal Properties - internal CookieCollection CookieCollection { + internal Func CookiesValidation { get { - return _cookies; + return _cookiesValidation; + } + + set { + _cookiesValidation = value; } } @@ -1264,7 +1270,8 @@ namespace WebSocketSharp return context.IsWebSocketRequest && validateHostHeader (context.Host) && !context.SecWebSocketKey.IsNullOrEmpty () && - ((version = context.SecWebSocketVersion) != null && version == _version); + ((version = context.SecWebSocketVersion) != null && version == _version) && + validateCookies (context.CookieCollection, _cookies); } // As client @@ -1276,6 +1283,14 @@ namespace WebSocketSharp ((version = response.Headers ["Sec-WebSocket-Version"]) == null || version == _version); } + // As server + private bool validateCookies (CookieCollection request, CookieCollection response) + { + return _cookiesValidation != null + ? _cookiesValidation (request, response) + : true; + } + // As server private bool validateHostHeader (string value) {