Refactored HttpListener.cs
This commit is contained in:
parent
157dcf26b4
commit
f46953a5ad
@ -61,6 +61,8 @@ namespace WebSocketSharp.Net
|
|||||||
private object _connectionsSync;
|
private object _connectionsSync;
|
||||||
private List<HttpListenerContext> _ctxQueue;
|
private List<HttpListenerContext> _ctxQueue;
|
||||||
private object _ctxQueueSync;
|
private object _ctxQueueSync;
|
||||||
|
private Dictionary<HttpListenerContext, HttpListenerContext> _ctxRegistry;
|
||||||
|
private object _ctxRegistrySync;
|
||||||
private Func<IIdentity, NetworkCredential> _credFinder;
|
private Func<IIdentity, NetworkCredential> _credFinder;
|
||||||
private X509Certificate2 _defaultCert;
|
private X509Certificate2 _defaultCert;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
@ -68,8 +70,6 @@ namespace WebSocketSharp.Net
|
|||||||
private bool _listening;
|
private bool _listening;
|
||||||
private HttpListenerPrefixCollection _prefixes;
|
private HttpListenerPrefixCollection _prefixes;
|
||||||
private string _realm;
|
private string _realm;
|
||||||
private Dictionary<HttpListenerContext, HttpListenerContext> _registry;
|
|
||||||
private object _registrySync;
|
|
||||||
private List<ListenerAsyncResult> _waitQueue;
|
private List<ListenerAsyncResult> _waitQueue;
|
||||||
private object _waitQueueSync;
|
private object _waitQueueSync;
|
||||||
|
|
||||||
@ -90,10 +90,10 @@ namespace WebSocketSharp.Net
|
|||||||
_ctxQueue = new List<HttpListenerContext> ();
|
_ctxQueue = new List<HttpListenerContext> ();
|
||||||
_ctxQueueSync = ((ICollection) _ctxQueue).SyncRoot;
|
_ctxQueueSync = ((ICollection) _ctxQueue).SyncRoot;
|
||||||
|
|
||||||
_prefixes = new HttpListenerPrefixCollection (this);
|
_ctxRegistry = new Dictionary<HttpListenerContext, HttpListenerContext> ();
|
||||||
|
_ctxRegistrySync = ((ICollection) _ctxRegistry).SyncRoot;
|
||||||
|
|
||||||
_registry = new Dictionary<HttpListenerContext, HttpListenerContext> ();
|
_prefixes = new HttpListenerPrefixCollection (this);
|
||||||
_registrySync = ((ICollection) _registry).SyncRoot;
|
|
||||||
|
|
||||||
_waitQueue = new List<ListenerAsyncResult> ();
|
_waitQueue = new List<ListenerAsyncResult> ();
|
||||||
_waitQueueSync = ((ICollection) _waitQueue).SyncRoot;
|
_waitQueueSync = ((ICollection) _waitQueue).SyncRoot;
|
||||||
@ -372,7 +372,7 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
private void cleanup (bool force)
|
private void cleanup (bool force)
|
||||||
{
|
{
|
||||||
lock (_registrySync) {
|
lock (_ctxRegistrySync) {
|
||||||
if (!force)
|
if (!force)
|
||||||
sendServiceUnavailable ();
|
sendServiceUnavailable ();
|
||||||
|
|
||||||
@ -400,17 +400,17 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
private void cleanupContextRegistry ()
|
private void cleanupContextRegistry ()
|
||||||
{
|
{
|
||||||
lock (_registrySync) {
|
lock (_ctxRegistrySync) {
|
||||||
if (_registry.Count == 0)
|
if (_ctxRegistry.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Need to copy this since closing will call UnregisterContext.
|
// Need to copy this since closing will call UnregisterContext.
|
||||||
var keys = _registry.Keys;
|
var keys = _ctxRegistry.Keys;
|
||||||
var all = new HttpListenerContext[keys.Count];
|
var ctxs = new HttpListenerContext[keys.Count];
|
||||||
keys.CopyTo (all, 0);
|
keys.CopyTo (ctxs, 0);
|
||||||
_registry.Clear ();
|
_ctxRegistry.Clear ();
|
||||||
for (var i = all.Length - 1; i >= 0; i--)
|
for (var i = ctxs.Length - 1; i >= 0; i--)
|
||||||
all[i].Connection.Close (true);
|
ctxs[i].Connection.Close (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,10 +476,10 @@ namespace WebSocketSharp.Net
|
|||||||
{
|
{
|
||||||
CheckDisposed ();
|
CheckDisposed ();
|
||||||
if (_prefixes.Count == 0)
|
if (_prefixes.Count == 0)
|
||||||
throw new InvalidOperationException ("Please, call AddPrefix before using this method.");
|
throw new InvalidOperationException ("AddPrefix must be called before using this method.");
|
||||||
|
|
||||||
if (!_listening)
|
if (!_listening)
|
||||||
throw new InvalidOperationException ("Please, call Start before using this method.");
|
throw new InvalidOperationException ("Start must be called before using this method.");
|
||||||
|
|
||||||
// Lock _waitQueue early to avoid race conditions.
|
// Lock _waitQueue early to avoid race conditions.
|
||||||
lock (_waitQueueSync) {
|
lock (_waitQueueSync) {
|
||||||
@ -505,8 +505,8 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
internal void RegisterContext (HttpListenerContext context)
|
internal void RegisterContext (HttpListenerContext context)
|
||||||
{
|
{
|
||||||
lock (_registrySync)
|
lock (_ctxRegistrySync)
|
||||||
_registry[context] = context;
|
_ctxRegistry[context] = context;
|
||||||
|
|
||||||
ListenerAsyncResult ares = null;
|
ListenerAsyncResult ares = null;
|
||||||
lock (_waitQueueSync) {
|
lock (_waitQueueSync) {
|
||||||
@ -539,8 +539,8 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
internal void UnregisterContext (HttpListenerContext context)
|
internal void UnregisterContext (HttpListenerContext context)
|
||||||
{
|
{
|
||||||
lock (_registrySync)
|
lock (_ctxRegistrySync)
|
||||||
_registry.Remove (context);
|
_ctxRegistry.Remove (context);
|
||||||
|
|
||||||
lock (_ctxQueueSync) {
|
lock (_ctxQueueSync) {
|
||||||
var i = _ctxQueue.IndexOf (context);
|
var i = _ctxQueue.IndexOf (context);
|
||||||
@ -566,21 +566,21 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Begins getting an incoming request information asynchronously.
|
/// Begins getting an incoming request asynchronously.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This asynchronous operation must be completed by calling the <c>EndGetContext</c> method.
|
/// This asynchronous operation must be completed by calling the <c>EndGetContext</c> method.
|
||||||
/// Typically, that method is invoked by the <paramref name="callback"/> delegate.
|
/// Typically, the method is invoked by the <paramref name="callback"/> delegate.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// An <see cref="IAsyncResult"/> that represents the status of the asynchronous operation.
|
/// An <see cref="IAsyncResult"/> that represents the status of the asynchronous operation.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
/// <param name="callback">
|
/// <param name="callback">
|
||||||
/// An <see cref="AsyncCallback"/> delegate that references the method(s) to invoke
|
/// An <see cref="AsyncCallback"/> delegate that references the method to invoke
|
||||||
/// when the asynchronous operation completes.
|
/// when the asynchronous operation completes.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="state">
|
/// <param name="state">
|
||||||
/// An <see cref="object"/> that contains a user defined object to pass to
|
/// An <see cref="object"/> that represents a user defined object to pass to
|
||||||
/// the <paramref name="callback"/> delegate.
|
/// the <paramref name="callback"/> delegate.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
@ -591,7 +591,7 @@ namespace WebSocketSharp.Net
|
|||||||
/// -or-
|
/// -or-
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// This listener hasn't been started or is stopped currently.
|
/// This listener hasn't been started, or is currently stopped.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
@ -615,14 +615,14 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ends an asynchronous operation to get an incoming request information.
|
/// Ends an asynchronous operation to get an incoming request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This method completes an asynchronous operation started by calling
|
/// This method completes an asynchronous operation started by calling
|
||||||
/// the <c>BeginGetContext</c> method.
|
/// the <c>BeginGetContext</c> method.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// A <see cref="HttpListenerContext"/> that contains a request information.
|
/// A <see cref="HttpListenerContext"/> that represents a request.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
/// <param name="asyncResult">
|
/// <param name="asyncResult">
|
||||||
/// An <see cref="IAsyncResult"/> obtained by calling the <c>BeginGetContext</c> method.
|
/// An <see cref="IAsyncResult"/> obtained by calling the <c>BeginGetContext</c> method.
|
||||||
@ -647,10 +647,10 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
var ares = asyncResult as ListenerAsyncResult;
|
var ares = asyncResult as ListenerAsyncResult;
|
||||||
if (ares == null)
|
if (ares == null)
|
||||||
throw new ArgumentException ("Wrong IAsyncResult.", "asyncResult");
|
throw new ArgumentException ("A wrong IAsyncResult.", "asyncResult");
|
||||||
|
|
||||||
if (ares.EndCalled)
|
if (ares.EndCalled)
|
||||||
throw new InvalidOperationException ("Cannot reuse this IAsyncResult.");
|
throw new InvalidOperationException ("This IAsyncResult cannot be reused.");
|
||||||
|
|
||||||
ares.EndCalled = true;
|
ares.EndCalled = true;
|
||||||
if (!ares.IsCompleted)
|
if (!ares.IsCompleted)
|
||||||
@ -671,14 +671,13 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an incoming request information.
|
/// Gets an incoming request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This method waits for an incoming request and returns a request information
|
/// This method waits for an incoming request, and returns when a request is received.
|
||||||
/// when the listener receives a request.
|
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// A <see cref="HttpListenerContext"/> that contains a request information.
|
/// A <see cref="HttpListenerContext"/> that represents a request.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// <para>
|
/// <para>
|
||||||
@ -688,7 +687,7 @@ namespace WebSocketSharp.Net
|
|||||||
/// -or-
|
/// -or-
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// This listener hasn't been started or is stopped currently.
|
/// This listener hasn't been started, or is currently stopped.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
@ -703,7 +702,7 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts to receive incoming requests.
|
/// Starts receiving incoming requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This listener has been closed.
|
/// This listener has been closed.
|
||||||
@ -737,17 +736,17 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Explicit Interface Implementation
|
#region Explicit Interface Implementations
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases all resource used by the listener.
|
/// Releases all resources used by the listener.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void IDisposable.Dispose ()
|
void IDisposable.Dispose ()
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
close (true); // TODO: Should we force here or not?
|
close (true);
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user