wasSharpNET – Diff between revs 19 and 20

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 19 Rev 20
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 = null; 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  
-   27 private readonly ManualResetEventSlim stopListen = new ManualResetEventSlim(false);
26   28  
27 public bool Start(IEnumerable<string> prefixes) 29 public bool Start(List<string> prefixes)
28 { 30 {
29 HTTPListener = new HttpListener() 31 HTTPListener = new HttpListener
30 { 32 {
31 AuthenticationSchemes = AuthenticationSchemes 33 AuthenticationSchemes = AuthenticationSchemes
32 }; 34 };
33   35  
34 // Add all prefixes. 36 // Add all prefixes.
35 HTTPListener.Prefixes.Clear(); 37 HTTPListener.Prefixes.Clear();
36 foreach (var prefix in prefixes) 38 foreach (var prefix in prefixes)
37 { 39 {
38 HTTPListener.Prefixes.Add(prefix); 40 HTTPListener.Prefixes.Add(prefix);
39 } 41 }
40   42  
41 // Do not bomb if the client disconnects. 43 // Do not bomb if the client disconnects.
42 HTTPListener.IgnoreWriteExceptions = true; 44 HTTPListener.IgnoreWriteExceptions = true;
43 HTTPListener.Start(); 45 HTTPListener.Start();
44 ThreadPool.QueueUserWorkItem(Listen, new HTTPServerCallbackState(HTTPListener)); 46 return ThreadPool.QueueUserWorkItem(Listen, new HTTPServerCallbackState(HTTPListener));
45 return true; -  
46 } 47 }
47   48  
48 public void Stop() 49 public void Stop()
49 { 50 {
50 HTTPListener.Stop(); 51 stopListen.Set();
51 } 52 }
52   53  
53 private void Listen(object state) 54 private void Listen(object state)
54 { 55 {
55 var callbackState = (HTTPServerCallbackState)state; 56 HTTPServerCallbackState callbackState = (HTTPServerCallbackState)state;
56   57  
57 while (callbackState.Listener.IsListening) 58 while (callbackState.Listener.IsListening)
58 { 59 {
59 callbackState.Listener.BeginGetContext(ContextCallback, callbackState); 60 callbackState.Listener.BeginGetContext(ContextCallback, callbackState);
-   61  
-   62 if (WaitHandle.WaitAny(new[] { callbackState.ContextRetrieved, stopListen.WaitHandle }) != 1)
-   63 continue;
-   64  
60 callbackState.ContextRetrieved.WaitOne(); 65 callbackState.Listener.Stop();
-   66 break;
61 } 67 }
62 } 68 }
63   69  
64 public abstract void ProcessHTTPContext(HttpListenerContext context); 70 public abstract void ProcessHTTPContext(HttpListenerContext context);
65   71  
66 private void ContextCallback(IAsyncResult ar) 72 private void ContextCallback(IAsyncResult ar)
67 { 73 {
68 var callbackState = (HTTPServerCallbackState)ar.AsyncState; 74 var callbackState = (HTTPServerCallbackState)ar.AsyncState;
69 HttpListenerContext httpContext = null; 75 HttpListenerContext httpContext;
70   76  
71 Interlocked.Increment(ref processedRequests); 77 Interlocked.Increment(ref processedRequests);
72 Interlocked.Increment(ref activeRequests); 78 Interlocked.Increment(ref activeRequests);
73   79  
74 try 80 try
75 { 81 {
76 httpContext = callbackState.Listener.EndGetContext(ar); 82 httpContext = callbackState.Listener.EndGetContext(ar);
77 } 83 }
78 catch (Exception) 84 catch (Exception)
79 { 85 {
80 Interlocked.Decrement(ref activeRequests); 86 Interlocked.Decrement(ref activeRequests);
81 return; 87 return;
82 } 88 }
83 finally 89 finally
84 { 90 {
85 callbackState.ContextRetrieved.Set(); 91 callbackState.ContextRetrieved.Set();
86 } 92 }
87   -  
88 if (httpContext == null) -  
89 return; -  
90   93  
91 try 94 try
92 { 95 {
93 ProcessHTTPContext(httpContext); 96 ProcessHTTPContext(httpContext);
94 } 97 }
95 finally 98 finally
96 { 99 {
97 Interlocked.Decrement(ref activeRequests); 100 Interlocked.Decrement(ref activeRequests);
98 } 101 }
99 } 102 }
100   103  
101 public void Dispose() 104 public void Dispose()
102 { 105 {
103 Stop(); 106 Stop();
104 HTTPListener = null; -  
105 } 107 }
106   108  
107 private class HTTPServerCallbackState 109 private class HTTPServerCallbackState
108 { 110 {
109 public HTTPServerCallbackState(HttpListener listener) 111 public HTTPServerCallbackState(HttpListener listener)
110 { 112 {
111 if (listener == null) 113 if (listener == null)
112 throw new ArgumentNullException("listener"); 114 throw new ArgumentNullException(nameof(listener));
113 Listener = listener; 115 Listener = listener;
114 ContextRetrieved = new AutoResetEvent(false); 116 ContextRetrieved = new AutoResetEvent(false);
115 } 117 }
116   118  
117 public HttpListener Listener { get; } 119 public HttpListener Listener { get; }
118   120  
119 public AutoResetEvent ContextRetrieved { get; } 121 public AutoResetEvent ContextRetrieved { get; }
120 } 122 }
121 } 123 }
122 } 124 }
123   125