fix Ext.cs, WebSocket.cs

This commit is contained in:
sta 2010-11-09 22:06:20 +09:00
parent 240a4e61ba
commit ab1f09283b
34 changed files with 85 additions and 54 deletions

View File

@ -1,8 +1,8 @@
<Properties> <Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug_Ubuntu" ctype="Workspace" /> <MonoDevelop.Ide.Workspace ActiveConfiguration="Release_Ubuntu" ctype="Workspace" />
<MonoDevelop.Ide.Workbench ActiveDocument="websocket-sharp/WebSocket.cs" ctype="Workbench"> <MonoDevelop.Ide.Workbench ActiveDocument="websocket-sharp/WebSocket.cs" ctype="Workbench">
<Files> <Files>
<File FileName="websocket-sharp/WebSocket.cs" Line="142" Column="22" /> <File FileName="websocket-sharp/WebSocket.cs" Line="282" Column="1" />
</Files> </Files>
</MonoDevelop.Ide.Workbench> </MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints> <MonoDevelop.Ide.DebuggingService.Breakpoints>

View File

@ -34,6 +34,22 @@ namespace WebSocketSharp
{ {
public static class Ext public static class Ext
{ {
public static bool AreNotEqualDo(
this string expected,
string actual,
Func<string, string, string> func,
out string ret)
{
if (expected != actual)
{
ret = func(expected, actual);
return true;
}
ret = String.Empty;
return false;
}
public static bool EqualsWithSaveTo(this int asByte, char c, List<byte> dist) public static bool EqualsWithSaveTo(this int asByte, char c, List<byte> dist)
{ {
byte b = (byte)asByte; byte b = (byte)asByte;
@ -83,7 +99,7 @@ namespace WebSocketSharp
return new String(secKey.ToArray()); return new String(secKey.ToArray());
} }
public static Byte[] InitializeWithPrintableASCII(this Byte[] bytes, Random rand) public static byte[] InitializeWithPrintableASCII(this byte[] bytes, Random rand)
{ {
for (int i = 0; i < bytes.Length; i++) for (int i = 0; i < bytes.Length; i++)
{ {
@ -93,12 +109,39 @@ namespace WebSocketSharp
return bytes; return bytes;
} }
public static void AreNotEqualDo(this string expected, string actual, Action<string, string> act) public static bool IsValid(this string[] response, byte[] expectedCR, byte[] actualCR, out string message)
{ {
if (expected != actual) string expectedCRtoHexStr = BitConverter.ToString(expectedCR);
string actualCRtoHexStr = BitConverter.ToString(actualCR);
Func<string, Func<string, string, string>> func = s =>
{ {
act(expected, actual); return (e, a) =>
{
#if DEBUG
Console.WriteLine("WS: Error @IsValid: Invalid {0} response.", s);
Console.WriteLine(" expected: {0}", e);
Console.WriteLine(" actual : {0}", a);
#endif
return String.Format("Invalid {0} response: {1}", s, a);
};
};
Func<string, string, string> func1 = func("handshake");
Func<string, string, string> func2 = func("challenge");
string msg;
if ("HTTP/1.1 101 WebSocket Protocol Handshake".AreNotEqualDo(response[0], func1, out msg) ||
"Upgrade: WebSocket".AreNotEqualDo(response[1], func1, out msg) ||
"Connection: Upgrade".AreNotEqualDo(response[2], func1, out msg) ||
expectedCRtoHexStr.AreNotEqualDo(actualCRtoHexStr, func2, out msg))
{
message = msg;
return false;
} }
message = String.Empty;
return true;
} }
public static void Times(this int n, Action act) public static void Times(this int n, Action act)

View File

@ -281,33 +281,12 @@ namespace WebSocketSharp
private void doHandshake() private void doHandshake()
{ {
byte[] expectedRes, actualRes = new byte[16]; byte[] expectedCR, actualCR;
string request = createOpeningHandshake(out expectedRes); string request = createOpeningHandshake(out expectedCR);
#if DEBUG #if DEBUG
Console.WriteLine("WS: Info @doHandshake: Handshake from client: \n{0}", request); Console.WriteLine("WS: Info @doHandshake: Handshake from client: \n{0}", request);
#endif #endif
byte[] sendBuffer = Encoding.UTF8.GetBytes(request); string[] response = sendOpeningHandshake(request, out actualCR);
wsStream.Write(sendBuffer, 0, sendBuffer.Length);
string[] response;
List<byte> rawdata = new List<byte>();
while (true)
{
if (wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata))
{
wsStream.Read(actualRes, 0, actualRes.Length);
rawdata.AddRange(actualRes);
break;
}
}
response = Encoding.UTF8.GetString(rawdata.ToArray())
.Replace("\r\n", "\n").Replace("\n\n", "\n")
.Split('\n');
#if DEBUG #if DEBUG
Console.WriteLine("WS: Info @doHandshake: Handshake from server:"); Console.WriteLine("WS: Info @doHandshake: Handshake from server:");
foreach (string s in response) foreach (string s in response)
@ -315,14 +294,11 @@ namespace WebSocketSharp
Console.WriteLine("{0}", s); Console.WriteLine("{0}", s);
} }
#endif #endif
Action<string, string> act = (e, a) => string msg;
if (!(response.IsValid(expectedCR, actualCR, out msg)))
{ {
throw new IOException("Invalid handshake response: " + a); throw new IOException(msg);
}; }
"HTTP/1.1 101 WebSocket Protocol Handshake".AreNotEqualDo(response[0], act);
"Upgrade: WebSocket".AreNotEqualDo(response[1], act);
"Connection: Upgrade".AreNotEqualDo(response[2], act);
for (int i = 3; i < response.Length; i++) for (int i = 3; i < response.Length; i++)
{ {
@ -336,23 +312,10 @@ namespace WebSocketSharp
#if DEBUG #if DEBUG
Console.WriteLine("WS: Info @doHandshake: Sub protocol: {0}", protocol); Console.WriteLine("WS: Info @doHandshake: Sub protocol: {0}", protocol);
#endif #endif
string expectedResToHexStr = BitConverter.ToString(expectedRes);
string actualResToHexStr = BitConverter.ToString(actualRes);
expectedResToHexStr.AreNotEqualDo(actualResToHexStr, (e, a) =>
{
#if DEBUG
Console.WriteLine("WS: Error @doHandshake: Invalid challenge response.");
Console.WriteLine("\texpected: {0}", e);
Console.WriteLine("\tactual : {0}", a);
#endif
throw new IOException("Invalid challenge response: " + a);
});
ReadyState = WsState.OPEN; ReadyState = WsState.OPEN;
} }
private string createOpeningHandshake(out byte[] expectedRes) private string createOpeningHandshake(out byte[] expectedCR)
{ {
string path = uri.PathAndQuery; string path = uri.PathAndQuery;
string host = uri.DnsSafeHost; string host = uri.DnsSafeHost;
@ -382,7 +345,7 @@ namespace WebSocketSharp
string key3ToAscii = Encoding.ASCII.GetString(key3); string key3ToAscii = Encoding.ASCII.GetString(key3);
expectedRes = createExpectedRes(key1, key2, key3); expectedCR = createExpectedCR(key1, key2, key3);
return "GET " + path + " HTTP/1.1\r\n" + return "GET " + path + " HTTP/1.1\r\n" +
"Upgrade: WebSocket\r\n" + "Upgrade: WebSocket\r\n" +
@ -395,7 +358,7 @@ namespace WebSocketSharp
key3ToAscii; key3ToAscii;
} }
private byte[] createExpectedRes(uint key1, uint key2, byte[] key3) private byte[] createExpectedCR(uint key1, uint key2, byte[] key3)
{ {
byte[] key1Bytes = BitConverter.GetBytes(key1); byte[] key1Bytes = BitConverter.GetBytes(key1);
byte[] key2Bytes = BitConverter.GetBytes(key2); byte[] key2Bytes = BitConverter.GetBytes(key2);
@ -409,6 +372,31 @@ namespace WebSocketSharp
return md5.ComputeHash(concatKeys); return md5.ComputeHash(concatKeys);
} }
private string[] sendOpeningHandshake(string openingHandshake, out byte[] challengeResponse)
{
challengeResponse = new byte[16];
List<byte> rawdata = new List<byte>();
byte[] sendBuffer = Encoding.UTF8.GetBytes(openingHandshake);
wsStream.Write(sendBuffer, 0, sendBuffer.Length);
while (true)
{
if (wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) &&
wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata))
{
wsStream.Read(challengeResponse, 0, challengeResponse.Length);
break;
}
}
return Encoding.UTF8.GetString(rawdata.ToArray())
.Replace("\r\n", "\n").Replace("\n\n", "\n")
.Split('\n');
}
private void message() private void message()
{ {
#if DEBUG #if DEBUG

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.