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

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