Ejemplo n.º 1
0
        /// <summary>
        /// Performs the actual writing of data to the socket. Used by all other Write* methods.
        /// </summary>
        /// <param name="socket">The <see cref="AsyncSocket"/> to write the data to</param>
        /// <param name="bytes">The bytes to write to the socket</param>
        /// <param name="timeout">The socket write timeout value</param>
        /// <param name="tag">The tag that will identify the write operation (can be referenced in the socket's DidWrite event)</param>
        /// <param name="disconnectAfterWriting">Indicates if the server should disconnect the socket after writing the data</param>
        /// <param name="requestComplete">Indicates if the request is complete once the data is written</param>
        protected void FinalWrite(AsyncSocket socket, byte[] bytes, int timeout, long tag, bool disconnectAfterWriting, bool requestComplete)
        {
            Data data = new Data(bytes);
            Log(data);

            // give any custom readers the change to modify the output before we send it (especially useful for WebSockets that need to frame their data)
            if (this.requestReader != null)
                this.requestReader.BeforeResponse(ref bytes);

            // if we are done sending stuff back (all responses and callbacks), we need to initiate an orderly shutdown
            if (!disconnectAfterWriting && requestComplete)
                OrderlySocketShutdown();

            // send the data
            socket.Write(bytes, timeout, tag);

            // if we are the ones disconnecting, do it now. (usually if we are sending back an error response)
            // if not, we can just leave the socket alone
            if (disconnectAfterWriting)
            {
                OnSocketUsageComplete(socket);
                socket.CloseAfterWriting();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handles the socket's DidRead event.
        /// Reads the HTTP headers and sends the handshake response.
        /// </summary>
        /// <param name="sender">The <see cref="AsyncSocket"/>.</param>
        /// <param name="data">The data read.</param>
        /// <param name="tag">The tag identifying the read request.</param>
        void socket_DidRead(AsyncSocket sender, byte[] data, long tag)
        {
            // remove this event handler since we dont need it any more
            sender.DidRead -= new AsyncSocket.SocketDidRead(this.socket_DidRead);

            // handle any data that may already have been read by the MessageHandler
            byte[] previousBytes = (byte[])sender.Tag;
            if (previousBytes != null) this.requestBytes = previousBytes;
            sender.Tag = null;

            // append the new data to any already-read data (this cant really happen now that we updated to the 07 spec, but it doenst hurt anything)
            if (this.requestBytes != null)
            {
                byte[] tempBytes = new byte[this.requestBytes.Length + data.Length];
                Array.Copy(this.requestBytes, tempBytes, this.requestBytes.Length);
                Array.Copy(data, 0, tempBytes, this.requestBytes.Length, data.Length);
                this.requestBytes = tempBytes;
            }
            else
            {
                this.requestBytes = data;
            }

            // check the handshake at this point so we know if we should be looking for the challenge bytes or not
            this.handshake = new Handshake(this.requestBytes, this.requestBytes.Length);

            // we could check the Sec-WebSocket-Origin here, but we really dont care where they are connecting from

            // calculate the handshake proof
            string key = handshake.Fields[HEADER_SEC_WEBSOCKET_KEY];
            string concat = key + WEBSOCKET_GUID;
            byte[] keyBytes = Encoding.UTF8.GetBytes(concat);
            SHA1 sha1 = SHA1.Create();
            byte[] sha1Bytes = sha1.ComputeHash(keyBytes);
            string accept = Convert.ToBase64String(sha1Bytes);

            // construct the handshake response
            string version = handshake.Fields[HEADER_SEC_WEBSOCKET_VERSION];
            string protocol = handshake.Fields.ContainsKey(HEADER_SEC_WEBSOCKET_PROTOCOL) ? handshake.Fields[HEADER_SEC_WEBSOCKET_PROTOCOL] : null;
            string response = handshake.GetHostResponse(accept, version, protocol);
            byte[] byteResponse = Encoding.UTF8.GetBytes(response);

            // send the response
            sender.DidWrite += new AsyncSocket.SocketDidWrite(socket_DidWrite);
            sender.Write(byteResponse, 0, byteResponse.Length, -1, HANDSHAKE_RESPONSE_TAG);
        }