wasSharpNET – Blame information for rev 11

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 {
14 public abstract class HTTPServer
15 {
16 private int activeRequests;
11 office 17  
10 office 18 private readonly HttpListener HTTPListener = new HttpListener()
19 {
20 AuthenticationSchemes = AuthenticationSchemes.None
21 };
11 office 22  
9 office 23 private int processedRequests;
24  
10 office 25 private readonly AutoResetEvent StopServerEvent = new AutoResetEvent(false);
26 private readonly AutoResetEvent ServerStoppedEvent = new AutoResetEvent(false);
9 office 27  
10 office 28 public AuthenticationSchemes AuthenticationSchemes
9 office 29 {
10 office 30 get
9 office 31 {
10 office 32 return HTTPListener.AuthenticationSchemes;
9 office 33 }
10 office 34 set
35 {
36 HTTPListener.AuthenticationSchemes = value;
37 }
38 }
9 office 39  
10 office 40 public bool IsRunning => HTTPListener.IsListening;
9 office 41  
10 office 42 public bool Start(IEnumerable<string> prefixes)
43 {
9 office 44 // Do not start the HTTP server if it is already running.
45 if (HTTPListener.IsListening)
46 return false;
47  
10 office 48 // Add all prefixes.
49 foreach (var prefix in prefixes)
50 {
51 HTTPListener.Prefixes.Add(prefix);
52 }
53  
9 office 54 // Do not bomb if the client disconnects.
55 HTTPListener.IgnoreWriteExceptions = true;
56 HTTPListener.Start();
10 office 57 ThreadPool.QueueUserWorkItem(Listen, new HTTPServerCallbackState(HTTPListener));
9 office 58 return true;
59 }
60  
61 public bool Stop()
62 {
10 office 63 StopServerEvent.Set();
64 ServerStoppedEvent.WaitOne();
65 HTTPListener.Prefixes.Clear();
66 return true;
9 office 67 }
68  
69 private void Listen(object state)
70 {
11 office 71 var callbackState = (HTTPServerCallbackState)state;
9 office 72  
73 while (callbackState.Listener.IsListening)
74 {
75 callbackState.Listener.BeginGetContext(ContextCallback, callbackState);
11 office 76 var n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ContextRetrieved, StopServerEvent });
9 office 77  
78 if (n.Equals(1))
79 {
80 callbackState.Listener.Stop();
81 break;
82 }
83 }
10 office 84  
85 ServerStoppedEvent.Set();
9 office 86 }
87  
88 public abstract void ProcessHTTPContext(HttpListenerContext context);
89  
90 private void ContextCallback(IAsyncResult ar)
91 {
11 office 92 var callbackState = (HTTPServerCallbackState)ar.AsyncState;
9 office 93 HttpListenerContext httpContext = null;
94  
95 Interlocked.Increment(ref processedRequests);
96 Interlocked.Increment(ref activeRequests);
97  
98 try
99 {
100 httpContext = callbackState.Listener.EndGetContext(ar);
101 }
102 catch (Exception)
103 {
104 Interlocked.Decrement(ref activeRequests);
105 return;
106 }
107 finally
108 {
109 callbackState.ContextRetrieved.Set();
110 }
111  
112 if (httpContext == null)
113 return;
114  
115 try
116 {
117 ProcessHTTPContext(httpContext);
118 }
119 finally
120 {
121 Interlocked.Decrement(ref activeRequests);
122 }
123 }
124  
125 private class HTTPServerCallbackState
126 {
127 public HTTPServerCallbackState(HttpListener listener)
128 {
129 if (listener == null)
130 throw new ArgumentNullException("listener");
131 Listener = listener;
132 ContextRetrieved = new AutoResetEvent(false);
133 }
134  
135 public HttpListener Listener { get; }
136  
137 public AutoResetEvent ContextRetrieved { get; }
138 }
139 }
11 office 140 }