source: binary-improvements/MapRendering/Web/Web.cs@ 233

Last change on this file since 233 was 230, checked in by alloc, 10 years ago

Binary improvements

File size: 5.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Net;
5using System.Net.Sockets;
6using System.Reflection;
7using System.Text;
8using System.Threading;
9using UnityEngine;
10
11namespace AllocsFixes.NetConnections.Servers.Web
12{
13 public class Web : IConsoleServer {
14 private readonly HttpListener _listener = new HttpListener ();
15 private Dictionary<string, PathHandler> handlers = new Dictionary<string, PathHandler> ();
16 private bool authEnabled = false;
17 private string realm = "7dtd Admin Panel";
18 public static int handlingCount = 0;
19 public static int currentHandlers = 0;
20 private string dataFolder;
21 private bool mapEnabled = false;
22
23 public Web () {
24 try {
25 int webPort = GamePrefs.GetInt (EnumGamePrefs.ControlPanelPort);
26 if (webPort < 1 || webPort > 65533) {
27 Log.Out ("Webserver not started (ControlPanelPort not within 1-65534)");
28 return;
29 }
30 if (!Directory.Exists (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + "/webserver")) {
31 Log.Out ("Webserver not started (folder \"webserver\" not found in WebInterface mod folder)");
32 return;
33 }
34
35 dataFolder = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + "/webserver";
36
37 if (!HttpListener.IsSupported) {
38 Log.Out ("Webserver not started (needs Windows XP SP2, Server 2003 or later or Mono)");
39 return;
40 }
41
42 handlers.Add (
43 "/index.htm",
44 new SimpleRedirectHandler ("/static/index.html"));
45 handlers.Add (
46 "/favicon.ico",
47 new SimpleRedirectHandler ("/static/favicon.ico"));
48 handlers.Add (
49 "/static/",
50 new StaticHandler (
51 "/static/",
52 dataFolder,
53 new AllocsFixes.FileCache.DirectAccess (),
54 true)
55 ); // TODO: Enable cache
56
57 handlers.Add (
58 "/map/",
59 new StaticHandler (
60 "/map/",
61 StaticDirectories.GetSaveGameDir () + "/map",
62 MapRendering.MapRendering.GetTileCache (),
63 false)
64 );
65
66 handlers.Add ("/api/", new ApiHandler ("/api/"));
67
68 _listener.Prefixes.Add (String.Format ("http://*:{0}/", webPort + 2));
69 authEnabled = File.Exists (dataFolder + "/protect");
70 if (authEnabled) {
71 _listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
72 }
73 _listener.Start ();
74 _listener.Realm = realm;
75
76 SdtdConsole.Instance.RegisterServer (this);
77
78 _listener.BeginGetContext (new AsyncCallback (HandleRequest), _listener);
79
80 Log.Out ("Started Webserver on " + (webPort + 2) + " (authentication " + (authEnabled ? "enabled" : "disabled") + ")");
81 } catch (Exception e) {
82 Log.Out ("Error in Web.ctor: " + e);
83 }
84 }
85
86 private void HandleRequest (IAsyncResult result) {
87 if (_listener.IsListening) {
88 Interlocked.Increment (ref handlingCount);
89 Interlocked.Increment (ref currentHandlers);
90 HttpListenerContext ctx = _listener.EndGetContext (result);
91 _listener.BeginGetContext (new AsyncCallback (HandleRequest), _listener);
92 try {
93 ctx.Response.ProtocolVersion = new Version ("1.0");
94
95 HttpListenerBasicIdentity user = Authorize (ctx);
96
97 if (!authEnabled || (user.Name.ToLower ().Equals ("admin") && user.Password.Equals (GamePrefs.GetString (EnumGamePrefs.ControlPanelPassword)))) {
98 if (ctx.Request.Url.AbsolutePath.Length < 2) {
99 handlers ["/index.htm"].HandleRequest (ctx.Request, ctx.Response, user);
100 return;
101 } else {
102 foreach (KeyValuePair<string, PathHandler> kvp in handlers) {
103 if (ctx.Request.Url.AbsolutePath.StartsWith (kvp.Key)) {
104 kvp.Value.HandleRequest (ctx.Request, ctx.Response, user);
105 return;
106 }
107 }
108 }
109
110 Log.Out ("Error in Web.HandleRequest(): No handler found for path \"" + ctx.Request.Url.AbsolutePath + "\"");
111 ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
112 } else {
113 ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
114 ctx.Response.Headers ["WWW-Authenticate"] = "Basic realm=\"" + realm + "\"";
115 }
116 } catch (IOException e) {
117 if (e.InnerException is SocketException) {
118 Log.Out ("Error in Web.HandleRequest(): Remote host closed connection: " + e.InnerException.Message);
119 } else {
120 Log.Out ("Error (IO) in Web.HandleRequest(): " + e);
121 }
122 } catch (Exception e) {
123 Log.Out ("Error in Web.HandleRequest(): " + e);
124 } finally {
125 if (ctx != null) {
126 ctx.Response.OutputStream.Close ();
127 }
128 Interlocked.Decrement (ref currentHandlers);
129 }
130 }
131 }
132
133 private HttpListenerBasicIdentity Authorize (HttpListenerContext ctx) {
134 try {
135 return (HttpListenerBasicIdentity)ctx.User.Identity;
136 } catch (NullReferenceException) {
137 return null;
138 }
139 }
140
141 public void Disconnect () {
142 try {
143 _listener.Stop ();
144 _listener.Close ();
145 } catch (Exception e) {
146 Log.Out ("Error in Web.Disconnect: " + e);
147 }
148 }
149
150 public void SendLine (string line) {
151 try {
152 //Log.Out ("NOT IMPLEMENTED: Web.WriteToClient");
153 } catch (Exception e) {
154 Log.Out ("Error in Web.WriteToClient: " + e);
155 }
156 }
157
158 public void SendLog (string text, string trace, UnityEngine.LogType type) {
159 //throw new System.NotImplementedException ();
160 }
161
162 public static void SetResponseTextContent (HttpListenerResponse resp, string text) {
163 byte[] buf = Encoding.UTF8.GetBytes (text);
164 resp.ContentLength64 = buf.Length;
165 resp.ContentType = "text/html";
166 resp.ContentEncoding = Encoding.UTF8;
167 resp.OutputStream.Write (buf, 0, buf.Length);
168 }
169
170 }
171}
Note: See TracBrowser for help on using the repository browser.