source: binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Web/Web.cs@ 183

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

fixes

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