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

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

fixes

File size: 4.6 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);
[185]22 if (webPort < 1 || webPort > 65533) {
23 Log.Out ("Webserver not started (ControlPanelPort not within 1-65534)");
[182]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
[183]31 if (!HttpListener.IsSupported) {
32 Log.Out ("Webserver not started (needs Windows XP SP2, Server 2003 or later or Mono)");
33 return;
34 }
[133]35
[154]36 handlers.Add ("/index.htm", new SimpleRedirectHandler ("/static/index.html"));
[151]37 handlers.Add ("/static/", new StaticHandler ("/static/", Application.dataPath + "/../webserver", false/*true*/, true)); // TODO: Enable cache
[134]38 handlers.Add ("/map/", new StaticHandler ("/map/", StaticDirectories.GetSaveGameDir () + "/map", false, false));
[154]39 handlers.Add ("/api/", new ApiHandler ("/api/"));
[133]40
[182]41 _listener.Prefixes.Add (String.Format ("http://*:{0}/", webPort + 2));
[172]42 authEnabled = File.Exists (Application.dataPath + "/../webserver/protect");
43 if (authEnabled)
[168]44 _listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
[133]45 _listener.Start ();
[172]46 _listener.Realm = realm;
[133]47
48 ThreadPool.QueueUserWorkItem ((o) =>
49 {
50 try {
51 while (_listener.IsListening) {
52 ThreadPool.QueueUserWorkItem ((c) =>
53 {
[134]54 HttpListenerContext ctx = c as HttpListenerContext;
55 HandleRequest (ctx);
[133]56 }, _listener.GetContext ());
57 }
58 } catch {
59 }
60 }
61 );
62
[182]63 NetTelnetServer.RegisterServer(this);
64
65
66 Log.Out ("Started Webserver on " + (webPort + 2) + " (authentication " + (authEnabled ? "enabled" : "disabled") + ")");
[133]67 } catch (Exception e) {
68 Log.Out ("Error in Web.ctor: " + e);
69 }
70 }
71
[134]72 private void HandleRequest (HttpListenerContext ctx)
[133]73 {
74 try {
[134]75 ctx.Response.ProtocolVersion = new Version ("1.1");
[133]76
[154]77 HttpListenerBasicIdentity user = Authorize (ctx);
[134]78
[172]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 }
[133]89 }
90 }
[172]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 + "\"";
[133]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);
[134]104 } catch (Exception e) {
105 Log.Out ("Error in Web.HandleRequest(): " + e);
[133]106 } finally {
[134]107 ctx.Response.Close ();
[133]108 }
109 }
110
[154]111 private HttpListenerBasicIdentity Authorize (HttpListenerContext ctx)
[134]112 {
113 try {
[154]114 return (HttpListenerBasicIdentity)ctx.User.Identity;
[134]115 } catch (NullReferenceException) {
[154]116 return null;
[134]117 }
118 }
119
[133]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
[190]130 public void SendLine (string line)
[133]131 {
132 try {
[142]133 //Log.Out ("NOT IMPLEMENTED: Web.WriteToClient");
[133]134 } catch (Exception e) {
135 Log.Out ("Error in Web.WriteToClient: " + e);
136 }
137 }
138
[190]139 public void SendLog (string text, string trace, UnityEngine.LogType type)
[133]140 {
[190]141 throw new System.NotImplementedException ();
[133]142 }
143
[163]144 public static void SetResponseTextContent (HttpListenerResponse resp, string text)
145 {
146 byte[] buf = Encoding.UTF8.GetBytes (text);
147 resp.ContentLength64 = buf.Length;
148 resp.ContentType = "text/html";
149 resp.ContentEncoding = Encoding.UTF8;
150 resp.OutputStream.Write (buf, 0, buf.Length);
151 }
152
[133]153 }
154}
Note: See TracBrowser for help on using the repository browser.