├── Example └── CMain.cs ├── README.md ├── SocketIO.sln ├── SocketIO.userprefs └── SocketIO ├── SimpleJson.cs ├── SocketIO.csproj ├── SocketIO.pidb ├── bin └── Debug │ ├── SimpleJson.dll │ ├── SocketIO.dll │ └── websocket-sharp.dll ├── socketio ├── Client.cs ├── EndPointClient.cs ├── ErrorEventArgs.cs ├── Helpers │ ├── SocketIOHandshake.cs │ └── SocketIOMessageTypes.cs ├── IClient.cs ├── IEndPointClient.cs ├── MessageEventArgs.cs └── Messages │ ├── AckMessage.cs │ ├── ConnectMessage.cs │ ├── DisconnectMessage.cs │ ├── ErrorMessage.cs │ ├── EventMessage.cs │ ├── Heartbeat.cs │ ├── Helper │ └── JsonEncodedEventMessage.cs │ ├── IMessage.cs │ ├── JSONMessage.cs │ ├── Message.cs │ ├── NoopMessage.cs │ ├── RegistrationManager.cs │ └── TextMessage.cs └── websocket-sharp ├── AssemblyInfo.cs ├── AuthenticationChallenge.cs ├── AuthenticationResponse.cs ├── ByteOrder.cs ├── CloseEventArgs.cs ├── CloseStatusCode.cs ├── CompressionMethod.cs ├── ErrorEventArgs.cs ├── Ext.cs ├── Fin.cs ├── HandshakeBase.cs ├── HandshakeRequest.cs ├── HandshakeResponse.cs ├── LogData.cs ├── LogLevel.cs ├── Logger.cs ├── Mask.cs ├── MessageEventArgs.cs ├── Net ├── AuthenticationSchemeSelector.cs ├── AuthenticationSchemes.cs ├── ChunkStream.cs ├── ChunkedInputStream.cs ├── Cookie.cs ├── CookieCollection.cs ├── CookieException.cs ├── EndPointListener.cs ├── EndPointManager.cs ├── HttpConnection.cs ├── HttpHeaderInfo.cs ├── HttpHeaderType.cs ├── HttpListener.cs ├── HttpListenerContext.cs ├── HttpListenerException.cs ├── HttpListenerPrefixCollection.cs ├── HttpListenerRequest.cs ├── HttpListenerResponse.cs ├── HttpStatusCode.cs ├── HttpStreamAsyncResult.cs ├── HttpUtility.cs ├── HttpVersion.cs ├── ListenerAsyncResult.cs ├── ListenerPrefix.cs ├── RequestStream.cs ├── ResponseStream.cs ├── Security │ └── SslStream.cs ├── WebHeaderCollection.cs └── WebSockets │ ├── HttpListenerWebSocketContext.cs │ ├── TcpListenerWebSocketContext.cs │ └── WebSocketContext.cs ├── Opcode.cs ├── PayloadData.cs ├── Rsv.cs ├── Server ├── HttpRequestEventArgs.cs ├── HttpServer.cs ├── IWebSocketSession.cs ├── ServerState.cs ├── WebSocketServer.cs ├── WebSocketService.cs ├── WebSocketServiceHost.cs ├── WebSocketServiceHostManager.cs └── WebSocketSessionManager.cs ├── WebSocket.cs ├── WebSocketException.cs ├── WebSocketState.cs ├── WsCredential.cs ├── WsFrame.cs ├── WsStream.cs ├── doc ├── .gitignore └── doc.sh ├── websocket-sharp.csproj └── websocket-sharp.snk /Example/CMain.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | public class CMain : MonoBehaviour { 6 | 7 | SocketIOClient.Client socket; 8 | 9 | void Start () { 10 | 11 | socket = new SocketIOClient.Client("http://127.0.0.1:80/"); 12 | socket.On("connect", (fn) => { 13 | Debug.Log ("connect - socket"); 14 | 15 | Dictionary args = new Dictionary(); 16 | args.Add("msg", "what's up?"); 17 | socket.Emit("SEND", args); 18 | }); 19 | socket.On("RECV", (data) => { 20 | Debug.Log (data.Json.ToJsonString()); 21 | }); 22 | socket.Error += (sender, e) => { 23 | Debug.Log ("socket Error: " + e.Message.ToString ()); 24 | }; 25 | socket.Connect(); 26 | } 27 | 28 | void Update () { 29 | 30 | } 31 | 32 | void OnGUI () { 33 | 34 | if (GUI.Button (new Rect (20, 70, 150, 30), "SEND")) { 35 | Debug.Log ("Sending"); 36 | 37 | Dictionary args = new Dictionary(); 38 | args.Add("msg", "hello!"); 39 | socket.Emit("SEND", args); 40 | } 41 | 42 | if (GUI.Button (new Rect (20, 120, 150, 30), "Close Connection")) { 43 | Debug.Log ("Closing"); 44 | 45 | socket.Close(); 46 | } 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UnitySocketIO-WebSocketSharp 2 | ============================ 3 | 4 | [UnitySocketIO](https://github.com/NetEase/UnitySocketIO) using [websocket-sharp](https://github.com/sta/websocket-sharp) instead of [WebSocket4Net](https://github.com/kerryjiang/WebSocket4Net) 5 | 6 | - UnitySocketIO is the only usable socket.io client for unity3d, but it's using WebSocket4Net and SuperSocket.ClientEngine as underlying libraries, which are somewhat buggy and unstable. 7 | - There are times when the MessageReceived event handler is not called, even though the client has received a message packet from the server, and the message silently gets dropped. 8 | - When WebSocket4Net library used by UnitySocketIO was replaced with websocket-sharp, the problem has been solved. 9 | - [SimpleJson](https://github.com/facebook-csharp-sdk/simple-json) library used by UnitySocketIO was updated to the latest version (v0.30.0), because the old one caused crashes in some cases. 10 | 11 | ### How to use 12 | 13 | Copy all the DLLs from /SocketIO/bin/Debug/ to any folder of your project (e.g. Assets/Plugins/SocketIO/) 14 | 15 | ### Avoiding too long wait on Close event 16 | 17 | websocket-sharp uses AutoResetEvent.WaitOne on Close event, but it looks like socket.io server doesn't return Close frame and the client must wait until the timeout (5 seconds) expires. 18 | 19 | If you add just one line below in the method "private bool close (byte [] frameAsBytes, int timeOut, Func release)" of "websocket-sharp/WebSocket.cs" file, it'll be solved. 20 | 21 | ``` 22 | private bool close (byte [] frameAsBytes, int timeOut, Func release) 23 | { 24 | timeOut = 0; // no closing handshake 25 | 26 | var sent = frameAsBytes != null && _stream.Write (frameAsBytes); 27 | ... 28 | ``` 29 | 30 | ### Building for iOS devices 31 | 32 | If you want to build this library for iOS devices, you have to copy all the sources of [SimpleJson](https://github.com/facebook-csharp-sdk/simple-json), [websocket-sharp](https://github.com/sta/websocket-sharp), UnitySocketIO-WebSocketSharp to a folder of your project, instead of the DLLs. 33 | 34 | - And before you build it, you have to modify WebSocket.cs of websocket-sharp as follows: 35 | 36 | ``` 37 | internal delegate bool SendBytesFunc (Opcode opcode, byte [] data); 38 | internal delegate bool SendStreamFunc (Opcode opcode, Stream stream); 39 | 40 | private void send (Opcode opcode, byte [] data, Action completed) 41 | { 42 | //Func sender = send; 43 | SendBytesFunc sender = send; 44 | ... 45 | } 46 | 47 | private void send (Opcode opcode, Stream stream, Action completed) 48 | { 49 | //Func sender = send; 50 | SendStreamFunc sender = send; 51 | ... 52 | } 53 | ``` 54 | 55 | - Modify Net/ListenerAsyncResult.cs of websocket-sharp as follows: 56 | 57 | ``` 58 | internal void Complete (Exception exc) 59 | { 60 | ... 61 | //ThreadPool.UnsafeQueueUserWorkItem (InvokeCB, this); 62 | ThreadPool.QueueUserWorkItem (InvokeCB, this); 63 | } 64 | 65 | ... 66 | 67 | internal void Complete (HttpListenerContext context, bool synch) 68 | { 69 | ... 70 | //ThreadPool.UnsafeQueueUserWorkItem (InvokeCB, this); 71 | ThreadPool.QueueUserWorkItem (InvokeCB, this); 72 | } 73 | ``` 74 | 75 | - Uncomment "#define SIMPLE_JSON_NO_LINQ_EXPRESSION" in SimpleJson.cs. 76 | 77 | 78 | ## License 79 | (The MIT License) 80 | 81 | Copyright (c) 2014 kaistseo and other contributors 82 | 83 | Permission is hereby granted, free of charge, to any person obtaining a 84 | copy of this software and associated documentation files (the 'Software'), 85 | to deal in the Software without restriction, including without limitation 86 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 87 | and/or sell copies of the Software, and to permit persons to whom the 88 | Software is furnished to do so, subject to the following conditions: 89 | 90 | The above copyright notice and this permission notice shall be included in 91 | all copies or substantial portions of the Software. 92 | 93 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 94 | -------------------------------------------------------------------------------- /SocketIO.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SocketIO", "SocketIO\SocketIO.csproj", "{2F18D000-F801-40FC-8B29-CA112E33536D}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {2F18D000-F801-40FC-8B29-CA112E33536D}.Debug|x86.ActiveCfg = Debug|x86 13 | {2F18D000-F801-40FC-8B29-CA112E33536D}.Debug|x86.Build.0 = Debug|x86 14 | {2F18D000-F801-40FC-8B29-CA112E33536D}.Release|x86.ActiveCfg = Release|x86 15 | {2F18D000-F801-40FC-8B29-CA112E33536D}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(MonoDevelopProperties) = preSolution 18 | StartupItem = SocketIO\SocketIO.csproj 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /SocketIO.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SocketIO/SocketIO.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 9.0.21022 7 | 2.0 8 | {2F18D000-F801-40FC-8B29-CA112E33536D} 9 | Library 10 | SocketIO 11 | SocketIO 12 | v3.5 13 | 14 | 15 | true 16 | full 17 | false 18 | bin\Debug 19 | DEBUG; 20 | prompt 21 | 4 22 | x86 23 | false 24 | 25 | 26 | none 27 | false 28 | bin\Release 29 | prompt 30 | 4 31 | x86 32 | false 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | bin\Debug\SimpleJson.dll 61 | 62 | 63 | bin\Debug\websocket-sharp.dll 64 | 65 | 66 | 67 | bin\Debug\SocketIO.dll 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /SocketIO/SocketIO.pidb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaistseo/UnitySocketIO-WebSocketSharp/07724b3b58fa175a6201a9798cf85f0bd72fd308/SocketIO/SocketIO.pidb -------------------------------------------------------------------------------- /SocketIO/bin/Debug/SimpleJson.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaistseo/UnitySocketIO-WebSocketSharp/07724b3b58fa175a6201a9798cf85f0bd72fd308/SocketIO/bin/Debug/SimpleJson.dll -------------------------------------------------------------------------------- /SocketIO/bin/Debug/SocketIO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaistseo/UnitySocketIO-WebSocketSharp/07724b3b58fa175a6201a9798cf85f0bd72fd308/SocketIO/bin/Debug/SocketIO.dll -------------------------------------------------------------------------------- /SocketIO/bin/Debug/websocket-sharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaistseo/UnitySocketIO-WebSocketSharp/07724b3b58fa175a6201a9798cf85f0bd72fd308/SocketIO/bin/Debug/websocket-sharp.dll -------------------------------------------------------------------------------- /SocketIO/socketio/EndPointClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient 7 | { 8 | class EndPointClient : IEndPointClient 9 | { 10 | public IClient Client { get; private set; } 11 | public string EndPoint { get; private set; } 12 | 13 | public EndPointClient(IClient client, string endPoint) 14 | { 15 | this.validateNameSpace(endPoint); 16 | this.Client = client; 17 | this.EndPoint = endPoint; 18 | } 19 | 20 | private void validateNameSpace(string name) 21 | { 22 | if (string.IsNullOrEmpty(name)) 23 | throw new ArgumentNullException("nameSpace", "Parameter cannot be null"); 24 | if (name.Contains(':')) 25 | throw new ArgumentException("Parameter cannot contain ':' characters", "nameSpace"); 26 | } 27 | 28 | public void On(string eventName, Action action) 29 | { 30 | this.Client.On(eventName, this.EndPoint, action); 31 | } 32 | 33 | public void Emit(string eventName, Object payload, Action callBack ) 34 | { 35 | this.Client.Emit(eventName, payload, this.EndPoint, callBack); 36 | } 37 | 38 | public void Send(Messages.IMessage msg) 39 | { 40 | msg.Endpoint = this.EndPoint; 41 | this.Client.Send(msg); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SocketIO/socketio/ErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient 7 | { 8 | public class ErrorEventArgs : EventArgs 9 | { 10 | 11 | public string Message { get; set; } 12 | public Exception Exception { get; set; } 13 | 14 | public ErrorEventArgs (string message) :base() 15 | { 16 | this.Message = message; 17 | } 18 | public ErrorEventArgs (string message, Exception exception) : base() 19 | { 20 | this.Message = message; 21 | this.Exception = exception; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SocketIO/socketio/Helpers/SocketIOHandshake.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient 7 | { 8 | public class SocketIOHandshake 9 | { 10 | public string SID { get; set; } 11 | public int HeartbeatTimeout { get; set; } 12 | public string ErrorMessage { get; set; } 13 | public bool HadError 14 | { 15 | get { return !string.IsNullOrEmpty(this.ErrorMessage); } 16 | 17 | } 18 | /// 19 | /// The HearbeatInterval will be approxamately 20% faster than the Socket.IO service indicated was required 20 | /// 21 | public TimeSpan HeartbeatInterval 22 | { 23 | get 24 | { 25 | return new TimeSpan(0, 0, HeartbeatTimeout); 26 | } 27 | } 28 | public int ConnectionTimeout { get; set; } 29 | public List Transports = new List(); 30 | 31 | public SocketIOHandshake() 32 | { 33 | 34 | } 35 | public static SocketIOHandshake LoadFromString(string value) 36 | { 37 | SocketIOHandshake returnItem = new SocketIOHandshake(); 38 | if (!string.IsNullOrEmpty(value)) 39 | { 40 | string[] items = value.Split(new char[] { ':' }); 41 | if (items.Count() == 4) 42 | { 43 | int hb = 0; 44 | int ct = 0; 45 | returnItem.SID = items[0]; 46 | 47 | if (int.TryParse(items[1], out hb)) 48 | { 49 | var pct = (int)(hb * .75); // setup client time to occure 25% faster than needed 50 | returnItem.HeartbeatTimeout = pct; 51 | } 52 | if (int.TryParse(items[2], out ct)) 53 | returnItem.ConnectionTimeout = ct; 54 | returnItem.Transports.AddRange(items[3].Split(new char[] { ',' })); 55 | return returnItem; 56 | } 57 | } 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SocketIO/socketio/Helpers/SocketIOMessageTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient 7 | { 8 | public enum SocketIOMessageTypes 9 | { 10 | Disconnect = 0, //Signals disconnection. If no endpoint is specified, disconnects the entire socket. 11 | Connect = 1, // Only used for multiple sockets. Signals a connection to the endpoint. Once the server receives it, it's echoed back to the client. 12 | Heartbeat = 2, 13 | Message = 3, // A regular message 14 | JSONMessage = 4, // A JSON message 15 | Event = 5, // An event is like a JSON message, but has mandatory name and args fields. 16 | ACK = 6, //An acknowledgment contains the message id as the message data. If a + sign follows the message id, it's treated as an event message packet. 17 | Error = 7, // Error 18 | Noop = 8 // No operation 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SocketIO/socketio/IClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SocketIOClient 3 | { 4 | /// 5 | /// C# Socket.IO client interface 6 | /// 7 | interface IClient 8 | { 9 | event EventHandler Opened; 10 | event EventHandler Message; 11 | event EventHandler SocketConnectionClosed; 12 | event EventHandler Error; 13 | 14 | SocketIOHandshake HandShake { get; } 15 | bool IsConnected { get; } 16 | WebSocketSharp.WebSocketState ReadyState { get; } 17 | 18 | void Connect(); 19 | IEndPointClient Connect(string endPoint); 20 | 21 | void Close(); 22 | void Dispose(); 23 | 24 | void On(string eventName, Action action); 25 | void On(string eventName, string endPoint, Action action); 26 | 27 | void Emit(string eventName, Object payload); 28 | void Emit(string eventName, Object payload, string endPoint , Action callBack ); 29 | 30 | void Send(SocketIOClient.Messages.IMessage msg); 31 | //void Send(string rawEncodedMessageText); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SocketIO/socketio/IEndPointClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient 7 | { 8 | public interface IEndPointClient 9 | { 10 | void On(string eventName, Action action); 11 | void Emit(string eventName, Object payload, Action callBack ); 12 | 13 | void Send(SocketIOClient.Messages.IMessage msg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SocketIO/socketio/MessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SocketIOClient.Messages; 6 | 7 | namespace SocketIOClient 8 | { 9 | public class MessageEventArgs : EventArgs 10 | { 11 | public IMessage Message { get; private set; } 12 | 13 | public MessageEventArgs(IMessage msg) 14 | : base() 15 | { 16 | this.Message = msg; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/AckMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace SocketIOClient.Messages 8 | { 9 | public sealed class AckMessage : Message 10 | { 11 | private static Regex reAckId = new Regex(@"^(\d{1,})"); 12 | private static Regex reAckPayload = new Regex(@"(?:[\d\+]*)(?.*)$"); 13 | private static Regex reAckComplex = new Regex(@"^\[(?.*)\]$"); 14 | 15 | private static object ackLock = new object(); 16 | private static int _akid = 0; 17 | public static int NextAckID 18 | { 19 | get 20 | { 21 | lock (ackLock) 22 | { 23 | _akid++; 24 | if (_akid < 0) 25 | _akid = 0; 26 | return _akid; 27 | } 28 | } 29 | } 30 | 31 | public Action Callback; 32 | 33 | public AckMessage() 34 | : base() 35 | { 36 | this.MessageType = SocketIOMessageTypes.ACK; 37 | } 38 | 39 | public static AckMessage Deserialize(string rawMessage) 40 | { 41 | AckMessage msg = new AckMessage(); 42 | // '6:::' [message id] '+' [data] 43 | // 6:::4 44 | // 6:::4+["A","B"] 45 | msg.RawMessage = rawMessage; 46 | 47 | string[] args = rawMessage.Split(SPLITCHARS, 4); 48 | if (args.Length == 4) 49 | { 50 | msg.Endpoint = args[2]; 51 | int id; 52 | string[] parts = args[3].Split(new char[] {'+'}); 53 | if (parts.Length > 1) 54 | { 55 | if (int.TryParse(parts[0], out id)) 56 | { 57 | msg.AckId = id; 58 | msg.MessageText = parts[1]; 59 | Match payloadMatch = reAckComplex.Match(msg.MessageText); 60 | 61 | if (payloadMatch.Success) 62 | { 63 | msg.Json = new JsonEncodedEventMessage(); 64 | msg.Json.args = new string[] {payloadMatch.Groups["payload"].Value}; 65 | } 66 | } 67 | } 68 | } 69 | return msg; 70 | } 71 | public override string Encoded 72 | { 73 | get 74 | { 75 | int msgId = (int)this.MessageType; 76 | if (this.AckId.HasValue) 77 | { 78 | if (this.Callback == null) 79 | return string.Format("{0}:{1}:{2}:{3}", msgId, this.AckId ?? -1, this.Endpoint, this.MessageText); 80 | else 81 | return string.Format("{0}:{1}+:{2}:{3}", msgId, this.AckId ?? -1, this.Endpoint, this.MessageText); 82 | } 83 | else 84 | return string.Format("{0}::{1}:{2}", msgId, this.Endpoint, this.MessageText); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/ConnectMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient.Messages 7 | { 8 | /// 9 | /// Signals a connection to the endpoint. Once the server receives it, it's echoed back to the client 10 | /// 11 | /// If the client is trying to connect to the endpoint /test, a message like this will be delivered: 12 | /// '1::' [path] [query] 13 | /// 14 | public class ConnectMessage : Message 15 | { 16 | public string Query { get; private set; } 17 | 18 | public override string Event 19 | { 20 | get { return "connect"; } 21 | } 22 | 23 | public ConnectMessage() : base() 24 | { 25 | this.MessageType = SocketIOMessageTypes.Connect; 26 | } 27 | public ConnectMessage(string endPoint) : this() 28 | { 29 | this.Endpoint = endPoint; 30 | } 31 | public static ConnectMessage Deserialize(string rawMessage) 32 | { 33 | ConnectMessage msg = new ConnectMessage(); 34 | // 1:: [path] [query] 35 | // 1::/test?my=param 36 | msg.RawMessage = rawMessage; 37 | 38 | string[] args = rawMessage.Split(SPLITCHARS, 3); 39 | if (args.Length == 3) 40 | { 41 | string[] pq = args[2].Split(new char[] { '?' }); 42 | 43 | if (pq.Length > 0) 44 | msg.Endpoint = pq[0]; 45 | 46 | if (pq.Length > 1) 47 | msg.Query = pq[1]; 48 | } 49 | return msg; 50 | } 51 | public override string Encoded 52 | { 53 | get 54 | { 55 | return string.Format("1::{0}{1}", this.Endpoint, string.IsNullOrEmpty(this.Query) ? string.Empty: string.Format("?{0}",this.Query)); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/DisconnectMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient.Messages 7 | { 8 | /// 9 | /// Signals disconnection. If no endpoint is specified, disconnects the entire socket. 10 | /// 11 | /// Disconnect a socket connected to the /test endpoint: 12 | /// 0::/test 13 | /// 14 | public class DisconnectMessage : Message 15 | { 16 | 17 | public override string Event 18 | { 19 | get { return "disconnect"; } 20 | } 21 | 22 | public DisconnectMessage() : base() 23 | { 24 | this.MessageType = SocketIOMessageTypes.Disconnect; 25 | } 26 | public DisconnectMessage(string endPoint) 27 | : this() 28 | { 29 | this.Endpoint = endPoint; 30 | } 31 | public static DisconnectMessage Deserialize(string rawMessage) 32 | { 33 | DisconnectMessage msg = new DisconnectMessage(); 34 | // 0:: 35 | // 0::/test 36 | msg.RawMessage = rawMessage; 37 | 38 | string[] args = rawMessage.Split(SPLITCHARS, 3); 39 | if (args.Length == 3) 40 | { 41 | if (!string.IsNullOrEmpty(args[2])) 42 | msg.Endpoint = args[2]; 43 | } 44 | return msg; 45 | } 46 | public override string Encoded 47 | { 48 | get 49 | { 50 | return string.Format("0::{0}", this.Endpoint); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/ErrorMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient.Messages 7 | { 8 | public class ErrorMessage : Message 9 | { 10 | 11 | public string Reason { get; set; } 12 | public string Advice { get; set; } 13 | 14 | public override string Event 15 | { 16 | get { return "error"; } 17 | } 18 | 19 | public ErrorMessage() 20 | { 21 | this.MessageType = SocketIOMessageTypes.Error; 22 | } 23 | 24 | /// 25 | /// 26 | /// 27 | /// '7::' [endpoint] ':' [reason] '+' [advice] 28 | /// ErrorMessage 29 | public static ErrorMessage Deserialize(string rawMessage) 30 | { 31 | ErrorMessage errMsg = new ErrorMessage(); 32 | string[] args = rawMessage.Split(':'); 33 | if (args.Length == 4) 34 | { 35 | errMsg.Endpoint = args[2]; 36 | errMsg.MessageText = args[3]; 37 | string[] complex = args[3].Split(new char[] { '+' }); 38 | if (complex.Length > 1) 39 | { 40 | errMsg.Advice = complex[1]; 41 | errMsg.Reason = complex[0]; 42 | } 43 | } 44 | return errMsg; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/EventMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | 7 | 8 | namespace SocketIOClient.Messages 9 | { 10 | public class EventMessage : Message 11 | { 12 | private static object ackLock = new object(); 13 | private static int _akid = 0; 14 | private static int NextAckID 15 | { 16 | get 17 | { 18 | lock (ackLock) 19 | { 20 | _akid++; 21 | if (_akid < 0) 22 | _akid = 0; 23 | return _akid; 24 | } 25 | } 26 | } 27 | 28 | public Action Callback; 29 | 30 | public EventMessage() 31 | { 32 | this.MessageType = SocketIOMessageTypes.Event; 33 | } 34 | 35 | public EventMessage(string eventName, object jsonObject, string endpoint , Action callBack ) 36 | : this() 37 | { 38 | this.Callback = callBack; 39 | this.Endpoint = endpoint; 40 | 41 | if (callBack != null) 42 | this.AckId = EventMessage.NextAckID; 43 | 44 | this.JsonEncodedMessage = new JsonEncodedEventMessage(eventName, jsonObject); 45 | this.MessageText = this.Json.ToJsonString(); 46 | } 47 | 48 | public static EventMessage Deserialize(string rawMessage) 49 | { 50 | EventMessage evtMsg = new EventMessage(); 51 | // '5:' [message id ('+')] ':' [message endpoint] ':' [json encoded event] 52 | // 5:1::{"a":"b"} 53 | evtMsg.RawMessage = rawMessage; 54 | try 55 | { 56 | string[] args = rawMessage.Split(SPLITCHARS, 4); // limit the number of pieces 57 | if (args.Length == 4) 58 | { 59 | int id; 60 | if (int.TryParse(args[1], out id)) 61 | evtMsg.AckId = id; 62 | evtMsg.Endpoint = args[2]; 63 | evtMsg.MessageText = args[3]; 64 | 65 | if (!string.IsNullOrEmpty(evtMsg.MessageText) && 66 | evtMsg.MessageText.Contains("name") && 67 | evtMsg.MessageText.Contains("args")) 68 | { 69 | evtMsg.Json = JsonEncodedEventMessage.Deserialize(evtMsg.MessageText); 70 | evtMsg.Event = evtMsg.Json.name; 71 | } 72 | else 73 | evtMsg.Json = new JsonEncodedEventMessage(); 74 | } 75 | } 76 | catch (Exception ex) 77 | { 78 | Trace.WriteLine(ex); 79 | } 80 | return evtMsg; 81 | } 82 | 83 | public override string Encoded 84 | { 85 | get 86 | { 87 | int msgId = (int)this.MessageType; 88 | if (this.AckId.HasValue) 89 | { 90 | if (this.Callback == null) 91 | return string.Format("{0}:{1}:{2}:{3}", msgId, this.AckId ?? -1, this.Endpoint, this.MessageText); 92 | else 93 | return string.Format("{0}:{1}+:{2}:{3}", msgId, this.AckId ?? -1, this.Endpoint, this.MessageText); 94 | } 95 | else 96 | return string.Format("{0}::{1}:{2}", msgId, this.Endpoint, this.MessageText); 97 | } 98 | } 99 | 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/Heartbeat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | 7 | namespace SocketIOClient.Messages 8 | { 9 | public class Heartbeat : Message 10 | { 11 | public static string HEARTBEAT = "2::"; 12 | 13 | public Heartbeat() 14 | { 15 | this.MessageType = SocketIOMessageTypes.Heartbeat; 16 | } 17 | 18 | public override string Encoded 19 | { 20 | get 21 | { 22 | return HEARTBEAT; 23 | } 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/Helper/JsonEncodedEventMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | //using SimpleJson.Reflection; 7 | 8 | namespace SocketIOClient.Messages 9 | { 10 | public class JsonEncodedEventMessage 11 | { 12 | public string name { get; set; } 13 | 14 | public object[] args { get; set; } 15 | 16 | public JsonEncodedEventMessage() 17 | { 18 | } 19 | 20 | public JsonEncodedEventMessage(string name, object payload) : this(name, new[]{payload}) 21 | { 22 | 23 | } 24 | 25 | public JsonEncodedEventMessage(string name, object[] payloads) 26 | { 27 | this.name = name; 28 | this.args = payloads; 29 | } 30 | 31 | public T GetFirstArgAs() 32 | { 33 | try 34 | { 35 | var firstArg = this.args.FirstOrDefault(); 36 | if (firstArg != null) 37 | return SimpleJson.SimpleJson.DeserializeObject(firstArg.ToString()); 38 | } 39 | catch (Exception ex) 40 | { 41 | // add error logging here 42 | throw; 43 | } 44 | return default(T); 45 | } 46 | public IEnumerable GetArgsAs() 47 | { 48 | List items = new List(); 49 | foreach (var i in this.args) 50 | { 51 | items.Add( SimpleJson.SimpleJson.DeserializeObject(i.ToString()) ); 52 | } 53 | return items.AsEnumerable(); 54 | } 55 | 56 | public string ToJsonString() 57 | { 58 | return SimpleJson.SimpleJson.SerializeObject(this); 59 | } 60 | 61 | public static JsonEncodedEventMessage Deserialize(string jsonString) 62 | { 63 | JsonEncodedEventMessage msg = null; 64 | try { msg = SimpleJson.SimpleJson.DeserializeObject(jsonString); } 65 | catch (Exception ex) 66 | { 67 | Trace.WriteLine(ex); 68 | } 69 | return msg; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/IMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | 7 | namespace SocketIOClient.Messages 8 | { 9 | /// 10 | /// Interface for core Message class 11 | /// 12 | public interface IMessage 13 | { 14 | /// 15 | /// Enumeration of one of 9 basic messages provided by socket.io 16 | /// 17 | SocketIOMessageTypes MessageType { get; } 18 | 19 | /// 20 | /// RawMessage includes the full socket.io message string 21 | /// [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data]) 22 | /// 23 | string RawMessage { get; } 24 | 25 | /// 26 | /// Event 'name' of originating message 27 | /// 28 | string Event { get; } 29 | /// 30 | /// AckId represents unique id associated with a message callback 31 | /// 32 | int? AckId { get; } 33 | 34 | /// 35 | /// Each socket is identified by an endpoint (can be omitted). 36 | /// 37 | string Endpoint { get; set; } 38 | 39 | /// 40 | /// String version of message data 41 | /// 42 | string MessageText { get; } 43 | 44 | JsonEncodedEventMessage Json { get; } 45 | [ObsoleteAttribute(".JsonEncodedMessage has been deprecated. Please use .Json instead.")] 46 | JsonEncodedEventMessage JsonEncodedMessage { get; } 47 | 48 | /// 49 | /// Socket.IO encoded message structure - represents the actual message string sent to Socket.IO 50 | /// [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data]) 51 | /// 52 | string Encoded { get; } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/JSONMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | 7 | namespace SocketIOClient.Messages 8 | { 9 | public class JSONMessage : Message 10 | { 11 | public void SetMessage(object value) 12 | { 13 | this.MessageText = SimpleJson.SimpleJson.SerializeObject(value); 14 | } 15 | 16 | public virtual T Message() 17 | { 18 | try { return SimpleJson.SimpleJson.DeserializeObject(this.MessageText); } 19 | catch (Exception ex) 20 | { 21 | // add error logging here 22 | throw; 23 | } 24 | } 25 | 26 | public JSONMessage() 27 | { 28 | this.MessageType = SocketIOMessageTypes.JSONMessage; 29 | } 30 | public JSONMessage(object jsonObject):this() 31 | { 32 | 33 | this.MessageText = SimpleJson.SimpleJson.SerializeObject(jsonObject ); 34 | } 35 | 36 | public JSONMessage(object jsonObject, int? ackId , string endpoint ):this() 37 | { 38 | this.AckId = ackId; 39 | this.Endpoint = endpoint; 40 | this.MessageText = SimpleJson.SimpleJson.SerializeObject(jsonObject ); 41 | } 42 | 43 | public static JSONMessage Deserialize(string rawMessage) 44 | { 45 | JSONMessage jsonMsg = new JSONMessage(); 46 | // '4:' [message id ('+')] ':' [message endpoint] ':' [json] 47 | // 4:1::{"a":"b"} 48 | jsonMsg.RawMessage = rawMessage; 49 | 50 | string[] args = rawMessage.Split(SPLITCHARS, 4); // limit the number of ' 51 | if (args.Length == 4) 52 | { 53 | int id; 54 | if (int.TryParse(args[1], out id)) 55 | jsonMsg.AckId = id; 56 | jsonMsg.Endpoint = args[2]; 57 | jsonMsg.MessageText = args[3]; 58 | } 59 | return jsonMsg; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/Message.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | 8 | 9 | namespace SocketIOClient.Messages 10 | { 11 | /// 12 | /// All Socket.IO messages have to be encoded before they're sent, and decoded when they're received. 13 | /// They all have the format of: [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data]) 14 | /// 15 | public abstract class Message : IMessage 16 | { 17 | private static Regex re = new Regex(@"\d:\d?:\w?:"); 18 | public static char[] SPLITCHARS = new char[] { ':' }; 19 | 20 | public string RawMessage { get; protected set; } 21 | 22 | /// 23 | /// The message type represents a single digit integer [0-8]. 24 | /// 25 | public SocketIOMessageTypes MessageType { get; protected set; } 26 | 27 | /// 28 | /// The message id is an incremental integer, required for ACKs (can be ommitted). 29 | /// If the message id is followed by a +, the ACK is not handled by socket.io, but by the user instead. 30 | /// 31 | public int? AckId { get; set; } 32 | 33 | /// 34 | /// Socket.IO has built-in support for multiple channels of communication (which we call "multiple sockets"). 35 | /// Each socket is identified by an endpoint (can be omitted). 36 | /// 37 | public string Endpoint { get; set; } 38 | 39 | /// 40 | /// String value of the message 41 | /// 42 | public string MessageText { get; set; } 43 | 44 | private JsonEncodedEventMessage _json; 45 | [ObsoleteAttribute(".JsonEncodedMessage has been deprecated. Please use .Json instead.")] 46 | public JsonEncodedEventMessage JsonEncodedMessage 47 | { 48 | get { return this.Json; } 49 | set { this._json = value; } 50 | } 51 | 52 | public JsonEncodedEventMessage Json 53 | { 54 | get 55 | { 56 | if (_json == null) 57 | { 58 | if (!string.IsNullOrEmpty(this.MessageText) && 59 | this.MessageText.Contains("name") && 60 | this.MessageText.Contains("args")) 61 | { 62 | this._json = JsonEncodedEventMessage.Deserialize(this.MessageText); 63 | } 64 | else 65 | this._json = new JsonEncodedEventMessage(); 66 | } 67 | return _json; 68 | 69 | } 70 | set { this._json = value; } 71 | } 72 | 73 | /// 74 | /// String value of the Event 75 | /// 76 | public virtual string Event { get; set; } 77 | 78 | /// 79 | /// Messages have to be encoded before they're sent. The structure of a message is as follows: 80 | /// [message type] ':' [message id ('+')] ':' [message endpoint] (':' [message data]) 81 | /// All message payloads are sent as strings 82 | /// 83 | public virtual string Encoded 84 | { 85 | get 86 | { 87 | int msgId = (int)this.MessageType; 88 | if (this.AckId.HasValue) 89 | return string.Format("{0}:{1}:{2}:{3}", msgId, this.AckId ?? -1, this.Endpoint, this.MessageText); 90 | else 91 | return string.Format("{0}::{1}:{2}", msgId, this.Endpoint, this.MessageText); 92 | } 93 | } 94 | 95 | 96 | public Message() 97 | { 98 | this.MessageType = SocketIOMessageTypes.Message; 99 | } 100 | 101 | public Message(string rawMessage) 102 | : this() 103 | { 104 | 105 | this.RawMessage = rawMessage; 106 | 107 | string[] args = rawMessage.Split(SPLITCHARS, 4); 108 | if (args.Length == 4) 109 | { 110 | int id; 111 | if (int.TryParse(args[1], out id)) 112 | this.AckId = id; 113 | this.Endpoint = args[2]; 114 | this.MessageText = args[3]; 115 | } 116 | } 117 | 118 | //public static Regex reMessageType = new Regex("^[0-8]{1}:", RegexOptions.IgnoreCase | RegexOptions.Compiled); 119 | public static Regex reMessageType = new Regex("^[0-8]{1}:", RegexOptions.IgnoreCase); 120 | public static IMessage Factory(string rawMessage) 121 | { 122 | 123 | if (reMessageType.IsMatch(rawMessage)) 124 | { 125 | char id = rawMessage.First(); 126 | switch (id) 127 | { 128 | case '0': 129 | return DisconnectMessage.Deserialize(rawMessage); 130 | case '1': 131 | return ConnectMessage.Deserialize(rawMessage); 132 | case '2': 133 | return new Heartbeat(); 134 | case '3': 135 | return TextMessage.Deserialize(rawMessage); 136 | case '4': 137 | return JSONMessage.Deserialize(rawMessage); 138 | case '5': 139 | return EventMessage.Deserialize(rawMessage); 140 | case '6': 141 | return AckMessage.Deserialize(rawMessage); 142 | case '7': 143 | return ErrorMessage.Deserialize(rawMessage); 144 | case '8': 145 | return new NoopMessage(); 146 | default: 147 | Trace.WriteLine(string.Format("Message.Factory undetermined message: {0}", rawMessage)); 148 | return new TextMessage(); 149 | } 150 | } 151 | else 152 | { 153 | Trace.WriteLine(string.Format("Message.Factory did not find matching message type: {0}", rawMessage)); 154 | return new NoopMessage(); 155 | } 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/NoopMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace SocketIOClient.Messages 7 | { 8 | /// 9 | /// Defined as No operation. Used for example to close a poll after the polling duration times out. 10 | /// 11 | public class NoopMessage : Message 12 | { 13 | public NoopMessage() 14 | { 15 | this.MessageType = SocketIOMessageTypes.Noop; 16 | } 17 | public static NoopMessage Deserialize(string rawMessage) 18 | { 19 | return new NoopMessage(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/RegistrationManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | //using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Text; 7 | using SocketIOClient.Messages; 8 | 9 | namespace SocketIOClient.Eventing 10 | { 11 | public class RegistrationManager : IDisposable 12 | { 13 | private Dictionary> callBackRegistry; 14 | private Dictionary> eventNameRegistry; 15 | 16 | public RegistrationManager() 17 | { 18 | this.callBackRegistry = new Dictionary>(); 19 | this.eventNameRegistry = new Dictionary>(); 20 | } 21 | 22 | public void AddCallBack(IMessage message) 23 | { 24 | EventMessage eventMessage = message as EventMessage; 25 | if (eventMessage != null) 26 | this.callBackRegistry.Add(eventMessage.AckId.Value, eventMessage.Callback); 27 | } 28 | public void AddCallBack(int ackId, Action callback) 29 | { 30 | this.callBackRegistry.Add(ackId, callback); 31 | } 32 | 33 | public void InvokeCallBack(int? ackId, string value) 34 | { 35 | Action target = null; 36 | if (ackId.HasValue) 37 | { 38 | if (this.callBackRegistry.TryGetValue(ackId.Value, out target)) // use TryRemove - callbacks are one-shot event registrations 39 | { 40 | //target.BeginInvoke(target.EndInvoke, value); 41 | target.BeginInvoke(value, target.EndInvoke, null); 42 | //this.callBackRegistry.Remove(ackId.Value); 43 | } 44 | } 45 | } 46 | public void InvokeCallBack(int? ackId, JsonEncodedEventMessage value) 47 | { 48 | Action target = null; 49 | if (ackId.HasValue) 50 | { 51 | if (this.callBackRegistry.TryGetValue(ackId.Value, out target)) 52 | { 53 | target.Invoke(value); 54 | //this.callBackRegistry.Remove(ackId.Value); 55 | //target.BeginInvoke(target.EndInvoke, value); 56 | } 57 | } 58 | } 59 | 60 | public void AddOnEvent(string eventName, Action callback) 61 | { 62 | this.eventNameRegistry.Add(eventName, callback ); 63 | } 64 | public void AddOnEvent(string eventName, string endPoint, Action callback) 65 | { 66 | this.eventNameRegistry.Add(string.Format("{0}::{1}",eventName, endPoint), callback); 67 | } 68 | /// 69 | /// If eventName is found, Executes Action delegate asynchronously 70 | /// 71 | /// 72 | /// 73 | /// 74 | public bool InvokeOnEvent(IMessage value) 75 | { 76 | bool foundEvent = false; 77 | try 78 | { 79 | Action target; 80 | 81 | string eventName = value.Event; 82 | if (!string.IsNullOrEmpty(value.Endpoint)) 83 | eventName = string.Format("{0}::{1}", value.Event, value.Endpoint); 84 | //UnityEngine.Debug.LogError("eventName:" + eventName); 85 | if (this.eventNameRegistry.TryGetValue(eventName, out target)) // use TryGet - do not destroy event name registration 86 | { 87 | foundEvent = true; 88 | target.Invoke(value); 89 | //this.eventNameRegistry.Remove(eventName); 90 | //target.BeginInvoke(value, target.EndInvoke, null); 91 | //Trace.WriteLine(string.Format("webSocket_{0}: {1}", value.Event, value.MessageText)); 92 | } 93 | } 94 | catch (Exception ex) 95 | { 96 | Trace.WriteLine("Exception on InvokeOnEvent: " + ex.Message); 97 | } 98 | return foundEvent; 99 | } 100 | 101 | // Dispose() calls Dispose(true) 102 | public void Dispose() 103 | { 104 | Dispose(true); 105 | GC.SuppressFinalize(this); 106 | } 107 | 108 | // The bulk of the clean-up code is implemented in Dispose(bool) 109 | protected virtual void Dispose(bool disposing) 110 | { 111 | this.callBackRegistry.Clear(); 112 | this.eventNameRegistry.Clear(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /SocketIO/socketio/Messages/TextMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SocketIOClient; 6 | using System.Text.RegularExpressions; 7 | 8 | 9 | namespace SocketIOClient.Messages 10 | { 11 | public class TextMessage : Message 12 | { 13 | private string eventName = "message"; 14 | public override string Event 15 | { 16 | get { return eventName; } 17 | } 18 | 19 | public TextMessage() 20 | { 21 | this.MessageType = SocketIOMessageTypes.Message; 22 | } 23 | public TextMessage(string textMessage) : this() 24 | { 25 | this.MessageText = textMessage; 26 | } 27 | 28 | public static TextMessage Deserialize(string rawMessage) 29 | { 30 | TextMessage msg = new TextMessage(); 31 | // '3:' [message id ('+')] ':' [message endpoint] ':' [data] 32 | // 3:1::blabla 33 | msg.RawMessage = rawMessage; 34 | 35 | string[] args = rawMessage.Split(SPLITCHARS, 4); 36 | if (args.Length == 4) 37 | { 38 | int id; 39 | if (int.TryParse(args[1], out id)) 40 | msg.AckId = id; 41 | msg.Endpoint = args[2]; 42 | msg.MessageText = args[3]; 43 | } 44 | else 45 | msg.MessageText = rawMessage; 46 | 47 | return msg; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("websocket-sharp")] 8 | [assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client and server")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("websocket-sharp.dll")] 12 | [assembly: AssemblyCopyright("sta.blockhead")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.2.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/AuthenticationChallenge.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * AuthenticationChallenge.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Text; 31 | 32 | namespace WebSocketSharp { 33 | 34 | internal class AuthenticationChallenge { 35 | 36 | #region Private Fields 37 | 38 | private string _algorithm; 39 | private string _domain; 40 | private string _nonce; 41 | private string _opaque; 42 | private string _qop; 43 | private string _realm; 44 | private string _scheme; 45 | private string _stale; 46 | 47 | #endregion 48 | 49 | #region Private Constructors 50 | 51 | private AuthenticationChallenge() 52 | { 53 | } 54 | 55 | #endregion 56 | 57 | #region Public Properties 58 | 59 | public string Algorithm { 60 | get { 61 | return _algorithm ?? String.Empty; 62 | } 63 | 64 | private set { 65 | _algorithm = value; 66 | } 67 | } 68 | 69 | public string Domain { 70 | get { 71 | return _domain ?? String.Empty; 72 | } 73 | 74 | private set { 75 | _domain = value; 76 | } 77 | } 78 | 79 | public string Nonce { 80 | get { 81 | return _nonce ?? String.Empty; 82 | } 83 | 84 | private set { 85 | _nonce = value; 86 | } 87 | } 88 | 89 | public string Opaque { 90 | get { 91 | return _opaque ?? String.Empty; 92 | } 93 | 94 | private set { 95 | _opaque = value; 96 | } 97 | } 98 | 99 | public string Qop { 100 | get { 101 | return _qop ?? String.Empty; 102 | } 103 | 104 | private set { 105 | _qop = value; 106 | } 107 | } 108 | 109 | public string Realm { 110 | get { 111 | return _realm ?? String.Empty; 112 | } 113 | 114 | private set { 115 | _realm = value; 116 | } 117 | } 118 | 119 | public string Scheme { 120 | get { 121 | return _scheme ?? String.Empty; 122 | } 123 | 124 | private set { 125 | _scheme = value; 126 | } 127 | } 128 | 129 | public string Stale { 130 | get { 131 | return _stale ?? String.Empty; 132 | } 133 | 134 | private set { 135 | _stale = value; 136 | } 137 | } 138 | 139 | #endregion 140 | 141 | #region Public Methods 142 | 143 | public static AuthenticationChallenge Parse(string challenge) 144 | { 145 | var authChallenge = new AuthenticationChallenge(); 146 | if (challenge.StartsWith("basic", StringComparison.OrdinalIgnoreCase)) 147 | { 148 | authChallenge.Scheme = "Basic"; 149 | authChallenge.Realm = challenge.Substring(6).GetValueInternal("=").Trim('"'); 150 | 151 | return authChallenge; 152 | } 153 | 154 | foreach (var p in challenge.SplitHeaderValue(',')) 155 | { 156 | var param = p.Trim(); 157 | if (param.StartsWith("digest", StringComparison.OrdinalIgnoreCase)) 158 | { 159 | authChallenge.Scheme = "Digest"; 160 | authChallenge.Realm = param.Substring(7).GetValueInternal("=").Trim('"'); 161 | 162 | continue; 163 | } 164 | 165 | var value = param.GetValueInternal("=").Trim('"'); 166 | if (param.StartsWith("domain", StringComparison.OrdinalIgnoreCase)) 167 | { 168 | authChallenge.Domain = value; 169 | continue; 170 | } 171 | 172 | if (param.StartsWith("nonce", StringComparison.OrdinalIgnoreCase)) 173 | { 174 | authChallenge.Nonce = value; 175 | continue; 176 | } 177 | 178 | if (param.StartsWith("opaque", StringComparison.OrdinalIgnoreCase)) 179 | { 180 | authChallenge.Opaque = value; 181 | continue; 182 | } 183 | 184 | if (param.StartsWith("stale", StringComparison.OrdinalIgnoreCase)) 185 | { 186 | authChallenge.Stale = value; 187 | continue; 188 | } 189 | 190 | if (param.StartsWith("algorithm", StringComparison.OrdinalIgnoreCase)) 191 | { 192 | authChallenge.Algorithm = value; 193 | continue; 194 | } 195 | 196 | if (param.StartsWith("qop", StringComparison.OrdinalIgnoreCase)) 197 | authChallenge.Qop = value; 198 | } 199 | 200 | return authChallenge; 201 | } 202 | 203 | #endregion 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/ByteOrder.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * ByteOrder.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | /// 34 | /// Contains the values that indicate whether the byte order is a Little-endian or Big-endian. 35 | /// 36 | public enum ByteOrder : byte 37 | { 38 | /// 39 | /// Indicates a Little-endian. 40 | /// 41 | LITTLE, 42 | /// 43 | /// Indicates a Big-endian. 44 | /// 45 | BIG 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/CloseEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * CloseEventArgs.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Text; 31 | 32 | namespace WebSocketSharp 33 | { 34 | /// 35 | /// Contains the event data associated with a event. 36 | /// 37 | /// 38 | /// A event occurs when the WebSocket connection has been closed. 39 | /// If you want to get the reason for closure, you access the or 40 | /// property. 41 | /// 42 | public class CloseEventArgs : EventArgs 43 | { 44 | #region Private Fields 45 | 46 | private bool _clean; 47 | private ushort _code; 48 | private string _reason; 49 | 50 | #endregion 51 | 52 | #region Internal Constructors 53 | 54 | internal CloseEventArgs (PayloadData payload) 55 | { 56 | var data = payload.ApplicationData; 57 | _code = getCodeFrom (data); 58 | _reason = getReasonFrom (data); 59 | _clean = false; 60 | } 61 | 62 | #endregion 63 | 64 | #region Public Properties 65 | 66 | /// 67 | /// Gets the status code for closure. 68 | /// 69 | /// 70 | /// A that indicates the status code for closure if any. 71 | /// 72 | public ushort Code { 73 | get { 74 | return _code; 75 | } 76 | } 77 | 78 | /// 79 | /// Gets the reason for closure. 80 | /// 81 | /// 82 | /// A that contains the reason for closure if any. 83 | /// 84 | public string Reason { 85 | get { 86 | return _reason; 87 | } 88 | } 89 | 90 | /// 91 | /// Gets a value indicating whether the WebSocket connection has been closed cleanly. 92 | /// 93 | /// 94 | /// true if the connection has been closed cleanly; otherwise, false. 95 | /// 96 | public bool WasClean { 97 | get { 98 | return _clean; 99 | } 100 | 101 | internal set { 102 | _clean = value; 103 | } 104 | } 105 | 106 | #endregion 107 | 108 | #region Private Methods 109 | 110 | private static ushort getCodeFrom (byte [] data) 111 | { 112 | return data.Length > 1 113 | ? data.SubArray (0, 2).ToUInt16 (ByteOrder.BIG) 114 | : (ushort) CloseStatusCode.NO_STATUS_CODE; 115 | } 116 | 117 | private static string getReasonFrom (byte [] data) 118 | { 119 | var len = data.Length; 120 | return len > 2 121 | ? Encoding.UTF8.GetString (data.SubArray (2, len - 2)) 122 | : String.Empty; 123 | } 124 | 125 | #endregion 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/CloseStatusCode.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * CloseStatusCode.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp 32 | { 33 | /// 34 | /// Contains the values of the status codes for the WebSocket connection closure. 35 | /// 36 | /// 37 | /// 38 | /// The CloseStatusCode enumeration contains the values of the status codes for the WebSocket 39 | /// connection closure defined in RFC 6455 40 | /// for the WebSocket protocol. 41 | /// 42 | /// 43 | /// "Reserved value" must not be set as a status code in a close control frame by an endpoint. 44 | /// It is designated for use in applications expecting a status code to indicate that connection 45 | /// was closed due to a system grounds. 46 | /// 47 | /// 48 | public enum CloseStatusCode : ushort 49 | { 50 | /// 51 | /// Equivalent to close status 1000. Indicates a normal closure. 52 | /// 53 | NORMAL = 1000, 54 | /// 55 | /// Equivalent to close status 1001. Indicates that an endpoint is "going away". 56 | /// 57 | AWAY = 1001, 58 | /// 59 | /// Equivalent to close status 1002. 60 | /// Indicates that an endpoint is terminating the connection due to a protocol error. 61 | /// 62 | PROTOCOL_ERROR = 1002, 63 | /// 64 | /// Equivalent to close status 1003. 65 | /// Indicates that an endpoint is terminating the connection because it has received 66 | /// a type of data it cannot accept. 67 | /// 68 | INCORRECT_DATA = 1003, 69 | /// 70 | /// Equivalent to close status 1004. Still undefined. Reserved value. 71 | /// 72 | UNDEFINED = 1004, 73 | /// 74 | /// Equivalent to close status 1005. 75 | /// Indicates that no status code was actually present. Reserved value. 76 | /// 77 | NO_STATUS_CODE = 1005, 78 | /// 79 | /// Equivalent to close status 1006. 80 | /// Indicates that the connection was closed abnormally. Reserved value. 81 | /// 82 | ABNORMAL = 1006, 83 | /// 84 | /// Equivalent to close status 1007. 85 | /// Indicates that an endpoint is terminating the connection because it has received 86 | /// data within a message that was not consistent with the type of the message. 87 | /// 88 | INCONSISTENT_DATA = 1007, 89 | /// 90 | /// Equivalent to close status 1008. 91 | /// Indicates that an endpoint is terminating the connection because it has received 92 | /// a message that violates its policy. 93 | /// 94 | POLICY_VIOLATION = 1008, 95 | /// 96 | /// Equivalent to close status 1009. 97 | /// Indicates that an endpoint is terminating the connection because it has received 98 | /// a message that is too big to process. 99 | /// 100 | TOO_BIG = 1009, 101 | /// 102 | /// Equivalent to close status 1010. 103 | /// Indicates that an endpoint (client) is terminating the connection because it has expected 104 | /// the server to negotiate one or more extension, but the server didn't return them 105 | /// in the response message of the WebSocket handshake. 106 | /// 107 | IGNORE_EXTENSION = 1010, 108 | /// 109 | /// Equivalent to close status 1011. 110 | /// Indicates that a server is terminating the connection because it encountered 111 | /// an unexpected condition that prevented it from fulfilling the request. 112 | /// 113 | SERVER_ERROR = 1011, 114 | /// 115 | /// Equivalent to close status 1015. 116 | /// Indicates that the connection was closed due to a failure to perform a TLS handshake. 117 | /// Reserved value. 118 | /// 119 | TLS_HANDSHAKE_FAILURE = 1015 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/CompressionMethod.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * CompressionMethod.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | /// 34 | /// Contains the values of the compression methods used to compress the payload data of the WebSocket Data frame. 35 | /// 36 | /// 37 | /// The CompressionMethod enumeration contains the values of the compression methods defined in 38 | /// Compression Extensions for WebSocket. 39 | /// 40 | public enum CompressionMethod : byte 41 | { 42 | /// 43 | /// Indicates non compression. 44 | /// 45 | NONE, 46 | /// 47 | /// Indicates using DEFLATE. 48 | /// 49 | DEFLATE 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/ErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * ErrorEventArgs.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp 32 | { 33 | /// 34 | /// Contains the event data associated with a event. 35 | /// 36 | /// 37 | /// A event occurs when the gets an error. 38 | /// If you want to get the error message, you access the property. 39 | /// 40 | public class ErrorEventArgs : EventArgs 41 | { 42 | #region Internal Constructors 43 | 44 | internal ErrorEventArgs (string message) 45 | { 46 | Message = message; 47 | } 48 | 49 | #endregion 50 | 51 | #region Public Properties 52 | 53 | /// 54 | /// Gets the error message. 55 | /// 56 | /// 57 | /// A that contains an error message. 58 | /// 59 | public string Message { get; private set; } 60 | 61 | #endregion 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Fin.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * Fin.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | internal enum Fin : byte 34 | { 35 | MORE = 0x0, 36 | FINAL = 0x1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/HandshakeBase.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * HandshakeBase.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Collections.Specialized; 31 | using System.Text; 32 | using WebSocketSharp.Net; 33 | 34 | namespace WebSocketSharp 35 | { 36 | internal abstract class HandshakeBase 37 | { 38 | #region Protected Const Fields 39 | 40 | protected const string CrLf = "\r\n"; 41 | 42 | #endregion 43 | 44 | #region Protected Constructors 45 | 46 | protected HandshakeBase () 47 | { 48 | ProtocolVersion = HttpVersion.Version11; 49 | Headers = new NameValueCollection (); 50 | } 51 | 52 | #endregion 53 | 54 | #region Public Properties 55 | 56 | public NameValueCollection Headers { 57 | get; protected set; 58 | } 59 | 60 | public Version ProtocolVersion { 61 | get; protected set; 62 | } 63 | 64 | #endregion 65 | 66 | #region Public Methods 67 | 68 | public void AddHeader (string name, string value) 69 | { 70 | Headers.Add (name, value); 71 | } 72 | 73 | public bool ContainsHeader (string name) 74 | { 75 | return Headers.Contains (name); 76 | } 77 | 78 | public bool ContainsHeader (string name, string value) 79 | { 80 | return Headers.Contains (name, value); 81 | } 82 | 83 | public string [] GetHeaderValues (string name) 84 | { 85 | return Headers.GetValues (name); 86 | } 87 | 88 | public byte [] ToByteArray () 89 | { 90 | return Encoding.UTF8.GetBytes (ToString ()); 91 | } 92 | 93 | #endregion 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/HandshakeRequest.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * HandshakeRequest.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Collections.Specialized; 31 | using System.Linq; 32 | using System.Text; 33 | using WebSocketSharp.Net; 34 | using WebSocketSharp.Net.WebSockets; 35 | 36 | namespace WebSocketSharp 37 | { 38 | internal class HandshakeRequest : HandshakeBase 39 | { 40 | #region Private Fields 41 | 42 | private NameValueCollection _queryString; 43 | 44 | #endregion 45 | 46 | #region Private Constructors 47 | 48 | private HandshakeRequest () 49 | { 50 | } 51 | 52 | #endregion 53 | 54 | #region Public Constructors 55 | 56 | public HandshakeRequest (string uriString) 57 | { 58 | HttpMethod = "GET"; 59 | RequestUri = uriString.ToUri (); 60 | AddHeader ("User-Agent", "websocket-sharp/1.0"); 61 | AddHeader ("Upgrade", "websocket"); 62 | AddHeader ("Connection", "Upgrade"); 63 | } 64 | 65 | #endregion 66 | 67 | #region Public Properties 68 | 69 | public CookieCollection Cookies { 70 | get { 71 | return Headers.GetCookies (false); 72 | } 73 | } 74 | 75 | public string HttpMethod { 76 | get; private set; 77 | } 78 | 79 | public bool IsWebSocketRequest { 80 | get { 81 | return HttpMethod == "GET" && 82 | ProtocolVersion >= HttpVersion.Version11 && 83 | Headers.Contains ("Upgrade", "websocket") && 84 | Headers.Contains ("Connection", "Upgrade"); 85 | } 86 | } 87 | 88 | public NameValueCollection QueryString { 89 | get { 90 | if (_queryString == null) 91 | { 92 | _queryString = new NameValueCollection (); 93 | var i = RawUrl.IndexOf ('?'); 94 | if (i > 0) 95 | { 96 | var query = RawUrl.Substring (i + 1); 97 | var components = query.Split ('&'); 98 | foreach (var c in components) 99 | { 100 | var nv = c.GetNameAndValue ("="); 101 | if (nv.Key != null) 102 | { 103 | var name = nv.Key.UrlDecode (); 104 | var val = nv.Value.UrlDecode (); 105 | _queryString.Add (name, val); 106 | } 107 | } 108 | } 109 | } 110 | 111 | return _queryString; 112 | } 113 | } 114 | 115 | public string RawUrl { 116 | get { 117 | return RequestUri.IsAbsoluteUri 118 | ? RequestUri.PathAndQuery 119 | : RequestUri.OriginalString; 120 | } 121 | } 122 | 123 | public Uri RequestUri { 124 | get; private set; 125 | } 126 | 127 | #endregion 128 | 129 | #region Public Methods 130 | 131 | public static HandshakeRequest Parse (string [] request) 132 | { 133 | var requestLine = request [0].Split (' '); 134 | if (requestLine.Length != 3) 135 | { 136 | var msg = "Invalid HTTP Request-Line: " + request [0]; 137 | throw new ArgumentException (msg, "request"); 138 | } 139 | 140 | var headers = new WebHeaderCollection (); 141 | for (int i = 1; i < request.Length; i++) 142 | headers.SetInternal (request [i], false); 143 | 144 | return new HandshakeRequest { 145 | Headers = headers, 146 | HttpMethod = requestLine [0], 147 | RequestUri = requestLine [1].ToUri (), 148 | ProtocolVersion = new Version (requestLine [2].Substring (5)) 149 | }; 150 | } 151 | 152 | public void SetCookies (CookieCollection cookies) 153 | { 154 | if (cookies == null || cookies.Count == 0) 155 | return; 156 | 157 | var sorted = cookies.Sorted.ToArray (); 158 | var header = new StringBuilder (sorted [0].ToString (), 64); 159 | for (int i = 1; i < sorted.Length; i++) 160 | if (!sorted [i].Expired) 161 | header.AppendFormat ("; {0}", sorted [i].ToString ()); 162 | 163 | AddHeader ("Cookie", header.ToString ()); 164 | } 165 | 166 | public void SetAuthorization (AuthenticationResponse response) 167 | { 168 | var credentials = response.ToString (); 169 | AddHeader ("Authorization", credentials); 170 | } 171 | 172 | public override string ToString () 173 | { 174 | var buffer = new StringBuilder (64); 175 | buffer.AppendFormat ("{0} {1} HTTP/{2}{3}", HttpMethod, RawUrl, ProtocolVersion, CrLf); 176 | foreach (string key in Headers.AllKeys) 177 | buffer.AppendFormat ("{0}: {1}{2}", key, Headers [key], CrLf); 178 | 179 | buffer.Append (CrLf); 180 | return buffer.ToString (); 181 | } 182 | 183 | #endregion 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/HandshakeResponse.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * HandshakeResponse.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Collections.Specialized; 31 | using System.Text; 32 | using WebSocketSharp.Net; 33 | 34 | namespace WebSocketSharp 35 | { 36 | internal class HandshakeResponse : HandshakeBase 37 | { 38 | #region Public Constructors 39 | 40 | public HandshakeResponse () 41 | : this (HttpStatusCode.SwitchingProtocols) 42 | { 43 | AddHeader ("Upgrade", "websocket"); 44 | AddHeader ("Connection", "Upgrade"); 45 | } 46 | 47 | public HandshakeResponse (HttpStatusCode code) 48 | { 49 | StatusCode = ((int) code).ToString (); 50 | Reason = code.GetDescription (); 51 | AddHeader ("Server", "websocket-sharp/1.0"); 52 | } 53 | 54 | #endregion 55 | 56 | #region Public Properties 57 | 58 | public AuthenticationChallenge AuthChallenge { 59 | get { 60 | var challenge = Headers ["WWW-Authenticate"]; 61 | return !challenge.IsNullOrEmpty () 62 | ? AuthenticationChallenge.Parse (challenge) 63 | : null; 64 | } 65 | } 66 | 67 | public CookieCollection Cookies { 68 | get { 69 | return Headers.GetCookies (true); 70 | } 71 | } 72 | 73 | public bool IsUnauthorized { 74 | get { 75 | return StatusCode == "401"; 76 | } 77 | } 78 | 79 | public bool IsWebSocketResponse { 80 | get { 81 | return ProtocolVersion >= HttpVersion.Version11 && 82 | StatusCode == "101" && 83 | Headers.Contains ("Upgrade", "websocket") && 84 | Headers.Contains ("Connection", "Upgrade"); 85 | } 86 | } 87 | 88 | public string Reason { 89 | get; private set; 90 | } 91 | 92 | public string StatusCode { 93 | get; private set; 94 | } 95 | 96 | #endregion 97 | 98 | #region Public Methods 99 | 100 | public static HandshakeResponse CreateCloseResponse (HttpStatusCode code) 101 | { 102 | var res = new HandshakeResponse (code); 103 | res.AddHeader ("Connection", "close"); 104 | 105 | return res; 106 | } 107 | 108 | public static HandshakeResponse Parse (string [] response) 109 | { 110 | var statusLine = response [0].Split (' '); 111 | if (statusLine.Length < 3) 112 | throw new ArgumentException ("Invalid status line."); 113 | 114 | var reason = new StringBuilder (statusLine [2], 64); 115 | for (int i = 3; i < statusLine.Length; i++) 116 | reason.AppendFormat (" {0}", statusLine [i]); 117 | 118 | var headers = new WebHeaderCollection (); 119 | for (int i = 1; i < response.Length; i++) 120 | headers.SetInternal (response [i], true); 121 | 122 | return new HandshakeResponse { 123 | Headers = headers, 124 | Reason = reason.ToString (), 125 | StatusCode = statusLine [1], 126 | ProtocolVersion = new Version (statusLine [0].Substring (5)) 127 | }; 128 | } 129 | 130 | public void SetCookies (CookieCollection cookies) 131 | { 132 | if (cookies == null || cookies.Count == 0) 133 | return; 134 | 135 | foreach (var cookie in cookies.Sorted) 136 | AddHeader ("Set-Cookie", cookie.ToResponseString ()); 137 | } 138 | 139 | public override string ToString () 140 | { 141 | var buffer = new StringBuilder (64); 142 | buffer.AppendFormat ("HTTP/{0} {1} {2}{3}", ProtocolVersion, StatusCode, Reason, CrLf); 143 | foreach (string key in Headers.AllKeys) 144 | buffer.AppendFormat ("{0}: {1}{2}", key, Headers [key], CrLf); 145 | 146 | buffer.Append (CrLf); 147 | return buffer.ToString (); 148 | } 149 | 150 | #endregion 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/LogData.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * LogData.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Diagnostics; 31 | using System.Text; 32 | 33 | namespace WebSocketSharp 34 | { 35 | /// 36 | /// Represents the log data used by the class. 37 | /// 38 | public class LogData 39 | { 40 | #region Private Fields 41 | 42 | private StackFrame _caller; 43 | private DateTime _date; 44 | private LogLevel _level; 45 | private string _message; 46 | 47 | #endregion 48 | 49 | #region Internal Constructors 50 | 51 | internal LogData (LogLevel level, StackFrame caller, string message) 52 | { 53 | _level = level; 54 | _caller = caller; 55 | _message = message; 56 | _date = DateTime.Now; 57 | } 58 | 59 | #endregion 60 | 61 | #region Public Properties 62 | 63 | /// 64 | /// Gets the information of the logging method caller. 65 | /// 66 | /// 67 | /// A that contains the information of a logging method caller. 68 | /// 69 | public StackFrame Caller { 70 | get { 71 | return _caller; 72 | } 73 | } 74 | 75 | /// 76 | /// Gets the date and time when the log data was created. 77 | /// 78 | /// 79 | /// A that contains the date and time when the log data was created. 80 | /// 81 | public DateTime Date { 82 | get { 83 | return _date; 84 | } 85 | } 86 | 87 | /// 88 | /// Gets the logging level associated with the log data. 89 | /// 90 | /// 91 | /// One of the values that indicates the logging level 92 | /// associated with the log data. 93 | /// 94 | public LogLevel Level { 95 | get { 96 | return _level; 97 | } 98 | } 99 | 100 | /// 101 | /// Gets the message of the log data. 102 | /// 103 | /// 104 | /// A that contains the message of a log data. 105 | /// 106 | public string Message { 107 | get { 108 | return _message; 109 | } 110 | } 111 | 112 | #endregion 113 | 114 | #region Public Methods 115 | 116 | /// 117 | /// Returns a that represents the current . 118 | /// 119 | /// 120 | /// A that represents the current . 121 | /// 122 | public override string ToString () 123 | { 124 | var header = String.Format ("{0}|{1,-5}|", _date, _level); 125 | var method = _caller.GetMethod (); 126 | var type = method.DeclaringType; 127 | #if DEBUG 128 | var lineNum = _caller.GetFileLineNumber (); 129 | var headerAndCaller = String.Format ("{0}{1}.{2}:{3}|", header, type.Name, method.Name, lineNum); 130 | #else 131 | var headerAndCaller = String.Format ("{0}{1}.{2}|", header, type.Name, method.Name); 132 | #endif 133 | 134 | var messages = _message.Replace ("\r\n", "\n").TrimEnd ('\n').Split ('\n'); 135 | if (messages.Length <= 1) 136 | return String.Format ("{0}{1}", headerAndCaller, _message); 137 | 138 | var output = new StringBuilder (String.Format ("{0}{1}\n", headerAndCaller, messages [0]), 64); 139 | var space = header.Length; 140 | var format = String.Format ("{{0,{0}}}{{1}}\n", space); 141 | for (var i = 1; i < messages.Length; i++) 142 | output.AppendFormat (format, "", messages [i]); 143 | 144 | output.Length--; 145 | return output.ToString (); 146 | } 147 | 148 | #endregion 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/LogLevel.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * LogLevel.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp 32 | { 33 | /// 34 | /// Contains the values of the logging level. 35 | /// 36 | public enum LogLevel 37 | { 38 | /// 39 | /// Indicates the bottom logging level. 40 | /// 41 | TRACE, 42 | /// 43 | /// Indicates the 2nd logging level from the bottom. 44 | /// 45 | DEBUG, 46 | /// 47 | /// Indicates the 3rd logging level from the bottom. 48 | /// 49 | INFO, 50 | /// 51 | /// Indicates the 3rd logging level from the top. 52 | /// 53 | WARN, 54 | /// 55 | /// Indicates the 2nd logging level from the top. 56 | /// 57 | ERROR, 58 | /// 59 | /// Indicates the top logging level. 60 | /// 61 | FATAL 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Mask.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * Mask.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | internal enum Mask : byte 34 | { 35 | UNMASK = 0x0, 36 | MASK = 0x1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/MessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * MessageEventArgs.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Text; 31 | 32 | namespace WebSocketSharp 33 | { 34 | /// 35 | /// Contains the event data associated with a event. 36 | /// 37 | /// 38 | /// A event occurs when the receives 39 | /// a text or binary data frame. 40 | /// If you want to get the received data, you access the or 41 | /// property. 42 | /// 43 | public class MessageEventArgs : EventArgs 44 | { 45 | #region Private Fields 46 | 47 | private string _data; 48 | private Opcode _opcode; 49 | private byte[] _rawData; 50 | 51 | #endregion 52 | 53 | #region Internal Constructors 54 | 55 | internal MessageEventArgs (Opcode opcode, byte[] data) 56 | { 57 | if ((ulong) data.LongLength > PayloadData.MaxLength) 58 | throw new WebSocketException (CloseStatusCode.TOO_BIG); 59 | 60 | _opcode = opcode; 61 | _rawData = data; 62 | _data = convertToString (opcode, data); 63 | } 64 | 65 | internal MessageEventArgs (Opcode opcode, PayloadData payload) 66 | { 67 | _opcode = opcode; 68 | _rawData = payload.ApplicationData; 69 | _data = convertToString (opcode, _rawData); 70 | } 71 | 72 | #endregion 73 | 74 | #region Public Properties 75 | 76 | /// 77 | /// Gets the received data as a . 78 | /// 79 | /// 80 | /// A that contains the received data. 81 | /// 82 | public string Data { 83 | get { 84 | return _data; 85 | } 86 | } 87 | 88 | /// 89 | /// Gets the received data as an array of . 90 | /// 91 | /// 92 | /// An array of that contains the received data. 93 | /// 94 | public byte [] RawData { 95 | get { 96 | return _rawData; 97 | } 98 | } 99 | 100 | /// 101 | /// Gets the type of the received data. 102 | /// 103 | /// 104 | /// One of the values, indicates the type of the received data. 105 | /// 106 | public Opcode Type { 107 | get { 108 | return _opcode; 109 | } 110 | } 111 | 112 | #endregion 113 | 114 | #region Private Methods 115 | 116 | private static string convertToString (Opcode opcode, byte [] data) 117 | { 118 | return data.LongLength == 0 119 | ? String.Empty 120 | : opcode == Opcode.TEXT 121 | ? Encoding.UTF8.GetString (data) 122 | : opcode.ToString (); 123 | } 124 | 125 | #endregion 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/AuthenticationSchemeSelector.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AuthenticationSchemeSelector.cs 3 | // Copied from System.Net.AuthenticationSchemeSelector.cs 4 | // 5 | // Author: 6 | // Gonzalo Paniagua Javier 7 | // 8 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | 32 | namespace WebSocketSharp.Net { 33 | 34 | /// 35 | /// Selects the authentication scheme for a instance. 36 | /// 37 | /// 38 | /// One of the values that indicates the scheme used to authenticate the specified client request. 39 | /// 40 | /// 41 | /// A that contains a client request information. 42 | /// 43 | public delegate AuthenticationSchemes AuthenticationSchemeSelector (HttpListenerRequest httpRequest); 44 | } 45 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/AuthenticationSchemes.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AuthenticationSchemes.cs 3 | // Copied from System.Net.AuthenticationSchemes.cs 4 | // 5 | // Author: 6 | // Atsushi Enomoto 7 | // 8 | // Copyright (C) 2005 Novell, Inc. (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | 32 | namespace WebSocketSharp.Net { 33 | 34 | /// 35 | /// Contains the values of the schemes for authentication. 36 | /// 37 | [Flags] 38 | public enum AuthenticationSchemes { 39 | 40 | /// 41 | /// Indicates that no authentication is allowed. 42 | /// 43 | None, 44 | /// 45 | /// Indicates digest authentication. 46 | /// 47 | Digest = 1, 48 | /// 49 | /// Indicates negotiating with the client to determine the authentication scheme. 50 | /// 51 | Negotiate = 2, 52 | /// 53 | /// Indicates NTLM authentication. 54 | /// 55 | Ntlm = 4, 56 | /// 57 | /// Indicates Windows authentication. 58 | /// 59 | IntegratedWindowsAuthentication = 6, 60 | /// 61 | /// Indicates basic authentication. 62 | /// 63 | Basic = 8, 64 | /// 65 | /// Indicates anonymous authentication. 66 | /// 67 | Anonymous = 0x8000, 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/ChunkedInputStream.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ChunkedInputStream.cs 3 | // Copied from System.Net.ChunkedInputStream.cs 4 | // 5 | // Authors: 6 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 7 | // 8 | // Copyright (c) 2005 Novell, Inc (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.IO; 32 | using System.Runtime.InteropServices; 33 | 34 | namespace WebSocketSharp.Net { 35 | 36 | class ChunkedInputStream : RequestStream { 37 | 38 | class ReadBufferState { 39 | 40 | public HttpStreamAsyncResult Ares; 41 | public byte [] Buffer; 42 | public int Count; 43 | public int InitialCount; 44 | public int Offset; 45 | 46 | public ReadBufferState ( 47 | byte [] buffer, int offset, int count, HttpStreamAsyncResult ares) 48 | { 49 | Buffer = buffer; 50 | Offset = offset; 51 | Count = count; 52 | InitialCount = count; 53 | Ares = ares; 54 | } 55 | } 56 | 57 | #region Fields 58 | 59 | HttpListenerContext context; 60 | ChunkStream decoder; 61 | bool disposed; 62 | bool no_more_data; 63 | 64 | #endregion 65 | 66 | #region Constructor 67 | 68 | public ChunkedInputStream ( 69 | HttpListenerContext context, Stream stream, byte [] buffer, int offset, int length) 70 | : base (stream, buffer, offset, length) 71 | { 72 | this.context = context; 73 | WebHeaderCollection coll = (WebHeaderCollection) context.Request.Headers; 74 | decoder = new ChunkStream (coll); 75 | } 76 | 77 | #endregion 78 | 79 | #region Property 80 | 81 | public ChunkStream Decoder { 82 | get { return decoder; } 83 | set { decoder = value; } 84 | } 85 | 86 | #endregion 87 | 88 | #region Private Method 89 | 90 | void OnRead (IAsyncResult base_ares) 91 | { 92 | var rb = (ReadBufferState) base_ares.AsyncState; 93 | var ares = rb.Ares; 94 | try { 95 | int nread = base.EndRead (base_ares); 96 | decoder.Write (ares.Buffer, ares.Offset, nread); 97 | nread = decoder.Read (rb.Buffer, rb.Offset, rb.Count); 98 | rb.Offset += nread; 99 | rb.Count -= nread; 100 | if (rb.Count == 0 || !decoder.WantMore || nread == 0) { 101 | no_more_data = !decoder.WantMore && nread == 0; 102 | ares.Count = rb.InitialCount - rb.Count; 103 | ares.Complete (); 104 | return; 105 | } 106 | 107 | ares.Offset = 0; 108 | ares.Count = Math.Min (8192, decoder.ChunkLeft + 6); 109 | base.BeginRead (ares.Buffer, ares.Offset, ares.Count, OnRead, rb); 110 | } catch (Exception e) { 111 | context.Connection.SendError (e.Message, 400); 112 | ares.Complete (e); 113 | } 114 | } 115 | 116 | #endregion 117 | 118 | #region Public Methods 119 | 120 | public override IAsyncResult BeginRead ( 121 | byte [] buffer, int offset, int count, AsyncCallback cback, object state) 122 | { 123 | if (disposed) 124 | throw new ObjectDisposedException (GetType ().ToString ()); 125 | 126 | if (buffer == null) 127 | throw new ArgumentNullException ("buffer"); 128 | 129 | int len = buffer.Length; 130 | if (offset < 0 || offset > len) 131 | throw new ArgumentOutOfRangeException ("'offset' exceeds the size of buffer."); 132 | 133 | if (count < 0 || offset > len - count) 134 | throw new ArgumentOutOfRangeException ("'offset' + 'count' exceeds the size of buffer."); 135 | 136 | var ares = new HttpStreamAsyncResult (); 137 | ares.Callback = cback; 138 | ares.State = state; 139 | if (no_more_data) { 140 | ares.Complete (); 141 | return ares; 142 | } 143 | 144 | int nread = decoder.Read (buffer, offset, count); 145 | offset += nread; 146 | count -= nread; 147 | if (count == 0) { 148 | // got all we wanted, no need to bother the decoder yet 149 | ares.Count = nread; 150 | ares.Complete (); 151 | return ares; 152 | } 153 | 154 | if (!decoder.WantMore) { 155 | no_more_data = nread == 0; 156 | ares.Count = nread; 157 | ares.Complete (); 158 | return ares; 159 | } 160 | 161 | ares.Buffer = new byte [8192]; 162 | ares.Offset = 0; 163 | ares.Count = 8192; 164 | var rb = new ReadBufferState (buffer, offset, count, ares); 165 | rb.InitialCount += nread; 166 | base.BeginRead (ares.Buffer, ares.Offset, ares.Count, OnRead, rb); 167 | return ares; 168 | } 169 | 170 | public override void Close () 171 | { 172 | if (!disposed) { 173 | disposed = true; 174 | base.Close (); 175 | } 176 | } 177 | 178 | public override int EndRead (IAsyncResult ares) 179 | { 180 | if (disposed) 181 | throw new ObjectDisposedException (GetType ().ToString ()); 182 | 183 | if (ares == null) 184 | throw new ArgumentException ("Invalid IAsyncResult.", "ares"); 185 | 186 | if (!ares.IsCompleted) 187 | ares.AsyncWaitHandle.WaitOne (); 188 | 189 | var ares_ = ares as HttpStreamAsyncResult; 190 | if (ares_.Error != null) 191 | throw new HttpListenerException (400, "I/O operation aborted."); 192 | 193 | return ares_.Count; 194 | } 195 | 196 | public override int Read ([In,Out] byte [] buffer, int offset, int count) 197 | { 198 | var ares = BeginRead (buffer, offset, count, null, null); 199 | return EndRead (ares); 200 | } 201 | 202 | #endregion 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/CookieException.cs: -------------------------------------------------------------------------------- 1 | // 2 | // CookieException.cs 3 | // Copied from System.Net.CookieException.cs 4 | // 5 | // Author: 6 | // Lawrence Pit (loz@cable.a2000.nl) 7 | // 8 | // Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.Globalization; 32 | using System.Runtime.Serialization; 33 | using System.Security.Permissions; 34 | 35 | namespace WebSocketSharp.Net { 36 | 37 | /// 38 | /// The exception that is thrown when a gets an error. 39 | /// 40 | [Serializable] 41 | public class CookieException : FormatException, ISerializable 42 | { 43 | #region Internal Constructors 44 | 45 | internal CookieException (string message) 46 | : base (message) 47 | { 48 | } 49 | 50 | internal CookieException (string message, Exception innerException) 51 | : base (message, innerException) 52 | { 53 | } 54 | 55 | #endregion 56 | 57 | #region Protected Constructor 58 | 59 | /// 60 | /// Initializes a new instance of the class 61 | /// with the specified and . 62 | /// 63 | /// 64 | /// A that holds the serialized object data. 65 | /// 66 | /// 67 | /// A that contains the contextual information about the source or destination. 68 | /// 69 | protected CookieException (SerializationInfo serializationInfo, StreamingContext streamingContext) 70 | : base (serializationInfo, streamingContext) 71 | { 72 | } 73 | 74 | #endregion 75 | 76 | #region Public Constructor 77 | 78 | /// 79 | /// Initializes a new instance of the class. 80 | /// 81 | public CookieException () 82 | : base () 83 | { 84 | } 85 | 86 | #endregion 87 | 88 | #region Explicit Interface Implementation 89 | 90 | /// 91 | /// Populates the specified with the data needed to serialize the . 92 | /// 93 | /// 94 | /// A that holds the serialized object data. 95 | /// 96 | /// 97 | /// A that specifies the destination for the serialization. 98 | /// 99 | [SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter, SerializationFormatter = true)] 100 | void ISerializable.GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext) 101 | { 102 | base.GetObjectData (serializationInfo, streamingContext); 103 | } 104 | 105 | #endregion 106 | 107 | #region Public Method 108 | 109 | /// 110 | /// Populates the specified with the data needed to serialize the . 111 | /// 112 | /// 113 | /// A that holds the serialized object data. 114 | /// 115 | /// 116 | /// A that specifies the destination for the serialization. 117 | /// 118 | [SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] 119 | public override void GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext) 120 | { 121 | base.GetObjectData (serializationInfo, streamingContext); 122 | } 123 | 124 | #endregion 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/EndPointManager.cs: -------------------------------------------------------------------------------- 1 | // 2 | // EndPointManager.cs 3 | // Copied from System.Net.EndPointManager.cs 4 | // 5 | // Author: 6 | // Gonzalo Paniagua Javier (gonzalo@ximian.com) 7 | // 8 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 9 | // Copyright (c) 2012-2013 sta.blockhead 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining 12 | // a copy of this software and associated documentation files (the 13 | // "Software"), to deal in the Software without restriction, including 14 | // without limitation the rights to use, copy, modify, merge, publish, 15 | // distribute, sublicense, and/or sell copies of the Software, and to 16 | // permit persons to whom the Software is furnished to do so, subject to 17 | // the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be 20 | // included in all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | // 30 | 31 | using System; 32 | using System.Collections; 33 | using System.Collections.Generic; 34 | using System.Net; 35 | 36 | namespace WebSocketSharp.Net 37 | { 38 | internal sealed class EndPointManager 39 | { 40 | #region Private Fields 41 | 42 | private static Dictionary> _ipToEndpoints = new Dictionary> (); 43 | 44 | #endregion 45 | 46 | #region Private Constructors 47 | 48 | private EndPointManager () 49 | { 50 | } 51 | 52 | #endregion 53 | 54 | #region Private Methods 55 | 56 | private static void addPrefix (string uriPrefix, HttpListener httpListener) 57 | { 58 | var prefix = new ListenerPrefix (uriPrefix); 59 | if (prefix.Path.IndexOf ('%') != -1) 60 | throw new HttpListenerException (400, "Invalid path."); 61 | 62 | if (prefix.Path.IndexOf ("//", StringComparison.Ordinal) != -1) // TODO: Code? 63 | throw new HttpListenerException (400, "Invalid path."); 64 | 65 | // Always listens on all the interfaces, no matter the host name/ip used. 66 | var epListener = getEndPointListener (IPAddress.Any, prefix.Port, httpListener, prefix.Secure); 67 | epListener.AddPrefix (prefix, httpListener); 68 | } 69 | 70 | private static EndPointListener getEndPointListener ( 71 | IPAddress address, int port, HttpListener httpListener, bool secure) 72 | { 73 | Dictionary endpoints = null; 74 | if (_ipToEndpoints.ContainsKey (address)) 75 | { 76 | endpoints = _ipToEndpoints [address]; 77 | } 78 | else 79 | { 80 | endpoints = new Dictionary (); 81 | _ipToEndpoints [address] = endpoints; 82 | } 83 | 84 | EndPointListener epListener = null; 85 | if (endpoints.ContainsKey (port)) 86 | { 87 | epListener = endpoints [port]; 88 | } 89 | else 90 | { 91 | epListener = new EndPointListener ( 92 | address, port, secure, httpListener.CertificateFolderPath, httpListener.DefaultCertificate); 93 | endpoints [port] = epListener; 94 | } 95 | 96 | return epListener; 97 | } 98 | 99 | private static void removePrefix (string uriPrefix, HttpListener httpListener) 100 | { 101 | var prefix = new ListenerPrefix (uriPrefix); 102 | if (prefix.Path.IndexOf ('%') != -1) 103 | return; 104 | 105 | if (prefix.Path.IndexOf ("//", StringComparison.Ordinal) != -1) 106 | return; 107 | 108 | var epListener = getEndPointListener (IPAddress.Any, prefix.Port, httpListener, prefix.Secure); 109 | epListener.RemovePrefix (prefix, httpListener); 110 | } 111 | 112 | #endregion 113 | 114 | #region Public Methods 115 | 116 | public static void AddListener (HttpListener httpListener) 117 | { 118 | var added = new List (); 119 | lock (((ICollection) _ipToEndpoints).SyncRoot) 120 | { 121 | try { 122 | foreach (var prefix in httpListener.Prefixes) 123 | { 124 | addPrefix (prefix, httpListener); 125 | added.Add (prefix); 126 | } 127 | } 128 | catch { 129 | foreach (var prefix in added) 130 | removePrefix (prefix, httpListener); 131 | 132 | throw; 133 | } 134 | } 135 | } 136 | 137 | public static void AddPrefix (string uriPrefix, HttpListener httpListener) 138 | { 139 | lock (((ICollection) _ipToEndpoints).SyncRoot) 140 | { 141 | addPrefix (uriPrefix, httpListener); 142 | } 143 | } 144 | 145 | public static void RemoveEndPoint (EndPointListener epListener, IPEndPoint endpoint) 146 | { 147 | lock (((ICollection) _ipToEndpoints).SyncRoot) 148 | { 149 | var endpoints = _ipToEndpoints [endpoint.Address]; 150 | endpoints.Remove (endpoint.Port); 151 | if (endpoints.Count == 0) 152 | _ipToEndpoints.Remove (endpoint.Address); 153 | 154 | epListener.Close (); 155 | } 156 | } 157 | 158 | public static void RemoveListener (HttpListener httpListener) 159 | { 160 | lock (((ICollection) _ipToEndpoints).SyncRoot) 161 | { 162 | foreach (var prefix in httpListener.Prefixes) 163 | removePrefix (prefix, httpListener); 164 | } 165 | } 166 | 167 | public static void RemovePrefix (string uriPrefix, HttpListener httpListener) 168 | { 169 | lock (((ICollection) _ipToEndpoints).SyncRoot) 170 | { 171 | removePrefix (uriPrefix, httpListener); 172 | } 173 | } 174 | 175 | #endregion 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/HttpHeaderInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // HttpHeaderInfo.cs 3 | // 4 | // Authors: 5 | // sta (sta.blockhead@gmail.com) 6 | // 7 | // Copyright (c) 2013 sta.blockhead 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp.Net { 32 | 33 | class HttpHeaderInfo { 34 | 35 | #region Constructor 36 | 37 | public HttpHeaderInfo () 38 | { 39 | } 40 | 41 | #endregion 42 | 43 | #region Properties 44 | 45 | public bool IsMultiValueInRequest { 46 | get { 47 | return (Type & HttpHeaderType.MultiValueInRequest) == HttpHeaderType.MultiValueInRequest; 48 | } 49 | } 50 | 51 | public bool IsMultiValueInResponse { 52 | get { 53 | return (Type & HttpHeaderType.MultiValueInResponse) == HttpHeaderType.MultiValueInResponse; 54 | } 55 | } 56 | 57 | public bool IsRequest { 58 | get { 59 | return (Type & HttpHeaderType.Request) == HttpHeaderType.Request; 60 | } 61 | } 62 | 63 | public bool IsResponse { 64 | get { 65 | return (Type & HttpHeaderType.Response) == HttpHeaderType.Response; 66 | } 67 | } 68 | 69 | public string Name { get; set; } 70 | 71 | public HttpHeaderType Type { get; set; } 72 | 73 | #endregion 74 | 75 | #region Methods 76 | 77 | public bool IsMultiValue (bool response) 78 | { 79 | return (Type & HttpHeaderType.MultiValue) != HttpHeaderType.MultiValue 80 | ? response 81 | ? IsMultiValueInResponse 82 | : IsMultiValueInRequest 83 | : response 84 | ? IsResponse 85 | : IsRequest; 86 | } 87 | 88 | public bool IsRestricted (bool response) 89 | { 90 | return (Type & HttpHeaderType.Restricted) != HttpHeaderType.Restricted 91 | ? false 92 | : response 93 | ? IsResponse 94 | : IsRequest; 95 | } 96 | 97 | #endregion 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/HttpHeaderType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // HttpHeaderType.cs 3 | // 4 | // Authors: 5 | // sta (sta.blockhead@gmail.com) 6 | // 7 | // Copyright (c) 2013 sta.blockhead 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining 10 | // a copy of this software and associated documentation files (the 11 | // "Software"), to deal in the Software without restriction, including 12 | // without limitation the rights to use, copy, modify, merge, publish, 13 | // distribute, sublicense, and/or sell copies of the Software, and to 14 | // permit persons to whom the Software is furnished to do so, subject to 15 | // the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be 18 | // included in all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp.Net { 32 | 33 | [Flags] 34 | enum HttpHeaderType 35 | { 36 | Unspecified = 0, 37 | Request = 1, 38 | Response = 1 << 1, 39 | Restricted = 1 << 2, 40 | MultiValue = 1 << 3, 41 | MultiValueInRequest = 1 << 4, 42 | MultiValueInResponse = 1 << 5 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/HttpListenerContext.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | // 3 | // HttpListenerContext.cs 4 | // Copied from System.Net.HttpListenerContext.cs 5 | // 6 | // Author: 7 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 8 | // 9 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | // Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com) 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining 13 | // a copy of this software and associated documentation files (the 14 | // "Software"), to deal in the Software without restriction, including 15 | // without limitation the rights to use, copy, modify, merge, publish, 16 | // distribute, sublicense, and/or sell copies of the Software, and to 17 | // permit persons to whom the Software is furnished to do so, subject to 18 | // the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be 21 | // included in all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | // 31 | #endregion 32 | 33 | using System; 34 | using System.Collections.Specialized; 35 | using System.IO; 36 | using System.Security.Principal; 37 | using System.Text; 38 | using WebSocketSharp.Net.WebSockets; 39 | 40 | namespace WebSocketSharp.Net { 41 | 42 | /// 43 | /// Provides access to the HTTP request and response objects used by the class. 44 | /// 45 | /// 46 | /// The HttpListenerContext class cannot be inherited. 47 | /// 48 | public sealed class HttpListenerContext { 49 | 50 | #region Private Fields 51 | 52 | private HttpConnection _connection; 53 | private string _error; 54 | private int _errorStatus; 55 | private HttpListenerRequest _request; 56 | private HttpListenerResponse _response; 57 | private IPrincipal _user; 58 | 59 | #endregion 60 | 61 | #region Internal Fields 62 | 63 | internal HttpListener Listener; 64 | 65 | #endregion 66 | 67 | #region Constructor 68 | 69 | internal HttpListenerContext (HttpConnection connection) 70 | { 71 | _connection = connection; 72 | _errorStatus = 400; 73 | _request = new HttpListenerRequest (this); 74 | _response = new HttpListenerResponse (this); 75 | } 76 | 77 | #endregion 78 | 79 | #region Internal Properties 80 | 81 | internal HttpConnection Connection { 82 | get { 83 | return _connection; 84 | } 85 | } 86 | 87 | internal string ErrorMessage { 88 | get { 89 | return _error; 90 | } 91 | 92 | set { 93 | _error = value; 94 | } 95 | } 96 | 97 | internal int ErrorStatus { 98 | get { 99 | return _errorStatus; 100 | } 101 | 102 | set { 103 | _errorStatus = value; 104 | } 105 | } 106 | 107 | internal bool HaveError { 108 | get { 109 | return _error != null; 110 | } 111 | } 112 | 113 | #endregion 114 | 115 | #region Public Properties 116 | 117 | /// 118 | /// Gets the that contains the HTTP request from a client. 119 | /// 120 | /// 121 | /// A that contains the HTTP request objects. 122 | /// 123 | public HttpListenerRequest Request { 124 | get { 125 | return _request; 126 | } 127 | } 128 | 129 | /// 130 | /// Gets the that contains the HTTP response to send to 131 | /// the client in response to the client's request. 132 | /// 133 | /// 134 | /// A that contains the HTTP response objects. 135 | /// 136 | public HttpListenerResponse Response { 137 | get { 138 | return _response; 139 | } 140 | } 141 | 142 | /// 143 | /// Gets the client information (identity, authentication information and security roles). 144 | /// 145 | /// 146 | /// A contains the client information. 147 | /// 148 | public IPrincipal User { 149 | get { 150 | return _user; 151 | } 152 | } 153 | 154 | #endregion 155 | 156 | #region Internal Methods 157 | 158 | internal void ParseAuthentication (AuthenticationSchemes expectedSchemes) 159 | { 160 | if (expectedSchemes == AuthenticationSchemes.Anonymous) 161 | return; 162 | 163 | // TODO: Handle NTLM/Digest modes. 164 | var header = _request.Headers ["Authorization"]; 165 | if (header == null || header.Length < 2) 166 | return; 167 | 168 | var authData = header.Split (new char [] {' '}, 2); 169 | if (authData [0].ToLower () == "basic") 170 | _user = ParseBasicAuthentication (authData [1]); 171 | 172 | // TODO: Throw if malformed -> 400 bad request. 173 | } 174 | 175 | internal IPrincipal ParseBasicAuthentication (string authData) 176 | { 177 | try { 178 | // HTTP Basic Authentication data is a formatted Base64 string. 179 | var authString = Encoding.Default.GetString (Convert.FromBase64String (authData)); 180 | 181 | // The format is domain\username:password. 182 | // Domain is optional. 183 | 184 | var pos = authString.IndexOf (':'); 185 | var user = authString.Substring (0, pos); 186 | var password = authString.Substring (pos + 1); 187 | 188 | // Check if there is a domain. 189 | pos = user.IndexOf ('\\'); 190 | if (pos > 0) 191 | user = user.Substring (pos + 1); 192 | 193 | var identity = new System.Net.HttpListenerBasicIdentity (user, password); 194 | // TODO: What are the roles MS sets? 195 | return new GenericPrincipal (identity, new string [0]); 196 | } catch { 197 | return null; 198 | } 199 | } 200 | 201 | #endregion 202 | 203 | #region Public Method 204 | 205 | /// 206 | /// Accepts a WebSocket connection by the . 207 | /// 208 | /// 209 | /// A that contains a WebSocket connection. 210 | /// 211 | public HttpListenerWebSocketContext AcceptWebSocket () 212 | { 213 | return new HttpListenerWebSocketContext (this); 214 | } 215 | 216 | #endregion 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/HttpListenerException.cs: -------------------------------------------------------------------------------- 1 | // 2 | // HttpListenerException.cs 3 | // Copied from System.Net.HttpListenerException.cs 4 | // 5 | // Author: 6 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 7 | // 8 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.ComponentModel; 32 | using System.Runtime.Serialization; 33 | 34 | namespace WebSocketSharp.Net { 35 | 36 | /// 37 | /// The exception that is thrown when an error occurs processing an HTTP request. 38 | /// 39 | [Serializable] 40 | public class HttpListenerException : Win32Exception { 41 | 42 | #region Public Constructors 43 | 44 | /// 45 | /// Initializes a new instance of the class. 46 | /// 47 | public HttpListenerException () 48 | { 49 | } 50 | 51 | /// 52 | /// Initializes a new instance of the class 53 | /// with the specified . 54 | /// 55 | /// 56 | /// An that contains an error code. 57 | /// 58 | public HttpListenerException (int errorCode) : base (errorCode) 59 | { 60 | } 61 | 62 | /// 63 | /// Initializes a new instance of the class 64 | /// with the specified and . 65 | /// 66 | /// 67 | /// An that contains an error code. 68 | /// 69 | /// 70 | /// A that describes the error. 71 | /// 72 | public HttpListenerException (int errorCode, string message) : base (errorCode, message) 73 | { 74 | } 75 | 76 | #endregion 77 | 78 | #region Protected Constructor 79 | 80 | /// 81 | /// Initializes a new instance of the class 82 | /// from the specified and classes. 83 | /// 84 | /// 85 | /// A that contains the information required to deserialize 86 | /// the new object. 87 | /// 88 | /// 89 | /// A . 90 | /// 91 | protected HttpListenerException (SerializationInfo serializationInfo, StreamingContext streamingContext) : base (serializationInfo, streamingContext) 92 | { 93 | } 94 | 95 | #endregion 96 | 97 | #region Property 98 | 99 | /// 100 | /// Gets a value that represents the error that occurred. 101 | /// 102 | /// 103 | /// An that contains an error code. 104 | /// 105 | public override int ErrorCode { 106 | get { return base.ErrorCode; } 107 | } 108 | 109 | #endregion 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/HttpStreamAsyncResult.cs: -------------------------------------------------------------------------------- 1 | // 2 | // HttpStreamAsyncResult.cs 3 | // Copied from System.Net.HttpStreamAsyncResult.cs 4 | // 5 | // Authors: 6 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 7 | // 8 | // Copyright (C) 2005 Novell, Inc (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.Threading; 32 | 33 | namespace WebSocketSharp.Net { 34 | 35 | class HttpStreamAsyncResult : IAsyncResult { 36 | 37 | #region Private Fields 38 | 39 | bool completed; 40 | ManualResetEvent handle; 41 | object locker = new object (); 42 | 43 | #endregion 44 | 45 | #region Internal Fields 46 | 47 | internal AsyncCallback Callback; 48 | internal int Count; 49 | internal byte [] Buffer; 50 | internal Exception Error; 51 | internal int Offset; 52 | internal object State; 53 | internal int SyncRead; 54 | 55 | #endregion 56 | 57 | #region Properties 58 | 59 | public object AsyncState { 60 | get { return State; } 61 | } 62 | 63 | public WaitHandle AsyncWaitHandle { 64 | get { 65 | lock (locker) { 66 | if (handle == null) 67 | handle = new ManualResetEvent (completed); 68 | } 69 | 70 | return handle; 71 | } 72 | } 73 | 74 | public bool CompletedSynchronously { 75 | get { return (SyncRead == Count); } 76 | } 77 | 78 | public bool IsCompleted { 79 | get { 80 | lock (locker) { 81 | return completed; 82 | } 83 | } 84 | } 85 | 86 | #endregion 87 | 88 | #region Public Methods 89 | 90 | public void Complete () 91 | { 92 | lock (locker) { 93 | if (completed) 94 | return; 95 | 96 | completed = true; 97 | if (handle != null) 98 | handle.Set (); 99 | 100 | if (Callback != null) 101 | Callback.BeginInvoke (this, null, null); 102 | } 103 | } 104 | 105 | public void Complete (Exception e) 106 | { 107 | Error = e; 108 | Complete (); 109 | } 110 | 111 | #endregion 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/HttpVersion.cs: -------------------------------------------------------------------------------- 1 | // 2 | // HttpVersion.cs 3 | // Copied from System.Net.HttpVersion.cs 4 | // 5 | // Author: 6 | // Lawrence Pit (loz@cable.a2000.nl) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining 9 | // a copy of this software and associated documentation files (the 10 | // "Software"), to deal in the Software without restriction, including 11 | // without limitation the rights to use, copy, modify, merge, publish, 12 | // distribute, sublicense, and/or sell copies of the Software, and to 13 | // permit persons to whom the Software is furnished to do so, subject to 14 | // the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be 17 | // included in all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | // 27 | 28 | using System; 29 | 30 | namespace WebSocketSharp.Net { 31 | 32 | /// 33 | /// Provides the HTTP version numbers. 34 | /// 35 | public class HttpVersion { 36 | 37 | /// 38 | /// Provides a instance for HTTP 1.0. 39 | /// 40 | public static readonly Version Version10 = new Version (1, 0); 41 | 42 | /// 43 | /// Provides a instance for HTTP 1.1. 44 | /// 45 | public static readonly Version Version11 = new Version (1, 1); 46 | 47 | /// 48 | /// Initializes a new instance of the class. 49 | /// 50 | public HttpVersion () {} 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/ListenerAsyncResult.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ListenerAsyncResult.cs 3 | // Copied from System.Net.ListenerAsyncResult.cs 4 | // 5 | // Authors: 6 | // Gonzalo Paniagua Javier (gonzalo@ximian.com) 7 | // 8 | // Copyright (c) 2005 Ximian, Inc (http://www.ximian.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.Net; 32 | using System.Threading; 33 | 34 | namespace WebSocketSharp.Net { 35 | 36 | class ListenerAsyncResult : IAsyncResult 37 | { 38 | #region Private Static Field 39 | 40 | static WaitCallback InvokeCB = new WaitCallback (InvokeCallback); 41 | 42 | #endregion 43 | 44 | #region Private Fields 45 | 46 | AsyncCallback cb; 47 | bool completed; 48 | HttpListenerContext context; 49 | Exception exception; 50 | ListenerAsyncResult forward; 51 | ManualResetEvent handle; 52 | object locker; 53 | object state; 54 | bool synch; 55 | 56 | #endregion 57 | 58 | #region Internal Fields 59 | 60 | internal bool EndCalled; 61 | internal bool InGet; 62 | 63 | #endregion 64 | 65 | #region Constructor 66 | 67 | public ListenerAsyncResult (AsyncCallback cb, object state) 68 | { 69 | this.cb = cb; 70 | this.state = state; 71 | this.locker = new object(); 72 | } 73 | 74 | #endregion 75 | 76 | #region Properties 77 | 78 | public object AsyncState { 79 | get { 80 | if (forward != null) 81 | return forward.AsyncState; 82 | 83 | return state; 84 | } 85 | } 86 | 87 | public WaitHandle AsyncWaitHandle { 88 | get { 89 | if (forward != null) 90 | return forward.AsyncWaitHandle; 91 | 92 | lock (locker) { 93 | if (handle == null) 94 | handle = new ManualResetEvent (completed); 95 | } 96 | 97 | return handle; 98 | } 99 | } 100 | 101 | public bool CompletedSynchronously { 102 | get { 103 | if (forward != null) 104 | return forward.CompletedSynchronously; 105 | 106 | return synch; 107 | } 108 | } 109 | 110 | public bool IsCompleted { 111 | get { 112 | if (forward != null) 113 | return forward.IsCompleted; 114 | 115 | lock (locker) { 116 | return completed; 117 | } 118 | } 119 | } 120 | 121 | #endregion 122 | 123 | #region Private Method 124 | 125 | static void InvokeCallback (object o) 126 | { 127 | ListenerAsyncResult ares = (ListenerAsyncResult) o; 128 | if (ares.forward != null) { 129 | InvokeCallback (ares.forward); 130 | return; 131 | } 132 | 133 | try { 134 | ares.cb (ares); 135 | } catch { 136 | } 137 | } 138 | 139 | #endregion 140 | 141 | #region Internal Methods 142 | 143 | internal void Complete (Exception exc) 144 | { 145 | if (forward != null) { 146 | forward.Complete (exc); 147 | return; 148 | } 149 | 150 | exception = exc; 151 | if (InGet && (exc is ObjectDisposedException)) 152 | exception = new HttpListenerException (500, "Listener closed"); 153 | 154 | lock (locker) { 155 | completed = true; 156 | if (handle != null) 157 | handle.Set (); 158 | 159 | if (cb != null) 160 | //ThreadPool.UnsafeQueueUserWorkItem (InvokeCB, this); 161 | ThreadPool.QueueUserWorkItem (InvokeCB, this); 162 | } 163 | } 164 | 165 | internal void Complete (HttpListenerContext context) 166 | { 167 | Complete (context, false); 168 | } 169 | 170 | internal void Complete (HttpListenerContext context, bool synch) 171 | { 172 | if (forward != null) { 173 | forward.Complete (context, synch); 174 | return; 175 | } 176 | 177 | this.synch = synch; 178 | this.context = context; 179 | lock (locker) { 180 | AuthenticationSchemes schemes = context.Listener.SelectAuthenticationScheme (context); 181 | if ((schemes == AuthenticationSchemes.Basic || context.Listener.AuthenticationSchemes == AuthenticationSchemes.Negotiate) && context.Request.Headers ["Authorization"] == null) { 182 | context.Response.StatusCode = 401; 183 | context.Response.Headers ["WWW-Authenticate"] = schemes + " realm=\"" + context.Listener.Realm + "\""; 184 | context.Response.OutputStream.Close (); 185 | IAsyncResult ares = context.Listener.BeginGetContext (cb, state); 186 | this.forward = (ListenerAsyncResult) ares; 187 | lock (forward.locker) { 188 | if (handle != null) 189 | forward.handle = handle; 190 | } 191 | 192 | ListenerAsyncResult next = forward; 193 | for (int i = 0; next.forward != null; i++) { 194 | if (i > 20) 195 | Complete (new HttpListenerException (400, "Too many authentication errors")); 196 | 197 | next = next.forward; 198 | } 199 | } else { 200 | completed = true; 201 | if (handle != null) 202 | handle.Set (); 203 | 204 | if (cb != null) 205 | //ThreadPool.UnsafeQueueUserWorkItem (InvokeCB, this); 206 | ThreadPool.QueueUserWorkItem (InvokeCB, this); 207 | } 208 | } 209 | } 210 | 211 | internal HttpListenerContext GetContext () 212 | { 213 | if (forward != null) 214 | return forward.GetContext (); 215 | 216 | if (exception != null) 217 | throw exception; 218 | 219 | return context; 220 | } 221 | 222 | #endregion 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/ListenerPrefix.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ListenerPrefix.cs 3 | // Copied from System.ListenerPrefix.cs 4 | // 5 | // Author: 6 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 7 | // Oleg Mihailik (mihailik gmail co_m) 8 | // 9 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | // Copyright (c) 2012-2013 sta.blockhead 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining 13 | // a copy of this software and associated documentation files (the 14 | // "Software"), to deal in the Software without restriction, including 15 | // without limitation the rights to use, copy, modify, merge, publish, 16 | // distribute, sublicense, and/or sell copies of the Software, and to 17 | // permit persons to whom the Software is furnished to do so, subject to 18 | // the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be 21 | // included in all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | // 31 | 32 | using System; 33 | using System.Net; 34 | 35 | namespace WebSocketSharp.Net 36 | { 37 | internal sealed class ListenerPrefix 38 | { 39 | #region Private Fields 40 | 41 | IPAddress [] _addresses; 42 | string _host; 43 | string _original; 44 | string _path; 45 | ushort _port; 46 | bool _secure; 47 | 48 | #endregion 49 | 50 | #region Public Fields 51 | 52 | public HttpListener Listener; 53 | 54 | #endregion 55 | 56 | #region Public Constructors 57 | 58 | // Must be called after calling ListenerPrefix.CheckUriPrefix. 59 | public ListenerPrefix (string uriPrefix) 60 | { 61 | _original = uriPrefix; 62 | parse (uriPrefix); 63 | } 64 | 65 | #endregion 66 | 67 | #region Public Properties 68 | 69 | public IPAddress [] Addresses { 70 | get { 71 | return _addresses; 72 | } 73 | 74 | set { 75 | _addresses = value; 76 | } 77 | } 78 | 79 | public string Host { 80 | get { 81 | return _host; 82 | } 83 | } 84 | 85 | public string Path { 86 | get { 87 | return _path; 88 | } 89 | } 90 | 91 | public int Port { 92 | get { 93 | return (int) _port; 94 | } 95 | } 96 | 97 | public bool Secure { 98 | get { 99 | return _secure; 100 | } 101 | } 102 | 103 | #endregion 104 | 105 | #region Private Methods 106 | 107 | private void parse (string uriPrefix) 108 | { 109 | int default_port = uriPrefix.StartsWith ("http://") ? 80 : 443; 110 | if (default_port == 443) 111 | _secure = true; 112 | 113 | int length = uriPrefix.Length; 114 | int start_host = uriPrefix.IndexOf (':') + 3; 115 | int colon = uriPrefix.IndexOf (':', start_host, length - start_host); 116 | int root; 117 | if (colon > 0) 118 | { 119 | root = uriPrefix.IndexOf ('/', colon, length - colon); 120 | _host = uriPrefix.Substring (start_host, colon - start_host); 121 | _port = (ushort) Int32.Parse (uriPrefix.Substring (colon + 1, root - colon - 1)); 122 | _path = uriPrefix.Substring (root); 123 | } 124 | else 125 | { 126 | root = uriPrefix.IndexOf ('/', start_host, length - start_host); 127 | _host = uriPrefix.Substring (start_host, root - start_host); 128 | _port = (ushort) default_port; 129 | _path = uriPrefix.Substring (root); 130 | } 131 | 132 | if (_path.Length != 1) 133 | _path = _path.Substring (0, _path.Length - 1); 134 | } 135 | 136 | #endregion 137 | 138 | #region public Methods 139 | 140 | public static void CheckUriPrefix (string uriPrefix) 141 | { 142 | if (uriPrefix == null) 143 | throw new ArgumentNullException ("uriPrefix"); 144 | 145 | int default_port = uriPrefix.StartsWith ("http://") ? 80 : -1; 146 | if (default_port == -1) 147 | default_port = uriPrefix.StartsWith ("https://") ? 443 : -1; 148 | 149 | if (default_port == -1) 150 | throw new ArgumentException ("Only 'http' and 'https' schemes are supported."); 151 | 152 | int length = uriPrefix.Length; 153 | int start_host = uriPrefix.IndexOf (':') + 3; 154 | if (start_host >= length) 155 | throw new ArgumentException ("No host specified."); 156 | 157 | int colon = uriPrefix.IndexOf (':', start_host, length - start_host); 158 | if (start_host == colon) 159 | throw new ArgumentException ("No host specified."); 160 | 161 | int root; 162 | if (colon > 0) 163 | { 164 | root = uriPrefix.IndexOf ('/', colon, length - colon); 165 | if (root == -1) 166 | throw new ArgumentException ("No path specified."); 167 | 168 | try { 169 | int port = Int32.Parse (uriPrefix.Substring (colon + 1, root - colon - 1)); 170 | if (port <= 0 || port >= 65536) 171 | throw new Exception (); 172 | } 173 | catch { 174 | throw new ArgumentException ("Invalid port."); 175 | } 176 | } 177 | else 178 | { 179 | root = uriPrefix.IndexOf ('/', start_host, length - start_host); 180 | if (root == -1) 181 | throw new ArgumentException ("No path specified."); 182 | } 183 | 184 | if (uriPrefix [uriPrefix.Length - 1] != '/') 185 | throw new ArgumentException ("The URI prefix must end with '/'."); 186 | } 187 | 188 | // Equals and GetHashCode are required to detect duplicates in HttpListenerPrefixCollection. 189 | public override bool Equals (object obj) 190 | { 191 | var other = obj as ListenerPrefix; 192 | if (other == null) 193 | return false; 194 | 195 | return _original == other._original; 196 | } 197 | 198 | public override int GetHashCode () 199 | { 200 | return _original.GetHashCode (); 201 | } 202 | 203 | public override string ToString () 204 | { 205 | return _original; 206 | } 207 | 208 | #endregion 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/RequestStream.cs: -------------------------------------------------------------------------------- 1 | // 2 | // RequestStream.cs 3 | // Copied from System.Net.RequestStream.cs 4 | // 5 | // Author: 6 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 7 | // 8 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.IO; 32 | using System.Runtime.InteropServices; 33 | 34 | namespace WebSocketSharp.Net { 35 | 36 | class RequestStream : Stream { 37 | 38 | #region Fields 39 | 40 | byte [] buffer; 41 | bool disposed; 42 | int length; 43 | int offset; 44 | long remaining_body; 45 | Stream stream; 46 | 47 | #endregion 48 | 49 | #region Constructors 50 | 51 | internal RequestStream (Stream stream, byte [] buffer, int offset, int length) 52 | : this (stream, buffer, offset, length, -1) 53 | { 54 | } 55 | 56 | internal RequestStream (Stream stream, byte [] buffer, int offset, int length, long contentlength) 57 | { 58 | this.stream = stream; 59 | this.buffer = buffer; 60 | this.offset = offset; 61 | this.length = length; 62 | this.remaining_body = contentlength; 63 | } 64 | 65 | #endregion 66 | 67 | #region Properties 68 | 69 | public override bool CanRead { 70 | get { return true; } 71 | } 72 | 73 | public override bool CanSeek { 74 | get { return false; } 75 | } 76 | 77 | public override bool CanWrite { 78 | get { return false; } 79 | } 80 | 81 | public override long Length { 82 | get { throw new NotSupportedException (); } 83 | } 84 | 85 | public override long Position { 86 | get { throw new NotSupportedException (); } 87 | set { throw new NotSupportedException (); } 88 | } 89 | 90 | #endregion 91 | 92 | #region Private Method 93 | 94 | // Returns 0 if we can keep reading from the base stream, 95 | // > 0 if we read something from the buffer. 96 | // -1 if we had a content length set and we finished reading that many bytes. 97 | int FillFromBuffer (byte [] buffer, int offset, int count) 98 | { 99 | if (buffer == null) 100 | throw new ArgumentNullException ("buffer"); 101 | 102 | if (offset < 0) 103 | throw new ArgumentOutOfRangeException ("offset", "< 0"); 104 | 105 | if (count < 0) 106 | throw new ArgumentOutOfRangeException ("count", "< 0"); 107 | 108 | int len = buffer.Length; 109 | if (offset > len) 110 | throw new ArgumentException ("Destination offset is beyond array size."); 111 | 112 | if (offset > len - count) 113 | throw new ArgumentException ("Reading would overrun buffer."); 114 | 115 | if (this.remaining_body == 0) 116 | return -1; 117 | 118 | if (this.length == 0) 119 | return 0; 120 | 121 | int size = Math.Min (this.length, count); 122 | if (this.remaining_body > 0) 123 | size = (int) Math.Min (size, this.remaining_body); 124 | 125 | if (this.offset > this.buffer.Length - size) { 126 | size = Math.Min (size, this.buffer.Length - this.offset); 127 | } 128 | 129 | if (size == 0) 130 | return 0; 131 | 132 | Buffer.BlockCopy (this.buffer, this.offset, buffer, offset, size); 133 | this.offset += size; 134 | this.length -= size; 135 | if (this.remaining_body > 0) 136 | remaining_body -= size; 137 | 138 | return size; 139 | } 140 | 141 | #endregion 142 | 143 | #region Public Methods 144 | 145 | public override IAsyncResult BeginRead ( 146 | byte [] buffer, int offset, int count, AsyncCallback cback, object state) 147 | { 148 | if (disposed) 149 | throw new ObjectDisposedException (GetType ().ToString ()); 150 | 151 | int nread = FillFromBuffer (buffer, offset, count); 152 | if (nread > 0 || nread == -1) { 153 | var ares = new HttpStreamAsyncResult (); 154 | ares.Buffer = buffer; 155 | ares.Offset = offset; 156 | ares.Count = count; 157 | ares.Callback = cback; 158 | ares.State = state; 159 | ares.SyncRead = nread; 160 | ares.Complete (); 161 | return ares; 162 | } 163 | 164 | // Avoid reading past the end of the request to allow 165 | // for HTTP pipelining 166 | if (remaining_body >= 0 && count > remaining_body) 167 | count = (int) Math.Min (Int32.MaxValue, remaining_body); 168 | 169 | return stream.BeginRead (buffer, offset, count, cback, state); 170 | } 171 | 172 | public override IAsyncResult BeginWrite ( 173 | byte [] buffer, int offset, int count, AsyncCallback cback, object state) 174 | { 175 | throw new NotSupportedException (); 176 | } 177 | 178 | public override void Close () 179 | { 180 | disposed = true; 181 | } 182 | 183 | public override int EndRead (IAsyncResult ares) 184 | { 185 | if (disposed) 186 | throw new ObjectDisposedException (GetType ().ToString ()); 187 | 188 | if (ares == null) 189 | throw new ArgumentNullException ("ares"); 190 | 191 | if (ares is HttpStreamAsyncResult) { 192 | var ares_ = (HttpStreamAsyncResult) ares; 193 | if (!ares.IsCompleted) 194 | ares.AsyncWaitHandle.WaitOne (); 195 | 196 | return ares_.SyncRead; 197 | } 198 | 199 | // Close on exception? 200 | int nread = stream.EndRead (ares); 201 | if (remaining_body > 0 && nread > 0) 202 | remaining_body -= nread; 203 | 204 | return nread; 205 | } 206 | 207 | public override void EndWrite (IAsyncResult async_result) 208 | { 209 | throw new NotSupportedException (); 210 | } 211 | 212 | public override void Flush () 213 | { 214 | } 215 | 216 | public override int Read ([In,Out] byte[] buffer, int offset, int count) 217 | { 218 | if (disposed) 219 | throw new ObjectDisposedException (GetType () .ToString ()); 220 | 221 | // Call FillFromBuffer to check for buffer boundaries even when remaining_body is 0 222 | int nread = FillFromBuffer (buffer, offset, count); 223 | if (nread == -1) { // No more bytes available (Content-Length) 224 | return 0; 225 | } else if (nread > 0) { 226 | return nread; 227 | } 228 | 229 | nread = stream.Read (buffer, offset, count); 230 | if (nread > 0 && remaining_body > 0) 231 | remaining_body -= nread; 232 | 233 | return nread; 234 | } 235 | 236 | public override long Seek (long offset, SeekOrigin origin) 237 | { 238 | throw new NotSupportedException (); 239 | } 240 | 241 | public override void SetLength (long value) 242 | { 243 | throw new NotSupportedException (); 244 | } 245 | 246 | public override void Write (byte[] buffer, int offset, int count) 247 | { 248 | throw new NotSupportedException (); 249 | } 250 | 251 | #endregion 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/ResponseStream.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ResponseStream.cs 3 | // Copied from System.Net.ResponseStream.cs 4 | // 5 | // Author: 6 | // Gonzalo Paniagua Javier (gonzalo@novell.com) 7 | // 8 | // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining 11 | // a copy of this software and associated documentation files (the 12 | // "Software"), to deal in the Software without restriction, including 13 | // without limitation the rights to use, copy, modify, merge, publish, 14 | // distribute, sublicense, and/or sell copies of the Software, and to 15 | // permit persons to whom the Software is furnished to do so, subject to 16 | // the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be 19 | // included in all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | // 29 | 30 | using System; 31 | using System.IO; 32 | using System.Net; 33 | using System.Net.Sockets; 34 | using System.Text; 35 | using System.Runtime.InteropServices; 36 | 37 | namespace WebSocketSharp.Net { 38 | 39 | // FIXME: Does this buffer the response until Close? 40 | // Update: we send a single packet for the first non-chunked Write 41 | // What happens when we set content-length to X and write X-1 bytes then close? 42 | // what if we don't set content-length at all? 43 | class ResponseStream : Stream { 44 | 45 | #region Private Static Field 46 | 47 | static byte [] crlf = new byte [] { 13, 10 }; 48 | 49 | #endregion 50 | 51 | #region Private Fields 52 | 53 | bool disposed; 54 | bool ignore_errors; 55 | HttpListenerResponse response; 56 | Stream stream; 57 | bool trailer_sent; 58 | 59 | #endregion 60 | 61 | #region Constructor 62 | 63 | internal ResponseStream (System.IO.Stream stream, HttpListenerResponse response, bool ignore_errors) 64 | { 65 | this.stream = stream; 66 | this.response = response; 67 | this.ignore_errors = ignore_errors; 68 | } 69 | 70 | #endregion 71 | 72 | #region Properties 73 | 74 | public override bool CanRead { 75 | get { return false; } 76 | } 77 | 78 | public override bool CanSeek { 79 | get { return false; } 80 | } 81 | 82 | public override bool CanWrite { 83 | get { return true; } 84 | } 85 | 86 | public override long Length { 87 | get { throw new NotSupportedException (); } 88 | } 89 | 90 | public override long Position { 91 | get { throw new NotSupportedException (); } 92 | set { throw new NotSupportedException (); } 93 | } 94 | 95 | #endregion 96 | 97 | #region Private Methods 98 | 99 | static byte [] GetChunkSizeBytes (int size, bool final) 100 | { 101 | string str = String.Format ("{0:x}\r\n{1}", size, final ? "\r\n" : ""); 102 | return Encoding.ASCII.GetBytes (str); 103 | } 104 | 105 | MemoryStream GetHeaders (bool closing) 106 | { 107 | if (response.HeadersSent) 108 | return null; 109 | 110 | MemoryStream ms = new MemoryStream (); 111 | response.SendHeaders (closing, ms); 112 | 113 | return ms; 114 | } 115 | 116 | #endregion 117 | 118 | #region Internal Method 119 | 120 | internal void InternalWrite (byte [] buffer, int offset, int count) 121 | { 122 | if (ignore_errors) { 123 | try { 124 | stream.Write (buffer, offset, count); 125 | } catch { 126 | } 127 | } else { 128 | stream.Write (buffer, offset, count); 129 | } 130 | } 131 | 132 | #endregion 133 | 134 | #region Public Methods 135 | 136 | public override IAsyncResult BeginRead ( 137 | byte [] buffer, 138 | int offset, 139 | int count, 140 | AsyncCallback cback, 141 | object state) 142 | { 143 | throw new NotSupportedException (); 144 | } 145 | 146 | public override IAsyncResult BeginWrite ( 147 | byte [] buffer, 148 | int offset, 149 | int count, 150 | AsyncCallback cback, 151 | object state) 152 | { 153 | if (disposed) 154 | throw new ObjectDisposedException (GetType ().ToString ()); 155 | 156 | byte [] bytes = null; 157 | MemoryStream ms = GetHeaders (false); 158 | bool chunked = response.SendChunked; 159 | if (ms != null) { 160 | long start = ms.Position; 161 | ms.Position = ms.Length; 162 | if (chunked) { 163 | bytes = GetChunkSizeBytes (count, false); 164 | ms.Write (bytes, 0, bytes.Length); 165 | } 166 | ms.Write (buffer, offset, count); 167 | buffer = ms.GetBuffer (); 168 | offset = (int) start; 169 | count = (int) (ms.Position - start); 170 | } else if (chunked) { 171 | bytes = GetChunkSizeBytes (count, false); 172 | InternalWrite (bytes, 0, bytes.Length); 173 | } 174 | 175 | return stream.BeginWrite (buffer, offset, count, cback, state); 176 | } 177 | 178 | public override void Close () 179 | { 180 | if (disposed == false) { 181 | disposed = true; 182 | byte [] bytes = null; 183 | MemoryStream ms = GetHeaders (true); 184 | bool chunked = response.SendChunked; 185 | if (ms != null) { 186 | long start = ms.Position; 187 | if (chunked && !trailer_sent) { 188 | bytes = GetChunkSizeBytes (0, true); 189 | ms.Position = ms.Length; 190 | ms.Write (bytes, 0, bytes.Length); 191 | } 192 | InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start)); 193 | trailer_sent = true; 194 | } else if (chunked && !trailer_sent) { 195 | bytes = GetChunkSizeBytes (0, true); 196 | InternalWrite (bytes, 0, bytes.Length); 197 | trailer_sent = true; 198 | } 199 | 200 | response.Close (); 201 | } 202 | } 203 | 204 | public override int EndRead (IAsyncResult ares) 205 | { 206 | throw new NotSupportedException (); 207 | } 208 | 209 | public override void EndWrite (IAsyncResult ares) 210 | { 211 | if (disposed) 212 | throw new ObjectDisposedException (GetType ().ToString ()); 213 | 214 | if (ignore_errors) { 215 | try { 216 | stream.EndWrite (ares); 217 | if (response.SendChunked) 218 | stream.Write (crlf, 0, 2); 219 | } catch { 220 | } 221 | } else { 222 | stream.EndWrite (ares); 223 | if (response.SendChunked) 224 | stream.Write (crlf, 0, 2); 225 | } 226 | } 227 | 228 | public override void Flush () 229 | { 230 | } 231 | 232 | public override int Read ([In,Out] byte[] buffer, int offset, int count) 233 | { 234 | throw new NotSupportedException (); 235 | } 236 | 237 | public override long Seek (long offset, SeekOrigin origin) 238 | { 239 | throw new NotSupportedException (); 240 | } 241 | 242 | public override void SetLength (long value) 243 | { 244 | throw new NotSupportedException (); 245 | } 246 | 247 | public override void Write (byte [] buffer, int offset, int count) 248 | { 249 | if (disposed) 250 | throw new ObjectDisposedException (GetType ().ToString ()); 251 | 252 | byte [] bytes = null; 253 | MemoryStream ms = GetHeaders (false); 254 | bool chunked = response.SendChunked; 255 | if (ms != null) { 256 | long start = ms.Position; // After the possible preamble for the encoding 257 | ms.Position = ms.Length; 258 | if (chunked) { 259 | bytes = GetChunkSizeBytes (count, false); 260 | ms.Write (bytes, 0, bytes.Length); 261 | } 262 | 263 | int new_count = Math.Min (count, 16384 - (int) ms.Position + (int) start); 264 | ms.Write (buffer, offset, new_count); 265 | count -= new_count; 266 | offset += new_count; 267 | InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start)); 268 | ms.SetLength (0); 269 | ms.Capacity = 0; // 'dispose' the buffer in ms. 270 | } else if (chunked) { 271 | bytes = GetChunkSizeBytes (count, false); 272 | InternalWrite (bytes, 0, bytes.Length); 273 | } 274 | 275 | if (count > 0) 276 | InternalWrite (buffer, offset, count); 277 | 278 | if (chunked) 279 | InternalWrite (crlf, 0, 2); 280 | } 281 | 282 | #endregion 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Net/Security/SslStream.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * SslStream.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Net.Security; 31 | using System.Net.Sockets; 32 | 33 | namespace WebSocketSharp.Net.Security { 34 | 35 | internal class SslStream : System.Net.Security.SslStream 36 | { 37 | #region Public Constructors 38 | 39 | public SslStream(NetworkStream innerStream) 40 | : base(innerStream) 41 | { 42 | } 43 | 44 | public SslStream(NetworkStream innerStream, bool leaveInnerStreamOpen) 45 | : base(innerStream, leaveInnerStreamOpen) 46 | { 47 | } 48 | 49 | public SslStream( 50 | NetworkStream innerStream, 51 | bool leaveInnerStreamOpen, 52 | RemoteCertificateValidationCallback userCertificateValidationCallback 53 | ) : base(innerStream, leaveInnerStreamOpen, userCertificateValidationCallback) 54 | { 55 | } 56 | 57 | public SslStream( 58 | NetworkStream innerStream, 59 | bool leaveInnerStreamOpen, 60 | RemoteCertificateValidationCallback userCertificateValidationCallback, 61 | LocalCertificateSelectionCallback userCertificateSelectionCallback 62 | ) : base( 63 | innerStream, 64 | leaveInnerStreamOpen, 65 | userCertificateValidationCallback, 66 | userCertificateSelectionCallback 67 | ) 68 | { 69 | } 70 | 71 | #endregion 72 | 73 | #region Public Properties 74 | 75 | public bool DataAvailable { 76 | get { 77 | return ((NetworkStream)InnerStream).DataAvailable; 78 | } 79 | } 80 | 81 | #endregion 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Opcode.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * Opcode.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | /// 34 | /// Contains the values of the opcodes that denotes the frame type of the WebSocket frame. 35 | /// 36 | /// 37 | /// The Opcode enumeration contains the values of the opcodes defined in 38 | /// RFC 6455 for the WebSocket protocol. 39 | /// 40 | public enum Opcode : byte 41 | { 42 | /// 43 | /// Equivalent to numeric value 0. Indicates a continuation frame. 44 | /// 45 | CONT = 0x0, 46 | /// 47 | /// Equivalent to numeric value 1. Indicates a text frame. 48 | /// 49 | TEXT = 0x1, 50 | /// 51 | /// Equivalent to numeric value 2. Indicates a binary frame. 52 | /// 53 | BINARY = 0x2, 54 | /// 55 | /// Equivalent to numeric value 8. Indicates a connection close frame. 56 | /// 57 | CLOSE = 0x8, 58 | /// 59 | /// Equivalent to numeric value 9. Indicates a ping frame. 60 | /// 61 | PING = 0x9, 62 | /// 63 | /// Equivalent to numeric value 10. Indicates a pong frame. 64 | /// 65 | PONG = 0xa 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/PayloadData.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * PayloadData.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Collections; 31 | using System.Collections.Generic; 32 | using System.IO; 33 | using System.Linq; 34 | using System.Text; 35 | 36 | namespace WebSocketSharp 37 | { 38 | internal class PayloadData : IEnumerable 39 | { 40 | #region Public Const Fields 41 | 42 | public const ulong MaxLength = long.MaxValue; 43 | 44 | #endregion 45 | 46 | #region Public Constructors 47 | 48 | public PayloadData () 49 | : this (new byte []{}) 50 | { 51 | } 52 | 53 | public PayloadData (byte [] appData) 54 | : this (new byte []{}, appData) 55 | { 56 | } 57 | 58 | public PayloadData (string appData) 59 | : this (Encoding.UTF8.GetBytes (appData)) 60 | { 61 | } 62 | 63 | public PayloadData (byte [] appData, bool masked) 64 | : this (new byte []{}, appData, masked) 65 | { 66 | } 67 | 68 | public PayloadData (byte [] extData, byte [] appData) 69 | : this (extData, appData, false) 70 | { 71 | } 72 | 73 | public PayloadData (byte [] extData, byte [] appData, bool masked) 74 | { 75 | if ((ulong) extData.LongLength + (ulong) appData.LongLength > MaxLength) 76 | throw new ArgumentOutOfRangeException ( 77 | "The length of 'extData' plus 'appData' must be less than MaxLength."); 78 | 79 | ExtensionData = extData; 80 | ApplicationData = appData; 81 | IsMasked = masked; 82 | } 83 | 84 | #endregion 85 | 86 | #region Internal Properties 87 | 88 | internal bool ContainsReservedCloseStatusCode { 89 | get { 90 | return ApplicationData.Length > 1 91 | ? ApplicationData.SubArray (0, 2).ToUInt16 (ByteOrder.BIG).IsReserved () 92 | : false; 93 | } 94 | } 95 | 96 | internal bool IsMasked { 97 | get; private set; 98 | } 99 | 100 | #endregion 101 | 102 | #region Public Properties 103 | 104 | public byte [] ExtensionData { 105 | get; private set; 106 | } 107 | 108 | public byte [] ApplicationData { 109 | get; private set; 110 | } 111 | 112 | public ulong Length { 113 | get { 114 | return (ulong) (ExtensionData.LongLength + ApplicationData.LongLength); 115 | } 116 | } 117 | 118 | #endregion 119 | 120 | #region Private Methods 121 | 122 | private static void mask (byte [] src, byte [] key) 123 | { 124 | for (long i = 0; i < src.LongLength; i++) 125 | src [i] = (byte) (src [i] ^ key [i % 4]); 126 | } 127 | 128 | #endregion 129 | 130 | #region Internal Methods 131 | 132 | #endregion 133 | 134 | #region Public Methods 135 | 136 | public IEnumerator GetEnumerator () 137 | { 138 | foreach (byte b in ExtensionData) 139 | yield return b; 140 | 141 | foreach (byte b in ApplicationData) 142 | yield return b; 143 | } 144 | 145 | public void Mask (byte [] maskingKey) 146 | { 147 | if (ExtensionData.LongLength > 0) 148 | mask (ExtensionData, maskingKey); 149 | 150 | if (ApplicationData.LongLength > 0) 151 | mask (ApplicationData, maskingKey); 152 | 153 | IsMasked = !IsMasked; 154 | } 155 | 156 | public byte [] ToByteArray () 157 | { 158 | return ExtensionData.LongLength > 0 159 | ? this.ToArray () 160 | : ApplicationData; 161 | } 162 | 163 | public override string ToString () 164 | { 165 | return BitConverter.ToString (ToByteArray ()); 166 | } 167 | 168 | #endregion 169 | 170 | #region Explicitly Implemented Interface Members 171 | 172 | IEnumerator IEnumerable.GetEnumerator () 173 | { 174 | return GetEnumerator (); 175 | } 176 | 177 | #endregion 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Rsv.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * Rsv.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | internal enum Rsv : byte 34 | { 35 | OFF = 0x0, 36 | ON = 0x1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Server/HttpRequestEventArgs.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * HttpRequestEventArgs.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using WebSocketSharp.Net; 31 | 32 | namespace WebSocketSharp.Server { 33 | 34 | /// 35 | /// Contains the event data associated with the HTTP request events of the class. 36 | /// 37 | /// 38 | /// An HTTP request event occurs when a instance receives an HTTP request. 39 | /// If you want to get the HTTP request objects, you should access the property. 40 | /// If you want to get the HTTP response objects to send, you should access the property. 41 | /// 42 | public class HttpRequestEventArgs : EventArgs 43 | { 44 | #region Internal Constructors 45 | 46 | internal HttpRequestEventArgs(HttpListenerContext context) 47 | { 48 | Request = context.Request; 49 | Response = context.Response; 50 | } 51 | 52 | #endregion 53 | 54 | #region Public Properties 55 | 56 | /// 57 | /// Gets the HTTP request objects sent from a client. 58 | /// 59 | /// 60 | /// A that contains the HTTP request objects. 61 | /// 62 | public HttpListenerRequest Request { get; private set; } 63 | 64 | /// 65 | /// Gets the HTTP response objects to send to the client in response to the client's request. 66 | /// 67 | /// 68 | /// A that contains the HTTP response objects. 69 | /// 70 | public HttpListenerResponse Response { get; private set; } 71 | 72 | #endregion 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Server/IWebSocketSession.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * IWebSocketSession.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using WebSocketSharp.Net.WebSockets; 31 | 32 | namespace WebSocketSharp.Server 33 | { 34 | /// 35 | /// Exposes the properties for the session to the WebSocket service. 36 | /// 37 | public interface IWebSocketSession 38 | { 39 | /// 40 | /// Gets the WebSocket connection request information. 41 | /// 42 | /// 43 | /// A that contains the WebSocket connection request information. 44 | /// 45 | WebSocketContext Context { get; } 46 | 47 | /// 48 | /// Gets the unique ID of the session to the WebSocket service. 49 | /// 50 | /// 51 | /// A that contains the unique ID of the session. 52 | /// 53 | string ID { get; } 54 | 55 | /// 56 | /// Gets the time that the session has been started. 57 | /// 58 | /// 59 | /// A that represents the time that the session has been started. 60 | /// 61 | DateTime StartTime { get; } 62 | 63 | /// 64 | /// Gets the state of the WebSocket connection. 65 | /// 66 | /// 67 | /// One of the values. 68 | /// 69 | WebSocketState State { get; } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Server/ServerState.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * ServerState.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp.Server 32 | { 33 | internal enum ServerState 34 | { 35 | READY, 36 | START, 37 | SHUTDOWN, 38 | STOP 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/Server/WebSocketServiceHost.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * WebSocketServiceHost.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | #region Contributors 30 | /* 31 | * Contributors: 32 | * Juan Manuel Lallana 33 | */ 34 | #endregion 35 | 36 | using System; 37 | using System.Collections.Generic; 38 | using WebSocketSharp.Net; 39 | using WebSocketSharp.Net.WebSockets; 40 | 41 | namespace WebSocketSharp.Server 42 | { 43 | /// 44 | /// Provides the methods and properties for the WebSocket service host. 45 | /// 46 | public abstract class WebSocketServiceHost 47 | { 48 | #region Protected Constructors 49 | 50 | /// 51 | /// Initializes a new instance of the class. 52 | /// 53 | protected WebSocketServiceHost () 54 | { 55 | } 56 | 57 | #endregion 58 | 59 | #region Public Properties 60 | 61 | /// 62 | /// Gets or sets a value indicating whether the WebSocket service host cleans up 63 | /// the inactive sessions periodically. 64 | /// 65 | /// 66 | /// true if the WebSocket service host cleans up the inactive sessions periodically; 67 | /// otherwise, false. 68 | /// 69 | public abstract bool KeepClean { get; set; } 70 | 71 | /// 72 | /// Gets the path to the WebSocket service managed by the WebSocket service host. 73 | /// 74 | /// 75 | /// A that contains an absolute path to the WebSocket service. 76 | /// 77 | public abstract string ServicePath { get; } 78 | 79 | /// 80 | /// Gets the number of the sessions to the WebSocket service. 81 | /// 82 | /// 83 | /// An that contains the session count. 84 | /// 85 | public abstract int SessionCount { get; } 86 | 87 | /// 88 | /// Gets the manager of the sessions to the WebSocket service. 89 | /// 90 | /// 91 | /// A that manages the sessions. 92 | /// 93 | public abstract WebSocketSessionManager Sessions { get; } 94 | 95 | #endregion 96 | 97 | #region Internal Methods 98 | 99 | /// 100 | /// Starts a new session to the WebSocket service using the specified . 101 | /// 102 | /// 103 | /// A that contains a WebSocket connection request objects. 104 | /// 105 | /// 106 | /// is . 107 | /// 108 | internal void StartSession (WebSocketContext context) 109 | { 110 | if (context == null) 111 | throw new ArgumentNullException ("context"); 112 | 113 | var session = CreateSession (); 114 | session.Start (context, Sessions); 115 | } 116 | 117 | #endregion 118 | 119 | #region Protected Methods 120 | 121 | /// 122 | /// Creates a new session to the WebSocket service. 123 | /// 124 | /// 125 | /// A instance that represents a new session. 126 | /// 127 | protected abstract WebSocketService CreateSession (); 128 | 129 | #endregion 130 | } 131 | 132 | /// 133 | /// Provides the methods and properties for the WebSocket service host. 134 | /// 135 | /// 136 | /// The type of the WebSocket service provided by the server. 137 | /// The T must inherit the class. 138 | /// 139 | internal class WebSocketServiceHost : WebSocketServiceHost 140 | where T : WebSocketService 141 | { 142 | #region Private Fields 143 | 144 | private Func _constructor; 145 | private string _path; 146 | private WebSocketSessionManager _sessions; 147 | 148 | #endregion 149 | 150 | #region Internal Constructors 151 | 152 | internal WebSocketServiceHost (string path, Func constructor, Logger logger) 153 | { 154 | _path = HttpUtility.UrlDecode (path).TrimEndSlash (); 155 | _constructor = constructor; 156 | _sessions = new WebSocketSessionManager (logger); 157 | } 158 | 159 | #endregion 160 | 161 | #region Public Properties 162 | 163 | /// 164 | /// Gets or sets a value indicating whether the WebSocket service host cleans up 165 | /// the inactive sessions periodically. 166 | /// 167 | /// 168 | /// true if the WebSocket service host cleans up the inactive sessions 169 | /// every 60 seconds; otherwise, false. The default value is true. 170 | /// 171 | public override bool KeepClean { 172 | get { 173 | return _sessions.KeepClean; 174 | } 175 | 176 | set { 177 | _sessions.KeepClean = value; 178 | } 179 | } 180 | 181 | /// 182 | /// Gets the path to the WebSocket service managed by the WebSocket service host. 183 | /// 184 | /// 185 | /// A that contains an absolute path to the WebSocket service. 186 | /// 187 | public override string ServicePath { 188 | get { 189 | return _path; 190 | } 191 | } 192 | 193 | /// 194 | /// Gets the number of the sessions to the WebSocket service. 195 | /// 196 | /// 197 | /// An that contains the session count. 198 | /// 199 | public override int SessionCount { 200 | get { 201 | return _sessions.Count; 202 | } 203 | } 204 | 205 | /// 206 | /// Gets the manager of the sessions to the WebSocket service. 207 | /// 208 | /// 209 | /// A that manages the sessions. 210 | /// 211 | public override WebSocketSessionManager Sessions { 212 | get { 213 | return _sessions; 214 | } 215 | } 216 | 217 | #endregion 218 | 219 | #region Protected Methods 220 | 221 | /// 222 | /// Creates a new session to the WebSocket service. 223 | /// 224 | /// 225 | /// A instance that represents a new session. 226 | /// 227 | protected override WebSocketService CreateSession () 228 | { 229 | return _constructor (); 230 | } 231 | 232 | #endregion 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/WebSocketException.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * WebSocketException.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2012-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp 32 | { 33 | /// 34 | /// Represents the exception that occurred when attempting to perform an operation 35 | /// on the WebSocket connection. 36 | /// 37 | public class WebSocketException : Exception 38 | { 39 | #region Internal Constructors 40 | 41 | internal WebSocketException () 42 | : this (CloseStatusCode.ABNORMAL) 43 | { 44 | } 45 | 46 | internal WebSocketException (CloseStatusCode code) 47 | : this (code, null) 48 | { 49 | } 50 | 51 | internal WebSocketException (string reason) 52 | : this (CloseStatusCode.ABNORMAL, reason) 53 | { 54 | } 55 | 56 | internal WebSocketException (CloseStatusCode code, string reason) 57 | : base (reason ?? code.GetMessage ()) 58 | { 59 | Code = code; 60 | } 61 | 62 | #endregion 63 | 64 | #region Public Properties 65 | 66 | /// 67 | /// Gets the associated with the . 68 | /// 69 | /// 70 | /// One of the values, indicates the causes of the . 71 | /// 72 | public CloseStatusCode Code { 73 | get; private set; 74 | } 75 | 76 | #endregion 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/WebSocketState.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * WebSocketState.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2010-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | /// 34 | /// Contains the values of the state of the WebSocket connection. 35 | /// 36 | /// 37 | /// The WebSocketState enumeration contains the values of the state of the WebSocket connection defined in 38 | /// The WebSocket API. 39 | /// 40 | public enum WebSocketState : ushort 41 | { 42 | /// 43 | /// Equivalent to numeric value 0. Indicates that the connection has not yet been established. 44 | /// 45 | CONNECTING = 0, 46 | /// 47 | /// Equivalent to numeric value 1. Indicates that the connection is established and the communication 48 | /// is possible. 49 | /// 50 | OPEN = 1, 51 | /// 52 | /// Equivalent to numeric value 2. Indicates that the connection is going through the closing handshake, 53 | /// or the WebSocket.Close method has been invoked. 54 | /// 55 | CLOSING = 2, 56 | /// 57 | /// Equivalent to numeric value 3. Indicates that the connection has been closed or could not be opened. 58 | /// 59 | CLOSED = 3 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/WsCredential.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * WsCredential.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | 31 | namespace WebSocketSharp { 32 | 33 | /// 34 | /// Provides the credentials for HTTP authentication (Basic/Digest). 35 | /// 36 | public class WsCredential { 37 | 38 | #region Private Fields 39 | 40 | string _domain; 41 | string _password; 42 | string _userName; 43 | 44 | #endregion 45 | 46 | #region Internal Constructors 47 | 48 | internal WsCredential() 49 | { 50 | } 51 | 52 | internal WsCredential(string userName, string password) 53 | : this(userName, password, null) 54 | { 55 | } 56 | 57 | internal WsCredential(string userName, string password, string domain) 58 | { 59 | _userName = userName; 60 | _password = password; 61 | _domain = domain; 62 | } 63 | 64 | #endregion 65 | 66 | #region Public Properties 67 | 68 | /// 69 | /// Gets the name of the user domain associated with the credentials. 70 | /// 71 | /// 72 | /// A that contains the name of the user domain associated with the credentials. 73 | /// Currently, returns the request uri of a WebSocket opening handshake. 74 | /// 75 | public string Domain { 76 | get { 77 | return _domain ?? String.Empty; 78 | } 79 | 80 | internal set { 81 | _domain = value; 82 | } 83 | } 84 | 85 | /// 86 | /// Gets the password for the user name associated with the credentials. 87 | /// 88 | /// 89 | /// A that contains the password for the user name associated with the credentials. 90 | /// 91 | public string Password { 92 | get { 93 | return _password ?? String.Empty; 94 | } 95 | 96 | internal set { 97 | _password = value; 98 | } 99 | } 100 | 101 | /// 102 | /// Gets the user name associated with the credentials. 103 | /// 104 | /// 105 | /// A that contains the user name associated with the credentials. 106 | /// 107 | public string UserName { 108 | get { 109 | return _userName ?? String.Empty; 110 | } 111 | 112 | internal set { 113 | _userName = value; 114 | } 115 | } 116 | 117 | #endregion 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/WsStream.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /* 3 | * WsStream.cs 4 | * 5 | * The MIT License 6 | * 7 | * Copyright (c) 2010-2013 sta.blockhead 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | #endregion 28 | 29 | using System; 30 | using System.Collections.Generic; 31 | using System.IO; 32 | using System.Net.Sockets; 33 | using System.Security.Cryptography.X509Certificates; 34 | using System.Text; 35 | using System.Threading; 36 | using WebSocketSharp.Net; 37 | using WebSocketSharp.Net.Security; 38 | 39 | namespace WebSocketSharp 40 | { 41 | internal class WsStream : IDisposable 42 | { 43 | #region Private Const Fields 44 | 45 | private const int _handshakeLimitLen = 8192; 46 | private const int _handshakeTimeout = 90000; 47 | 48 | #endregion 49 | 50 | #region Private Fields 51 | 52 | private object _forWrite; 53 | private Stream _innerStream; 54 | private bool _secure; 55 | 56 | #endregion 57 | 58 | #region Private Constructors 59 | 60 | private WsStream (Stream innerStream, bool secure) 61 | { 62 | _innerStream = innerStream; 63 | _secure = secure; 64 | _forWrite = new object (); 65 | } 66 | 67 | #endregion 68 | 69 | #region Internal Constructors 70 | 71 | internal WsStream (NetworkStream innerStream) 72 | : this (innerStream, false) 73 | { 74 | } 75 | 76 | internal WsStream (SslStream innerStream) 77 | : this (innerStream, true) 78 | { 79 | } 80 | 81 | #endregion 82 | 83 | #region Public Properties 84 | 85 | public bool DataAvailable { 86 | get { 87 | return _secure 88 | ? ((SslStream) _innerStream).DataAvailable 89 | : ((NetworkStream) _innerStream).DataAvailable; 90 | } 91 | } 92 | 93 | public bool IsSecure { 94 | get { 95 | return _secure; 96 | } 97 | } 98 | 99 | #endregion 100 | 101 | #region Internal Methods 102 | 103 | internal static WsStream CreateClientStream ( 104 | TcpClient client, 105 | bool secure, 106 | string host, 107 | System.Net.Security.RemoteCertificateValidationCallback validationCallback 108 | ) 109 | { 110 | var netStream = client.GetStream (); 111 | if (secure) 112 | { 113 | if (validationCallback == null) 114 | validationCallback = (sender, certificate, chain, sslPolicyErrors) => true; 115 | 116 | var sslStream = new SslStream (netStream, false, validationCallback); 117 | sslStream.AuthenticateAsClient (host); 118 | 119 | return new WsStream (sslStream); 120 | } 121 | 122 | return new WsStream (netStream); 123 | } 124 | 125 | internal static WsStream CreateServerStream (TcpClient client, bool secure, X509Certificate cert) 126 | { 127 | var netStream = client.GetStream (); 128 | if (secure) 129 | { 130 | var sslStream = new SslStream (netStream, false); 131 | sslStream.AuthenticateAsServer (cert); 132 | 133 | return new WsStream (sslStream); 134 | } 135 | 136 | return new WsStream (netStream); 137 | } 138 | 139 | internal static WsStream CreateServerStream (HttpListenerContext context) 140 | { 141 | var conn = context.Connection; 142 | return new WsStream (conn.Stream, conn.IsSecure); 143 | } 144 | 145 | internal bool Write (byte [] data) 146 | { 147 | lock (_forWrite) 148 | { 149 | try { 150 | _innerStream.Write (data, 0, data.Length); 151 | return true; 152 | } 153 | catch { 154 | return false; 155 | } 156 | } 157 | } 158 | 159 | #endregion 160 | 161 | #region Public Methods 162 | 163 | public void Close () 164 | { 165 | _innerStream.Close (); 166 | } 167 | 168 | public void Dispose () 169 | { 170 | _innerStream.Dispose (); 171 | } 172 | 173 | public WsFrame ReadFrame () 174 | { 175 | return WsFrame.Parse (_innerStream, true); 176 | } 177 | 178 | public void ReadFrameAsync (Action completed, Action error) 179 | { 180 | WsFrame.ParseAsync (_innerStream, true, completed, error); 181 | } 182 | 183 | public string [] ReadHandshake () 184 | { 185 | var read = false; 186 | var exception = false; 187 | 188 | var buffer = new List (); 189 | Action add = i => buffer.Add ((byte) i); 190 | 191 | var timeout = false; 192 | var timer = new Timer ( 193 | state => 194 | { 195 | timeout = true; 196 | _innerStream.Close (); 197 | }, 198 | null, 199 | _handshakeTimeout, 200 | -1); 201 | 202 | try { 203 | while (buffer.Count < _handshakeLimitLen) 204 | { 205 | if (_innerStream.ReadByte ().EqualsWith ('\r', add) && 206 | _innerStream.ReadByte ().EqualsWith ('\n', add) && 207 | _innerStream.ReadByte ().EqualsWith ('\r', add) && 208 | _innerStream.ReadByte ().EqualsWith ('\n', add)) 209 | { 210 | read = true; 211 | break; 212 | } 213 | } 214 | } 215 | catch { 216 | exception = true; 217 | } 218 | finally { 219 | timer.Change (-1, -1); 220 | timer.Dispose (); 221 | } 222 | 223 | var reason = timeout 224 | ? "A timeout has occurred while receiving a handshake." 225 | : exception 226 | ? "An exception has occurred while receiving a handshake." 227 | : !read 228 | ? "A handshake length is greater than the limit length." 229 | : null; 230 | 231 | if (reason != null) 232 | throw new WebSocketException (reason); 233 | 234 | return Encoding.UTF8.GetString (buffer.ToArray ()) 235 | .Replace ("\r\n", "\n") 236 | .Replace ("\n ", " ") 237 | .Replace ("\n\t", " ") 238 | .TrimEnd ('\n') 239 | .Split ('\n'); 240 | } 241 | 242 | public bool WriteFrame (WsFrame frame) 243 | { 244 | return Write (frame.ToByteArray ()); 245 | } 246 | 247 | public bool WriteHandshake (HandshakeBase handshake) 248 | { 249 | return Write (handshake.ToByteArray ()); 250 | } 251 | 252 | #endregion 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/doc/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore MonoDevelop build results. 2 | 3 | html 4 | mdoc 5 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/doc/doc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # @(#) doc.sh ver.0.0.2 2013.01.24 4 | # 5 | # Usage: 6 | # doc.sh 7 | # 8 | # Description: 9 | # Creating documentation for websocket-sharp. 10 | # 11 | ########################################################################### 12 | 13 | SRC_DIR="../bin/Release_Ubuntu" 14 | XML="${SRC_DIR}/websocket-sharp.xml" 15 | DLL="${SRC_DIR}/websocket-sharp.dll" 16 | 17 | DOC_DIR="." 18 | MDOC_DIR="${DOC_DIR}/mdoc" 19 | HTML_DIR="${DOC_DIR}/html" 20 | 21 | createDir() { 22 | if [ ! -d $1 ]; then 23 | mkdir -p $1 24 | fi 25 | } 26 | 27 | set -e 28 | createDir ${MDOC_DIR} 29 | createDir ${HTML_DIR} 30 | mdoc update --delete -fno-assembly-versions -i ${XML} -o ${MDOC_DIR}/ ${DLL} 31 | mdoc export-html -o ${HTML_DIR}/ ${MDOC_DIR}/ 32 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/websocket-sharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {B357BAC7-529E-4D81-A0D2-71041B19C8DE} 9 | Library 10 | WebSocketSharp 11 | websocket-sharp 12 | v3.5 13 | true 14 | websocket-sharp.snk 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug 21 | DEBUG 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | none 28 | false 29 | bin\Release 30 | prompt 31 | 4 32 | false 33 | 34 | 35 | true 36 | full 37 | false 38 | bin\Debug_Ubuntu 39 | DEBUG 40 | prompt 41 | 4 42 | false 43 | 44 | 45 | none 46 | false 47 | bin\Release_Ubuntu 48 | prompt 49 | 4 50 | false 51 | true 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /SocketIO/websocket-sharp/websocket-sharp.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaistseo/UnitySocketIO-WebSocketSharp/07724b3b58fa175a6201a9798cf85f0bd72fd308/SocketIO/websocket-sharp/websocket-sharp.snk --------------------------------------------------------------------------------