wasSharpNET – Blame information for rev 16

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