forked from IslandzVW/AIS
-
Notifications
You must be signed in to change notification settings - Fork 1
/
APIServer.cs
123 lines (104 loc) · 4.21 KB
/
APIServer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Net;
using System.Threading;
using System.Text;
using log4net;
namespace SimpleAPIServer
{
public delegate void WebHandler(HttpListenerRequest request, HttpListenerResponse response);
public class APIServer
{
private static readonly ILog m_log = LogManager.GetLogger(typeof(APIServer));
private readonly HttpListener _listener = new HttpListener();
private readonly WebHandler _handler;
public APIServer(WebHandler handler, string[] prefixes)
{
if (!HttpListener.IsSupported)
throw new NotSupportedException("Unsupported platform.");
// URI prefixes (routes) are required.
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
// A responder method is required
if (handler == null)
throw new ArgumentException("callback");
Console.CancelKeyPress += new ConsoleCancelEventHandler(CtrlBreakHandler);
foreach (string s in prefixes)
_listener.Prefixes.Add(s);
_handler = handler;
}
static public void SetResponse(HttpListenerResponse response, HttpStatusCode status, string content)
{
response.StatusCode = (int)status;
byte[] buffer = Encoding.UTF8.GetBytes(content);
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
}
static public void SetResponse(HttpListenerResponse response, string content)
{
SetResponse(response, HttpStatusCode.OK, content);
}
public void SendGenericResponse(HttpListenerRequest request, string[] requestParts, HttpListenerResponse response)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<HTML><BODY><h1>Generic Handler</h1><p>{0}</p><p></p>", DateTime.Now);
int x = 0;
foreach (var part in requestParts)
{
sb.AppendFormat("<div><code>[{0}] is {1}</code></div>", x++, part);
}
sb.Append("</BODY></HTML>");
APIServer.SetResponse(response, sb.ToString());
}
protected void CtrlBreakHandler(object sender, ConsoleCancelEventArgs args)
{
m_log.Info("Shutdown requested.");
args.Cancel = true; // don't pass the key on
Stop();
}
public bool IsRunning
{
get { return (_listener == null) ? false : _listener.IsListening; }
}
public void Run()
{
_listener.Start();
ThreadPool.QueueUserWorkItem((o) =>
{
try
{
while (_listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var ctx = c as HttpListenerContext;
try
{
_handler(ctx.Request, ctx.Response);
// Log the request
if (ctx.Response.StatusCode > 299)
m_log.WarnFormat("[{0}]: {1}", ctx.Response.StatusCode, ctx.Request.RawUrl);
else
m_log.InfoFormat("[{0}]: {1}", ctx.Response.StatusCode, ctx.Request.RawUrl);
}
catch (Exception e) {
m_log.Error("Exception: " + e.Message);
} // suppress any exceptions
finally
{
// always close the stream
ctx.Response.OutputStream.Close();
}
}, _listener.GetContext());
}
}
catch { } // suppress any exceptions
});
}
public void Stop()
{
_listener.Stop();
_listener.Close();
}
}
}