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

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

fixes

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