diff options
author | onefang | 2019-08-13 07:35:50 +1000 |
---|---|---|
committer | onefang | 2019-08-13 07:35:50 +1000 |
commit | 70efa042176d2dd1c49f9f00a6e5b9452bbc9de6 (patch) | |
tree | d1219b7ae93e6346ae8400086ff41ffa49f4a7e4 | |
parent | Godliness can be in the first name as well. (diff) | |
download | opensim-SC-70efa042176d2dd1c49f9f00a6e5b9452bbc9de6.zip opensim-SC-70efa042176d2dd1c49f9f00a6e5b9452bbc9de6.tar.gz opensim-SC-70efa042176d2dd1c49f9f00a6e5b9452bbc9de6.tar.bz2 opensim-SC-70efa042176d2dd1c49f9f00a6e5b9452bbc9de6.tar.xz |
Beef up the web server a bit.
Sanatize the path.
Add support for Last-Modified, If-Modified-Since, and Cache-Control:
no-cache.
Teach the base server about more binary content types.
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 4 | ||||
-rw-r--r-- | OpenSim/Server/Handlers/Web/WebServerConnector.cs | 37 |
2 files changed, 41 insertions, 0 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index c53c0ce..26694b5 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -1840,6 +1840,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1840 | { | 1840 | { |
1841 | if (!(contentType.Contains("image") | 1841 | if (!(contentType.Contains("image") |
1842 | || contentType.Contains("x-shockwave-flash") | 1842 | || contentType.Contains("x-shockwave-flash") |
1843 | || contentType.Contains("application/gzip") | ||
1844 | || contentType.Contains("application/pdf") | ||
1845 | || contentType.Contains("application/zip") | ||
1846 | || contentType.Contains("application/x-xz") | ||
1843 | || contentType.Contains("application/x-oar") | 1847 | || contentType.Contains("application/x-oar") |
1844 | || contentType.Contains("application/vnd.ll.mesh"))) | 1848 | || contentType.Contains("application/vnd.ll.mesh"))) |
1845 | { | 1849 | { |
diff --git a/OpenSim/Server/Handlers/Web/WebServerConnector.cs b/OpenSim/Server/Handlers/Web/WebServerConnector.cs index 2607386..06fd892 100644 --- a/OpenSim/Server/Handlers/Web/WebServerConnector.cs +++ b/OpenSim/Server/Handlers/Web/WebServerConnector.cs | |||
@@ -91,6 +91,7 @@ namespace OpenSim.Server.Handlers.Web | |||
91 | long HGin = m_database.Count("Presence", "UserID NOT IN (SELECT PrincipalID FROM UserAccounts)"); // HGers in world. | 91 | long HGin = m_database.Count("Presence", "UserID NOT IN (SELECT PrincipalID FROM UserAccounts)"); // HGers in world. |
92 | long locOut = m_database.Count("hg_traveling_data", "GridExternalName != '" + ssi["uri"] + "'"); // Locals that are HGing. | 92 | long locOut = m_database.Count("hg_traveling_data", "GridExternalName != '" + ssi["uri"] + "'"); // Locals that are HGing. |
93 | Hashtable reply = new Hashtable(); | 93 | Hashtable reply = new Hashtable(); |
94 | Hashtable replyHeaders = new Hashtable(); | ||
94 | ssi["members"] = m_database.Count("UserAccounts").ToString(); | 95 | ssi["members"] = m_database.Count("UserAccounts").ToString(); |
95 | ssi["sims"] = m_database.Count("regions").ToString(); | 96 | ssi["sims"] = m_database.Count("regions").ToString(); |
96 | ssi["inworld"] = (locIn - HGin).ToString(); | 97 | ssi["inworld"] = (locIn - HGin).ToString(); |
@@ -107,6 +108,16 @@ namespace OpenSim.Server.Handlers.Web | |||
107 | string file = reqpath.Remove(0, 5); | 108 | string file = reqpath.Remove(0, 5); |
108 | string path = Path.Combine(Util.webDir(), file); | 109 | string path = Path.Combine(Util.webDir(), file); |
109 | 110 | ||
111 | if (! Path.GetFullPath(path).StartsWith(Path.GetFullPath(Util.webDir()))) | ||
112 | { | ||
113 | m_log.ErrorFormat("[WEB SERVICE]: INVALID PATH {0} != {1}", Path.GetFullPath(path), Path.GetFullPath(Util.webDir())); | ||
114 | reply["int_response_code"] = 404; | ||
115 | reply["content_type"] = "text/html"; | ||
116 | reply["str_response_string"] = "<html><title>404 Unknown page</title><head></head><body bgcolor=\"black\" text=\"white\" alink=\"red\" link=\"blue\" vlink=\"purple\">" + | ||
117 | "404 error, can't find the " + reqpath + " page.<p> </p></body></html>"; | ||
118 | return reply; | ||
119 | } | ||
120 | |||
110 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} type {2} body {3}.", method, reqpath, type, body); | 121 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} type {2} body {3}.", method, reqpath, type, body); |
111 | foreach (DictionaryEntry h in headers) | 122 | foreach (DictionaryEntry h in headers) |
112 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} header {2} = {3}", method, reqpath, (string) h.Key, (string) h.Value); | 123 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} header {2} = {3}", method, reqpath, (string) h.Key, (string) h.Value); |
@@ -118,12 +129,36 @@ namespace OpenSim.Server.Handlers.Web | |||
118 | { | 129 | { |
119 | if (File.Exists(path)) | 130 | if (File.Exists(path)) |
120 | { | 131 | { |
132 | DateTime dt = File.GetLastWriteTimeUtc(path); | ||
121 | string m = (string) mime[Path.GetExtension(path).ToLower()]; | 133 | string m = (string) mime[Path.GetExtension(path).ToLower()]; |
122 | reply["content_type"] = m; | 134 | reply["content_type"] = m; |
123 | if ((null == m) || ("text/" != m.Substring(0, 5))) | 135 | if ((null == m) || ("text/" != m.Substring(0, 5))) |
136 | { | ||
137 | string ifdtr = (string) headers["if-modified-since"]; | ||
138 | if (null != ifdtr) | ||
139 | { | ||
140 | try | ||
141 | { | ||
142 | DateTime ifdt = DateTime.Parse(ifdtr, System.Globalization.CultureInfo.InvariantCulture); | ||
143 | if (0 >= DateTime.Compare(ifdt, dt)) | ||
144 | { | ||
145 | reply["int_response_code"] = 304; | ||
146 | m_log.InfoFormat("[WEB SERVICE]: If-Modified-Since is earliar or equal to Last-Modified, from {0}", path); | ||
147 | reply["headers"] = replyHeaders; | ||
148 | return reply; | ||
149 | } | ||
150 | } | ||
151 | catch (Exception) | ||
152 | { | ||
153 | m_log.ErrorFormat("[WEB SERVICE]: Invalid If-Modified-Since header, ignoring it, from {0}", path); | ||
154 | } | ||
155 | } | ||
156 | replyHeaders["Last-Modified"] = dt.ToString("R"); | ||
124 | reply["bin_response_data"] = File.ReadAllBytes(path); | 157 | reply["bin_response_data"] = File.ReadAllBytes(path); |
158 | } | ||
125 | else | 159 | else |
126 | { | 160 | { |
161 | replyHeaders["Cache-Control"] = "no-cache"; | ||
127 | StreamReader csr = File.OpenText(path); | 162 | StreamReader csr = File.OpenText(path); |
128 | string content = csr.ReadToEnd(); | 163 | string content = csr.ReadToEnd(); |
129 | // Slow and wasteful, but I'm expecting only tiny web files, not accessed very often. | 164 | // Slow and wasteful, but I'm expecting only tiny web files, not accessed very often. |
@@ -169,6 +204,7 @@ namespace OpenSim.Server.Handlers.Web | |||
169 | 204 | ||
170 | if ("account.html" == file) | 205 | if ("account.html" == file) |
171 | { | 206 | { |
207 | replyHeaders["Cache-Control"] = "no-cache"; | ||
172 | if ("logout" == fields["doit"].ToString()) | 208 | if ("logout" == fields["doit"].ToString()) |
173 | reply["str_response_string"] = loginPage(null, "Logged out."); | 209 | reply["str_response_string"] = loginPage(null, "Logged out."); |
174 | else if ("create" == fields["doit"].ToString()) | 210 | else if ("create" == fields["doit"].ToString()) |
@@ -213,6 +249,7 @@ namespace OpenSim.Server.Handlers.Web | |||
213 | } | 249 | } |
214 | 250 | ||
215 | m_log.Info("[WEB SERVICE]: "); | 251 | m_log.Info("[WEB SERVICE]: "); |
252 | reply["headers"] = replyHeaders; | ||
216 | return reply; | 253 | return reply; |
217 | } | 254 | } |
218 | 255 | ||