fix Ext.cs, WebSocket.cs for implementation of Sec-WebSocket-Key*.

This commit is contained in:
sta
2010-10-25 20:56:26 +09:00
parent 3f5215844f
commit b683db43fc
23 changed files with 159 additions and 11 deletions

View File

@@ -33,11 +33,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Security.Cryptography;
namespace WebSocketSharp
{
@@ -256,17 +258,39 @@ namespace WebSocketSharp
host += ":" + port;
}
string subprotocol = protocol != String.Empty
string subProtocol = protocol != String.Empty
? String.Format("Sec-WebSocket-Protocol: {0}\r\n", protocol)
: protocol;
#if !CHALLENGE
string secKeys = String.Empty;
string key3AsASCII = String.Empty;
#else
Random rand = new Random();
uint key1, key2;
string secKey1 = rand.GenerateSecKey(out key1);
string secKey2 = rand.GenerateSecKey(out key2);
byte[] key3 = new byte[8].InitializeWithASCII(rand);
string secKeys = "Sec-WebSocket-Key1: {0}\r\n" +
"Sec-WebSocket-Key2: {1}\r\n";
secKeys = String.Format(secKeys, secKey1, secKey2);
string key3AsASCII = Encoding.ASCII.GetString(key3);
byte[] expectedRes = createExpectedRes(key1, key2, key3);
byte[] actualRes = new byte[16];
#endif
string request = "GET " + path + " HTTP/1.1\r\n" +
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
subprotocol +
subProtocol +
"Host: " + host + "\r\n" +
"Origin: " + origin + "\r\n" +
"\r\n";
secKeys +
"\r\n" +
key3AsASCII;
#if DEBUG
Console.WriteLine("WS: Info @doHandshake: Handshake from client: \n{0}", request);
#endif
@@ -283,6 +307,10 @@ namespace WebSocketSharp
wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata))
{
#if CHALLENGE
wsStream.Read(actualRes, 0, actualRes.Length);
rawdata.AddRange(actualRes);
#endif
break;
}
}
@@ -297,15 +325,25 @@ namespace WebSocketSharp
Console.WriteLine("{0}", s);
}
#endif
Action<string> action = s => { throw new IOException("Invalid handshake response: " + s); };
Action<string, string> action = (a, b) =>
{
throw new IOException("Invalid handshake response: " + a);
};
#if !CHALLENGE
response[0].NotEqualsDo("HTTP/1.1 101 Web Socket Protocol Handshake", action);
#else
response[0].NotEqualsDo("HTTP/1.1 101 WebSocket Protocol Handshake", action);
#endif
response[1].NotEqualsDo("Upgrade: WebSocket", action);
response[2].NotEqualsDo("Connection: Upgrade", action);
for (int i = 3; i < response.Length; i++)
{
#if !CHALLENGE
if (response[i].Contains("WebSocket-Protocol:"))
// if (response[i].Contains("Sec-WebSocket-Protocol:"))
#else
if (response[i].Contains("Sec-WebSocket-Protocol:"))
#endif
{
int j = response[i].IndexOf(":");
protocol = response[i].Substring(j + 1).Trim();
@@ -315,10 +353,39 @@ namespace WebSocketSharp
#if DEBUG
Console.WriteLine("WS: Info @doHandshake: Sub protocol: {0}", protocol);
#endif
#if CHALLENGE
string expectedResHexStr = BitConverter.ToString(expectedRes);
string actualResHexStr = BitConverter.ToString(actualRes);
actualResHexStr.NotEqualsDo(expectedResHexStr, (a, b) =>
{
Console.WriteLine("WS: Error @doHandshake: Invalid challenge response.");
Console.WriteLine("\texpected: {0}", b);
Console.WriteLine("\tactual : {0}", a);
throw new IOException("Invalid challenge response: " + a);
}
);
#if DEBUG
Console.WriteLine("WS: Info @doHandshake: challenge response: {0}", actualResHexStr);
#endif
#endif
ReadyState = WsState.OPEN;
}
private byte[] createExpectedRes(uint key1, uint key2, byte[] key3)
{
byte[] key1Bytes = BitConverter.GetBytes(key1);
byte[] key2Bytes = BitConverter.GetBytes(key2);
Array.Reverse(key1Bytes);
Array.Reverse(key2Bytes);
byte[] concatKeys = key1Bytes.Concat(key2Bytes).Concat(key3).ToArray();
MD5 md5 = MD5.Create();
return md5.ComputeHash(concatKeys);
}
private void message()
{
#if DEBUG