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

Last change on this file since 185 was 185, checked in by alloc, 6 years ago

fixes

File size: 4.7 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 (webPort < 1 || webPort > 65533) {
23                                        Log.Out ("Webserver not started (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.