Bauglir.Ex.WebSocketServer.AddConnection C# (CSharp) Method

AddConnection() protected method

basic function to add WebSocket connection to list of connections
protected AddConnection ( TcpClient aClient, Stream aStream ) : WebSocketServerConnection
aClient System.Net.Sockets.TcpClient incomming connection
aStream Stream
return WebSocketServerConnection
        protected WebSocketServerConnection AddConnection(TcpClient aClient, Stream aStream)
        {
            WebSocketHeaders headers = new WebSocketHeaders();
            //NetworkStream stream = aClient.GetStream();

            Stream stream = aStream == null ? aClient.GetStream() : aStream; //getStream(aClient);

            StreamReader sr = new StreamReader(stream);
            StreamWriter sw = new StreamWriter(stream);
            string line = String.Empty;
            string get = String.Empty;
            string[] parts;
            string cookie = "-";
            string extension = "-";
            string origin = "-";
            string protocol = "-";
            string host = "";
            string port = "";
            string resourceName = "";
            string version = "";
            Char[] separator = new char[] { ':' };
            Char[] separator2 = new char[] { ' ' };
            bool doCreate = true;
            WebSocketServerConnection result = null;
            string key = String.Empty;
            string tmpS;
            byte[] tmpB;
            int resultHTTP = 101;
            SHA1 sha = new SHA1CryptoServiceProvider();
            bool canAdd = true;
            int iversion;

            stream.ReadTimeout = 60 * 1000;
            //sr.

            try
            {
                // read resourceName
                get = sr.ReadLine();
                if (get != null)
                {
                    parts = get.Split(separator2);
                    if ((get.ToUpper().IndexOf("GET ") > -1) && (get.ToUpper().IndexOf(" HTTP/1.1") > -1) && (parts.Length >= 3))
                    {
                        parts = get.Split(separator2, 2);
                        resourceName = parts[1].Trim();
                        parts = resourceName.Split(separator2, 2);
                        resourceName = parts[0].Trim();
                    }
                }
                doCreate = resourceName != String.Empty;

                // read all headers
                if (doCreate)
                {
                    do
                    {
                        line = sr.ReadLine();
                        if (!String.IsNullOrEmpty(line))
                        {
                            parts = line.Split(separator, 2);
                            headers.Append(parts[0].ToLower(), parts.Length == 2 ? parts[1] : "");
                            //headers.Add("brona", "klucka");
                        }

                    } while (!String.IsNullOrEmpty(line));
                    if (line == null)
                    {
                        doCreate = false;

                    }
                }

                //host & port
                if (doCreate)
                {
                    if (headers.Contains("host"))
                    {
                        parts = headers["host"].Split(separator);
                        host = parts[0].Trim();
                        if (parts.Length > 1)
                        {
                            port = parts[1].Trim();
                        }
                    }
                    doCreate = doCreate && (host != String.Empty);
                }

                //websocket key
                if (doCreate)
                {
                    if (headers.Contains("sec-websocket-key"))
                    {
                        tmpS = headers["sec-websocket-key"].Trim();
                        tmpB = Convert.FromBase64String(tmpS);
                        tmpS = Encoding.ASCII.GetString(tmpB);
                        if (tmpS.Length == 16)
                        {
                            key = headers["sec-websocket-key"].Trim();
                        }
                    }
                    doCreate = doCreate && (key != String.Empty);
                }

                //websocket version
                iversion = 0;
                if (doCreate)
                {
                    if (headers.Contains("sec-websocket-version"))
                    {
                        tmpS = headers["sec-websocket-version"].Trim();
                        if ((tmpS == "8") || (tmpS == "7") || (tmpS == "13"))
                        {
                            version = tmpS;
                            iversion = int.Parse(version);
                        }
                    }
                    doCreate = doCreate && (version != String.Empty);
                }

                //upgrade and connection
                if (doCreate)
                {
                    doCreate = doCreate &&
                              (headers.Contains("upgrade")) && (headers["upgrade"].Trim().ToLower() == "websocket".ToLower()) &&
                              (headers.Contains("connection")) && (headers["connection"].Trim().ToLower().IndexOf("upgrade") > -1);
                }

                if (doCreate)
                {
                    if (iversion < 13)
                    {
                        if (headers.Contains("sec-websocket-origin")) origin = headers["sec-websocket-origin"].Trim();
                    }
                    else
                    {
                        if (headers.Contains("origin")) origin = headers["origin"].Trim();
                    }
                    if (headers.Contains("sec-websocket-protocol")) protocol = headers["sec-websocket-protocol"].Trim();
                    if (headers.Contains("sec-websocket-extensions")) extension = headers["sec-websocket-extensions"].Trim();
                    if (headers.Contains("cookie")) cookie = headers["cookie"].Trim();
                }
            }
            catch (SocketException e)
            {
                if (SocketError != null) SocketError(this, e);
                doCreate = false;
            }
            catch (Exception)
            {
                doCreate = false;
            }
            finally
            {

            }

            result = GetConnectionInstance(aClient, headers, host, port, resourceName, origin, cookie, version, ref protocol, ref extension, ref resultHTTP);
            if (result == null)
            {
                if (resultHTTP == 101) resultHTTP = 404;
            }

            try
            {
                doCreate = doCreate && stream.CanWrite;
                if (doCreate)
                {
                    if (resultHTTP != 101)
                    {
                        sw.Write(String.Format("HTTP/1.1 {0} {1}\r\n", resultHTTP, this.httpCode(resultHTTP)));
                        sw.Write(String.Format("{0} {1}\r\n", resultHTTP, this.httpCode(resultHTTP)));
                        sw.Write("\r\n");
                        sw.Flush();
                        doCreate = false;
                    }
                }
                if (!doCreate)
                {
                    //DoLog("close");
                    aClient.Close();
                    return null;
                }
                else
                {
                    //result = new WebSocketServerConnection(aClient);
                    result.fCookie = cookie;
                    result.fExtension = extension;
                    result.fOrigin = origin;
                    result.fProtocol = protocol;
                    result.fHost = host;
                    result.fPort = port;
                    result.fResourceName = resourceName;
                    result.fVersion = int.Parse(version);
                    result.fHeaders = headers;
                    result.fSsl = fSsl;
                    result.fHandshake = true;
                    if (fSsl)
                    {
                        result.fSslStream = (SslStream)aStream;
                    }

                    if (BeforeAddConnection != null)
                    {
                        canAdd = true;
                        BeforeAddConnection(this, result, ref canAdd);
                        doCreate = canAdd;
                    }
                    if (doCreate)
                    {
                        tmpB = System.Text.Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
                        key = Convert.ToBase64String(sha.ComputeHash(tmpB));

                        sw.Write("HTTP/1.1 101 Switching Protocols\r\n");
                        sw.Write("Upgrade: websocket\r\n");
                        sw.Write("Connection: Upgrade\r\n");
                        sw.Write(String.Format("Sec-WebSocket-Accept: {0}\r\n", key));
                        if (protocol != "-")
                            sw.Write(String.Format("Sec-WebSocket-Protocol: {0}\r\n", protocol));
                        if (extension != "-")
                            sw.Write(String.Format("Sec-WebSocket-Extensions: {0}\r\n", extension));
                        sw.Write("\r\n");
                        sw.Flush();
                        return result;
                    }
                    else
                    {
                        aClient.Close();
                        return null;
                    }

                }
            }
            catch (SocketException e)
            {
                if (SocketError != null) SocketError(this, e);
                aClient.Close();
                return null;
            }
            catch (Exception)
            {
                aClient.Close();
                return null;
            }
            finally
            {

            }
        }