opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Net;
32 using System.Text;
33 using log4net;
34 using OpenSim.Framework;
35 using OpenSim.Framework.Console;
36 using OpenSim.Framework.Servers.HttpServer;
37  
38 namespace OpenSim.Framework.Servers
39 {
40 public class MainServer
41 {
42 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43  
44 private static BaseHttpServer instance = null;
45 private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
46  
47 /// <summary>
48 /// Control the printing of certain debug messages.
49 /// </summary>
50 /// <remarks>
51 /// If DebugLevel >= 1 then short warnings are logged when receiving bad input data.
52 /// If DebugLevel >= 2 then long warnings are logged when receiving bad input data.
53 /// If DebugLevel >= 3 then short notices about all incoming non-poll HTTP requests are logged.
54 /// If DebugLevel >= 4 then the time taken to fulfill the request is logged.
55 /// If DebugLevel >= 5 then the start of the body of incoming non-poll HTTP requests will be logged.
56 /// If DebugLevel >= 6 then the entire body of incoming non-poll HTTP requests will be logged.
57 /// </remarks>
58 public static int DebugLevel
59 {
60 get { return s_debugLevel; }
61 set
62 {
63 s_debugLevel = value;
64  
65 lock (m_Servers)
66 foreach (BaseHttpServer server in m_Servers.Values)
67 server.DebugLevel = s_debugLevel;
68 }
69 }
70  
71 private static int s_debugLevel;
72  
73 /// <summary>
74 /// Set the main HTTP server instance.
75 /// </summary>
76 /// <remarks>
77 /// This will be used to register all handlers that listen to the default port.
78 /// </remarks>
79 /// <exception cref='Exception'>
80 /// Thrown if the HTTP server has not already been registered via AddHttpServer()
81 /// </exception>
82 public static BaseHttpServer Instance
83 {
84 get { return instance; }
85  
86 set
87 {
88 lock (m_Servers)
89 if (!m_Servers.ContainsValue(value))
90 throw new Exception("HTTP server must already have been registered to be set as the main instance");
91  
92 instance = value;
93 }
94 }
95  
96 /// <summary>
97 /// Get all the registered servers.
98 /// </summary>
99 /// <remarks>
100 /// Returns a copy of the dictionary so this can be iterated through without locking.
101 /// </remarks>
102 /// <value></value>
103 public static Dictionary<uint, BaseHttpServer> Servers
104 {
105 get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
106 }
107  
108 public static void RegisterHttpConsoleCommands(ICommandConsole console)
109 {
110 console.Commands.AddCommand(
111 "Comms", false, "show http-handlers",
112 "show http-handlers",
113 "Show all registered http handlers", HandleShowHttpHandlersCommand);
114  
115 console.Commands.AddCommand(
116 "Debug", false, "debug http", "debug http <in|out|all> [<level>]",
117 "Turn on http request logging.",
118 "If in or all and\n"
119 + " level <= 0 then no extra logging is done.\n"
120 + " level >= 1 then short warnings are logged when receiving bad input data.\n"
121 + " level >= 2 then long warnings are logged when receiving bad input data.\n"
122 + " level >= 3 then short notices about all incoming non-poll HTTP requests are logged.\n"
123 + " level >= 4 then the time taken to fulfill the request is logged.\n"
124 + " level >= 5 then a sample from the beginning of the data is logged.\n"
125 + " level >= 6 then the entire data is logged.\n"
126 + " no level is specified then the current level is returned.\n\n"
127 + "If out or all and\n"
128 + " level >= 3 then short notices about all outgoing requests going through WebUtil are logged.\n"
129 + " level >= 4 then the time taken to fulfill the request is logged.\n"
130 + " level >= 5 then a sample from the beginning of the data is logged.\n"
131 + " level >= 6 then the entire data is logged.\n",
132 HandleDebugHttpCommand);
133 }
134  
135 /// <summary>
136 /// Turn on some debugging values for OpenSim.
137 /// </summary>
138 /// <param name="args"></param>
139 private static void HandleDebugHttpCommand(string module, string[] cmdparams)
140 {
141 if (cmdparams.Length < 3)
142 {
143 MainConsole.Instance.Output("Usage: debug http <in|out|all> 0..6");
144 return;
145 }
146  
147 bool inReqs = false;
148 bool outReqs = false;
149 bool allReqs = false;
150  
151 string subCommand = cmdparams[2];
152  
153 if (subCommand.ToLower() == "in")
154 {
155 inReqs = true;
156 }
157 else if (subCommand.ToLower() == "out")
158 {
159 outReqs = true;
160 }
161 else if (subCommand.ToLower() == "all")
162 {
163 allReqs = true;
164 }
165 else
166 {
167 MainConsole.Instance.Output("You must specify in, out or all");
168 return;
169 }
170  
171 if (cmdparams.Length >= 4)
172 {
173 string rawNewDebug = cmdparams[3];
174 int newDebug;
175  
176 if (!int.TryParse(rawNewDebug, out newDebug))
177 {
178 MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawNewDebug);
179 return;
180 }
181  
182 if (newDebug < 0 || newDebug > 6)
183 {
184 MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0..6", newDebug);
185 return;
186 }
187  
188 if (allReqs || inReqs)
189 {
190 MainServer.DebugLevel = newDebug;
191 MainConsole.Instance.OutputFormat("IN debug level set to {0}", newDebug);
192 }
193  
194 if (allReqs || outReqs)
195 {
196 WebUtil.DebugLevel = newDebug;
197 MainConsole.Instance.OutputFormat("OUT debug level set to {0}", newDebug);
198 }
199 }
200 else
201 {
202 if (allReqs || inReqs)
203 MainConsole.Instance.OutputFormat("Current IN debug level is {0}", MainServer.DebugLevel);
204  
205 if (allReqs || outReqs)
206 MainConsole.Instance.OutputFormat("Current OUT debug level is {0}", WebUtil.DebugLevel);
207 }
208 }
209  
210 private static void HandleShowHttpHandlersCommand(string module, string[] args)
211 {
212 if (args.Length != 2)
213 {
214 MainConsole.Instance.Output("Usage: show http-handlers");
215 return;
216 }
217  
218 StringBuilder handlers = new StringBuilder();
219  
220 lock (m_Servers)
221 {
222 foreach (BaseHttpServer httpServer in m_Servers.Values)
223 {
224 handlers.AppendFormat(
225 "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
226  
227 handlers.AppendFormat("* XMLRPC:\n");
228 foreach (String s in httpServer.GetXmlRpcHandlerKeys())
229 handlers.AppendFormat("\t{0}\n", s);
230  
231 handlers.AppendFormat("* HTTP:\n");
232 foreach (String s in httpServer.GetHTTPHandlerKeys())
233 handlers.AppendFormat("\t{0}\n", s);
234  
235 handlers.AppendFormat("* HTTP (poll):\n");
236 foreach (String s in httpServer.GetPollServiceHandlerKeys())
237 handlers.AppendFormat("\t{0}\n", s);
238  
239 handlers.AppendFormat("* JSONRPC:\n");
240 foreach (String s in httpServer.GetJsonRpcHandlerKeys())
241 handlers.AppendFormat("\t{0}\n", s);
242  
243 // handlers.AppendFormat("* Agent:\n");
244 // foreach (String s in httpServer.GetAgentHandlerKeys())
245 // handlers.AppendFormat("\t{0}\n", s);
246  
247 handlers.AppendFormat("* LLSD:\n");
248 foreach (String s in httpServer.GetLLSDHandlerKeys())
249 handlers.AppendFormat("\t{0}\n", s);
250  
251 handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
252 foreach (String s in httpServer.GetStreamHandlerKeys())
253 handlers.AppendFormat("\t{0}\n", s);
254  
255 handlers.Append("\n");
256 }
257 }
258  
259 MainConsole.Instance.Output(handlers.ToString());
260 }
261  
262 /// <summary>
263 /// Register an already started HTTP server to the collection of known servers.
264 /// </summary>
265 /// <param name='server'></param>
266 public static void AddHttpServer(BaseHttpServer server)
267 {
268 lock (m_Servers)
269 {
270 if (m_Servers.ContainsKey(server.Port))
271 throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port));
272  
273 m_Servers.Add(server.Port, server);
274 }
275 }
276  
277 /// <summary>
278 /// Removes the http server listening on the given port.
279 /// </summary>
280 /// <remarks>
281 /// It is the responsibility of the caller to do clean up.
282 /// </remarks>
283 /// <param name='port'></param>
284 /// <returns></returns>
285 public static bool RemoveHttpServer(uint port)
286 {
287 lock (m_Servers)
288 {
289 if (instance != null && instance.Port == port)
290 instance = null;
291  
292 return m_Servers.Remove(port);
293 }
294 }
295  
296 /// <summary>
297 /// Does this collection of servers contain one with the given port?
298 /// </summary>
299 /// <remarks>
300 /// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port.
301 /// </remarks>
302 /// <param name='port'></param>
303 /// <returns>true if a server with the given port is registered, false otherwise.</returns>
304 public static bool ContainsHttpServer(uint port)
305 {
306 lock (m_Servers)
307 return m_Servers.ContainsKey(port);
308 }
309  
310 /// <summary>
311 /// Get the default http server or an http server for a specific port.
312 /// </summary>
313 /// <remarks>
314 /// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
315 /// </remarks>
316 /// <returns></returns>
317 /// <param name='port'>If 0 then the default HTTP server is returned.</param>
318 public static IHttpServer GetHttpServer(uint port)
319 {
320 return GetHttpServer(port, null);
321 }
322  
323 /// <summary>
324 /// Get the default http server, an http server for a specific port
325 /// and/or an http server bound to a specific address
326 /// </summary>
327 /// <remarks>
328 /// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
329 /// </remarks>
330 /// <returns></returns>
331 /// <param name='port'>If 0 then the default HTTP server is returned.</param>
332 /// <param name='ipaddr'>A specific IP address to bind to. If null then the default IP address is used.</param>
333 public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
334 {
335 if (port == 0)
336 return Instance;
337  
338 if (instance != null && port == Instance.Port)
339 return Instance;
340  
341 lock (m_Servers)
342 {
343 if (m_Servers.ContainsKey(port))
344 return m_Servers[port];
345  
346 m_Servers[port] = new BaseHttpServer(port);
347  
348 if (ipaddr != null)
349 m_Servers[port].ListenIPAddress = ipaddr;
350  
351 m_Servers[port].Start();
352  
353 return m_Servers[port];
354 }
355 }
356 }
357 }