wasSharpNET – Diff between revs 20 and 22

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 20 Rev 22
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 using System; 7 using System;
8 using System.Collections.Generic; 8 using System.Collections.Generic;
9 using System.Net; 9 using System.Net;
10 using System.Threading; 10 using System.Threading;
11   11  
12 namespace wasSharpNET.Network.HTTP 12 namespace wasSharpNET.Network.HTTP
13 { 13 {
14 public abstract class HTTPServer : IDisposable 14 public abstract class HTTPServer : IDisposable
15 { 15 {
16 private int activeRequests; 16 private int activeRequests;
17   17  
18 private HttpListener HTTPListener; 18 private HttpListener HTTPListener;
19   19  
20 private int processedRequests; 20 private int processedRequests;
21   21  
22 public AuthenticationSchemes AuthenticationSchemes { get; set; } = 22 public AuthenticationSchemes AuthenticationSchemes { get; set; } =
23 AuthenticationSchemes.None; 23 AuthenticationSchemes.None;
24   24  
25 public bool IsRunning => HTTPListener != null && HTTPListener.IsListening; 25 public bool IsRunning => HTTPListener != null && HTTPListener.IsListening;
26   26  
27 private readonly ManualResetEventSlim stopListen = new ManualResetEventSlim(false); 27 private readonly ManualResetEventSlim stopListen = new ManualResetEventSlim(false);
-   28 private readonly ManualResetEventSlim listenStop = new ManualResetEventSlim(false);
28   29  
29 public bool Start(List<string> prefixes) 30 public bool Start(List<string> prefixes)
30 { 31 {
31 HTTPListener = new HttpListener 32 HTTPListener = new HttpListener
32 { 33 {
33 AuthenticationSchemes = AuthenticationSchemes 34 AuthenticationSchemes = AuthenticationSchemes
34 }; 35 };
35   36  
36 // Add all prefixes. 37 // Add all prefixes.
37 HTTPListener.Prefixes.Clear(); 38 HTTPListener.Prefixes.Clear();
38 foreach (var prefix in prefixes) 39 foreach (var prefix in prefixes)
39 { 40 {
40 HTTPListener.Prefixes.Add(prefix); 41 HTTPListener.Prefixes.Add(prefix);
41 } 42 }
42   43  
43 // Do not bomb if the client disconnects. 44 // Do not bomb if the client disconnects.
44 HTTPListener.IgnoreWriteExceptions = true; 45 HTTPListener.IgnoreWriteExceptions = true;
45 HTTPListener.Start(); 46 HTTPListener.Start();
46 return ThreadPool.QueueUserWorkItem(Listen, new HTTPServerCallbackState(HTTPListener)); 47 return ThreadPool.QueueUserWorkItem(Listen, new HTTPServerCallbackState(HTTPListener));
47 } 48 }
48   49  
49 public void Stop() 50 public bool Stop(int timeout)
50 { 51 {
-   52 stopListen.Set();
51 stopListen.Set(); 53 return listenStop.Wait(timeout);
52 } 54 }
53   55  
54 private void Listen(object state) 56 private void Listen(object state)
55 { 57 {
56 HTTPServerCallbackState callbackState = (HTTPServerCallbackState)state; 58 HTTPServerCallbackState callbackState = (HTTPServerCallbackState)state;
57   59  
58 while (callbackState.Listener.IsListening) 60 while (callbackState.Listener.IsListening)
59 { 61 {
60 callbackState.Listener.BeginGetContext(ContextCallback, callbackState); 62 callbackState.Listener?.BeginGetContext(ContextCallback, callbackState);
61   63  
62 if (WaitHandle.WaitAny(new[] { callbackState.ContextRetrieved, stopListen.WaitHandle }) != 1) 64 if (WaitHandle.WaitAny(new[] { callbackState.ContextRetrieved, stopListen.WaitHandle }) != 1)
63 continue; 65 continue;
-   66  
-   67 try
64   68 {
-   69 callbackState.Listener.Stop();
-   70 callbackState.Listener.Close();
-   71 }
-   72 finally
-   73 {
-   74 listenStop.Set();
65 callbackState.Listener.Stop(); 75 }
66 break; 76 break;
67 } 77 }
68 } 78 }
69   79  
70 public abstract void ProcessHTTPContext(HttpListenerContext context); 80 public abstract void ProcessHTTPContext(HttpListenerContext context);
71   81  
72 private void ContextCallback(IAsyncResult ar) 82 private void ContextCallback(IAsyncResult ar)
73 { 83 {
74 var callbackState = (HTTPServerCallbackState)ar.AsyncState; 84 var callbackState = (HTTPServerCallbackState)ar.AsyncState;
75 HttpListenerContext httpContext; 85 HttpListenerContext httpContext;
76   86  
77 Interlocked.Increment(ref processedRequests); 87 Interlocked.Increment(ref processedRequests);
78 Interlocked.Increment(ref activeRequests); 88 Interlocked.Increment(ref activeRequests);
79   89  
80 try 90 try
81 { 91 {
82 httpContext = callbackState.Listener.EndGetContext(ar); 92 httpContext = callbackState.Listener.EndGetContext(ar);
83 } 93 }
84 catch (Exception) 94 catch (Exception)
85 { 95 {
86 Interlocked.Decrement(ref activeRequests); 96 Interlocked.Decrement(ref activeRequests);
87 return; 97 return;
88 } 98 }
89 finally 99 finally
90 { 100 {
91 callbackState.ContextRetrieved.Set(); 101 callbackState.ContextRetrieved.Set();
92 } 102 }
93   103  
94 try 104 try
95 { 105 {
96 ProcessHTTPContext(httpContext); 106 ProcessHTTPContext(httpContext);
97 } 107 }
98 finally 108 finally
99 { 109 {
100 Interlocked.Decrement(ref activeRequests); 110 Interlocked.Decrement(ref activeRequests);
101 } 111 }
102 } 112 }
103   113  
104 public void Dispose() 114 public void Dispose()
105 { 115 {
106 Stop(); 116 stopListen.Set();
107 } 117 }
108   118  
109 private class HTTPServerCallbackState 119 private class HTTPServerCallbackState
110 { 120 {
111 public HTTPServerCallbackState(HttpListener listener) 121 public HTTPServerCallbackState(HttpListener listener)
112 { 122 {
113 if (listener == null) 123 if (listener == null)
114 throw new ArgumentNullException(nameof(listener)); 124 throw new ArgumentNullException(nameof(listener));
115 Listener = listener; 125 Listener = listener;
116 ContextRetrieved = new AutoResetEvent(false); 126 ContextRetrieved = new AutoResetEvent(false);
117 } 127 }
118   128  
119 public HttpListener Listener { get; } 129 public HttpListener Listener { get; }
120   130  
121 public AutoResetEvent ContextRetrieved { get; } 131 public AutoResetEvent ContextRetrieved { get; }
122 } 132 }
123 } 133 }
124 } 134 }
125   135