OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
MainServer.cs
Go to the documentation of this file.
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 
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 
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 
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 
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 
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 
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 
304  public static bool ContainsHttpServer(uint port)
305  {
306  lock (m_Servers)
307  return m_Servers.ContainsKey(port);
308  }
309 
318  public static IHttpServer GetHttpServer(uint port)
319  {
320  return GetHttpServer(port, null);
321  }
322 
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 }
static void AddHttpServer(BaseHttpServer server)
Register an already started HTTP server to the collection of known servers.
Definition: MainServer.cs:266
Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.) for given URLs.
Definition: IHttpServer.cs:36
static IHttpServer GetHttpServer(uint port)
Get the default http server or an http server for a specific port.
Definition: MainServer.cs:318
static bool ContainsHttpServer(uint port)
Does this collection of servers contain one with the given port?
Definition: MainServer.cs:304
static void RegisterHttpConsoleCommands(ICommandConsole console)
Definition: MainServer.cs:108
static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
Get the default http server, an http server for a specific port and/or an http server bound to a spec...
Definition: MainServer.cs:333
static bool RemoveHttpServer(uint port)
Removes the http server listening on the given port.
Definition: MainServer.cs:285