Fix for issue #6 - 1

This commit is contained in:
sta 2012-09-01 17:01:05 +09:00
parent 75417fba70
commit 3ef6d58f31
49 changed files with 151 additions and 83 deletions

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.

Binary file not shown.

Binary file not shown.

View File

@ -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.

Binary file not shown.

View File

@ -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);

View File

@ -37,19 +37,65 @@ 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 Constructor
public WebSocketServer(string url)
{
_uri = new Uri(url);
if (!isValidScheme(_uri))
{
var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
throw new ArgumentException(msg);
}
var host = _uri.DnsSafeHost;
var ips = Dns.GetHostAddresses(host);
if (ips.Length == 0)
{
var msg = "Invalid WebSocket URI host: " + host;
throw new ArgumentException(msg);
}
var scheme = _uri.Scheme;
var port = _uri.Port;
if (port <= 0)
{
port = 80;
if (scheme == "wss")
port = 443;
}
_tcpListener = new TcpListener(ips[0], port);
_services = new Dictionary<string, WebSocketService>();
}
public WebSocketServer(string absPath, int port)
{
_uri = new Uri(absPath, UriKind.Relative);
if (port <= 0)
port = 80;
_tcpListener = new TcpListener(IPAddress.Any, port);
_services = new Dictionary<string, WebSocketService>();
}
#endregion
#region Properties
public IPAddress Address
@ -80,69 +126,27 @@ namespace WebSocketSharp.Server
#endregion
#region Public Constructor
public WebSocketServer(string url)
{
_uri = new Uri(url);
if (!isValidScheme(_uri))
{
var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
throw new ArgumentException(msg);
}
string scheme = _uri.Scheme;
int port = _uri.Port;
if (port <= 0)
{
if (scheme == "wss")
{
port = 443;
}
else
{
port = 80;
}
}
_tcpListener = new TcpListener(IPAddress.Any, port);
_services = new Dictionary<string, WebSocketService>();
}
#endregion
#region Private Methods
private void acceptClient(IAsyncResult ar)
private void acceptClient()
{
TcpListener listener = (TcpListener)ar.AsyncState;
if (listener.Server == null || !listener.Server.IsBound)
while (true)
{
return;
try {
var client = _tcpListener.AcceptTcpClient();
startService(client);
}
catch (SocketException)
{
// TcpListener has been stopped.
break;
}
catch (Exception ex)
{
error(ex.Message);
break;
}
}
try
{
TcpClient client = listener.EndAcceptTcpClient(ar);
WebSocket socket = new WebSocket(_uri, client);
T service = new T();
service.Bind(socket, _services);
service.Start();
}
catch (ObjectDisposedException)
{
// TcpListener has been stopped.
return;
}
catch (Exception ex)
{
error(ex.Message);
}
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,9 +225,7 @@ namespace WebSocketSharp.Server
lock (((ICollection)_services).SyncRoot)
{
foreach (WebSocketService service in _services.Values)
{
service.Stop(code, reason);
}
}
}

View File

@ -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,16 +518,18 @@ 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 (_uri.PathAndQuery.NotEqualsDo(request.Uri, func("Request URI"), out message, false))
return false;
if (!isValidRequestHost(request.GetHeaderValues("Host")[0], func("Host"), out message))
return false;
}
if (expectedHost.NotEqualsDo(request.GetHeaderValues("Host")[0], func("Host"), out message, false))
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)

Binary file not shown.