private static void SendServerHandshake(ServerHandshake handshake, Context context) { // generate a byte array representation of the handshake including the answer to the challenge string temp = handshake.ToString(); byte[] handshakeBytes = Encoding.UTF8.GetBytes(temp); context.UserContext.Send(handshakeBytes, true); }
/// <summary> /// Handles the request. /// </summary> /// <param name="context">The user context.</param> public override void HandleRequest(Context context) { context.FrameReader.Append(context.Buffer, context.ReceivedByteCount); foreach (var frameData in context.FrameReader.ReadFrames()) { if (frameData.OpCode == WebSocketOpCode.Ping) { frameData.OpCode = WebSocketOpCode.Pong; context.UserContext.Send(frameData); continue; } if (frameData.OpCode == WebSocketOpCode.Pong) continue; if (frameData.OpCode == WebSocketOpCode.Close) { context.UserContext.Send(DataFrame.CloseResponseFrame, true); continue; } context.UserContext.OnReceive(frameData); } }
public bool Authenticate(Context ctx) { var context = (ServerContext)ctx; if (context.ReceivedByteCount > 8) { var handshake = new ClientHandshake(context.Header); // See if our header had the required information if (handshake.IsValid()) { var origin = context.Server.Origin; // Optionally check Origin and Location if they're set. if (!String.IsNullOrEmpty(origin)) { var expectedOrigin = origin; if (!origin.Contains("://")) { expectedOrigin = "http://" + origin; } if (!handshake.Origin.Equals(expectedOrigin, StringComparison.InvariantCultureIgnoreCase)) return (false); } var destination = context.Server.Destination; if (!String.IsNullOrEmpty(destination)) { if (handshake.Host != destination + ":" + context.Server.Port) return (false); } // Generate response handshake for the client var serverShake = GenerateResponseHandshake(handshake, context.Server); // Send the response handshake SendServerHandshake(serverShake, context); return (true); } } return (false); }
/// <summary> /// Processes the header. /// </summary> /// <param name="context">The user context.</param> public void ProcessHeader(Context context) { var serverContext = (ServerContext)context; // Find two line-breaks var buffer = context.Buffer; var bytesRead = context.ReceivedByteCount; var originalSize = context.HeaderStream.Length; var headerEnd = FindHeaderEnd(buffer); if (headerEnd < 0) // Didn't finish reading header; wait for next reader { context.HeaderStream.Write(buffer, 0, bytesRead); return; } context.HeaderStream.Write(buffer, 0, headerEnd); var headerBuffer = context.HeaderStream.ToArray(); var headerBytesInBuffer = headerBuffer.Length - originalSize; var extraBytes = bytesRead - (headerBytesInBuffer); string data = Encoding.UTF8.GetString(headerBuffer, 0, headerBuffer.Length); //Check first to see if this is a flash socket XML request. if (data == "<policy-file-request/>\0") { //if it is, we access the Access Policy Server instance to send the appropriate response. serverContext.Server.AccessPolicyServer.SendResponse(context.Connection); } else //If it isn't, process http/websocket header as normal. { context.Header = new Header(data); switch (context.Header.Protocol) { case Protocol.WebSocketRFC6455: context.Handler = HandlerBase.GetHandler<WebSocket.rfc6455.Handler>(); context.FrameReader = new WebSocket.rfc6455.DataFrameReaderRfc6455(); break; default: context.Header.Protocol = Protocol.None; break; } if (context.Header.Protocol == Protocol.None) { context.UserContext.Send(Response.NotImplemented, true); context.Stop(); } if (context.Handler.Authentication.Authenticate(context)) { context.UserContext.OnConnected(); if (extraBytes > 0) { var extraBytesBuffer = new byte[extraBytes]; Array.Copy(context.Buffer, headerBytesInBuffer, extraBytesBuffer, 0, extraBytes); context.ReceivedByteCount = (int)extraBytes; context.Handler.HandleRequest(context); } } else { context.Stop(); } } }
/// <summary> /// Handles the initial request. /// Attempts to process the header that should have been sent. /// </summary> /// <param name="context">The user context.</param> public override void HandleRequest(Context context) { ProcessHeader(context); }
public abstract void HandleRequest(Context context);
/// <summary> /// Initializes a new instance of the <see cref="UserContext"/> class. /// </summary> /// <param name="context">The user context.</param> internal UserContext(Context context) { Context = context; }
private void StartContext(Context context) { SendHeader(); BeginReceive(context); }
private void ProcessData(Context context) { if (state == WebSocketClientState.Handshaking) { // Assuming we've read the whole response, and that this response has no payload // Definitely not gaurenteed to be true var someBytes = new byte[context.ReceivedByteCount]; Array.Copy(context.Buffer, someBytes, context.ReceivedByteCount); var authenticated = CheckAuthenticationResponse(someBytes); frameReader = new DataFrameReaderRfc6455(); if (!authenticated) { Disconnect(); } else { state = WebSocketClientState.Open; context.UserContext.OnConnected(); } } else { Debug.Assert(state == WebSocketClientState.Open); frameReader.Append(context.Buffer, context.ReceivedByteCount); foreach (var frameData in frameReader.ReadFrames()) context.UserContext.OnReceive(frameData); } }
private void BeginReceive(Context context) { var args = new SocketAsyncEventArgs { UserToken = context }; args.Completed += DataReceivedHandler; args.SetBuffer(context.Buffer, 0, context.Buffer.Length); if (!context.Connection.Client.ReceiveAsync(args)) DataReceivedHandler(context.Connection.Client, args); }
/// <summary> /// Begin connecting to a WebSocket server. Upon returning from this method, the server /// will be in the Handshaking state. This means the client is waiting for the handshake /// response from the server. Messages may not be sent until the OnConnected event has fired. /// </summary> public void BeginConnect() { if (state != WebSocketClientState.Closed) throw new InvalidOperationException(); try { state = WebSocketClientState.Connecting; client = new TcpClient(); client.Connect(host, port); state = WebSocketClientState.Handshaking; context = CreateContext(); StartContext(context); } catch (Exception e) { state = WebSocketClientState.Closed; throw e; } }
private void OnSocketClose(Context c) { c.UserContext.OnDisconnect(); c.Connection.Close(); }
private void BeginReceive(Context context) { try { var args = new SocketAsyncEventArgs { UserToken = context }; args.Completed += SocketReceiveHandler; args.SetBuffer(context.Buffer, 0, context.Buffer.Length); bool completedSyncronusly = !context.Connection.Client.ReceiveAsync(args); if (completedSyncronusly) SocketReceiveHandler(context.Connection.Client, args); } catch (SocketException) { OnSocketClose(context); } }