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
{
}
}