Example #1
0
        public async Task OpenAsync(string uri)
        {
            if (Opened)
            {
                throw new ApplicationException("WebSocket is already opened.");
            }

            Uri u = new Uri(uri);
            HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, uri);

            byte[] nonce = new byte[16];
            new Random().NextBytes(nonce);
            string requestKey = Convert.ToBase64String(nonce);

            req.Headers.Add("Host", u.Host);
            req.Headers.Add("User-Agent", UserAgent);
            req.Headers.Add("Accept", "text/html");
            req.Headers.Add("Sec-WebSocket-Version", "13");
            req.Headers.Add("Origin", "null");
            req.Headers.Add("Sec-WebSocket-Key", requestKey);
            req.Headers.Add("Connection", "keep-alive, Upgrade");
            req.Headers.Add("Pragma", "no-cache");
            req.Headers.Add("Cache-Control", "no-cache");
            req.Headers.Add("Upgrade", "websocket");

            StringWriter tmpWriter = new StringWriter();

            tmpWriter.WriteLine($"{req.Method} {req.RequestUri.PathAndQuery} HTTP/1.1");
            tmpWriter.WriteLine(req.Headers.ToString());

            await st.WriteAsyncWithTimeout(tmpWriter.AsciiToByteArray(),
                                           timeout : this.TimeoutOpen,
                                           cancel : this.Cancel);

            Dictionary <string, string> headers = new Dictionary <string, string>();
            int num          = 0;
            int responseCode = 0;

            StreamReader tmpReader = new StreamReader(st);

            while (true)
            {
                string line = await WebSocketHelper.DoAsyncWithTimeout((procCancel) => tmpReader.ReadLineAsync(),
                                                                       timeout : this.TimeoutOpen,
                                                                       cancel : this.Cancel);

                if (line == "")
                {
                    break;
                }

                if (num == 0)
                {
                    string[] tokens = line.Split(' ');
                    if (tokens[0] != "HTTP/1.1")
                    {
                        throw new ApplicationException($"Cannot establish the WebSocket Protocol. Response: \"{tokens}\"");
                    }
                    responseCode = int.Parse(tokens[1]);
                }
                else
                {
                    string[] tokens = line.Split(':');
                    string   name   = tokens[0].Trim();
                    string   value  = tokens[1].Trim();
                    headers[name] = value;
                }

                num++;
            }

            if (responseCode != 101)
            {
                throw new ApplicationException($"Cannot establish the WebSocket Protocol. Perhaps the destination host does not support WebSocket. Wrong response code: \"{responseCode}\"");
            }

            if (headers["Upgrade"].Equals("websocket", StringComparison.InvariantCultureIgnoreCase) == false)
            {
                throw new ApplicationException($"Wrong Upgrade header: \"{headers["Upgrade"]}\"");
            }

            string acceptKey  = headers["Sec-WebSocket-Accept"];
            string keyCalcStr = requestKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
            SHA1   sha1       = new SHA1Managed();
            string acceptKey2 = Convert.ToBase64String(sha1.ComputeHash(keyCalcStr.AsciiToByteArray()));

            if (acceptKey != acceptKey2)
            {
                throw new ApplicationException($"Wrong accept_key: \'{acceptKey}\'");
            }

            Opened = true;
        }