示例#1
0
        /// <summary>
        /// Upgrades the connection to the particular protocol. Handles the handshake.
        /// </summary>
        /// <param name="context"><see cref="ProcessingContext"/> for the current connection.</param>
        /// <param name="httpContext"><see cref="HttpContext"/> for the current connection.</param>
        /// <returns>The handlers that have been inserted in the pipeline.</returns>
        public WebSocketPipeline Upgrade(ProcessingContext context, HttpContext httpContext)
        {
            var request = httpContext.Request;
            var builder = new StringBuilder();

            builder.Append("HTTP/1.1 101 WebSocket Protocol Handshake\r\n");
            builder.Append("Upgrade: WebSocket\r\n");
            builder.Append("Connection: Upgrade\r\n");
            builder.AppendFormat("Sec-WebSocket-Origin: {0}\r\n", request.Headers["Origin"]);
            //builder.AppendFormat("Sec-WebSocket-Location: {0}://{1}{2}\r\n", secure ? "wss" : "ws", request.Headers["Host"], request.Path);
            builder.AppendFormat("Sec-WebSocket-Location: {0}://{1}{2}\r\n", "ws", request.Headers["Host"], request.Path);

            if (request.Headers["Sec-WebSocket-Protocol"] != null)
            {
                builder.AppendFormat("Sec-WebSocket-Protocol: {0}\r\n", request.Headers["Sec-WebSocket-Protocol"]);
            }

            builder.Append("\r\n");

            var key1 = request.Headers["Sec-WebSocket-Key1"];
            var key2 = request.Headers["Sec-WebSocket-Key2"];

            // Get last bytes
            byte[] challenge = request.Body;

            // Compile the body
            var part1  = Encoding.ASCII.GetBytes(builder.ToString());
            var part2  = CalculateAnswerBytes(key1, key2, challenge);
            var buffer = new byte[part1.Length + part2.Length];

            Memory.Copy(part1, 0, buffer, 0, part1.Length);
            Memory.Copy(part2, 0, buffer, part1.Length, part2.Length);

            // Prepare the response packet
            var response = BytePacket.Acquire(buffer);

            // Get the channel
            var channel = httpContext.Connection;

            // Send the handshake response
            channel.Send(response);

            // Set the encoder & the decoder for this websocket handler
            channel.Encoding.PipelineAddLast(Encode.WebSocketDraft76);
            channel.Decoding.PipelineAddFirst(Decode.WebSocketDraft76);

            // Trace a websocket event
            NetTrace.WriteLine("Upgraded to Draft76 ", channel, NetTraceCategory.WebSocket);
            return(new WebSocketPipeline(Encode.WebSocketDraft76, Decode.WebSocketDraft76));
        }