Fix for issue #6 - 1

master
sta 13 years ago
parent 75417fba70
commit 3ef6d58f31

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -7,13 +7,14 @@ namespace Example2
{
public static void Main(string[] args)
{
var wssv = new WebSocketServer<Echo>("ws://localhost:4649");
//var wssv = new WebSocketServer<Echo>("ws://localhost:4649");
//var wssv = new WebSocketServer<Chat>("ws://localhost:4649");
var wssv = new WebSocketServer<Echo>("/", 4649);
wssv.Start();
Console.WriteLine(
"WebSocket Server (url: {0}) listening on port: {1}\n",
wssv.Url, wssv.Port);
"WebSocket Server (url: {0})\n listening on address: {1} port: {2}\n",
wssv.Url, wssv.Address, wssv.Port);
Console.WriteLine("Press any key to stop server...");
Console.ReadLine();

Binary file not shown.

Binary file not shown.

@ -57,6 +57,8 @@ namespace WebSocketSharp
public static bool EqualsAndSaveTo(this int value, char c, List<byte> dest)
{
if (value < 0)
throw new ArgumentOutOfRangeException("value");
byte b = (byte)value;
dest.Add(b);
return b == Convert.ToByte(c);

@ -37,112 +37,116 @@ using System.Net.Sockets;
using System.Threading;
using WebSocketSharp.Frame;
namespace WebSocketSharp.Server
{
namespace WebSocketSharp.Server {
public class WebSocketServer<T>
where T : WebSocketService, new()
{
#region Private Fields
private Thread _acceptClientThread;
private Dictionary<string, WebSocketService> _services;
private TcpListener _tcpListener;
private Uri _uri;
#endregion
#region Properties
#region Constructor
public IPAddress Address
public WebSocketServer(string url)
{
get { return Endpoint.Address; }
_uri = new Uri(url);
if (!isValidScheme(_uri))
{
var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
throw new ArgumentException(msg);
}
public IPEndPoint Endpoint
var host = _uri.DnsSafeHost;
var ips = Dns.GetHostAddresses(host);
if (ips.Length == 0)
{
get { return (IPEndPoint)_tcpListener.LocalEndpoint; }
var msg = "Invalid WebSocket URI host: " + host;
throw new ArgumentException(msg);
}
public int Port
var scheme = _uri.Scheme;
var port = _uri.Port;
if (port <= 0)
{
get { return Endpoint.Port; }
port = 80;
if (scheme == "wss")
port = 443;
}
public string Url
{
get { return _uri.ToString(); }
_tcpListener = new TcpListener(ips[0], port);
_services = new Dictionary<string, WebSocketService>();
}
#endregion
public WebSocketServer(string absPath, int port)
{
_uri = new Uri(absPath, UriKind.Relative);
#region Events
if (port <= 0)
port = 80;
public event EventHandler<ErrorEventArgs> OnError;
_tcpListener = new TcpListener(IPAddress.Any, port);
_services = new Dictionary<string, WebSocketService>();
}
#endregion
#region Public Constructor
#region Properties
public WebSocketServer(string url)
public IPAddress Address
{
_uri = new Uri(url);
get { return Endpoint.Address; }
}
if (!isValidScheme(_uri))
public IPEndPoint Endpoint
{
var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
throw new ArgumentException(msg);
get { return (IPEndPoint)_tcpListener.LocalEndpoint; }
}
string scheme = _uri.Scheme;
int port = _uri.Port;
if (port <= 0)
{
if (scheme == "wss")
public int Port
{
port = 443;
get { return Endpoint.Port; }
}
else
public string Url
{
port = 80;
}
get { return _uri.ToString(); }
}
_tcpListener = new TcpListener(IPAddress.Any, port);
_services = new Dictionary<string, WebSocketService>();
}
#endregion
#region Events
public event EventHandler<ErrorEventArgs> OnError;
#endregion
#region Private Methods
private void acceptClient(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
if (listener.Server == null || !listener.Server.IsBound)
private void acceptClient()
{
return;
}
try
while (true)
{
TcpClient client = listener.EndAcceptTcpClient(ar);
WebSocket socket = new WebSocket(_uri, client);
T service = new T();
service.Bind(socket, _services);
service.Start();
try {
var client = _tcpListener.AcceptTcpClient();
startService(client);
}
catch (ObjectDisposedException)
catch (SocketException)
{
// TcpListener has been stopped.
return;
break;
}
catch (Exception ex)
{
error(ex.Message);
break;
}
}
listener.BeginAcceptTcpClient(acceptClient, listener);
}
private void error(string message)
@ -157,28 +161,57 @@ namespace WebSocketSharp.Server
private bool isValidScheme(Uri uri)
{
string scheme = uri.Scheme;
var scheme = uri.Scheme;
if (scheme == "ws" || scheme == "wss")
{
return true;
}
return false;
}
private void startAcceptClientThread()
{
_acceptClientThread = new Thread(new ThreadStart(acceptClient));
_acceptClientThread.IsBackground = true;
_acceptClientThread.Start();
}
private void startService(TcpClient client)
{
WaitCallback startCb = (state) =>
{
try {
var socket = new WebSocket(_uri, client);
BindWebSocket(socket);
}
catch (Exception ex)
{
error(ex.Message);
}
};
ThreadPool.QueueUserWorkItem(startCb);
}
#endregion
#region Public Methods
public void BindWebSocket(WebSocket socket)
{
T service = new T();
service.Bind(socket, _services);
service.Start();
}
public void Start()
{
_tcpListener.Start();
_tcpListener.BeginAcceptTcpClient(acceptClient, _tcpListener);
startAcceptClientThread();
}
public void Stop()
{
_tcpListener.Stop();
_acceptClientThread.Join(5 * 1000);
StopServices();
}
@ -192,11 +225,9 @@ namespace WebSocketSharp.Server
lock (((ICollection)_services).SyncRoot)
{
foreach (WebSocketService service in _services.Values)
{
service.Stop(code, reason);
}
}
}
#endregion
}

@ -62,6 +62,7 @@ namespace WebSocketSharp
private string _base64key;
private string _binaryType;
private IPEndPoint _endPoint;
private AutoResetEvent _exitedMessageLoop;
private string _extensions;
private Object _forClose;
@ -106,6 +107,7 @@ namespace WebSocketSharp
{
_uri = uri;
_tcpClient = tcpClient;
_endPoint = (IPEndPoint)_tcpClient.Client.LocalEndPoint;
_isClient = false;
}
@ -177,15 +179,24 @@ namespace WebSocketSharp
get { return _extensions; }
}
public bool IsConnected
{
get
{
if (_readyState != WsState.OPEN) return false;
public bool IsConnected {
get {
if (_readyState != WsState.OPEN)
return false;
return Ping();
}
}
public bool IsSecure {
get {
if (_endPoint.Port == 443)
return true;
return false;
}
}
public string Protocol
{
get { return _protocol; }
@ -447,7 +458,7 @@ namespace WebSocketSharp
{
_netStream = _tcpClient.GetStream();
if (_uri.Scheme == "wss")
if (IsSecure)
{
_sslStream = new SslStream(_netStream);
@ -507,15 +518,17 @@ namespace WebSocketSharp
};
};
string expectedHost = _uri.DnsSafeHost;
int port = ((IPEndPoint)_tcpClient.Client.LocalEndPoint).Port;
if (port != 80)
expectedHost += ":" + port;
if (_uri.IsAbsoluteUri)
{
if (_uri.PathAndQuery.NotEqualsDo(request.Uri, func("Request URI"), out message, false))
return false;
if (expectedHost.NotEqualsDo(request.GetHeaderValues("Host")[0], func("Host"), out message, false))
if (!isValidRequestHost(request.GetHeaderValues("Host")[0], func("Host"), out message))
return false;
}
if (!_uri.IsAbsoluteUri)
if (_uri.ToString().NotEqualsDo(request.Uri, func("Request URI"), out message, false))
return false;
if (!request.HeaderExists("Sec-WebSocket-Version", _version))
@ -536,6 +549,27 @@ namespace WebSocketSharp
return true;
}
private bool isValidRequestHost(string value, Func<string, string, string> func, out string message)
{
var address = _endPoint.Address;
var port = _endPoint.Port;
var expectedHost1 = _uri.DnsSafeHost;
var expectedHost2 = address.ToString();
if (port != 80)
{
expectedHost1 += ":" + port;
expectedHost2 += ":" + port;
}
if (expectedHost1.NotEqualsDo(value, func, out message, false))
if (expectedHost2.NotEqualsDo(value, func, out message, false))
return false;
message = String.Empty;
return true;
}
private bool isValidResponse(ResponseHandshake response, out string message)
{
if (!response.IsWebSocketResponse)

Loading…
Cancel
Save