wasSharpNET – Blame information for rev 27

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