├── .gitignore ├── LICENSE.txt ├── README.md ├── SolutionSettings.StyleCop ├── WebSocketSharp.Tests ├── EnumerableStream.cs ├── Properties │ └── AssemblyInfo.cs ├── SecureWebSocketServerTests.cs ├── Settings.StyleCop ├── TestEchoService.cs ├── TestRadioService.cs ├── WebSocketServerTests.cs ├── WebSocketSharp.Tests.csproj ├── WebSocketStreamReaderTests.cs ├── WebSocketTests.cs └── packages.config ├── global.json ├── packages.config ├── packages └── repositories.config ├── websocket-sharp.clone ├── AsyncEx.cs ├── ByteOrder.cs ├── CloseEventArgs.cs ├── CloseStatusCode.cs ├── CompressionMethod.cs ├── ErrorEventArgs.cs ├── Ext.cs ├── Fin.cs ├── FragmentedMessage.cs ├── HttpBase.cs ├── HttpRequest.cs ├── HttpResponse.cs ├── Mask.cs ├── MessageEventArgs.cs ├── Net │ ├── AuthenticationBase.cs │ ├── AuthenticationChallenge.cs │ ├── AuthenticationResponse.cs │ ├── AuthenticationSchemes.cs │ ├── ClientSslConfiguration.cs │ ├── Cookie.cs │ ├── CookieCollection.cs │ ├── CookieException.cs │ ├── HttpBasicIdentity.cs │ ├── HttpDigestIdentity.cs │ ├── HttpHeaderInfo.cs │ ├── HttpHeaderType.cs │ ├── HttpStatusCode.cs │ ├── HttpUtility.cs │ ├── HttpVersion.cs │ ├── InputState.cs │ ├── LineState.cs │ ├── NetworkCredential.cs │ ├── QueryStringCollection.cs │ ├── ServerSslConfiguration.cs │ ├── SslConfiguration.cs │ ├── WebHeaderCollection.cs │ └── WebSockets │ │ ├── TcpListenerWebSocketContext.cs │ │ └── WebSocketContext.cs ├── Opcode.cs ├── PayloadData.cs ├── Properties │ └── AssemblyInfo.cs ├── Rsv.cs ├── Server │ ├── IWebSocketSession.cs │ ├── ServerState.cs │ ├── WebSocketBehavior.cs │ ├── WebSocketServer.cs │ ├── WebSocketServiceHost.cs │ ├── WebSocketServiceManager.cs │ └── WebSocketSessionManager.cs ├── Settings.StyleCop ├── StreamReadInfo.cs ├── SubStream.cs ├── WebSocket.cs ├── WebSocketDataStream.cs ├── WebSocketException.cs ├── WebSocketFrame.cs ├── WebSocketFrameHeader.cs ├── WebSocketMessage.cs ├── WebSocketSharp.csproj ├── WebSocketState.cs ├── WebSocketStreamReader.cs ├── doc │ ├── .gitignore │ └── doc.sh ├── project.json └── websocket-sharp.clone.xproj ├── websocket-sharp.ruleset ├── websocket-sharp.sln ├── websocket-sharp.sln.DotSettings ├── websocket-sharp.snk ├── websocket-sharp_icon.png └── websocket-sharp_logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore build results and temporary files. 2 | BuildOutput 3 | Backup* 4 | _UpgradeReport_Files 5 | [Bb]in 6 | [Oo]bj 7 | 8 | *.mdb 9 | *.pdb 10 | *.pidb 11 | *.suo 12 | *.user 13 | *.userprefs 14 | UpgradeLog*.* 15 | /packages 16 | TestResult.xml 17 | *.Cache 18 | *.db 19 | project.lock.json 20 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2010-2014 Reimers.dk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. -------------------------------------------------------------------------------- /WebSocketSharp.Tests/EnumerableStream.cs: -------------------------------------------------------------------------------- 1 | namespace WebSocketSharp.Tests 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | 7 | internal class EnumerableStream : Stream 8 | { 9 | private readonly IEnumerator _enumerator; 10 | 11 | public EnumerableStream(IEnumerable bytes) 12 | { 13 | _enumerator = bytes.GetEnumerator(); 14 | } 15 | 16 | public override void Flush() 17 | { 18 | } 19 | 20 | public override long Seek(long offset, SeekOrigin origin) 21 | { 22 | throw new NotSupportedException(); 23 | } 24 | 25 | public override void SetLength(long value) 26 | { 27 | throw new NotSupportedException(); 28 | } 29 | 30 | public override int Read(byte[] buffer, int offset, int count) 31 | { 32 | for (int i = 0; i < count; i++) 33 | { 34 | Position += 1; 35 | 36 | if (_enumerator.MoveNext()) 37 | { 38 | buffer[offset + i] = _enumerator.Current; 39 | } 40 | else 41 | { 42 | return i; 43 | } 44 | } 45 | 46 | return count; 47 | } 48 | 49 | public override void Write(byte[] buffer, int offset, int count) 50 | { 51 | throw new NotSupportedException(); 52 | } 53 | 54 | public override bool CanRead => true; 55 | 56 | public override bool CanSeek => false; 57 | 58 | public override bool CanWrite => false; 59 | 60 | public override long Length 61 | { 62 | get 63 | { 64 | throw new NotSupportedException(); 65 | } 66 | } 67 | 68 | public override long Position { get; set; } 69 | } 70 | } -------------------------------------------------------------------------------- /WebSocketSharp.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // AssemblyInfo.cs 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | using System.Reflection; 19 | using System.Runtime.InteropServices; 20 | 21 | // General Information about an assembly is controlled through the following 22 | // set of attributes. Change these attribute values to modify the information 23 | // associated with an assembly. 24 | [assembly: AssemblyTitle("WebSocketSharp.Tests")] 25 | [assembly: AssemblyDescription("")] 26 | [assembly: AssemblyConfiguration("")] 27 | [assembly: AssemblyCompany("Reimers.dk")] 28 | [assembly: AssemblyProduct("WebSocketSharp.Tests")] 29 | [assembly: AssemblyCopyright("Copyright © Reimers.dk 2014")] 30 | [assembly: AssemblyTrademark("")] 31 | [assembly: AssemblyCulture("")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | [assembly: ComVisible(false)] 37 | 38 | // The following GUID is for the ID of the typelib if this project is exposed to COM 39 | [assembly: Guid("d7b0ca47-dc92-4458-9718-ea96e8b85713")] 40 | 41 | // Version information for an assembly consists of the following four values: 42 | // 43 | // Major Version 44 | // Minor Version 45 | // Build Number 46 | // Revision 47 | // 48 | // You can specify all the values or you can default the Build and Revision Numbers 49 | // by using the '*' as shown below: 50 | // [assembly: AssemblyVersion("1.0.*")] 51 | [assembly: AssemblyVersion("1.0.2.0")] 52 | [assembly: AssemblyFileVersion("1.0.2.0")] 53 | -------------------------------------------------------------------------------- /WebSocketSharp.Tests/Settings.StyleCop: -------------------------------------------------------------------------------- 1 | 2 | 3 | Linked 4 | ..\SolutionSettings.StyleCop 5 | 6 | 7 | -------------------------------------------------------------------------------- /WebSocketSharp.Tests/TestEchoService.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the TestEchoService type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp.Tests 19 | { 20 | using System; 21 | using System.Threading.Tasks; 22 | 23 | using WebSocketSharp.Server; 24 | 25 | public class TestEchoService : WebSocketBehavior 26 | { 27 | protected override async Task OnMessage(MessageEventArgs e) 28 | { 29 | switch (e.Opcode) 30 | { 31 | case Opcode.Text: 32 | var text = await e.Text.ReadToEndAsync().ConfigureAwait(false); 33 | await Send(text).ConfigureAwait(false); 34 | return; 35 | case Opcode.Binary: 36 | await Send(e.Data).ConfigureAwait(false); 37 | return; 38 | case Opcode.Cont: 39 | case Opcode.Close: 40 | case Opcode.Ping: 41 | case Opcode.Pong: 42 | default: 43 | throw new ArgumentOutOfRangeException(); 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /WebSocketSharp.Tests/TestRadioService.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the TestRadioService type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp.Tests 19 | { 20 | using System; 21 | using System.Threading.Tasks; 22 | 23 | using WebSocketSharp.Server; 24 | 25 | public class TestRadioService : WebSocketBehavior 26 | { 27 | protected override async Task OnMessage(MessageEventArgs e) 28 | { 29 | switch (e.Opcode) 30 | { 31 | case Opcode.Text: 32 | var text = await e.Text.ReadToEndAsync().ConfigureAwait(false); 33 | await Sessions.Broadcast(text).ConfigureAwait(false); 34 | return; 35 | case Opcode.Binary: 36 | await Sessions.Broadcast(e.Data).ConfigureAwait(false); 37 | return; 38 | case Opcode.Cont: 39 | case Opcode.Close: 40 | case Opcode.Ping: 41 | case Opcode.Pong: 42 | return; 43 | default: 44 | throw new ArgumentOutOfRangeException(); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /WebSocketSharp.Tests/WebSocketSharp.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D24DD051-53FD-4567-B6AD-F6306E715E47} 8 | Library 9 | Properties 10 | WebSocketSharp.Tests 11 | WebSocketSharp.Tests 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | 36 | 37 | ..\websocket-sharp.snk 38 | 39 | 40 | 41 | ..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll 42 | True 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | {b357bac7-529e-4d81-a0d2-71041b19c8de} 64 | WebSocketSharp 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /WebSocketSharp.Tests/WebSocketStreamReaderTests.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the WebSocketStreamReaderTests type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp.Tests 19 | { 20 | using System; 21 | using System.IO; 22 | using System.Linq; 23 | using System.Threading; 24 | using System.Threading.Tasks; 25 | 26 | using NUnit.Framework; 27 | 28 | public class WebSocketStreamReaderTests 29 | { 30 | private WebSocketStreamReaderTests() 31 | { 32 | } 33 | 34 | [TestFixture] 35 | public class GivenAWebSocketStreamReader 36 | { 37 | private WebSocketStreamReader _sut; 38 | 39 | [SetUp] 40 | public async Task Setup() 41 | { 42 | var data1 = Enumerable.Repeat((byte)1, 1000).ToArray(); 43 | var frame1 = new WebSocketFrame(Fin.More, Opcode.Binary, data1, false, true); 44 | var data2 = Enumerable.Repeat((byte)2, 1000).ToArray(); 45 | var frame2 = new WebSocketFrame(Fin.Final, Opcode.Cont, data2, false, true); 46 | var frame3 = new WebSocketFrame(Fin.Final, Opcode.Close, new byte[0], false, true); 47 | var stream = new MemoryStream( 48 | (await frame1.ToByteArray().ConfigureAwait(false)) 49 | .Concat(await frame2.ToByteArray().ConfigureAwait(false)) 50 | .Concat(await frame3.ToByteArray().ConfigureAwait(false)) 51 | .ToArray()); 52 | _sut = new WebSocketStreamReader(stream, 100000); 53 | } 54 | 55 | [Test] 56 | public async Task WhenReadingMessageThenGetsAllFrames() 57 | { 58 | var msg = await _sut.Read(CancellationToken.None).ConfigureAwait(false); 59 | 60 | var buffer = new byte[2000]; 61 | var bytesRead = msg.RawData.Read(buffer, 0, 2000); 62 | 63 | var expected = Enumerable.Repeat((byte)1, 1000).Concat(Enumerable.Repeat((byte)2, 1000)).ToArray(); 64 | CollectionAssert.AreEqual(expected, buffer); 65 | } 66 | 67 | [Test] 68 | public async Task WhenMessageDataIsNotConsumedThenDoesNotGetSecondMessage() 69 | { 70 | using (var source = new CancellationTokenSource(TimeSpan.FromSeconds(1))) 71 | { 72 | var read = await _sut.Read(CancellationToken.None).ConfigureAwait(false); 73 | 74 | try 75 | { 76 | var x = await _sut.Read(source.Token).ConfigureAwait(false); 77 | } 78 | catch (OperationCanceledException) 79 | { 80 | Assert.Pass(); 81 | } 82 | catch (Exception x) 83 | { 84 | Assert.Fail("Did not expect " + x.GetType()); 85 | } 86 | } 87 | } 88 | 89 | [Test] 90 | public async Task WhenMessageDataIsConsumedThenGetsSecondMessage() 91 | { 92 | var count = 0; 93 | WebSocketMessage message = null; 94 | while ((message = await _sut.Read(default(CancellationToken)).ConfigureAwait(false)) != null) 95 | { 96 | await message.Consume().ConfigureAwait(false); 97 | count++; 98 | } 99 | 100 | Assert.AreEqual(2, count); 101 | } 102 | 103 | [Test] 104 | public async Task WhenReadCalledAfterCloseFrameThenReturnsNull() 105 | { 106 | WebSocketMessage message; 107 | while ((message = await _sut.Read(CancellationToken.None).ConfigureAwait(false)) != null) 108 | { 109 | await message.Consume().ConfigureAwait(false); 110 | } 111 | 112 | var second = await _sut.Read(default(CancellationToken)).ConfigureAwait(false); 113 | 114 | Assert.Null(second); 115 | } 116 | 117 | [Test] 118 | public async Task WhenReadingStreamWithPingsThenReadsAllData() 119 | { 120 | var data1 = Enumerable.Repeat((byte)1, 1000000).ToArray(); 121 | var frame1 = new WebSocketFrame(Fin.More, Opcode.Binary, data1, false, true); 122 | var data2 = Enumerable.Repeat((byte)2, 1000000).ToArray(); 123 | var frame2 = new WebSocketFrame(Fin.Final, Opcode.Cont, data2, false, true); 124 | var frame3 = new WebSocketFrame(Fin.Final, Opcode.Ping, new byte[0], false, true); 125 | var frame4 = new WebSocketFrame(Fin.Final, Opcode.Binary, data1, false, true); 126 | var frame5 = new WebSocketFrame(Fin.Final, Opcode.Ping, new byte[0], false, true); 127 | 128 | var stream = new MemoryStream( 129 | (await frame1.ToByteArray().ConfigureAwait(false)) 130 | .Concat(await frame2.ToByteArray().ConfigureAwait(false)) 131 | .Concat(await frame3.ToByteArray().ConfigureAwait(false)) 132 | .Concat(await frame4.ToByteArray().ConfigureAwait(false)) 133 | .Concat(await frame5.ToByteArray().ConfigureAwait(false)) 134 | .ToArray()); 135 | _sut = new WebSocketStreamReader(stream, 100000); 136 | 137 | int messages = 0; 138 | WebSocketMessage message; 139 | while ((message = await _sut.Read(CancellationToken.None).ConfigureAwait(false)) != null) 140 | { 141 | await message.Consume().ConfigureAwait(false); 142 | messages += 1; 143 | } 144 | 145 | Assert.AreEqual(4, messages); 146 | } 147 | 148 | [Test] 149 | public async Task WhenReadingStreamWithCompressedFramesAndPingsThenReadsAllData() 150 | { 151 | var data1 = new MemoryStream(Enumerable.Repeat((byte)1, 1000000).ToArray()); 152 | var frame1Compressed = await (await data1.Compress().ConfigureAwait(false)).ToByteArray().ConfigureAwait(false); 153 | var frame1 = new WebSocketFrame(Fin.More, Opcode.Binary, frame1Compressed, false, true); 154 | var data2 = new MemoryStream(Enumerable.Repeat((byte)2, 1000000).ToArray()); 155 | var frame2Compressed = await (await data2.Compress().ConfigureAwait(false)).ToByteArray().ConfigureAwait(false); 156 | var frame2 = new WebSocketFrame(Fin.Final, Opcode.Cont, frame2Compressed, false, true); 157 | var frame3 = new WebSocketFrame(Fin.Final, Opcode.Ping, new byte[0], false, true); 158 | var frame4 = new WebSocketFrame(Fin.Final, Opcode.Binary, frame1Compressed, false, true); 159 | var frame5 = new WebSocketFrame(Fin.Final, Opcode.Ping, new byte[0], false, true); 160 | 161 | var stream = new MemoryStream( 162 | (await frame1.ToByteArray().ConfigureAwait(false)) 163 | .Concat(await frame2.ToByteArray().ConfigureAwait(false)) 164 | .Concat(await frame3.ToByteArray().ConfigureAwait(false)) 165 | .Concat(await frame4.ToByteArray().ConfigureAwait(false)) 166 | .Concat(await frame5.ToByteArray().ConfigureAwait(false)) 167 | .ToArray()); 168 | _sut = new WebSocketStreamReader(stream, 100000); 169 | 170 | int messages = 0; 171 | WebSocketMessage message; 172 | while ((message = await _sut.Read(CancellationToken.None).ConfigureAwait(false)) != null) 173 | { 174 | await message.Consume().ConfigureAwait(false); 175 | messages += 1; 176 | } 177 | 178 | 179 | Assert.AreEqual(4, messages); 180 | } 181 | } 182 | } 183 | } -------------------------------------------------------------------------------- /WebSocketSharp.Tests/WebSocketTests.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the WebSocketTests type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp.Tests 19 | { 20 | using System; 21 | using System.Threading; 22 | using System.Threading.Tasks; 23 | 24 | using NUnit.Framework; 25 | 26 | public class WebSocketTests 27 | { 28 | public class GivenAWebSocket 29 | { 30 | private WebSocket _sut; 31 | 32 | [SetUp] 33 | public void Setup() 34 | { 35 | _sut = new WebSocket("ws://echo.websocket.org", onError: PrintError); 36 | } 37 | 38 | [TearDown] 39 | public void Teardown() 40 | { 41 | if (_sut.ReadyState != WebSocketState.Closed) 42 | { 43 | _sut.Dispose(); 44 | } 45 | } 46 | 47 | [Test] 48 | public async Task WhenClosingThenCloses() 49 | { 50 | await _sut.Close().ConfigureAwait(false); 51 | 52 | Assert.AreEqual(WebSocketState.Closed, _sut.ReadyState); 53 | } 54 | 55 | [Test] 56 | public async Task WhenSendingMessageThenReceivesEcho() 57 | { 58 | var waitHandle = new ManualResetEventSlim(false); 59 | const string Message = "Test Ping"; 60 | var echoReceived = false; 61 | Func onMessage = async e => 62 | { 63 | var readToEnd = await e.Text.ReadToEndAsync().ConfigureAwait(false); 64 | echoReceived = readToEnd == Message; 65 | waitHandle.Set(); 66 | }; 67 | _sut = new WebSocket("ws://echo.websocket.org", onError: PrintError, onMessage: onMessage); 68 | var connected = await _sut.Connect().ConfigureAwait(false); 69 | Console.WriteLine("Connected: " + connected); 70 | 71 | var sent = await _sut.Send(Message).ConfigureAwait(false); 72 | Console.WriteLine("Sent: " + sent); 73 | 74 | var result = waitHandle.Wait(2000); 75 | 76 | Assert.True(result && echoReceived); 77 | } 78 | 79 | [Test] 80 | public async Task WhenConnectingToAddressThenConnects() 81 | { 82 | var connected = await _sut.Connect().ConfigureAwait(false); 83 | Assert.IsTrue(_sut.ReadyState == WebSocketState.Open); 84 | } 85 | 86 | private Task PrintError(ErrorEventArgs e) 87 | { 88 | Console.WriteLine(e.Message); 89 | return AsyncEx.Completed(); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /WebSocketSharp.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "1.0.0-rc2-16357", 4 | "runtime": "clr", 5 | "architecture": "x64" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /websocket-sharp.clone/AsyncEx.cs: -------------------------------------------------------------------------------- 1 | namespace WebSocketSharp 2 | { 3 | using System.Threading.Tasks; 4 | 5 | internal static class AsyncEx 6 | { 7 | public static Task Completed() 8 | { 9 | return Task.FromResult(0); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/ByteOrder.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ByteOrder.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | /// 30 | /// Contains the values that indicate whether the byte order is a Little-endian or Big-endian. 31 | /// 32 | public enum ByteOrder : byte 33 | { 34 | /// 35 | /// Indicates a Little-endian. 36 | /// 37 | Little, 38 | /// 39 | /// Indicates a Big-endian. 40 | /// 41 | Big 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /websocket-sharp.clone/CloseEventArgs.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * CloseEventArgs.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | 31 | /// 32 | /// Contains the event data associated with a event. 33 | /// 34 | /// 35 | /// 36 | /// A event occurs when the WebSocket connection has been 37 | /// closed. 38 | /// 39 | /// 40 | /// If you would like to get the reason for the close, you should access 41 | /// the or property. 42 | /// 43 | /// 44 | public class CloseEventArgs : EventArgs 45 | { 46 | private readonly byte[] _rawData; 47 | 48 | private PayloadData _payloadData; 49 | 50 | internal CloseEventArgs() 51 | { 52 | _payloadData = new PayloadData(); 53 | _rawData = _payloadData.ApplicationData; 54 | } 55 | 56 | private CloseEventArgs(ushort code) 57 | { 58 | _rawData = code.InternalToByteArray(ByteOrder.Big); 59 | } 60 | 61 | internal CloseEventArgs(CloseStatusCode code) 62 | : this((ushort)code) 63 | { 64 | } 65 | 66 | internal CloseEventArgs(PayloadData payloadData) 67 | { 68 | _payloadData = payloadData; 69 | _rawData = payloadData.ApplicationData; 70 | } 71 | 72 | internal CloseEventArgs(ushort code, string reason) 73 | { 74 | _rawData = code.Append(reason); 75 | } 76 | 77 | internal CloseEventArgs(CloseStatusCode code, string reason) 78 | : this((ushort)code, reason) 79 | { 80 | } 81 | 82 | internal PayloadData PayloadData => _payloadData ?? (_payloadData = new PayloadData(_rawData)); 83 | 84 | internal byte[] RawData => _rawData; 85 | 86 | /// 87 | /// Gets a value indicating whether the WebSocket connection has been closed cleanly. 88 | /// 89 | /// 90 | /// true if the WebSocket connection has been closed cleanly; otherwise, false. 91 | /// 92 | public bool WasClean { get; internal set; } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /websocket-sharp.clone/CloseStatusCode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * CloseStatusCode.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | /// 30 | /// Contains the values of the status code for the WebSocket connection close. 31 | /// 32 | /// 33 | /// 34 | /// The values of the status code are defined in 35 | /// Section 7.4 36 | /// of RFC 6455. 37 | /// 38 | /// 39 | /// "Reserved value" must not be set as a status code in a close control frame 40 | /// by an endpoint. It's designated for use in applications expecting a status 41 | /// code to indicate that the connection was closed due to the system grounds. 42 | /// 43 | /// 44 | public enum CloseStatusCode : ushort 45 | { 46 | /// 47 | /// Equivalent to close status 1000. 48 | /// Indicates a normal close. 49 | /// 50 | Normal = 1000, 51 | 52 | /// 53 | /// Equivalent to close status 1001. 54 | /// Indicates that an endpoint is going away. 55 | /// 56 | Away = 1001, 57 | 58 | /// 59 | /// Equivalent to close status 1002. 60 | /// Indicates that an endpoint is terminating the connection due to a protocol error. 61 | /// 62 | ProtocolError = 1002, 63 | 64 | /// 65 | /// Equivalent to close status 1003. 66 | /// Indicates that an endpoint is terminating the connection because it has received 67 | /// an unacceptable type message. 68 | /// 69 | IncorrectData = 1003, 70 | 71 | /// 72 | /// Equivalent to close status 1004. 73 | /// Still undefined. A Reserved value. 74 | /// 75 | Undefined = 1004, 76 | 77 | /// 78 | /// Equivalent to close status 1005. 79 | /// Indicates that no status code was actually present. A Reserved value. 80 | /// 81 | NoStatusCode = 1005, 82 | 83 | /// 84 | /// Equivalent to close status 1006. 85 | /// Indicates that the connection was closed abnormally. A Reserved value. 86 | /// 87 | Abnormal = 1006, 88 | 89 | /// 90 | /// Equivalent to close status 1007. 91 | /// Indicates that an endpoint is terminating the connection because it has received 92 | /// a message that contains a data that isn't consistent with the type of the message. 93 | /// 94 | InconsistentData = 1007, 95 | 96 | /// 97 | /// Equivalent to close status 1008. 98 | /// Indicates that an endpoint is terminating the connection because it has received 99 | /// a message that violates its policy. 100 | /// 101 | PolicyViolation = 1008, 102 | 103 | /// 104 | /// Equivalent to close status 1009. 105 | /// Indicates that an endpoint is terminating the connection because it has received 106 | /// a message that is too big to process. 107 | /// 108 | TooBig = 1009, 109 | 110 | /// 111 | /// Equivalent to close status 1010. 112 | /// Indicates that the client is terminating the connection because it has expected 113 | /// the server to negotiate one or more extension, but the server didn't return them 114 | /// in the handshake response. 115 | /// 116 | IgnoreExtension = 1010, 117 | 118 | /// 119 | /// Equivalent to close status 1011. 120 | /// Indicates that the server is terminating the connection because it has encountered 121 | /// an unexpected condition that prevented it from fulfilling the request. 122 | /// 123 | ServerError = 1011, 124 | 125 | /// 126 | /// Equivalent to close status 1015. 127 | /// Indicates that the connection was closed due to a failure to perform a TLS handshake. 128 | /// A Reserved value. 129 | /// 130 | TlsHandshakeFailure = 1015 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /websocket-sharp.clone/CompressionMethod.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * CompressionMethod.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | /// Contains the values of the compression method used to compress the message on the WebSocket connection. 30 | /// The values of the compression method are defined in Compression Extensions for WebSocket. 31 | public enum CompressionMethod : byte 32 | { 33 | /// 34 | /// Indicates non compression. 35 | /// 36 | None, 37 | 38 | /// 39 | /// Indicates using DEFLATE. 40 | /// 41 | Deflate 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /websocket-sharp.clone/ErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ErrorEventArgs.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Contributors: 29 | * - Frank Razenberg 30 | */ 31 | 32 | namespace WebSocketSharp 33 | { 34 | using System; 35 | 36 | /// 37 | /// Contains the event data associated with a event. 38 | /// 39 | /// 40 | /// 41 | /// A event occurs when the gets 42 | /// an error. 43 | /// 44 | /// 45 | /// If you would like to get the error message, you should access 46 | /// the property. 47 | /// 48 | /// 49 | /// And if the error is due to an exception, you can get the 50 | /// instance by accessing the property. 51 | /// 52 | /// 53 | public class ErrorEventArgs : EventArgs 54 | { 55 | internal ErrorEventArgs(string message, Exception exception) 56 | { 57 | Message = message; 58 | Exception = exception; 59 | } 60 | 61 | /// 62 | /// Gets the instance that caused the error. 63 | /// 64 | /// 65 | /// An instance that represents the cause of the error, 66 | /// or if the error isn't due to an exception. 67 | /// 68 | public Exception Exception { get; } 69 | 70 | /// 71 | /// Gets the error message. 72 | /// 73 | /// 74 | /// A that represents the error message. 75 | /// 76 | public string Message { get; } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Fin.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Fin.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | internal enum Fin : byte 30 | { 31 | More = 0x0, 32 | Final = 0x1 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /websocket-sharp.clone/FragmentedMessage.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the FragmentedMessage type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp 19 | { 20 | using System; 21 | using System.IO; 22 | using System.Threading; 23 | using System.Threading.Tasks; 24 | 25 | internal class FragmentedMessage : WebSocketMessage 26 | { 27 | private readonly Stream _stream; 28 | 29 | public FragmentedMessage(Opcode opcode, Stream stream, StreamReadInfo initialRead, Func> payloadFunc, SemaphoreSlim waitHandle, int fragmentLength) 30 | : base(opcode, waitHandle, fragmentLength) 31 | { 32 | _stream = new WebSocketDataStream(stream, initialRead, payloadFunc, Consume); 33 | Text = new StreamReader(_stream, true); 34 | } 35 | 36 | public override Stream RawData => _stream; 37 | 38 | public override StreamReader Text { get; } 39 | } 40 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/HttpBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpBase.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | using System.Collections.Generic; 31 | using System.Collections.Specialized; 32 | using System.IO; 33 | using System.Text; 34 | using System.Threading; 35 | using System.Threading.Tasks; 36 | 37 | using WebSocketSharp.Net; 38 | 39 | internal abstract class HttpBase 40 | { 41 | private const int HeadersMaxLength = 8192; 42 | 43 | internal byte[] EntityBodyData; 44 | 45 | protected const string CrLf = "\r\n"; 46 | 47 | protected HttpBase(Version version, NameValueCollection headers) 48 | { 49 | ProtocolVersion = version; 50 | Headers = headers; 51 | } 52 | 53 | public string EntityBody 54 | { 55 | get 56 | { 57 | if (EntityBodyData == null || EntityBodyData.Length == 0) 58 | { 59 | return string.Empty; 60 | } 61 | 62 | Encoding enc = null; 63 | 64 | var contentType = Headers["Content-Type"]; 65 | if (!string.IsNullOrEmpty(contentType)) 66 | { 67 | enc = HttpUtility.GetEncoding(contentType); 68 | } 69 | 70 | return (enc ?? Encoding.UTF8).GetString(EntityBodyData, 0, EntityBodyData.Length); 71 | } 72 | } 73 | 74 | public NameValueCollection Headers { get; } 75 | 76 | public Version ProtocolVersion { get; } 77 | 78 | private static async Task ReadEntityBody(Stream stream, string length) 79 | { 80 | long len; 81 | if (!Int64.TryParse(length, out len)) 82 | { 83 | throw new ArgumentException("Cannot be parsed.", nameof(length)); 84 | } 85 | 86 | if (len < 0) 87 | { 88 | throw new ArgumentOutOfRangeException(nameof(length), "Less than zero."); 89 | } 90 | 91 | return len > 1024 92 | ? await stream.ReadBytes(len, 1024).ConfigureAwait(false) 93 | : len > 0 94 | ? await stream.ReadBytes((int)len).ConfigureAwait(false) 95 | : null; 96 | } 97 | 98 | private static string[] ReadHeaders(Stream stream, int maxLength) 99 | { 100 | var buff = new List(); 101 | var cnt = 0; 102 | Action add = i => 103 | { 104 | buff.Add((byte)i); 105 | cnt++; 106 | }; 107 | 108 | var read = false; 109 | while (cnt < maxLength) 110 | { 111 | if (stream.ReadByte().EqualsWith('\r', add) && 112 | stream.ReadByte().EqualsWith('\n', add) && 113 | stream.ReadByte().EqualsWith('\r', add) && 114 | stream.ReadByte().EqualsWith('\n', add)) 115 | { 116 | read = true; 117 | break; 118 | } 119 | } 120 | 121 | if (!read) 122 | { 123 | throw new WebSocketException("The length of header part is greater than the max length."); 124 | } 125 | 126 | var array = buff.ToArray(); 127 | return Encoding.UTF8.GetString(array, 0, array.Length) 128 | .Replace(CrLf + " ", " ") 129 | .Replace(CrLf + "\t", " ") 130 | .Split(new[] { CrLf }, StringSplitOptions.RemoveEmptyEntries); 131 | } 132 | 133 | protected static async Task Read(Stream stream, Func parser, int millisecondsTimeout) 134 | where T : HttpBase 135 | { 136 | var timeout = false; 137 | var timer = new Timer( 138 | state => 139 | { 140 | timeout = true; 141 | stream.Close(); 142 | }, 143 | null, 144 | millisecondsTimeout, 145 | -1); 146 | 147 | T http = null; 148 | Exception exception = null; 149 | try 150 | { 151 | http = parser(ReadHeaders(stream, HeadersMaxLength)); 152 | var contentLen = http.Headers["Content-Length"]; 153 | if (!string.IsNullOrEmpty(contentLen)) 154 | { 155 | http.EntityBodyData = await ReadEntityBody(stream, contentLen).ConfigureAwait(false); 156 | } 157 | } 158 | catch (Exception ex) 159 | { 160 | exception = ex; 161 | } 162 | finally 163 | { 164 | timer.Change(-1, -1); 165 | timer.Dispose(); 166 | } 167 | 168 | var msg = timeout 169 | ? "A timeout has occurred while reading an HTTP request/response." 170 | : exception != null 171 | ? "An exception has occurred while reading an HTTP request/response." 172 | : null; 173 | 174 | if (msg != null) 175 | { 176 | throw new WebSocketException(msg, exception); 177 | } 178 | 179 | return http; 180 | } 181 | 182 | public byte[] ToByteArray() 183 | { 184 | return Encoding.UTF8.GetBytes(ToString()); 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /websocket-sharp.clone/HttpRequest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpRequest.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | using System.Collections.Specialized; 31 | using System.IO; 32 | using System.Linq; 33 | using System.Text; 34 | using System.Threading.Tasks; 35 | 36 | using WebSocketSharp.Net; 37 | 38 | internal class HttpRequest : HttpBase 39 | { 40 | private string _method; 41 | private string _uri; 42 | private bool _websocketRequest; 43 | private bool _websocketRequestWasSet; 44 | 45 | private HttpRequest(string method, string uri, Version version, NameValueCollection headers) 46 | : base(version, headers) 47 | { 48 | _method = method; 49 | _uri = uri; 50 | } 51 | 52 | internal HttpRequest(string method, string uri) 53 | : this(method, uri, HttpVersion.Version11, new NameValueCollection()) 54 | { 55 | Headers["User-Agent"] = "websocket-sharp/1.0"; 56 | } 57 | 58 | public AuthenticationResponse AuthenticationResponse 59 | { 60 | get 61 | { 62 | var res = Headers["Authorization"]; 63 | return !string.IsNullOrEmpty(res) 64 | ? AuthenticationResponse.Parse(res) 65 | : null; 66 | } 67 | } 68 | 69 | public CookieCollection Cookies => Headers.GetCookies(false); 70 | 71 | public string HttpMethod => _method; 72 | 73 | public bool IsWebSocketRequest 74 | { 75 | get 76 | { 77 | if (!_websocketRequestWasSet) 78 | { 79 | var headers = Headers; 80 | _websocketRequest = _method == "GET" && 81 | ProtocolVersion > HttpVersion.Version10 && 82 | headers.Contains("Upgrade", "websocket") && 83 | headers.Contains("Connection", "Upgrade"); 84 | 85 | _websocketRequestWasSet = true; 86 | } 87 | 88 | return _websocketRequest; 89 | } 90 | } 91 | 92 | public string RequestUri => _uri; 93 | 94 | internal static HttpRequest CreateConnectRequest(Uri uri) 95 | { 96 | var host = uri.DnsSafeHost; 97 | var port = uri.Port; 98 | var authority = string.Format("{0}:{1}", host, port); 99 | var req = new HttpRequest("CONNECT", authority); 100 | req.Headers["Host"] = port == 80 ? host : authority; 101 | 102 | return req; 103 | } 104 | 105 | internal static HttpRequest CreateWebSocketRequest(Uri uri) 106 | { 107 | var req = new HttpRequest("GET", uri.PathAndQuery); 108 | 109 | var headers = req.Headers; 110 | headers["Upgrade"] = "websocket"; 111 | headers["Connection"] = "Upgrade"; 112 | headers["Host"] = uri.Port == 80 ? uri.DnsSafeHost : uri.Authority; 113 | 114 | return req; 115 | } 116 | 117 | internal async Task GetResponse(Stream stream, int millisecondsTimeout) 118 | { 119 | var buff = ToByteArray(); 120 | await stream.WriteAsync(buff, 0, buff.Length).ConfigureAwait(false); 121 | 122 | return await Read(stream, HttpResponse.Parse, millisecondsTimeout).ConfigureAwait(false); 123 | } 124 | 125 | private static HttpRequest Parse(string[] headerParts) 126 | { 127 | var requestLine = headerParts[0].Split(new[] { ' ' }, 3); 128 | if (requestLine.Length != 3) 129 | throw new ArgumentException("Invalid request line: " + headerParts[0]); 130 | 131 | var headers = new WebHeaderCollection(); 132 | for (int i = 1; i < headerParts.Length; i++) 133 | { 134 | headers.InternalSet(headerParts[i], false); 135 | } 136 | 137 | return new HttpRequest(requestLine[0], requestLine[1], new Version(requestLine[2].Substring(5)), headers); 138 | } 139 | 140 | internal static Task Read(Stream stream, int millisecondsTimeout) 141 | { 142 | return Read(stream, Parse, millisecondsTimeout); 143 | } 144 | 145 | public void SetCookies(CookieCollection cookies) 146 | { 147 | if (cookies == null || cookies.Count == 0) 148 | { 149 | return; 150 | } 151 | 152 | var nonExpired = cookies.Sorted.Where(c => !c.Expired).ToArray(); 153 | if (nonExpired.Any()) 154 | { 155 | Headers["Cookie"] = string.Join("; ", nonExpired.Select(c => c.ToRequestString(null))); 156 | } 157 | } 158 | 159 | public override string ToString() 160 | { 161 | var output = new StringBuilder(64); 162 | output.AppendFormat("{0} {1} HTTP/{2}{3}", _method, _uri, ProtocolVersion, CrLf); 163 | 164 | var headers = Headers; 165 | foreach (var key in headers.AllKeys) 166 | output.AppendFormat("{0}: {1}{2}", key, headers[key], CrLf); 167 | 168 | output.Append(CrLf); 169 | 170 | var entity = EntityBody; 171 | if (entity.Length > 0) 172 | output.Append(entity); 173 | 174 | return output.ToString(); 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /websocket-sharp.clone/HttpResponse.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpResponse.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | using System.Collections.Specialized; 31 | using System.Text; 32 | 33 | using WebSocketSharp.Net; 34 | 35 | internal class HttpResponse : HttpBase 36 | { 37 | private readonly string _code; 38 | private readonly string _reason; 39 | 40 | private HttpResponse(string code, string reason, Version version, NameValueCollection headers) 41 | : base(version, headers) 42 | { 43 | _code = code; 44 | _reason = reason; 45 | } 46 | 47 | internal HttpResponse(HttpStatusCode code) 48 | : this(code, code.GetDescription()) 49 | { 50 | } 51 | 52 | internal HttpResponse(HttpStatusCode code, string reason) 53 | : this(((int)code).ToString(), reason, HttpVersion.Version11, new NameValueCollection()) 54 | { 55 | Headers["Server"] = "websocket-sharp/1.0"; 56 | } 57 | 58 | public AuthenticationChallenge AuthenticationChallenge 59 | { 60 | get 61 | { 62 | var chal = Headers["WWW-Authenticate"]; 63 | return chal != null && chal.Length > 0 64 | ? AuthenticationChallenge.Parse(chal) 65 | : null; 66 | } 67 | } 68 | 69 | public CookieCollection Cookies => Headers.GetCookies(true); 70 | 71 | public bool IsProxyAuthenticationRequired => _code == "407"; 72 | 73 | public bool IsUnauthorized => _code == "401"; 74 | 75 | public bool IsWebSocketResponse 76 | { 77 | get 78 | { 79 | var headers = Headers; 80 | return ProtocolVersion > HttpVersion.Version10 && 81 | _code == "101" && 82 | headers.Contains("Upgrade", "websocket") && 83 | headers.Contains("Connection", "Upgrade"); 84 | } 85 | } 86 | 87 | public AuthenticationChallenge ProxyAuthenticationChallenge 88 | { 89 | get 90 | { 91 | var chal = Headers["Proxy-Authenticate"]; 92 | return chal != null && chal.Length > 0 93 | ? AuthenticationChallenge.Parse(chal) 94 | : null; 95 | } 96 | } 97 | 98 | public string StatusCode => _code; 99 | 100 | internal static HttpResponse CreateCloseResponse(HttpStatusCode code) 101 | { 102 | var res = new HttpResponse(code); 103 | res.Headers["Connection"] = "close"; 104 | 105 | return res; 106 | } 107 | 108 | internal static HttpResponse CreateUnauthorizedResponse(string challenge) 109 | { 110 | var res = new HttpResponse(HttpStatusCode.Unauthorized); 111 | res.Headers["WWW-Authenticate"] = challenge; 112 | 113 | return res; 114 | } 115 | 116 | internal static HttpResponse CreateWebSocketResponse() 117 | { 118 | var res = new HttpResponse(HttpStatusCode.SwitchingProtocols); 119 | 120 | var headers = res.Headers; 121 | headers["Upgrade"] = "websocket"; 122 | headers["Connection"] = "Upgrade"; 123 | 124 | return res; 125 | } 126 | 127 | internal static HttpResponse Parse(string[] headerParts) 128 | { 129 | var statusLine = headerParts[0].Split(new[] { ' ' }, 3); 130 | if (statusLine.Length != 3) 131 | throw new ArgumentException("Invalid status line: " + headerParts[0]); 132 | 133 | var headers = new WebHeaderCollection(); 134 | for (int i = 1; i < headerParts.Length; i++) 135 | headers.InternalSet(headerParts[i], true); 136 | 137 | return new HttpResponse( 138 | statusLine[1], statusLine[2], new Version(statusLine[0].Substring(5)), headers); 139 | } 140 | 141 | public void SetCookies(CookieCollection cookies) 142 | { 143 | if (cookies == null || cookies.Count == 0) 144 | return; 145 | 146 | var headers = Headers; 147 | foreach (var cookie in cookies.Sorted) 148 | headers.Add("Set-Cookie", cookie.ToResponseString()); 149 | } 150 | 151 | public override string ToString() 152 | { 153 | var output = new StringBuilder(64); 154 | output.AppendFormat("HTTP/{0} {1} {2}{3}", ProtocolVersion, _code, _reason, CrLf); 155 | 156 | var headers = Headers; 157 | foreach (var key in headers.AllKeys) 158 | output.AppendFormat("{0}: {1}{2}", key, headers[key], CrLf); 159 | 160 | output.Append(CrLf); 161 | 162 | var entity = EntityBody; 163 | if (entity.Length > 0) 164 | output.Append(entity); 165 | 166 | return output.ToString(); 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Mask.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Mask.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | internal enum Mask : byte 30 | { 31 | Unmask = 0x0, 32 | Mask = 0x1 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /websocket-sharp.clone/MessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * MessageEventArgs.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | using System.IO; 31 | 32 | /// 33 | /// Contains the event data associated with a event. 34 | /// 35 | /// 36 | /// 37 | /// A event occurs when the receives 38 | /// a text or binary message. 39 | /// 40 | /// 41 | /// If you would like to get the message data, you should access 42 | /// the or property. 43 | /// 44 | /// 45 | public class MessageEventArgs : EventArgs 46 | { 47 | private readonly WebSocketMessage _message; 48 | 49 | internal MessageEventArgs(WebSocketMessage message) 50 | { 51 | _message = message; 52 | } 53 | 54 | public Opcode Opcode => _message.Opcode; 55 | 56 | public StreamReader Text => _message.Text; 57 | 58 | public Stream Data => _message.RawData; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/AuthenticationBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * AuthenticationBase.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net 28 | { 29 | using System; 30 | using System.Collections.Specialized; 31 | using System.Text; 32 | 33 | internal abstract class AuthenticationBase 34 | { 35 | private readonly AuthenticationSchemes _scheme; 36 | 37 | internal readonly NameValueCollection Parameters; 38 | 39 | protected AuthenticationBase(AuthenticationSchemes scheme, NameValueCollection parameters) 40 | { 41 | _scheme = scheme; 42 | Parameters = parameters; 43 | } 44 | 45 | public AuthenticationSchemes Scheme => _scheme; 46 | 47 | internal static string CreateNonceValue() 48 | { 49 | var src = new byte[16]; 50 | var rand = new Random(); 51 | rand.NextBytes(src); 52 | 53 | var res = new StringBuilder(32); 54 | foreach (var b in src) 55 | res.Append(b.ToString("x2")); 56 | 57 | return res.ToString(); 58 | } 59 | 60 | internal static NameValueCollection ParseParameters(string value) 61 | { 62 | var res = new NameValueCollection(); 63 | foreach (var param in value.SplitHeaderValue(',')) 64 | { 65 | var i = param.IndexOf('='); 66 | var name = i > 0 ? param.Substring(0, i).Trim() : null; 67 | var val = i < 0 68 | ? param.Trim().Trim('"') 69 | : i < param.Length - 1 70 | ? param.Substring(i + 1).Trim().Trim('"') 71 | : string.Empty; 72 | 73 | res.Add(name, val); 74 | } 75 | 76 | return res; 77 | } 78 | 79 | internal abstract string ToBasicString(); 80 | 81 | internal abstract string ToDigestString(); 82 | 83 | public override string ToString() 84 | { 85 | return _scheme == AuthenticationSchemes.Basic 86 | ? ToBasicString() 87 | : _scheme == AuthenticationSchemes.Digest 88 | ? ToDigestString() 89 | : string.Empty; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/AuthenticationChallenge.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * AuthenticationChallenge.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net 28 | { 29 | using System.Collections.Specialized; 30 | using System.Text; 31 | 32 | internal class AuthenticationChallenge : AuthenticationBase 33 | { 34 | private AuthenticationChallenge(AuthenticationSchemes scheme, NameValueCollection parameters) 35 | : base(scheme, parameters) 36 | { 37 | } 38 | 39 | private AuthenticationChallenge(AuthenticationSchemes scheme, string realm) 40 | : base(scheme, new NameValueCollection()) 41 | { 42 | Parameters["realm"] = realm; 43 | if (scheme == AuthenticationSchemes.Digest) 44 | { 45 | Parameters["nonce"] = CreateNonceValue(); 46 | Parameters["algorithm"] = "MD5"; 47 | Parameters["qop"] = "auth"; 48 | } 49 | } 50 | 51 | internal static AuthenticationChallenge CreateBasicChallenge(string realm) 52 | { 53 | return new AuthenticationChallenge(AuthenticationSchemes.Basic, realm); 54 | } 55 | 56 | internal static AuthenticationChallenge CreateDigestChallenge(string realm) 57 | { 58 | return new AuthenticationChallenge(AuthenticationSchemes.Digest, realm); 59 | } 60 | 61 | internal static AuthenticationChallenge Parse(string value) 62 | { 63 | var chal = value.Split(new[] { ' ' }, 2); 64 | if (chal.Length != 2) 65 | return null; 66 | 67 | var schm = chal[0].ToLower(); 68 | return schm == "basic" 69 | ? new AuthenticationChallenge( 70 | AuthenticationSchemes.Basic, ParseParameters(chal[1])) 71 | : schm == "digest" 72 | ? new AuthenticationChallenge( 73 | AuthenticationSchemes.Digest, ParseParameters(chal[1])) 74 | : null; 75 | } 76 | 77 | internal override string ToBasicString() 78 | { 79 | return string.Format("Basic realm=\"{0}\"", Parameters["realm"]); 80 | } 81 | 82 | internal override string ToDigestString() 83 | { 84 | var output = new StringBuilder(128); 85 | 86 | var domain = Parameters["domain"]; 87 | if (domain != null) 88 | output.AppendFormat( 89 | "Digest realm=\"{0}\", domain=\"{1}\", nonce=\"{2}\"", 90 | Parameters["realm"], 91 | domain, 92 | Parameters["nonce"]); 93 | else 94 | output.AppendFormat( 95 | "Digest realm=\"{0}\", nonce=\"{1}\"", Parameters["realm"], Parameters["nonce"]); 96 | 97 | var opaque = Parameters["opaque"]; 98 | if (opaque != null) 99 | output.AppendFormat(", opaque=\"{0}\"", opaque); 100 | 101 | var stale = Parameters["stale"]; 102 | if (stale != null) 103 | output.AppendFormat(", stale={0}", stale); 104 | 105 | var algo = Parameters["algorithm"]; 106 | if (algo != null) 107 | output.AppendFormat(", algorithm={0}", algo); 108 | 109 | var qop = Parameters["qop"]; 110 | if (qop != null) 111 | output.AppendFormat(", qop=\"{0}\"", qop); 112 | 113 | return output.ToString(); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/AuthenticationResponse.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * AuthenticationResponse.cs 3 | * 4 | * ParseBasicCredentials is derived from System.Net.HttpListenerContext.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | * Copyright (c) 2013-2014 sta.blockhead 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to deal 14 | * in the Software without restriction, including without limitation the rights 15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | * THE SOFTWARE. 29 | */ 30 | 31 | namespace WebSocketSharp.Net 32 | { 33 | using System; 34 | using System.Collections.Specialized; 35 | using System.Security.Cryptography; 36 | using System.Security.Principal; 37 | using System.Text; 38 | 39 | internal class AuthenticationResponse : AuthenticationBase 40 | { 41 | private uint _nonceCount; 42 | 43 | private AuthenticationResponse(AuthenticationSchemes scheme, NameValueCollection parameters) 44 | : base(scheme, parameters) 45 | { 46 | } 47 | 48 | internal AuthenticationResponse(NetworkCredential credentials) 49 | : this(AuthenticationSchemes.Basic, new NameValueCollection(), credentials, 0) 50 | { 51 | } 52 | 53 | internal AuthenticationResponse( 54 | AuthenticationChallenge challenge, NetworkCredential credentials, uint nonceCount) 55 | : this(challenge.Scheme, challenge.Parameters, credentials, nonceCount) 56 | { 57 | } 58 | 59 | internal AuthenticationResponse( 60 | AuthenticationSchemes scheme, 61 | NameValueCollection parameters, 62 | NetworkCredential credentials, 63 | uint nonceCount) 64 | : base(scheme, parameters) 65 | { 66 | Parameters["username"] = credentials.UserName; 67 | Parameters["password"] = credentials.Password; 68 | Parameters["uri"] = credentials.Domain; 69 | _nonceCount = nonceCount; 70 | if (scheme == AuthenticationSchemes.Digest) 71 | InitAsDigest(); 72 | } 73 | 74 | internal uint NonceCount => _nonceCount < UInt32.MaxValue 75 | ? _nonceCount 76 | : 0; 77 | 78 | private static string createA1(string username, string password, string realm) 79 | { 80 | return string.Format("{0}:{1}:{2}", username, realm, password); 81 | } 82 | 83 | private static string createA1( 84 | string username, string password, string realm, string nonce, string cnonce) 85 | { 86 | return string.Format( 87 | "{0}:{1}:{2}", Hash(createA1(username, password, realm)), nonce, cnonce); 88 | } 89 | 90 | private static string createA2(string method, string uri) 91 | { 92 | return string.Format("{0}:{1}", method, uri); 93 | } 94 | 95 | private static string createA2(string method, string uri, string entity) 96 | { 97 | return string.Format("{0}:{1}:{2}", method, uri, Hash(entity)); 98 | } 99 | 100 | private static string Hash(string value) 101 | { 102 | var src = Encoding.UTF8.GetBytes(value); 103 | var md5 = MD5.Create(); 104 | var hashed = md5.ComputeHash(src); 105 | 106 | var res = new StringBuilder(64); 107 | foreach (var b in hashed) 108 | res.Append(b.ToString("x2")); 109 | 110 | return res.ToString(); 111 | } 112 | 113 | private void InitAsDigest() 114 | { 115 | var qops = Parameters["qop"]; 116 | if (qops != null) 117 | { 118 | if (qops.Split(',').Contains(qop => qop.Trim().ToLower() == "auth")) 119 | { 120 | Parameters["qop"] = "auth"; 121 | Parameters["cnonce"] = CreateNonceValue(); 122 | Parameters["nc"] = string.Format("{0:x8}", ++_nonceCount); 123 | } 124 | else 125 | { 126 | Parameters["qop"] = null; 127 | } 128 | } 129 | 130 | Parameters["method"] = "GET"; 131 | Parameters["response"] = CreateRequestDigest(Parameters); 132 | } 133 | 134 | internal static string CreateRequestDigest(NameValueCollection parameters) 135 | { 136 | var user = parameters["username"]; 137 | var pass = parameters["password"]; 138 | var realm = parameters["realm"]; 139 | var nonce = parameters["nonce"]; 140 | var uri = parameters["uri"]; 141 | var algo = parameters["algorithm"]; 142 | var qop = parameters["qop"]; 143 | var cnonce = parameters["cnonce"]; 144 | var nc = parameters["nc"]; 145 | var method = parameters["method"]; 146 | 147 | var a1 = algo != null && algo.ToLower() == "md5-sess" 148 | ? createA1(user, pass, realm, nonce, cnonce) 149 | : createA1(user, pass, realm); 150 | 151 | var a2 = qop != null && qop.ToLower() == "auth-int" 152 | ? createA2(method, uri, parameters["entity"]) 153 | : createA2(method, uri); 154 | 155 | var secret = Hash(a1); 156 | var data = qop != null 157 | ? string.Format("{0}:{1}:{2}:{3}:{4}", nonce, nc, cnonce, qop, Hash(a2)) 158 | : string.Format("{0}:{1}", nonce, Hash(a2)); 159 | 160 | return Hash(string.Format("{0}:{1}", secret, data)); 161 | } 162 | 163 | internal static AuthenticationResponse Parse(string value) 164 | { 165 | try 166 | { 167 | var cred = value.Split(new[] { ' ' }, 2); 168 | if (cred.Length != 2) 169 | return null; 170 | 171 | var schm = cred[0].ToLower(); 172 | return schm == "basic" 173 | ? new AuthenticationResponse( 174 | AuthenticationSchemes.Basic, ParseBasicCredentials(cred[1])) 175 | : schm == "digest" 176 | ? new AuthenticationResponse( 177 | AuthenticationSchemes.Digest, ParseParameters(cred[1])) 178 | : null; 179 | } 180 | catch 181 | { 182 | } 183 | 184 | return null; 185 | } 186 | 187 | internal static NameValueCollection ParseBasicCredentials(string value) 188 | { 189 | // Decode the basic-credentials (a Base64 encoded string). 190 | var userPass = Encoding.UTF8.GetString(Convert.FromBase64String(value)); 191 | 192 | // The format is [\]:. 193 | var i = userPass.IndexOf(':'); 194 | var user = userPass.Substring(0, i); 195 | var pass = i < userPass.Length - 1 ? userPass.Substring(i + 1) : string.Empty; 196 | 197 | // Check if 'domain' exists. 198 | i = user.IndexOf('\\'); 199 | if (i > -1) 200 | user = user.Substring(i + 1); 201 | 202 | var res = new NameValueCollection(); 203 | res["username"] = user; 204 | res["password"] = pass; 205 | 206 | return res; 207 | } 208 | 209 | internal override string ToBasicString() 210 | { 211 | var userPass = string.Format("{0}:{1}", Parameters["username"], Parameters["password"]); 212 | var cred = Convert.ToBase64String(Encoding.UTF8.GetBytes(userPass)); 213 | 214 | return "Basic " + cred; 215 | } 216 | 217 | internal override string ToDigestString() 218 | { 219 | var output = new StringBuilder(256); 220 | output.AppendFormat( 221 | "Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", response=\"{4}\"", 222 | Parameters["username"], 223 | Parameters["realm"], 224 | Parameters["nonce"], 225 | Parameters["uri"], 226 | Parameters["response"]); 227 | 228 | var opaque = Parameters["opaque"]; 229 | if (opaque != null) 230 | output.AppendFormat(", opaque=\"{0}\"", opaque); 231 | 232 | var algo = Parameters["algorithm"]; 233 | if (algo != null) 234 | output.AppendFormat(", algorithm={0}", algo); 235 | 236 | var qop = Parameters["qop"]; 237 | if (qop != null) 238 | output.AppendFormat( 239 | ", qop={0}, cnonce=\"{1}\", nc={2}", qop, Parameters["cnonce"], Parameters["nc"]); 240 | 241 | return output.ToString(); 242 | } 243 | 244 | public IIdentity ToIdentity() 245 | { 246 | var schm = Scheme; 247 | return schm == AuthenticationSchemes.Basic 248 | ? new HttpBasicIdentity(Parameters["username"], Parameters["password"]) as IIdentity 249 | : schm == AuthenticationSchemes.Digest 250 | ? new HttpDigestIdentity(Parameters) 251 | : null; 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/AuthenticationSchemes.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * AuthenticationSchemes.cs 3 | * 4 | * This code is derived from System.Net.AuthenticationSchemes.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | * Copyright (c) 2012-2014 sta.blockhead 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to deal 14 | * in the Software without restriction, including without limitation the rights 15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | * THE SOFTWARE. 29 | */ 30 | 31 | /* 32 | * Authors: 33 | * - Atsushi Enomoto 34 | */ 35 | 36 | namespace WebSocketSharp.Net 37 | { 38 | using System; 39 | 40 | /// 41 | /// Contains the values of the schemes for authentication. 42 | /// 43 | [Flags] 44 | public enum AuthenticationSchemes 45 | { 46 | /// 47 | /// Indicates that no authentication is allowed. 48 | /// 49 | None, 50 | 51 | /// 52 | /// Indicates digest authentication. 53 | /// 54 | Digest = 1, 55 | 56 | /// 57 | /// Indicates basic authentication. 58 | /// 59 | Basic = 8, 60 | 61 | /// 62 | /// Indicates anonymous authentication. 63 | /// 64 | Anonymous = 0x8000 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/ClientSslConfiguration.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ClientSslConfiguration.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2014 liryna 7 | * Copyright (c) 2014 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 | 28 | /* 29 | * Authors: 30 | * - Liryna 31 | */ 32 | 33 | namespace WebSocketSharp.Net 34 | { 35 | using System.Net.Security; 36 | using System.Security.Authentication; 37 | using System.Security.Cryptography.X509Certificates; 38 | 39 | /// 40 | /// Stores the parameters used to configure a instance as a client. 41 | /// 42 | public class ClientSslConfiguration : SslConfiguration 43 | { 44 | private X509CertificateCollection _certs; 45 | private string _host; 46 | 47 | /// 48 | /// Initializes a new instance of the class with 49 | /// the specified , , 50 | /// , and . 51 | /// 52 | /// 53 | /// A that represents the name of the server that shares 54 | /// a secure connection. 55 | /// 56 | /// 57 | /// A that contains client certificates. 58 | /// 59 | /// 60 | /// The enum value that represents the protocols used for 61 | /// authentication. 62 | /// 63 | /// 64 | /// true if the certificate revocation list is checked during authentication; 65 | /// otherwise, false. 66 | /// 67 | public ClientSslConfiguration( 68 | string targetHost, 69 | X509CertificateCollection clientCertificates = null, 70 | SslProtocols enabledSslProtocols = SslProtocols.Default, 71 | LocalCertificateSelectionCallback certificateSelection = null, 72 | bool checkCertificateRevocation = false, 73 | RemoteCertificateValidationCallback certificateValidationCallback = null) 74 | : base(enabledSslProtocols, checkCertificateRevocation) 75 | { 76 | _host = targetHost; 77 | _certs = clientCertificates; 78 | ClientCertificates = clientCertificates; 79 | EnabledSslProtocols = enabledSslProtocols; 80 | CertificateSelection = certificateSelection; 81 | CheckCertificateRevocation = checkCertificateRevocation; 82 | CertificateValidationCallback = certificateValidationCallback; 83 | } 84 | 85 | /// 86 | /// Gets or sets the collection that contains client certificates. 87 | /// 88 | /// 89 | /// A that contains client certificates. 90 | /// 91 | public X509CertificateCollection ClientCertificates { get; private set; } 92 | 93 | /// 94 | /// Gets or sets the callback used to select a client certificate to supply to the server. 95 | /// 96 | /// 97 | /// If this callback returns , no client certificate will be supplied. 98 | /// 99 | /// 100 | /// A delegate that references the method 101 | /// used to select the client certificate. The default value is a function that only returns 102 | /// . 103 | /// 104 | public LocalCertificateSelectionCallback ClientCertificateSelectionCallback { get; private set; } 105 | 106 | public LocalCertificateSelectionCallback CertificateSelection { get; private set; } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/CookieException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * CookieException.cs 3 | * 4 | * This code is derived from System.Net.CookieException.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2012-2014 sta.blockhead 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | */ 29 | 30 | /* 31 | * Authors: 32 | * - Lawrence Pit 33 | */ 34 | 35 | namespace WebSocketSharp.Net 36 | { 37 | using System; 38 | using System.Runtime.Serialization; 39 | using System.Security.Permissions; 40 | 41 | /// 42 | /// The exception that is thrown when a gets an error. 43 | /// 44 | [Serializable] 45 | internal class CookieException : FormatException, ISerializable 46 | { 47 | internal CookieException(string message) 48 | : base(message) 49 | { 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the class from 54 | /// the specified and . 55 | /// 56 | /// 57 | /// A that contains the serialized object data. 58 | /// 59 | /// 60 | /// A that specifies the source for the deserialization. 61 | /// 62 | protected CookieException( 63 | SerializationInfo serializationInfo, StreamingContext streamingContext) 64 | : base(serializationInfo, streamingContext) 65 | { 66 | } 67 | 68 | /// 69 | /// Initializes a new instance of the class. 70 | /// 71 | public CookieException() 72 | { 73 | } 74 | 75 | /// 76 | /// Populates the specified with the data needed to serialize 77 | /// the current . 78 | /// 79 | /// 80 | /// A that holds the serialized object data. 81 | /// 82 | /// 83 | /// A that specifies the destination for the serialization. 84 | /// 85 | [SecurityPermission( 86 | SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] 87 | public override void GetObjectData( 88 | SerializationInfo serializationInfo, StreamingContext streamingContext) 89 | { 90 | base.GetObjectData(serializationInfo, streamingContext); 91 | } 92 | 93 | /// 94 | /// Populates the specified with the data needed to serialize 95 | /// the current . 96 | /// 97 | /// 98 | /// A that holds the serialized object data. 99 | /// 100 | /// 101 | /// A that specifies the destination for the serialization. 102 | /// 103 | [SecurityPermission( 104 | SecurityAction.LinkDemand, 105 | Flags = SecurityPermissionFlag.SerializationFormatter, 106 | SerializationFormatter = true)] 107 | void ISerializable.GetObjectData( 108 | SerializationInfo serializationInfo, StreamingContext streamingContext) 109 | { 110 | base.GetObjectData(serializationInfo, streamingContext); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/HttpBasicIdentity.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpBasicIdentity.cs 3 | * 4 | * This code is derived from System.Net.HttpListenerBasicIdentity.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | * Copyright (c) 2014 sta.blockhead 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to deal 14 | * in the Software without restriction, including without limitation the rights 15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | * THE SOFTWARE. 29 | */ 30 | 31 | /* 32 | * Authors: 33 | * - Gonzalo Paniagua Javier 34 | */ 35 | 36 | namespace WebSocketSharp.Net 37 | { 38 | using System.Security.Principal; 39 | 40 | /// 41 | /// Holds the user name and password from the HTTP Basic authentication credentials. 42 | /// 43 | internal class HttpBasicIdentity : GenericIdentity 44 | { 45 | private string _password; 46 | 47 | internal HttpBasicIdentity(string username, string password) 48 | : base(username, "Basic") 49 | { 50 | _password = password; 51 | } 52 | 53 | /// 54 | /// Gets the password from the HTTP Basic authentication credentials. 55 | /// 56 | /// 57 | /// A that represents the password. 58 | /// 59 | public string Password => _password; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/HttpDigestIdentity.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpDigestIdentity.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net 28 | { 29 | using System.Collections.Specialized; 30 | using System.Security.Principal; 31 | 32 | /// 33 | /// Holds the user name and other parameters from the HTTP Digest authentication credentials. 34 | /// 35 | internal class HttpDigestIdentity : GenericIdentity 36 | { 37 | private readonly NameValueCollection _parameters; 38 | 39 | internal HttpDigestIdentity(NameValueCollection parameters) 40 | : base(parameters["username"], "Digest") 41 | { 42 | _parameters = parameters; 43 | } 44 | 45 | internal bool IsValid(string password, string realm, string method, string entity) 46 | { 47 | var parameters = new NameValueCollection(_parameters); 48 | parameters["password"] = password; 49 | parameters["realm"] = realm; 50 | parameters["method"] = method; 51 | parameters["entity"] = entity; 52 | 53 | return _parameters["response"] == AuthenticationResponse.CreateRequestDigest(parameters); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/HttpHeaderInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpHeaderInfo.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net 28 | { 29 | internal class HttpHeaderInfo 30 | { 31 | private HttpHeaderType _type; 32 | 33 | private bool IsMultiValueInRequest => (_type & HttpHeaderType.MultiValueInRequest) == HttpHeaderType.MultiValueInRequest; 34 | 35 | private bool IsMultiValueInResponse => (_type & HttpHeaderType.MultiValueInResponse) == HttpHeaderType.MultiValueInResponse; 36 | 37 | public bool IsRequest => (_type & HttpHeaderType.Request) == HttpHeaderType.Request; 38 | 39 | public bool IsResponse => (_type & HttpHeaderType.Response) == HttpHeaderType.Response; 40 | 41 | public string Name 42 | { 43 | get; 44 | set; 45 | } 46 | 47 | public HttpHeaderType Type 48 | { 49 | get 50 | { 51 | return _type; 52 | } 53 | 54 | set 55 | { 56 | _type = value; 57 | } 58 | } 59 | 60 | public bool IsMultiValue(bool response) 61 | { 62 | return (_type & HttpHeaderType.MultiValue) != HttpHeaderType.MultiValue 63 | ? response 64 | ? IsMultiValueInResponse 65 | : IsMultiValueInRequest 66 | : response 67 | ? IsResponse 68 | : IsRequest; 69 | } 70 | 71 | public bool IsRestricted(bool response) 72 | { 73 | return (_type & HttpHeaderType.Restricted) != HttpHeaderType.Restricted 74 | ? false 75 | : response 76 | ? IsResponse 77 | : IsRequest; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/HttpHeaderType.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpHeaderType.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net 28 | { 29 | using System; 30 | 31 | [Flags] 32 | internal enum HttpHeaderType 33 | { 34 | Unspecified = 0, 35 | Request = 1, 36 | Response = 1 << 1, 37 | Restricted = 1 << 2, 38 | MultiValue = 1 << 3, 39 | MultiValueInRequest = 1 << 4, 40 | MultiValueInResponse = 1 << 5 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/HttpVersion.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * HttpVersion.cs 3 | * 4 | * This code is derived from System.Net.HttpVersion.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2012-2014 sta.blockhead 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | */ 29 | 30 | /* 31 | * Authors: 32 | * - Lawrence Pit 33 | */ 34 | 35 | namespace WebSocketSharp.Net 36 | { 37 | using System; 38 | 39 | /// 40 | /// Provides the HTTP version numbers. 41 | /// 42 | internal class HttpVersion 43 | { 44 | /// 45 | /// Provides a instance for HTTP 1.0. 46 | /// 47 | public static readonly Version Version10 = new Version(1, 0); 48 | 49 | /// 50 | /// Provides a instance for HTTP 1.1. 51 | /// 52 | public static readonly Version Version11 = new Version(1, 1); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/InputState.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * InputState.cs 3 | * 4 | * This code is derived from System.Net.HttpConnection.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | * Copyright (c) 2014 sta.blockhead 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to deal 14 | * in the Software without restriction, including without limitation the rights 15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | * THE SOFTWARE. 29 | */ 30 | 31 | /* 32 | * Authors: 33 | * - Gonzalo Paniagua Javier 34 | */ 35 | 36 | namespace WebSocketSharp.Net 37 | { 38 | internal enum InputState 39 | { 40 | RequestLine, 41 | Headers 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/LineState.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * LineState.cs 3 | * 4 | * This code is derived from System.Net.HttpConnection.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 10 | * Copyright (c) 2014 sta.blockhead 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to deal 14 | * in the Software without restriction, including without limitation the rights 15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | * THE SOFTWARE. 29 | */ 30 | 31 | /* 32 | * Authors: 33 | * - Gonzalo Paniagua Javier 34 | */ 35 | 36 | namespace WebSocketSharp.Net 37 | { 38 | internal enum LineState 39 | { 40 | None, 41 | Cr, 42 | Lf 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/NetworkCredential.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * NetworkCredential.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net 28 | { 29 | using System; 30 | 31 | /// 32 | /// Provides the credentials for HTTP authentication (Basic/Digest). 33 | /// 34 | public class NetworkCredential 35 | { 36 | private string _domain; 37 | private string _password; 38 | private string[] _roles; 39 | private string _username; 40 | 41 | /// 42 | /// Initializes a new instance of the class 43 | /// with the specified user name and password. 44 | /// 45 | /// 46 | /// A that represents the user name associated with the 47 | /// credentials. 48 | /// 49 | /// 50 | /// A that represents the password for the user name 51 | /// associated with the credentials. 52 | /// 53 | /// 54 | /// is or empty. 55 | /// 56 | public NetworkCredential(string username, string password) 57 | : this(username, password, null) 58 | { 59 | } 60 | 61 | /// 62 | /// Initializes a new instance of the class 63 | /// with the specified user name, password, domain, and roles. 64 | /// 65 | /// 66 | /// A that represents the user name associated with the 67 | /// credentials. 68 | /// 69 | /// 70 | /// A that represents the password for the user name 71 | /// associated with the credentials. 72 | /// 73 | /// 74 | /// A that represents the name of the user domain 75 | /// associated with the credentials. 76 | /// 77 | /// 78 | /// An array of that contains the role names to which 79 | /// the user associated with the credentials belongs if any. 80 | /// 81 | /// 82 | /// is or empty. 83 | /// 84 | public NetworkCredential( 85 | string username, string password, string domain, params string[] roles) 86 | { 87 | if (username == null || username.Length == 0) 88 | throw new ArgumentException("Must not be null or empty.", "username"); 89 | 90 | _username = username; 91 | _password = password; 92 | _domain = domain; 93 | _roles = roles; 94 | } 95 | 96 | /// 97 | /// Gets the name of the user domain associated with the credentials. 98 | /// 99 | /// 100 | /// A that represents the name of the user domain 101 | /// associated with the credentials. 102 | /// 103 | public string Domain 104 | { 105 | get 106 | { 107 | return _domain ?? string.Empty; 108 | } 109 | 110 | internal set 111 | { 112 | _domain = value; 113 | } 114 | } 115 | 116 | /// 117 | /// Gets the password for the user name associated with the credentials. 118 | /// 119 | /// 120 | /// A that represents the password for the user name 121 | /// associated with the credentials. 122 | /// 123 | public string Password 124 | { 125 | get 126 | { 127 | return _password ?? string.Empty; 128 | } 129 | 130 | internal set 131 | { 132 | _password = value; 133 | } 134 | } 135 | 136 | /// 137 | /// Gets the role names to which the user associated with the credentials 138 | /// belongs. 139 | /// 140 | /// 141 | /// An array of that contains the role names to which 142 | /// the user associated with the credentials belongs. 143 | /// 144 | public string[] Roles 145 | { 146 | get 147 | { 148 | return _roles; 149 | } 150 | 151 | internal set 152 | { 153 | _roles = value; 154 | } 155 | } 156 | 157 | /// 158 | /// Gets the user name associated with the credentials. 159 | /// 160 | /// 161 | /// A that represents the user name associated with the 162 | /// credentials. 163 | /// 164 | public string UserName 165 | { 166 | get 167 | { 168 | return _username; 169 | } 170 | 171 | internal set 172 | { 173 | _username = value; 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/QueryStringCollection.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * QueryStringCollection.cs 3 | * 4 | * This code is derived from System.Net.HttpUtility.cs of Mono 5 | * (http://www.mono-project.com). 6 | * 7 | * The MIT License 8 | * 9 | * Copyright (c) 2005-2009 Novell, Inc. (http://www.novell.com) 10 | * Copyright (c) 2014 sta.blockhead 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to deal 14 | * in the Software without restriction, including without limitation the rights 15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | * THE SOFTWARE. 29 | */ 30 | 31 | /* 32 | * Authors: 33 | * - Patrik Torstensson 34 | * - Wictor Wilén (decode/encode functions) 35 | * - Tim Coleman 36 | * - Gonzalo Paniagua Javier 37 | */ 38 | 39 | namespace WebSocketSharp.Net 40 | { 41 | using System.Collections.Specialized; 42 | using System.Text; 43 | 44 | internal sealed class QueryStringCollection : NameValueCollection 45 | { 46 | public override string ToString() 47 | { 48 | var cnt = Count; 49 | if (cnt == 0) 50 | { 51 | return string.Empty; 52 | } 53 | 54 | var output = new StringBuilder(); 55 | var keys = AllKeys; 56 | foreach (var key in keys) 57 | { 58 | output.AppendFormat("{0}={1}&", key, this[key]); 59 | } 60 | 61 | if (output.Length > 0) 62 | { 63 | output.Length--; 64 | } 65 | 66 | return output.ToString(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/ServerSslConfiguration.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ServerSslConfiguration.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2014 liryna 7 | * Copyright (c) 2014 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 | 28 | /* 29 | * Authors: 30 | * - Liryna 31 | */ 32 | 33 | namespace WebSocketSharp.Net 34 | { 35 | using System.Net.Security; 36 | using System.Security.Authentication; 37 | using System.Security.Cryptography.X509Certificates; 38 | 39 | /// 40 | /// Stores the parameters used to configure a instance as a server. 41 | /// 42 | public class ServerSslConfiguration : SslConfiguration 43 | { 44 | /// 45 | /// Initializes a new instance of the class with 46 | /// the specified , 47 | /// , , 48 | /// and . 49 | /// 50 | /// 51 | /// A that represents the certificate used to authenticate 52 | /// the server. 53 | /// 54 | /// 55 | /// true if the client must supply a certificate for authentication; 56 | /// otherwise, false. 57 | /// 58 | /// 59 | /// The enum value that represents the protocols used for 60 | /// authentication. 61 | /// 62 | /// 63 | /// true if the certificate revocation list is checked during authentication; 64 | /// otherwise, false. 65 | /// 66 | /// A user delegate used to verify remote SSL certificate 67 | /// A user delegate used to select local SSL certificate 68 | public ServerSslConfiguration( 69 | X509Certificate2 serverCertificate, 70 | bool clientCertificateRequired = false, 71 | SslProtocols enabledSslProtocols = SslProtocols.Default, 72 | bool checkCertificateRevocation = false, 73 | RemoteCertificateValidationCallback clientCertificateValidationCallback = null, 74 | LocalCertificateSelectionCallback userCertificateSelectionCallback = null) 75 | : base(enabledSslProtocols, checkCertificateRevocation) 76 | { 77 | ServerCertificate = serverCertificate; 78 | ClientCertificateRequired = clientCertificateRequired; 79 | ClientCertificateValidationCallback = clientCertificateValidationCallback; 80 | UserCertificateSelectionCallback = userCertificateSelectionCallback; 81 | EnabledSslProtocols = enabledSslProtocols; 82 | CheckCertificateRevocation = checkCertificateRevocation; 83 | } 84 | 85 | /// 86 | /// Gets or sets a value indicating whether the client must supply a certificate for 87 | /// authentication. 88 | /// 89 | /// 90 | /// true if the client must supply a certificate; otherwise, false. 91 | /// 92 | public bool ClientCertificateRequired { get; private set; } 93 | 94 | /// 95 | /// Gets or sets the callback used to validate the certificate supplied by the client. 96 | /// 97 | /// 98 | /// If this callback returns true, the client certificate will be valid. 99 | /// 100 | /// 101 | /// A delegate that references the method 102 | /// used to validate the client certificate. The default value is a function that only returns 103 | /// true. 104 | /// 105 | public RemoteCertificateValidationCallback ClientCertificateValidationCallback { get; private set; } 106 | 107 | public LocalCertificateSelectionCallback UserCertificateSelectionCallback { get; private set; } 108 | 109 | /// 110 | /// Gets or sets the certificate used to authenticate the server on the secure connection. 111 | /// 112 | /// 113 | /// A that represents the certificate used to authenticate 114 | /// the server. 115 | /// 116 | public X509Certificate2 ServerCertificate { get; private set; } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/SslConfiguration.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SslConfiguration.cs 3 | * 4 | * This code is derived from ClientSslConfiguration.cs. 5 | * 6 | * The MIT License 7 | * 8 | * Copyright (c) 2014 liryna 9 | * Copyright (c) 2014 sta.blockhead 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | */ 29 | 30 | /* 31 | * Authors: 32 | * - Liryna 33 | */ 34 | 35 | namespace WebSocketSharp.Net 36 | { 37 | using System.Net.Security; 38 | using System.Security.Authentication; 39 | 40 | /// 41 | /// Stores the parameters used to configure a instance. 42 | /// 43 | /// 44 | /// The SslConfiguration class is an abstract class. 45 | /// 46 | public abstract class SslConfiguration 47 | { 48 | private LocalCertificateSelectionCallback _certSelectionCallback; 49 | private RemoteCertificateValidationCallback _certValidationCallback; 50 | 51 | /// 52 | /// Initializes a new instance of the class with 53 | /// the specified and 54 | /// . 55 | /// 56 | /// 57 | /// The enum value that represents the protocols used for 58 | /// authentication. 59 | /// 60 | /// 61 | /// true if the certificate revocation list is checked during authentication; 62 | /// otherwise, false. 63 | /// 64 | protected SslConfiguration(SslProtocols enabledSslProtocols, bool checkCertificateRevocation) 65 | { 66 | EnabledSslProtocols = enabledSslProtocols; 67 | CheckCertificateRevocation = checkCertificateRevocation; 68 | } 69 | 70 | /// 71 | /// Gets or sets the callback used to select a certificate to supply to the remote party. 72 | /// 73 | /// 74 | /// If this callback returns , no certificate will be supplied. 75 | /// 76 | /// 77 | /// A delegate that references the method 78 | /// used to select a certificate. The default value is a function that only returns 79 | /// . 80 | /// 81 | protected LocalCertificateSelectionCallback CertificateSelectionCallback 82 | { 83 | get 84 | { 85 | return _certSelectionCallback ?? 86 | (_certSelectionCallback = 87 | (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => 88 | null); 89 | } 90 | 91 | set 92 | { 93 | _certSelectionCallback = value; 94 | } 95 | } 96 | 97 | /// 98 | /// Gets or sets the callback used to validate the certificate supplied by the remote party. 99 | /// 100 | /// 101 | /// If this callback returns true, the certificate will be valid. 102 | /// 103 | /// 104 | /// A delegate that references the method 105 | /// used to validate the certificate. The default value is a function that only returns 106 | /// true. 107 | /// 108 | internal RemoteCertificateValidationCallback CertificateValidationCallback 109 | { 110 | get 111 | { 112 | return _certValidationCallback ?? (_certValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true); 113 | } 114 | 115 | set 116 | { 117 | _certValidationCallback = value; 118 | } 119 | } 120 | 121 | /// 122 | /// Gets or sets a value indicating whether the certificate revocation list is checked 123 | /// during authentication. 124 | /// 125 | /// 126 | /// true if the certificate revocation list is checked; otherwise, false. 127 | /// 128 | public bool CheckCertificateRevocation { get; protected set; } 129 | 130 | /// 131 | /// Gets or sets the SSL protocols used for authentication. 132 | /// 133 | /// 134 | /// The enum value that represents the protocols used for 135 | /// authentication. 136 | /// 137 | public SslProtocols EnabledSslProtocols { get; protected set; } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Net/WebSockets/WebSocketContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketContext.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Net.WebSockets 28 | { 29 | using System; 30 | using System.Collections.Generic; 31 | using System.Collections.Specialized; 32 | using System.Net; 33 | using System.Security.Principal; 34 | using System.Threading.Tasks; 35 | 36 | using CookieCollection = WebSocketSharp.Net.CookieCollection; 37 | 38 | /// 39 | /// Exposes the properties used to access the information in a WebSocket connection request. 40 | /// 41 | /// 42 | /// The WebSocketContext class is an abstract class. 43 | /// 44 | public abstract class WebSocketContext 45 | { 46 | /// 47 | /// Gets the HTTP cookies included in the request. 48 | /// 49 | /// 50 | /// A that contains the cookies. 51 | /// 52 | public abstract Task GetCookieCollection(); 53 | 54 | /// 55 | /// Gets the HTTP headers included in the request. 56 | /// 57 | /// 58 | /// A that contains the headers. 59 | /// 60 | public abstract Task GetHeader(string key); 61 | 62 | /// 63 | /// Gets the value of the Host header included in the request. 64 | /// 65 | /// 66 | /// A that represents the value of the Host header. 67 | /// 68 | public abstract Task GetHost(); 69 | 70 | /// 71 | /// Gets a value indicating whether the client is authenticated. 72 | /// 73 | /// 74 | /// true if the client is authenticated; otherwise, false. 75 | /// 76 | public abstract bool IsAuthenticated { get; } 77 | 78 | /// 79 | /// Gets a value indicating whether the client connected from the local computer. 80 | /// 81 | /// 82 | /// true if the client connected from the local computer; otherwise, false. 83 | /// 84 | public abstract bool IsLocal { get; } 85 | 86 | /// 87 | /// Gets a value indicating whether the WebSocket connection is secured. 88 | /// 89 | /// 90 | /// true if the connection is secured; otherwise, false. 91 | /// 92 | public abstract bool IsSecureConnection { get; } 93 | 94 | /// 95 | /// Gets a value indicating whether the request is a WebSocket connection request. 96 | /// 97 | /// 98 | /// true if the request is a WebSocket connection request; otherwise, false. 99 | /// 100 | public abstract Task IsWebSocketRequest(); 101 | 102 | /// 103 | /// Gets the value of the Origin header included in the request. 104 | /// 105 | /// 106 | /// A that represents the value of the Origin header. 107 | /// 108 | public abstract Task GetOrigin(); 109 | 110 | /// 111 | /// Gets the query string included in the request. 112 | /// 113 | /// 114 | /// A that contains the query string parameters. 115 | /// 116 | public abstract Task GetQueryString(); 117 | 118 | /// 119 | /// Gets the URI requested by the client. 120 | /// 121 | /// 122 | /// A that represents the requested URI. 123 | /// 124 | public abstract Task GetRequestUri(); 125 | 126 | /// 127 | /// Gets the value of the Sec-WebSocket-Key header included in the request. 128 | /// 129 | /// 130 | /// This property provides a part of the information used by the server to prove that it 131 | /// received a valid WebSocket connection request. 132 | /// 133 | /// 134 | /// A that represents the value of the Sec-WebSocket-Key header. 135 | /// 136 | public abstract Task GetSecWebSocketKey(); 137 | 138 | /// 139 | /// Gets the values of the Sec-WebSocket-Protocol header included in the request. 140 | /// 141 | /// 142 | /// This property represents the subprotocols requested by the client. 143 | /// 144 | /// 145 | /// An instance that provides 146 | /// an enumerator which supports the iteration over the values of the Sec-WebSocket-Protocol 147 | /// header. 148 | /// 149 | public abstract Task> GetSecWebSocketProtocols(); 150 | 151 | /// 152 | /// Gets the value of the Sec-WebSocket-Version header included in the request. 153 | /// 154 | /// 155 | /// This property represents the WebSocket protocol version. 156 | /// 157 | /// 158 | /// A that represents the value of the Sec-WebSocket-Version header. 159 | /// 160 | public abstract Task GetSecWebSocketVersion(); 161 | 162 | /// 163 | /// Gets the server endpoint as an IP address and a port number. 164 | /// 165 | /// 166 | /// A that represents the server endpoint. 167 | /// 168 | public abstract IPEndPoint ServerEndPoint { get; } 169 | 170 | /// 171 | /// Gets the client information (identity, authentication, and security roles). 172 | /// 173 | /// 174 | /// A that represents the client information. 175 | /// 176 | public abstract IPrincipal User { get; } 177 | 178 | /// 179 | /// Gets the client endpoint as an IP address and a port number. 180 | /// 181 | /// 182 | /// A that represents the client endpoint. 183 | /// 184 | public abstract IPEndPoint UserEndPoint { get; } 185 | 186 | /// 187 | /// Gets the instance used for two-way communication 188 | /// between client and server. 189 | /// 190 | /// 191 | /// A . 192 | /// 193 | public abstract WebSocket WebSocket { get; } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Opcode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Opcode.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | /// 30 | /// Contains the values of the opcode that indicates the type of a WebSocket frame. 31 | /// 32 | /// 33 | /// The values of the opcode are defined in 34 | /// Section 5.2 of RFC 6455. 35 | /// 36 | public enum Opcode : byte 37 | { 38 | /// 39 | /// Equivalent to numeric value 0. 40 | /// Indicates a continuation frame. 41 | /// 42 | Cont = 0x0, 43 | 44 | /// 45 | /// Equivalent to numeric value 1. 46 | /// Indicates a text frame. 47 | /// 48 | Text = 0x1, 49 | 50 | /// 51 | /// Equivalent to numeric value 2. 52 | /// Indicates a binary frame. 53 | /// 54 | Binary = 0x2, 55 | 56 | /// 57 | /// Equivalent to numeric value 8. 58 | /// Indicates a connection close frame. 59 | /// 60 | Close = 0x8, 61 | 62 | /// 63 | /// Equivalent to numeric value 9. 64 | /// Indicates a ping frame. 65 | /// 66 | Ping = 0x9, 67 | 68 | /// 69 | /// Equivalent to numeric value 10. 70 | /// Indicates a pong frame. 71 | /// 72 | Pong = 0xa 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /websocket-sharp.clone/PayloadData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * PayloadData.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | using System.Collections; 31 | using System.Collections.Generic; 32 | 33 | internal class PayloadData : IEnumerable 34 | { 35 | private readonly byte[] _data; 36 | private readonly long _length; 37 | private bool _masked; 38 | 39 | internal PayloadData() 40 | { 41 | _data = new byte[0]; 42 | } 43 | 44 | internal PayloadData(byte[] data) 45 | { 46 | _data = data; 47 | _masked = false; 48 | _length = data.LongLength; 49 | } 50 | 51 | public byte[] ApplicationData => _data; 52 | 53 | public ulong Length => (ulong)_length; 54 | 55 | internal void Mask(byte[] key) 56 | { 57 | for (long i = 0; i < _length; i++) 58 | { 59 | _data[i] = (byte)(_data[i] ^ key[i % 4]); 60 | } 61 | 62 | _masked = !_masked; 63 | } 64 | 65 | public IEnumerator GetEnumerator() 66 | { 67 | return ((IEnumerable)_data).GetEnumerator(); 68 | } 69 | 70 | public byte[] ToByteArray() 71 | { 72 | return _data; 73 | } 74 | 75 | public override string ToString() 76 | { 77 | return BitConverter.ToString(_data); 78 | } 79 | 80 | IEnumerator IEnumerable.GetEnumerator() 81 | { 82 | return GetEnumerator(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // AssemblyInfo.cs 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | using System.Reflection; 19 | using System.Runtime.CompilerServices; 20 | // Information about this assembly is defined by the following attributes. 21 | // Change them to the values specific to your project. 22 | 23 | [assembly: AssemblyTitle("WebSocket#")] 24 | [assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client and server")] 25 | [assembly: AssemblyConfiguration("")] 26 | [assembly: AssemblyCompany("Reimers.dk")] 27 | [assembly: AssemblyProduct("WebSocket#")] 28 | [assembly: AssemblyCopyright("sta.blockhead, Reimers.dk")] 29 | [assembly: AssemblyTrademark("")] 30 | [assembly: AssemblyCulture("")] 31 | 32 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 33 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 34 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 35 | 36 | [assembly: AssemblyVersion("1.0.2.*")] 37 | 38 | // The following attributes are used to specify the signing key for the assembly, 39 | // if desired. See the Mono documentation for more information about signing. 40 | 41 | //[assembly: AssemblyDelaySign(false)] 42 | //[assembly: AssemblyKeyFile("")] 43 | [assembly: AssemblyFileVersion("1.0.2.0")] 44 | [assembly: InternalsVisibleTo("WebSocketSharp.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000110000002917fb89fec391f72bcb8be261d23f05936d65a89e6372a6f5d52cf29d20fa0bc0706af6887e8b903f39f576c848e0bb7bb27bedd310a71a0f70980f7ff44b5309d2a5ef36c356b4aaf0917263250789e0933e3f2ef2b9730e12155d4356c3f470a589fef7f6ac3e77c2d8d08491f40cd1f38edcc3c3b8383d0cbf17de2078c1")] 45 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Rsv.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Rsv.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | internal enum Rsv : byte 30 | { 31 | Off = 0x0, 32 | On = 0x1 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Server/IWebSocketSession.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * IWebSocketSession.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Server 28 | { 29 | using System; 30 | 31 | using WebSocketSharp.Net.WebSockets; 32 | 33 | /// 34 | /// Exposes the properties used to access the information in a session in a WebSocket service. 35 | /// 36 | public interface IWebSocketSession 37 | { 38 | /// 39 | /// Gets the information in the connection request to the WebSocket service. 40 | /// 41 | /// 42 | /// A that provides the access to the connection request. 43 | /// 44 | WebSocketContext Context { get; } 45 | 46 | /// 47 | /// Gets the unique ID of the session. 48 | /// 49 | /// 50 | /// A that represents the unique ID of the session. 51 | /// 52 | string Id { get; } 53 | 54 | /// 55 | /// Gets the WebSocket subprotocol used in the session. 56 | /// 57 | /// 58 | /// A that represents the subprotocol if any. 59 | /// 60 | string Protocol { get; } 61 | 62 | /// 63 | /// Gets the time that the session has started. 64 | /// 65 | /// 66 | /// A that represents the time that the session has started. 67 | /// 68 | DateTime StartTime { get; } 69 | 70 | /// 71 | /// Gets the state of the used in the session. 72 | /// 73 | /// 74 | /// One of the enum values, indicates the state of 75 | /// the used in the session. 76 | /// 77 | WebSocketState State { get; } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Server/ServerState.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ServerState.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2013-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp.Server 28 | { 29 | internal enum ServerState 30 | { 31 | Ready, 32 | Start, 33 | ShuttingDown, 34 | Stop 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Server/WebSocketServiceHost.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServiceHost.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | /* 28 | * Contributors: 29 | * - Juan Manuel Lallana 30 | */ 31 | 32 | namespace WebSocketSharp.Server 33 | { 34 | using System; 35 | using System.Threading.Tasks; 36 | 37 | using WebSocketSharp.Net.WebSockets; 38 | 39 | /// 40 | /// Exposes the methods and properties used to access the information in a WebSocket service provided by the . 41 | /// 42 | /// 43 | /// The WebSocketServiceHost class is an abstract class. 44 | /// 45 | public abstract class WebSocketServiceHost 46 | { 47 | internal ServerState State => Sessions.State; 48 | 49 | /// 50 | /// Gets or sets a value indicating whether the WebSocket service cleans up 51 | /// the inactive sessions periodically. 52 | /// 53 | /// 54 | /// true if the service cleans up the inactive sessions periodically; 55 | /// otherwise, false. 56 | /// 57 | public abstract bool KeepClean { get; set; } 58 | 59 | /// 60 | /// Gets the path to the WebSocket service. 61 | /// 62 | /// 63 | /// A that represents the absolute path to the service. 64 | /// 65 | public abstract string Path { get; } 66 | 67 | /// 68 | /// Gets the access to the sessions in the WebSocket service. 69 | /// 70 | /// 71 | /// A that manages the sessions in the service. 72 | /// 73 | public abstract WebSocketSessionManager Sessions { get; } 74 | 75 | /// 76 | /// Gets the of the behavior of the WebSocket service. 77 | /// 78 | /// 79 | /// A that represents the type of the behavior of the service. 80 | /// 81 | public abstract Type Type { get; } 82 | 83 | /// 84 | /// Gets or sets the wait time for the response to the WebSocket Ping or Close. 85 | /// 86 | /// 87 | /// A that represents the wait time. The default value is 88 | /// the same as 1 second. 89 | /// 90 | public abstract TimeSpan WaitTime { get; set; } 91 | 92 | internal void Start() 93 | { 94 | Sessions.Start(); 95 | } 96 | 97 | internal Task StartSession(WebSocketContext context) 98 | { 99 | var session = CreateSession(); 100 | return session.Start(context, Sessions); 101 | } 102 | 103 | internal async Task Stop(ushort code, string reason) 104 | { 105 | var e = new CloseEventArgs(code, reason); 106 | 107 | var send = !code.IsReserved(); 108 | var bytes = 109 | send ? await WebSocketFrame.CreateCloseFrame(e.PayloadData, false).ToByteArray().ConfigureAwait(false) : null; 110 | 111 | var timeout = send ? WaitTime : TimeSpan.Zero; 112 | await Sessions.Stop(e, bytes, timeout).ConfigureAwait(false); 113 | } 114 | 115 | /// 116 | /// Creates a new session in the WebSocket service. 117 | /// 118 | /// 119 | /// A instance that represents a new session. 120 | /// 121 | protected abstract WebSocketBehavior CreateSession(); 122 | } 123 | 124 | internal class WebSocketServiceHost : WebSocketServiceHost 125 | where TBehavior : WebSocketBehavior 126 | { 127 | private readonly Func _initializer; 128 | private readonly string _path; 129 | private readonly WebSocketSessionManager _sessions; 130 | 131 | internal WebSocketServiceHost(string path, int fragmentSize, Func initializer) 132 | { 133 | _path = path; 134 | _initializer = initializer; 135 | _sessions = new WebSocketSessionManager(fragmentSize); 136 | } 137 | 138 | public override bool KeepClean 139 | { 140 | get 141 | { 142 | return _sessions.KeepClean; 143 | } 144 | 145 | set 146 | { 147 | var msg = _sessions.State.CheckIfStartable(); 148 | if (msg != null) 149 | { 150 | return; 151 | } 152 | 153 | _sessions.KeepClean = value; 154 | } 155 | } 156 | 157 | public override string Path => _path; 158 | 159 | public override WebSocketSessionManager Sessions => _sessions; 160 | 161 | public override Type Type => typeof(TBehavior); 162 | 163 | public override TimeSpan WaitTime 164 | { 165 | get 166 | { 167 | return _sessions.WaitTime; 168 | } 169 | 170 | set 171 | { 172 | var msg = _sessions.State.CheckIfStartable() ?? value.CheckIfValidWaitTime(); 173 | if (msg != null) 174 | { 175 | return; 176 | } 177 | 178 | _sessions.WaitTime = value; 179 | } 180 | } 181 | 182 | protected override WebSocketBehavior CreateSession() 183 | { 184 | return _initializer(); 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /websocket-sharp.clone/Settings.StyleCop: -------------------------------------------------------------------------------- 1 | 2 | 3 | Linked 4 | ..\SolutionSettings.StyleCop 5 | 6 | 7 | -------------------------------------------------------------------------------- /websocket-sharp.clone/StreamReadInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the StreamReadInfo type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp 19 | { 20 | internal class StreamReadInfo 21 | { 22 | public StreamReadInfo(bool isFinal, ulong payloadLength, byte[] maskingKey) 23 | { 24 | IsFinal = isFinal; 25 | PayloadLength = payloadLength; 26 | MaskingKey = maskingKey; 27 | } 28 | 29 | public bool IsFinal { get; } 30 | 31 | public ulong PayloadLength { get; private set; } 32 | 33 | public byte[] MaskingKey { get; } 34 | 35 | public void ReducePayloadLength(ulong reduction) 36 | { 37 | PayloadLength -= reduction; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/SubStream.cs: -------------------------------------------------------------------------------- 1 | namespace WebSocketSharp 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | internal class SubStream : Stream 9 | { 10 | private readonly Stream _innerStream; 11 | private readonly long _length; 12 | 13 | public SubStream(Stream innerStream, long length) 14 | { 15 | if (innerStream == null) 16 | { 17 | throw new ArgumentNullException(nameof(innerStream)); 18 | } 19 | 20 | _innerStream = innerStream; 21 | _length = Math.Max(0, length); 22 | } 23 | 24 | /// 25 | /// When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device. 26 | /// 27 | /// An I/O error occurs. 28 | public override void Flush() 29 | { 30 | _innerStream.Flush(); 31 | } 32 | 33 | public override Task FlushAsync(CancellationToken cancellationToken) 34 | { 35 | return _innerStream.FlushAsync(cancellationToken); 36 | } 37 | 38 | /// 39 | /// When overridden in a derived class, sets the position within the current stream. 40 | /// 41 | /// 42 | /// The new position within the current stream. 43 | /// 44 | /// A byte offset relative to the parameter. A value of type indicating the reference point used to obtain the new position. An I/O error occurs. The stream does not support seeking, such as if the stream is constructed from a pipe or console output. Methods were called after the stream was closed. 45 | public override long Seek(long offset, SeekOrigin origin) 46 | { 47 | switch (origin) 48 | { 49 | case SeekOrigin.Begin: 50 | if (offset > _length) 51 | { 52 | throw new ArgumentOutOfRangeException(nameof(offset)); 53 | } 54 | break; 55 | case SeekOrigin.Current: 56 | if (Position + offset > _length) 57 | { 58 | throw new ArgumentOutOfRangeException(nameof(offset)); 59 | } 60 | break; 61 | case SeekOrigin.End: 62 | throw new NotSupportedException(nameof(origin)); 63 | default: 64 | throw new ArgumentOutOfRangeException(nameof(origin), origin, null); 65 | } 66 | 67 | return _innerStream.Seek(offset, origin); 68 | } 69 | 70 | /// 71 | /// When overridden in a derived class, sets the length of the current stream. 72 | /// 73 | /// The desired length of the current stream in bytes. An I/O error occurs. The stream does not support both writing and seeking, such as if the stream is constructed from a pipe or console output. Methods were called after the stream was closed. 74 | public override void SetLength(long value) 75 | { 76 | throw new NotSupportedException(); 77 | } 78 | 79 | /// 80 | /// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. 81 | /// 82 | /// 83 | /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached. 84 | /// 85 | /// An array of bytes. When this method returns, the buffer contains the specified byte array with the values between and ( + - 1) replaced by the bytes read from the current source. The zero-based byte offset in at which to begin storing the data read from the current stream. The maximum number of bytes to be read from the current stream. The sum of and is larger than the buffer length. is null. or is negative. An I/O error occurs. The stream does not support reading. Methods were called after the stream was closed. 86 | public override int Read(byte[] buffer, int offset, int count) 87 | { 88 | var actualCount = (int)Math.Min(_length - Position, count); 89 | return _innerStream.Read(buffer, offset, actualCount); 90 | } 91 | 92 | public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) 93 | { 94 | var actualCount = (int)Math.Min(_length - Position, count); 95 | return _innerStream.ReadAsync(buffer, offset, actualCount, cancellationToken); 96 | } 97 | 98 | /// 99 | /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. 100 | /// 101 | /// An array of bytes. This method copies bytes from to the current stream. The zero-based byte offset in at which to begin copying bytes to the current stream. The number of bytes to be written to the current stream. 102 | public override void Write(byte[] buffer, int offset, int count) 103 | { 104 | throw new NotSupportedException(); 105 | } 106 | 107 | public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) 108 | { 109 | throw new NotSupportedException(); 110 | } 111 | 112 | /// 113 | /// When overridden in a derived class, gets a value indicating whether the current stream supports reading. 114 | /// 115 | /// 116 | /// true if the stream supports reading; otherwise, false. 117 | /// 118 | public override bool CanRead => true; 119 | 120 | /// 121 | /// When overridden in a derived class, gets a value indicating whether the current stream supports seeking. 122 | /// 123 | /// 124 | /// true if the stream supports seeking; otherwise, false. 125 | /// 126 | public override bool CanSeek => true; 127 | 128 | /// 129 | /// When overridden in a derived class, gets a value indicating whether the current stream supports writing. 130 | /// 131 | /// 132 | /// true if the stream supports writing; otherwise, false. 133 | /// 134 | public override bool CanWrite => false; 135 | 136 | /// 137 | /// When overridden in a derived class, gets the length in bytes of the stream. 138 | /// 139 | /// 140 | /// A long value representing the length of the stream in bytes. 141 | /// 142 | /// A class derived from Stream does not support seeking. Methods were called after the stream was closed. 143 | public override long Length => _length; 144 | 145 | /// 146 | /// When overridden in a derived class, gets or sets the position within the current stream. 147 | /// 148 | /// 149 | /// The current position within the stream. 150 | /// 151 | /// An I/O error occurs. The stream does not support seeking. Methods were called after the stream was closed. 152 | public override long Position 153 | { 154 | get 155 | { 156 | return _innerStream.Position; 157 | } 158 | set 159 | { 160 | if (value > _length) 161 | { 162 | throw new ArgumentOutOfRangeException(nameof(value)); 163 | } 164 | _innerStream.Position = value; 165 | } 166 | } 167 | } 168 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketDataStream.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the WebSocketDataStream type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp 19 | { 20 | using System; 21 | using System.Diagnostics; 22 | using System.IO; 23 | using System.Threading; 24 | using System.Threading.Tasks; 25 | 26 | internal class WebSocketDataStream : Stream 27 | { 28 | private readonly Func> _readInfoFunc; 29 | private readonly Func _consumedAction; 30 | private readonly Stream _innerStream; 31 | private StreamReadInfo _readInfo; 32 | 33 | private long _position; 34 | 35 | public WebSocketDataStream(Stream innerStream, StreamReadInfo initialReadInfo, Func> readInfoFunc, Func consumedAction) 36 | { 37 | _innerStream = innerStream; 38 | _readInfo = initialReadInfo; 39 | _readInfoFunc = readInfoFunc; 40 | _consumedAction = consumedAction; 41 | } 42 | 43 | public override void Flush() 44 | { 45 | } 46 | 47 | public override long Seek(long offset, SeekOrigin origin) 48 | { 49 | throw new NotSupportedException(); 50 | } 51 | 52 | public override void SetLength(long value) 53 | { 54 | throw new NotSupportedException(); 55 | } 56 | 57 | public override int Read(byte[] buffer, int offset, int count) 58 | { 59 | var task = ReadAsync(buffer, offset, count, CancellationToken.None); 60 | return task.Result; 61 | } 62 | 63 | public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) 64 | { 65 | var position = offset; 66 | var bytesRead = 0; 67 | 68 | while (bytesRead < count && _readInfo.PayloadLength > 0) 69 | { 70 | var toread = Math.Min((ulong)(count - bytesRead), _readInfo.PayloadLength); 71 | toread = Math.Min(toread, int.MaxValue); 72 | 73 | var read = await _innerStream.ReadAsync(buffer, position, (int)toread, cancellationToken).ConfigureAwait(false); 74 | bytesRead += read; 75 | 76 | _readInfo.ReducePayloadLength(Convert.ToUInt32(read)); 77 | 78 | if (_readInfo.MaskingKey.Length > 0) 79 | { 80 | var max = position + (int)toread; 81 | 82 | for (var pos = position; pos < max; pos++) 83 | { 84 | buffer[pos] = (byte)(buffer[pos] ^ _readInfo.MaskingKey[pos % 4]); 85 | } 86 | } 87 | 88 | position += read; 89 | _position = position; 90 | if (_readInfo.PayloadLength == 0) 91 | { 92 | if (!_readInfo.IsFinal) 93 | { 94 | try 95 | { 96 | _readInfo = await _readInfoFunc().ConfigureAwait(false); 97 | } 98 | catch 99 | { 100 | Debug.WriteLine("Failed at position {0}", Position); 101 | } 102 | } 103 | else 104 | { 105 | await _consumedAction().ConfigureAwait(false); 106 | } 107 | } 108 | } 109 | 110 | return bytesRead; 111 | } 112 | 113 | public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) 114 | { 115 | throw new NotSupportedException(); 116 | } 117 | 118 | public override int EndRead(IAsyncResult asyncResult) 119 | { 120 | throw new NotSupportedException(); 121 | } 122 | 123 | public override int ReadByte() 124 | { 125 | var buffer = new byte[1]; 126 | var bytesRead = Read(buffer, 0, 1); 127 | return bytesRead == 0 ? -1 : buffer[0]; 128 | } 129 | 130 | public override void Write(byte[] buffer, int offset, int count) 131 | { 132 | throw new NotSupportedException(); 133 | } 134 | 135 | public override bool CanRead => true; 136 | 137 | public override bool CanSeek => false; 138 | 139 | public override bool CanWrite => false; 140 | 141 | public override long Length 142 | { 143 | get 144 | { 145 | throw new NotSupportedException(); 146 | } 147 | } 148 | 149 | public override long Position 150 | { 151 | get 152 | { 153 | return _position; 154 | } 155 | set 156 | { 157 | throw new NotSupportedException(); 158 | } 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketException.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketException.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | 31 | /// 32 | /// The exception that is thrown when a gets a fatal error. 33 | /// 34 | internal class WebSocketException : Exception 35 | { 36 | private readonly CloseStatusCode _code; 37 | 38 | internal WebSocketException(string message) 39 | : this(CloseStatusCode.Abnormal, message, null) 40 | { 41 | } 42 | 43 | internal WebSocketException(string message, Exception innerException) 44 | : this(CloseStatusCode.Abnormal, message, innerException) 45 | { 46 | } 47 | 48 | internal WebSocketException(CloseStatusCode code, string message, Exception innerException = null) 49 | : base(message ?? code.GetMessage(), innerException) 50 | { 51 | _code = code; 52 | } 53 | 54 | /// 55 | /// Gets the status code indicating the cause of the exception. 56 | /// 57 | /// 58 | /// One of the enum values, represents the status code 59 | /// indicating the cause of the exception. 60 | /// 61 | public CloseStatusCode Code => _code; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketFrame.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketFrame.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | using System; 30 | using System.Collections; 31 | using System.Collections.Generic; 32 | using System.IO; 33 | using System.Threading.Tasks; 34 | 35 | internal class WebSocketFrame : IEnumerable 36 | { 37 | private readonly byte[] _extPayloadLength; 38 | private readonly Fin _fin; 39 | private readonly Mask _mask; 40 | private readonly byte[] _maskingKey; 41 | private readonly Opcode _opcode; 42 | private readonly PayloadData _payloadData; 43 | private readonly byte _payloadLength; 44 | private readonly Rsv _rsv1; 45 | private readonly Rsv _rsv2; 46 | private readonly Rsv _rsv3; 47 | 48 | internal static readonly byte[] EmptyUnmaskPingBytes; 49 | 50 | static WebSocketFrame() 51 | { 52 | EmptyUnmaskPingBytes = CreatePingFrame(false).ToByteArray().Result; 53 | } 54 | 55 | internal WebSocketFrame(Fin fin, Opcode opcode, byte[] data, bool compressed, bool mask) 56 | : this(fin, opcode, new PayloadData(data), compressed, mask) 57 | { 58 | } 59 | 60 | private WebSocketFrame(Fin fin, Opcode opcode, PayloadData payloadData, bool compressed, bool mask) 61 | { 62 | _fin = fin; 63 | _rsv1 = IsData(opcode) && compressed ? Rsv.On : Rsv.Off; 64 | _rsv2 = Rsv.Off; 65 | _rsv3 = Rsv.Off; 66 | _opcode = opcode; 67 | 68 | var len = payloadData.Length; 69 | if (len < 126) 70 | { 71 | _payloadLength = (byte)len; 72 | _extPayloadLength = new byte[0]; 73 | } 74 | else if (len < 0x010000) 75 | { 76 | _payloadLength = 126; 77 | _extPayloadLength = ((ushort)len).InternalToByteArray(ByteOrder.Big); 78 | } 79 | else 80 | { 81 | _payloadLength = 127; 82 | _extPayloadLength = len.InternalToByteArray(ByteOrder.Big); 83 | } 84 | 85 | if (mask) 86 | { 87 | _mask = Mask.Mask; 88 | _maskingKey = CreateMaskingKey(); 89 | payloadData.Mask(_maskingKey); 90 | } 91 | else 92 | { 93 | _mask = Mask.Unmask; 94 | _maskingKey = new byte[0]; 95 | } 96 | 97 | _payloadData = payloadData; 98 | } 99 | 100 | private static byte[] CreateMaskingKey() 101 | { 102 | var key = new byte[4]; 103 | var rand = new Random(); 104 | rand.NextBytes(key); 105 | 106 | return key; 107 | } 108 | 109 | private static bool IsData(Opcode opcode) 110 | { 111 | return opcode == Opcode.Text || opcode == Opcode.Binary; 112 | } 113 | 114 | internal static WebSocketFrame CreateCloseFrame(PayloadData payloadData, bool mask) 115 | { 116 | return new WebSocketFrame(Fin.Final, Opcode.Close, payloadData, false, mask); 117 | } 118 | 119 | internal static WebSocketFrame CreatePingFrame(bool mask) 120 | { 121 | return new WebSocketFrame(Fin.Final, Opcode.Ping, new PayloadData(), false, mask); 122 | } 123 | 124 | internal static WebSocketFrame CreatePingFrame(byte[] data, bool mask) 125 | { 126 | return new WebSocketFrame(Fin.Final, Opcode.Ping, new PayloadData(data), false, mask); 127 | } 128 | 129 | internal static WebSocketFrame CreatePongFrame(byte[] data, bool mask) 130 | { 131 | return new WebSocketFrame(Fin.Final, Opcode.Pong, new PayloadData(data), false, mask); 132 | } 133 | 134 | public IEnumerator GetEnumerator() 135 | { 136 | return ((IEnumerable)ToByteArray()).GetEnumerator(); 137 | } 138 | 139 | public async Task ToByteArray() 140 | { 141 | using (var buff = new MemoryStream()) 142 | { 143 | var header = (int)_fin; 144 | header = (header << 1) + (int)_rsv1; 145 | header = (header << 1) + (int)_rsv2; 146 | header = (header << 1) + (int)_rsv3; 147 | header = (header << 4) + (int)_opcode; 148 | header = (header << 1) + (int)_mask; 149 | header = (header << 7) + _payloadLength; 150 | await buff.WriteAsync(((ushort)header).InternalToByteArray(ByteOrder.Big), 0, 2).ConfigureAwait(false); 151 | 152 | if (_payloadLength > 125) 153 | { 154 | await buff.WriteAsync(_extPayloadLength, 0, _extPayloadLength.Length).ConfigureAwait(false); 155 | } 156 | 157 | if (_mask == Mask.Mask) 158 | { 159 | await buff.WriteAsync(_maskingKey, 0, _maskingKey.Length).ConfigureAwait(false); 160 | } 161 | 162 | if (_payloadLength > 0) 163 | { 164 | var payload = _payloadData.ToByteArray(); 165 | if (_payloadLength < 127) 166 | { 167 | await buff.WriteAsync(payload, 0, payload.Length).ConfigureAwait(false); 168 | } 169 | else 170 | { 171 | await buff.WriteBytes(payload).ConfigureAwait(false); 172 | } 173 | } 174 | 175 | buff.Close(); 176 | return buff.ToArray(); 177 | } 178 | } 179 | 180 | public override string ToString() 181 | { 182 | var byteArray = ToByteArray().Result; 183 | return BitConverter.ToString(byteArray); 184 | } 185 | 186 | IEnumerator IEnumerable.GetEnumerator() 187 | { 188 | return GetEnumerator(); 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketFrameHeader.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the WebSocketFrameHeader type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp 19 | { 20 | using System.Diagnostics; 21 | 22 | internal class WebSocketFrameHeader 23 | { 24 | public WebSocketFrameHeader(byte[] header) 25 | { 26 | /* Header */ 27 | 28 | // FIN 29 | Fin = (header[0] & 0x80) == 0x80 ? Fin.Final : Fin.More; 30 | // RSV1 31 | Rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off; 32 | // RSV2 33 | Rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off; 34 | // RSV3 35 | Rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off; 36 | // Opcode 37 | Opcode = (Opcode)(header[0] & 0x0f); 38 | // MASK 39 | Mask = (header[1] & 0x80) == 0x80 ? Mask.Mask : Mask.Unmask; 40 | // Payload Length 41 | PayloadLength = (byte)(header[1] & 0x7f); 42 | } 43 | 44 | public Fin Fin { get; private set; } 45 | 46 | public Rsv Rsv1 { get; private set; } 47 | 48 | public Rsv Rsv2 { get; private set; } 49 | 50 | public Rsv Rsv3 { get; private set; } 51 | 52 | public Opcode Opcode { get; private set; } 53 | 54 | public Mask Mask { get; private set; } 55 | 56 | public byte PayloadLength { get; private set; } 57 | 58 | public static string Validate(WebSocketFrameHeader header) 59 | { 60 | // Check if valid header 61 | var err = IsControl(header.Opcode) && header.PayloadLength > 125 62 | ? "A control frame has a payload data which is greater than the allowable max size." 63 | : IsControl(header.Opcode) && header.Fin == Fin.More 64 | ? "A control frame is fragmented." 65 | : !IsData(header.Opcode) && header.Rsv1 == Rsv.On 66 | ? "A non data frame (" + header.Opcode + ") is compressed." 67 | : null; 68 | 69 | if (!string.IsNullOrWhiteSpace(err)) 70 | { 71 | Trace.TraceError(err); 72 | } 73 | 74 | return err; 75 | } 76 | 77 | private static bool IsControl(Opcode opcode) 78 | { 79 | return opcode == Opcode.Close || opcode == Opcode.Ping || opcode == Opcode.Pong; 80 | } 81 | 82 | private static bool IsData(Opcode opcode) 83 | { 84 | return opcode == Opcode.Text || opcode == Opcode.Binary; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketMessage.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the WebSocketMessage type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp 19 | { 20 | using System.IO; 21 | using System.Threading; 22 | using System.Threading.Tasks; 23 | 24 | internal abstract class WebSocketMessage 25 | { 26 | private readonly SemaphoreSlim _waitHandle; 27 | 28 | private readonly int _fragmentLength; 29 | 30 | protected WebSocketMessage(Opcode opcode, SemaphoreSlim waitHandle, int fragmentLength) 31 | { 32 | _waitHandle = waitHandle; 33 | _fragmentLength = fragmentLength; 34 | Opcode = opcode; 35 | } 36 | 37 | public Opcode Opcode { get; private set; } 38 | 39 | public abstract Stream RawData { get; } 40 | 41 | public abstract StreamReader Text { get; } 42 | 43 | internal async Task Consume() 44 | { 45 | if (RawData != null) 46 | { 47 | var buffer = new byte[_fragmentLength]; 48 | while (await RawData.ReadAsync(buffer, 0, _fragmentLength).ConfigureAwait(false) == _fragmentLength) 49 | { 50 | } 51 | } 52 | 53 | _waitHandle.Release(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketSharp.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 | WebSocketSharp 12 | v4.5 13 | true 14 | ..\websocket-sharp.snk 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | 22 | 23 | true 24 | full 25 | false 26 | bin\Debug 27 | DEBUG 28 | prompt 29 | 4 30 | false 31 | false 32 | 33 | 34 | pdbonly 35 | false 36 | bin\Release 37 | prompt 38 | 4 39 | false 40 | false 41 | $(OutputPath)\WebSocketSharp.xml 42 | 43 | 44 | true 45 | full 46 | false 47 | bin\Debug_Ubuntu 48 | DEBUG 49 | prompt 50 | 4 51 | false 52 | false 53 | 54 | 55 | none 56 | false 57 | bin\Release_Ubuntu 58 | prompt 59 | 4 60 | false 61 | true 62 | 63 | 64 | 65 | 66 | 67 | false 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 | -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketState.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketState.cs 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2010-2014 sta.blockhead 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | namespace WebSocketSharp 28 | { 29 | /// 30 | /// Contains the values of the state of the WebSocket connection. 31 | /// 32 | /// 33 | /// The values of the state are defined in 34 | /// The WebSocket API. 35 | /// 36 | public enum WebSocketState : ushort 37 | { 38 | /// 39 | /// Equivalent to numeric value 0. 40 | /// Indicates that the connection hasn't yet been established. 41 | /// 42 | Connecting = 0, 43 | 44 | /// 45 | /// Equivalent to numeric value 1. 46 | /// Indicates that the connection is established and the communication is possible. 47 | /// 48 | Open = 1, 49 | 50 | /// 51 | /// Equivalent to numeric value 2. 52 | /// Indicates that the connection is going through the closing handshake or 53 | /// the WebSocket.Close method has been invoked. 54 | /// 55 | Closing = 2, 56 | 57 | /// 58 | /// Equivalent to numeric value 3. 59 | /// Indicates that the connection has been closed or couldn't be opened. 60 | /// 61 | Closed = 3 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /websocket-sharp.clone/WebSocketStreamReader.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // The MIT License 4 | // Copyright (c) 2012-2014 sta.blockhead 5 | // Copyright (c) 2014 Reimers.dk 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | // 11 | // 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. 12 | // 13 | // 14 | // Defines the WebSocketStreamReader type. 15 | // 16 | // -------------------------------------------------------------------------------------------------------------------- 17 | 18 | namespace WebSocketSharp 19 | { 20 | using System.IO; 21 | using System.Threading; 22 | using System.Threading.Tasks; 23 | 24 | internal class WebSocketStreamReader 25 | { 26 | private readonly Stream _innerStream; 27 | private readonly int _fragmentLength; 28 | private readonly SemaphoreSlim _waitHandle = new SemaphoreSlim(1); 29 | private bool _isClosed; 30 | 31 | public WebSocketStreamReader(Stream innerStream, int fragmentLength) 32 | { 33 | _innerStream = innerStream; 34 | _fragmentLength = fragmentLength; 35 | } 36 | 37 | public async Task Read(CancellationToken cancellationToken) 38 | { 39 | WebSocketFrameHeader header; 40 | StreamReadInfo readInfo = null; 41 | 42 | await _waitHandle.WaitAsync(cancellationToken).ConfigureAwait(false); 43 | 44 | if (_isClosed) 45 | { 46 | return null; 47 | } 48 | 49 | header = await ReadHeader(cancellationToken).ConfigureAwait(false); 50 | if (header == null) 51 | { 52 | return null; 53 | } 54 | 55 | readInfo = await GetStreamReadInfo(header, cancellationToken).ConfigureAwait(false); 56 | 57 | var msg = CreateMessage(header, readInfo, _waitHandle); 58 | if (msg.Opcode == Opcode.Close) 59 | { 60 | _isClosed = true; 61 | } 62 | 63 | return msg; 64 | } 65 | 66 | private WebSocketMessage CreateMessage(WebSocketFrameHeader header, StreamReadInfo readInfo, SemaphoreSlim waitHandle) 67 | { 68 | switch (header.Opcode) 69 | { 70 | case Opcode.Cont: 71 | throw new WebSocketException(CloseStatusCode.InconsistentData, "Did not expect continuation frame."); 72 | default: 73 | case Opcode.Close: 74 | case Opcode.Text: 75 | case Opcode.Binary: 76 | return new FragmentedMessage(header.Opcode, _innerStream, readInfo, GetStreamReadInfo, waitHandle, _fragmentLength); 77 | } 78 | } 79 | 80 | private async Task GetStreamReadInfo() 81 | { 82 | var h = await ReadHeader(CancellationToken.None).ConfigureAwait(false); 83 | return await GetStreamReadInfo(h, CancellationToken.None).ConfigureAwait(false); 84 | } 85 | 86 | private async Task GetStreamReadInfo(WebSocketFrameHeader header, CancellationToken cancellationToken) 87 | { 88 | cancellationToken.ThrowIfCancellationRequested(); 89 | /* Extended Payload Length */ 90 | 91 | var size = header.PayloadLength < 126 ? 0 : header.PayloadLength == 126 ? 2 : 8; 92 | 93 | var extPayloadLen = size > 0 ? await _innerStream.ReadBytes(size).ConfigureAwait(false) : new byte[0]; 94 | if (size > 0 && extPayloadLen.Length != size) 95 | { 96 | throw new WebSocketException("The 'Extended Payload Length' of a frame cannot be read from the data source."); 97 | } 98 | 99 | /* Masking Key */ 100 | 101 | var masked = header.Mask == Mask.Mask; 102 | var maskingKey = masked ? await _innerStream.ReadBytes(4).ConfigureAwait(false) : new byte[0]; 103 | if (masked && maskingKey.Length != 4) 104 | { 105 | throw new WebSocketException("The 'Masking Key' of a frame cannot be read from the data source."); 106 | } 107 | 108 | /* Payload Data */ 109 | 110 | var len = header.PayloadLength < 126 111 | ? header.PayloadLength 112 | : header.PayloadLength == 126 113 | ? extPayloadLen.ToUInt16(ByteOrder.Big) 114 | : extPayloadLen.ToUInt64(ByteOrder.Big); 115 | 116 | return new StreamReadInfo(header.Fin == Fin.Final, len, maskingKey); 117 | } 118 | 119 | private async Task ReadHeader(CancellationToken cancellationToken) 120 | { 121 | cancellationToken.ThrowIfCancellationRequested(); 122 | var header = new byte[2]; 123 | 124 | var headerLength = 0; 125 | try 126 | { 127 | headerLength = await _innerStream.ReadAsync(header, 0, 2, cancellationToken).ConfigureAwait(false); 128 | } 129 | catch (IOException) 130 | { 131 | return null; 132 | } 133 | 134 | if (headerLength == 0) 135 | { 136 | return null; 137 | } 138 | 139 | if (headerLength != 2) 140 | { 141 | throw new WebSocketException("The header part of a frame cannot be read from the data source."); 142 | } 143 | 144 | var frameHeader = new WebSocketFrameHeader(header); 145 | var validation = WebSocketFrameHeader.Validate(frameHeader); 146 | 147 | if (validation != null) 148 | { 149 | throw new WebSocketException(CloseStatusCode.ProtocolError, validation); 150 | } 151 | 152 | return frameHeader; 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/doc/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore MonoDevelop build results. 2 | 3 | html 4 | mdoc 5 | -------------------------------------------------------------------------------- /websocket-sharp.clone/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 | -------------------------------------------------------------------------------- /websocket-sharp.clone/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.0.0-*", 3 | "title": "WebSocket#", 4 | "description": "WebSocket# provides the WebSocket protocol client and server.\r\n\r\nIt supports:\r\n- WebSocket Client and Server\r\n- RFC 6455\r\n- Per-message Compression extension\r\n- Secure Connection\r\n- HTTP Authentication\r\n- Query String, Origin header and Cookies\r\n- Infinite streaming\r\n- .NET 4.5 or later", 5 | "authors": [ "Jacob Reimers" ], 6 | "owners": [ "Jacob Reimers" ], 7 | "tags": [ "websocket" ], 8 | "requireLicenseAcceptance": false, 9 | "projectUrl": "https://github.com/jjrdk/websocket-sharp", 10 | "licenseUrl": "https://raw.githubusercontent.com/jjrdk/websocket-sharp/master/LICENSE.txt", 11 | "summary": "This is a clone of websocket-sharp which is updated to use .NET 4.5 in order to make use of task based asynchronicity.", 12 | "releaseNotes": "This version removes all synchronous reads and writes.", 13 | "dependencies": { 14 | }, 15 | 16 | "runtimes": { 17 | "win": { }, 18 | "linux": { }, 19 | "osx": { } 20 | }, 21 | "frameworks": { 22 | "net45": { } 23 | } 24 | } -------------------------------------------------------------------------------- /websocket-sharp.clone/websocket-sharp.clone.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | e3718457-ea93-4d8c-b187-439230f0d271 10 | WebSocketSharp 11 | ..\artifacts\obj\$(MSBuildProjectName) 12 | ..\artifacts\bin\$(MSBuildProjectName)\ 13 | 14 | 15 | 2.0 16 | 17 | 18 | True 19 | 20 | 21 | True 22 | 23 | 24 | -------------------------------------------------------------------------------- /websocket-sharp.ruleset: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /websocket-sharp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebSocketSharp.Tests", "WebSocketSharp.Tests\WebSocketSharp.Tests.csproj", "{D24DD051-53FD-4567-B6AD-F6306E715E47}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{06BF336E-24FF-4267-A4AE-0D0CA8BB60F4}" 9 | ProjectSection(SolutionItems) = preProject 10 | .gitignore = .gitignore 11 | global.json = global.json 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebSocketSharp", "websocket-sharp.clone\WebSocketSharp.csproj", "{B357BAC7-529E-4D81-A0D2-71041B19C8DE}" 16 | EndProject 17 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "websocket-sharp.clone", "websocket-sharp.clone\websocket-sharp.clone.xproj", "{E3718457-EA93-4D8C-B187-439230F0D271}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Release|Any CPU = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {D24DD051-53FD-4567-B6AD-F6306E715E47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {D24DD051-53FD-4567-B6AD-F6306E715E47}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {D24DD051-53FD-4567-B6AD-F6306E715E47}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {D24DD051-53FD-4567-B6AD-F6306E715E47}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {E3718457-EA93-4D8C-B187-439230F0D271}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {E3718457-EA93-4D8C-B187-439230F0D271}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {E3718457-EA93-4D8C-B187-439230F0D271}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {E3718457-EA93-4D8C-B187-439230F0D271}.Release|Any CPU.Build.0 = Release|Any CPU 37 | EndGlobalSection 38 | GlobalSection(SolutionProperties) = preSolution 39 | HideSolutionNode = FALSE 40 | EndGlobalSection 41 | GlobalSection(MonoDevelopProperties) = preSolution 42 | StartupItem = websocket-sharp\websocket-sharp.csproj 43 | Policies = $0 44 | $0.TextStylePolicy = $1 45 | $1.inheritsSet = null 46 | $1.scope = text/x-csharp 47 | $0.CSharpFormattingPolicy = $2 48 | $2.inheritsSet = Mono 49 | $2.inheritsScope = text/x-csharp 50 | $2.scope = text/x-csharp 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /websocket-sharp.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrdk/websocket-sharp/6e998c6652e648081d892e1b34e7d006a85dfd90/websocket-sharp.snk -------------------------------------------------------------------------------- /websocket-sharp_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrdk/websocket-sharp/6e998c6652e648081d892e1b34e7d006a85dfd90/websocket-sharp_icon.png -------------------------------------------------------------------------------- /websocket-sharp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjrdk/websocket-sharp/6e998c6652e648081d892e1b34e7d006a85dfd90/websocket-sharp_logo.png --------------------------------------------------------------------------------