public static WSClientHandshake FromBytes(byte[] buffer) { WSClientHandshake handshake = new WSClientHandshake(); string hs = new string(Encoding.UTF8.GetChars(buffer)); string[] lines = hs.Split('\r', '\n'); foreach (string line in lines) { if (!Utils.StringIsNullOrEmpty(line)) { int idx = line.IndexOf(": "); if (idx == -1) // first line { handshake.ResourcePath = line.Split(' ')[1]; } else { string name = line.Substring(0, idx); string value = line.Substring(idx + 2); switch (name.ToLower()) { case "host": handshake.Host = value; break; case "origin": handshake.Origin = value; break; case "sec-websocket-key": handshake.Key = value; break; case "sec-websocket-version": handshake.Version = value; break; case "sec-websocket-protocol": handshake.SubProtocol = value; break; case "cookie": handshake.Cookies = new HttpCookieCollection(); string[] cookies = value.Split(';'); foreach (string item in cookies) { int i = item.IndexOf("="); string c_name = item.Substring(0, i); string c_value = item.Substring(i + 1); handshake.Cookies.Add(new HttpCookie(c_name.TrimStart(), c_value)); } break; default: if (handshake.AdditionalFields == null) { handshake.AdditionalFields = new Hashtable(); } handshake.AdditionalFields[name] = value; break; } } } } return(handshake); //string pattern = @"^(?<connect>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + // request line // @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]+)\r\n)+"; // unordered set of fields (name-chars colon space any-chars cr lf) //string paramNamePattern = @"[^:\r\n]+"; //string paramValuePattern = @"[^\r\n]+"; //string pattern = @"^[\S]+\s([\S]+)\sHTTP\/1\.1\r\n" + // "((" + paramNamePattern + @"):\s(" + paramValuePattern + @")\r\n)+"; //string pattern2 = @"([^:\r\n]+):\s([^\r\n]+)\r\n"; // subtract the challenge bytes from the handshake //handshake.ChallengeBytes = new byte[8]; //Array.Copy(buffer, buffer.Length - 8, handshake.ChallengeBytes, 0, 8); // get the rest of the handshake //byte[] buffer2 = new byte[buffer.Length - 8]; //Array.Copy(buffer, 0, buffer2, 0, buffer.Length - 8); //string utf8_handshake = new string(Encoding.UTF8.GetChars(buffer2)); //string utf8_handshake = new string(Encoding.UTF8.GetChars(buffer)); //Regex regex; //try //{ // regex = new Regex(pattern, RegexOptions.IgnoreCase); //} //catch (Exception e) //{ // Debug.Print("Exception thrown from method ParseClientHandshake:\n" + e.Message); // return null; //} //var match = regex.Match(utf8_handshake); //var groups = match.Groups; //// save the request path //handshake.ResourcePath = groups["path"].Value; //// run through every match and save them in the handshake object //for (int i = 0; i < groups["field_name"].Captures.Count; i++) //{ // var name = groups["field_name"].Captures[i].ToString(); // var value = groups["field_value"].Captures[i].ToString(); // switch (name.ToLower()) // { // case "sec-websocket-key": // handshake.Key = value; // break; // //case "sec-websocket-key1": // // handshake.Key1 = value; // // break; // //case "sec-websocket-key2": // // handshake.Key2 = value; // // break; // case "sec-websocket-protocol": // handshake.SubProtocol = value; // break; // case "origin": // handshake.Origin = value; // break; // case "host": // handshake.Host = value; // break; // case "cookie": // // // create and fill a cookie collection from the data in the handshake // // handshake.Cookies = new HttpCookieCollection(); // // var cookies = value.Split(';'); // // foreach (var item in cookies) // // { // // // the name if before the '=' char // // var c_name = item.Remove(item.IndexOf('=')); // // // the value is after // // var c_value = item.Substring(item.IndexOf('=') + 1); // // // put the cookie in the collection (this also parses the sub-values and such) // // handshake.Cookies.Add(new HttpCookie(c_name.TrimStart(), c_value)); // // } // break; // default: // // // some field that we don't know about // // if (handshake.AdditionalFields == null) // // handshake.AdditionalFields = new Dictionary<string, string>(); // // handshake.AdditionalFields[name] = value; // break; // } //} //return handshake; }
public static WSClientHandshake FromBytes(byte[] buffer) { WSClientHandshake handshake = new WSClientHandshake(); string hs = new string(Encoding.UTF8.GetChars(buffer)); string[] lines = hs.Split('\r', '\n'); foreach (string line in lines) { if (!Utils.StringIsNullOrEmpty(line)) { int idx = line.IndexOf(": "); if (idx == -1) // first line handshake.ResourcePath = line.Split(' ')[1]; else { string name = line.Substring(0, idx); string value = line.Substring(idx + 2); switch (name.ToLower()) { case "host": handshake.Host = value; break; case "origin": handshake.Origin = value; break; case "sec-websocket-key": handshake.Key = value; break; case "sec-websocket-version": handshake.Version = value; break; case "sec-websocket-protocol": handshake.SubProtocol = value; break; case "cookie": handshake.Cookies = new HttpCookieCollection(); string[] cookies = value.Split(';'); foreach (string item in cookies) { int i = item.IndexOf("="); string c_name = item.Substring(0, i); string c_value = item.Substring(i + 1); handshake.Cookies.Add(new HttpCookie(c_name.TrimStart(), c_value)); } break; default: if (handshake.AdditionalFields == null) handshake.AdditionalFields = new Hashtable(); handshake.AdditionalFields[name] = value; break; } } } } return handshake; //string pattern = @"^(?<connect>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + // request line // @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]+)\r\n)+"; // unordered set of fields (name-chars colon space any-chars cr lf) //string paramNamePattern = @"[^:\r\n]+"; //string paramValuePattern = @"[^\r\n]+"; //string pattern = @"^[\S]+\s([\S]+)\sHTTP\/1\.1\r\n" + // "((" + paramNamePattern + @"):\s(" + paramValuePattern + @")\r\n)+"; //string pattern2 = @"([^:\r\n]+):\s([^\r\n]+)\r\n"; // subtract the challenge bytes from the handshake //handshake.ChallengeBytes = new byte[8]; //Array.Copy(buffer, buffer.Length - 8, handshake.ChallengeBytes, 0, 8); // get the rest of the handshake //byte[] buffer2 = new byte[buffer.Length - 8]; //Array.Copy(buffer, 0, buffer2, 0, buffer.Length - 8); //string utf8_handshake = new string(Encoding.UTF8.GetChars(buffer2)); //string utf8_handshake = new string(Encoding.UTF8.GetChars(buffer)); //Regex regex; //try //{ // regex = new Regex(pattern, RegexOptions.IgnoreCase); //} //catch (Exception e) //{ // Debug.Print("Exception thrown from method ParseClientHandshake:\n" + e.Message); // return null; //} //var match = regex.Match(utf8_handshake); //var groups = match.Groups; //// save the request path //handshake.ResourcePath = groups["path"].Value; //// run through every match and save them in the handshake object //for (int i = 0; i < groups["field_name"].Captures.Count; i++) //{ // var name = groups["field_name"].Captures[i].ToString(); // var value = groups["field_value"].Captures[i].ToString(); // switch (name.ToLower()) // { // case "sec-websocket-key": // handshake.Key = value; // break; // //case "sec-websocket-key1": // // handshake.Key1 = value; // // break; // //case "sec-websocket-key2": // // handshake.Key2 = value; // // break; // case "sec-websocket-protocol": // handshake.SubProtocol = value; // break; // case "origin": // handshake.Origin = value; // break; // case "host": // handshake.Host = value; // break; // case "cookie": // // // create and fill a cookie collection from the data in the handshake // // handshake.Cookies = new HttpCookieCollection(); // // var cookies = value.Split(';'); // // foreach (var item in cookies) // // { // // // the name if before the '=' char // // var c_name = item.Remove(item.IndexOf('=')); // // // the value is after // // var c_value = item.Substring(item.IndexOf('=') + 1); // // // put the cookie in the collection (this also parses the sub-values and such) // // handshake.Cookies.Add(new HttpCookie(c_name.TrimStart(), c_value)); // // } // break; // default: // // // some field that we don't know about // // if (handshake.AdditionalFields == null) // // handshake.AdditionalFields = new Dictionary<string, string>(); // // handshake.AdditionalFields[name] = value; // break; // } //} //return handshake; }
private bool tcpServer_SessionReceived(TcpSession session, byte[] data) { if (!session.IsHandshaked) { // from tablet: /* * GET /Typhoon HTTP/1.1 * Upgrade: WebSocket * Connection: Upgrade * Host: 192.168.0.102:2013 * Origin: http://192.168.0.102:81 * Sec-Websocket-Key: +d6dlnAp7rrQ3otS7Zvi7g== * Sec-WebSocket-Version: 13 +d6dlnAp7rrQ3otS7Zvi7g==: websocket +d6dlnAp7rrQ3otS7Zvi7g==: Upgrade */ // from local: /* * GET /Typhoon HTTP/1.1 * Upgrade: WebSocket * Connection: Upgrade * Host: localhost:2013 * Origin: http://localhost:81 * Sec-Websocket-Key: K92AZtSFpS+9OgiwcPMheg== * Sec-WebSocket-Version: 13 * K92AZtSFpS+9OgiwcPMheg==: websocket * K92AZtSFpS+9OgiwcPMheg==: x-webkit-deflate-frame * K92AZtSFpS+9OgiwcPMheg==: Upgrade */ // location: ws://localhost:2013 // origin: "http://localhost:81" WSClientHandshake chs = WSClientHandshake.FromBytes(data); //if (chs.IsValid && "ws://" + chs.Host == location && chs.Origin == origin) //if (chs.IsValid && "ws://" + chs.Host == location) if (chs.IsValid) { WSServerHandshake shs = new WSServerHandshake(chs.Key); string stringShake = shs.ToString(); byte[] byteResponse = Encoding.UTF8.GetBytes(stringShake); session.Send(byteResponse); session.IsHandshaked = true; // for debug: //client.Send(WebSocketDataFrame.WrapString("Hello from server!!!")); return(false); } else { return(true); // disconnect client } } else { WSDataFrame frame = new WSDataFrame(data); byte[] payload = null; if (frame.IsValid() && frame.FIN) { payload = frame.GetPayload(); } // for debug: //string s = new string(Encoding.UTF8.GetChars(payload)); //string b = ""; //b += s; return(SessionDataReceived != null?SessionDataReceived(session, payload) : false); } }