Permalink
Browse files

Implemented Alchemy client and added integration tests between client…

… and server.
  • Loading branch information...
DorianGray committed Dec 19, 2011
1 parent 16cc497 commit 8ce624b10d82fef6d01b806052d783072b143ba4
View
@@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Alchemy", "Alchemy", "{DEF8
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Alchemy", "test\Unit\Alchemy\Alchemy.csproj", "{D62E2F92-A930-44D9-90FB-864CAF837BAE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Alchemy", "Alchemy", "{D629207E-B540-40F6-B2B4-5BCDD033EAD6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Alchemy", "test\Integration\Alchemy\Alchemy.csproj", "{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -51,6 +55,18 @@ Global
{D62E2F92-A930-44D9-90FB-864CAF837BAE}.Release|Mixed Platforms.Build.0 = Release|x64
{D62E2F92-A930-44D9-90FB-864CAF837BAE}.Release|x64.ActiveCfg = Release|Any CPU
{D62E2F92-A930-44D9-90FB-864CAF837BAE}.Release|x86.ActiveCfg = Release|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Debug|x64.ActiveCfg = Debug|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Debug|x86.ActiveCfg = Debug|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Release|Any CPU.Build.0 = Release|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Release|x64.ActiveCfg = Release|Any CPU
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -59,8 +75,10 @@ Global
{45486CDE-86A3-4769-952F-E0821BF79493} = {8C9C334C-588E-41A1-85FC-9DC035821D27}
{24B00C6C-88BE-4F83-B2E1-8CC8F145BFB9} = {32470B4C-0665-44B9-9A55-AF9C671FDAA5}
{A8BCA98B-12E7-4E13-99FE-09DDCA10BB26} = {32470B4C-0665-44B9-9A55-AF9C671FDAA5}
{D629207E-B540-40F6-B2B4-5BCDD033EAD6} = {24B00C6C-88BE-4F83-B2E1-8CC8F145BFB9}
{DEF8E4AE-D1A2-4C33-A4EC-A51BDF6BD09F} = {A8BCA98B-12E7-4E13-99FE-09DDCA10BB26}
{D62E2F92-A930-44D9-90FB-864CAF837BAE} = {DEF8E4AE-D1A2-4C33-A4EC-A51BDF6BD09F}
{D7B6AB15-5986-4FDC-ADA8-9EF14DF8F26D} = {D629207E-B540-40F6-B2B4-5BCDD033EAD6}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Server.csproj
@@ -10,7 +10,7 @@ namespace Alchemy
/// It manages sending the XML cross domain policy to flash socket clients over port 843.
/// See http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html for details.
/// </summary>
public class AccessPolicyServer : TcpServer, IDisposable
internal class AccessPolicyServer : TcpServer, IDisposable
{
/// <summary>
/// The pre-formatted XML response.
@@ -86,6 +86,7 @@
<Compile Include="Handlers\WebSocket\IWebSocketAuthentication.cs" />
<Compile Include="Handlers\WebSocket\WebSocketHandler.cs" />
<Compile Include="TcpServer.cs" />
<Compile Include="WebSocketClient.cs" />
<Compile Include="WebSocketServer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@@ -24,7 +24,7 @@ public class Context : IDisposable
/// <summary>
/// The max frame that we will accept from the client
/// </summary>
public UInt64 MaxFrameSize;
public UInt64 MaxFrameSize = Int64.MaxValue;
/// <summary>
/// Whether or not the TCPClient is still connected.
@@ -24,7 +24,7 @@ public class Header
/// Regular expression to parse http header
/// </summary>
public static string Pattern =
@"^(?<connect>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + // HTTP Request
@"^(?<connect>[^\s]+)?\s?(?<path>[^\s]+)?\s?HTTP\/1\.1(.*?)?\r\n" + // HTTP Request
@"((?<field_name>[^:\r\n]+):(?<field_value>[^\r\n]+)\r\n)+";
// HTTP Header Fields (<Field_Name>: <Field_Value> CR LF)
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
@@ -116,13 +117,15 @@ public void Send(DataFrame dataFrame, Context context, bool raw = false, bool cl
context.SendReady.Wait();
try
{
context.Connection.Client.BeginSend(raw ? dataFrame.AsRaw() : dataFrame.AsFrame(), SocketFlags.None,
List<ArraySegment<byte>> list = raw ? dataFrame.AsRaw() : dataFrame.AsFrame();
context.Connection.Client.BeginSend(list, SocketFlags.None,
callback,
context);
}
catch
catch(Exception e)
{
context.SendReady.Release();
Console.WriteLine(e);

This comment has been minimized.

@ShyRed

ShyRed Dec 20, 2011

Is Console.WriteLine(e) some debugging code you forgot to remove?

This comment has been minimized.

@DorianGray

DorianGray Dec 20, 2011

Member

It is indeed. I'll put some time into cleaning up tonight. The client also, if you haven't noticed, still needs some love.

This comment has been minimized.

@ShyRed

ShyRed Dec 20, 2011

Just wanted to point stuff out that I notice while looking through the commits. :-)

This comment has been minimized.

@DorianGray

DorianGray Dec 21, 2011

Member

Haha, thanks! it prompted me to rip out all the debug stuff lying around and do some more cleanup.

}
}
@@ -31,6 +31,9 @@ public class ClientHandshake
public string Origin = String.Empty;
public string ResourcePath = String.Empty;
public ClientHandshake()
{}
/// <summary>
/// Initializes a new instance of the <see cref="ClientHandshake"/> class.
/// </summary>
@@ -51,7 +51,7 @@ protected override bool CheckAuthentication(Context context)
}
}
// Generate response handshake for the client
ServerHandshake serverShake = GenerateResponseHandshake(handshake, context);
ServerHandshake serverShake = GenerateResponseHandshake(handshake);
serverShake.SubProtocol = handshake.SubProtocol;
// Send the response handshake
SendServerHandshake(serverShake, context);
@@ -61,9 +61,9 @@ protected override bool CheckAuthentication(Context context)
return false;
}
private static ServerHandshake GenerateResponseHandshake(ClientHandshake handshake, Context context)
private static ServerHandshake GenerateResponseHandshake(ClientHandshake handshake)
{
var responseHandshake = new ServerHandshake {Accept = GenerateAccept(handshake.Key, context)};
var responseHandshake = new ServerHandshake {Accept = GenerateAccept(handshake.Key)};
return responseHandshake;
}
@@ -75,13 +75,20 @@ private static void SendServerHandshake(ServerHandshake handshake, Context conte
context.UserContext.Send(handshakeBytes, true);
}
private static string GenerateAccept(string key, Context context)
public static string GenerateAccept(string key)
{
string rawAnswer = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
if (!String.IsNullOrEmpty(key))
{
string rawAnswer = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
// Create a hash of the rawAnswer and return it
SHA1 hasher = SHA1.Create();
return Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(rawAnswer)));
// Create a hash of the rawAnswer and return it
SHA1 hasher = SHA1.Create();
return Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(rawAnswer)));
}
else
{
return String.Empty;
}
}
}
}
@@ -18,10 +18,10 @@ public class ClientHandshake
private const String Handshake =
"GET {0} HTTP/1.1\r\n" +
"Host: {2}\r\n" +
"Origin: {1}\r\n" +
"Upgrade: websocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Key: {4}\r\n" +
"Sec-WebSocket-Origin: {1}\r\n" +
"Sec-WebSocket-Protocol: {3}\r\n" +
"Sec-WebSocket-Version: 8\r\n" +
"{5}";
@@ -31,6 +31,9 @@ public class ClientHandshake
public string Origin = String.Empty;
public string ResourcePath = String.Empty;
public ClientHandshake()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ClientHandshake"/> class.
/// </summary>
@@ -118,6 +121,20 @@ public class ServerHandshake
public Dictionary<string, string> AdditionalFields { get; set; }
public ServerHandshake()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerHandshake"/> class.
/// </summary>
/// <param name="header">The header.</param>
public ServerHandshake(Header header)
{
Accept = header["Sec-WebSocket-Accept"];
SubProtocol = header["Sec-WebSocket-Protocol"];
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
Oops, something went wrong.

0 comments on commit 8ce624b

Please sign in to comment.