aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers')
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs431
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs277
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs22
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs3
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs148
-rw-r--r--OpenSim/Framework/Servers/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs566
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs2
9 files changed, 1006 insertions, 509 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index cf19002..2c21800 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -38,6 +38,8 @@ using log4net;
38using log4net.Appender; 38using log4net.Appender;
39using log4net.Core; 39using log4net.Core;
40using log4net.Repository; 40using log4net.Repository;
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
41using OpenSim.Framework; 43using OpenSim.Framework;
42using OpenSim.Framework.Console; 44using OpenSim.Framework.Console;
43using OpenSim.Framework.Monitoring; 45using OpenSim.Framework.Monitoring;
@@ -45,16 +47,12 @@ using OpenSim.Framework.Servers;
45using OpenSim.Framework.Servers.HttpServer; 47using OpenSim.Framework.Servers.HttpServer;
46using Timer=System.Timers.Timer; 48using Timer=System.Timers.Timer;
47 49
48using OpenMetaverse;
49using OpenMetaverse.StructuredData;
50
51
52namespace OpenSim.Framework.Servers 50namespace OpenSim.Framework.Servers
53{ 51{
54 /// <summary> 52 /// <summary>
55 /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) 53 /// Common base for the main OpenSimServers (user, grid, inventory, region, etc)
56 /// </summary> 54 /// </summary>
57 public abstract class BaseOpenSimServer 55 public abstract class BaseOpenSimServer : ServerBase
58 { 56 {
59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
60 58
@@ -63,27 +61,6 @@ namespace OpenSim.Framework.Servers
63 /// server. 61 /// server.
64 /// </summary> 62 /// </summary>
65 private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); 63 private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
66
67 protected CommandConsole m_console;
68 protected OpenSimAppender m_consoleAppender;
69 protected IAppender m_logFileAppender = null;
70
71 /// <summary>
72 /// Time at which this server was started
73 /// </summary>
74 protected DateTime m_startuptime;
75
76 /// <summary>
77 /// Record the initial startup directory for info purposes
78 /// </summary>
79 protected string m_startupDirectory = Environment.CurrentDirectory;
80
81 /// <summary>
82 /// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
83 /// </summary>
84 protected string m_version;
85
86 protected string m_pidFile = String.Empty;
87 64
88 /// <summary> 65 /// <summary>
89 /// Random uuid for private data 66 /// Random uuid for private data
@@ -96,35 +73,13 @@ namespace OpenSim.Framework.Servers
96 get { return m_httpServer; } 73 get { return m_httpServer; }
97 } 74 }
98 75
99 /// <summary> 76 public BaseOpenSimServer() : base()
100 /// Holds the non-viewer statistics collection object for this service/server
101 /// </summary>
102 protected IStatsCollector m_stats;
103
104 public BaseOpenSimServer()
105 { 77 {
106 m_startuptime = DateTime.Now;
107 m_version = VersionInfo.Version;
108
109 // Random uuid for private data 78 // Random uuid for private data
110 m_osSecret = UUID.Random().ToString(); 79 m_osSecret = UUID.Random().ToString();
111 80
112 m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); 81 m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
113 m_periodicDiagnosticsTimer.Enabled = true; 82 m_periodicDiagnosticsTimer.Enabled = true;
114
115 // This thread will go on to become the console listening thread
116 Thread.CurrentThread.Name = "ConsoleThread";
117
118 ILoggerRepository repository = LogManager.GetRepository();
119 IAppender[] appenders = repository.GetAppenders();
120
121 foreach (IAppender appender in appenders)
122 {
123 if (appender.Name == "LogFileAppender")
124 {
125 m_logFileAppender = appender;
126 }
127 }
128 } 83 }
129 84
130 /// <summary> 85 /// <summary>
@@ -132,76 +87,46 @@ namespace OpenSim.Framework.Servers
132 /// </summary> 87 /// </summary>
133 protected virtual void StartupSpecific() 88 protected virtual void StartupSpecific()
134 { 89 {
135 if (m_console != null) 90 if (m_console == null)
136 { 91 return;
137 ILoggerRepository repository = LogManager.GetRepository(); 92
138 IAppender[] appenders = repository.GetAppenders(); 93 RegisterCommonCommands();
139 94
140 foreach (IAppender appender in appenders) 95 m_console.Commands.AddCommand("General", false, "quit",
141 { 96 "quit",
142 if (appender.Name == "Console") 97 "Quit the application", HandleQuit);
143 { 98
144 m_consoleAppender = (OpenSimAppender)appender; 99 m_console.Commands.AddCommand("General", false, "shutdown",
145 break; 100 "shutdown",
146 } 101 "Quit the application", HandleQuit);
147 } 102
148 103 m_console.Commands.AddCommand("General", false, "show threads",
149 if (null == m_consoleAppender) 104 "show threads",
150 { 105 "Show thread status", HandleShow);
151 Notice("No appender named Console found (see the log4net config file for this executable)!"); 106
152 } 107 m_console.Commands.AddCommand("General", false, "show version",
153 else 108 "show version",
154 { 109 "Show server version", HandleShow);
155 m_consoleAppender.Console = m_console; 110
156 111 m_console.Commands.AddCommand("General", false, "threads abort",
157 // If there is no threshold set then the threshold is effectively everything. 112 "threads abort <thread-id>",
158 if (null == m_consoleAppender.Threshold) 113 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
159 m_consoleAppender.Threshold = Level.All; 114
160 115 m_console.Commands.AddCommand("General", false, "threads show",
161 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); 116 "threads show",
162 } 117 "Show thread status. Synonym for \"show threads\"",
163 118 (string module, string[] args) => Notice(GetThreadsReport()));
164 m_console.Commands.AddCommand("General", false, "quit", 119
165 "quit", 120 m_console.Commands.AddCommand("General", false, "force gc",
166 "Quit the application", HandleQuit); 121 "force gc",
167 122 "Manually invoke runtime garbage collection. For debugging purposes",
168 m_console.Commands.AddCommand("General", false, "shutdown", 123 HandleForceGc);
169 "shutdown", 124 }
170 "Quit the application", HandleQuit); 125
171 126 private void HandleForceGc(string module, string[] args)
172 m_console.Commands.AddCommand("General", false, "set log level", 127 {
173 "set log level <level>", 128 MainConsole.Instance.Output("Manually invoking runtime garbage collection");
174 "Set the console logging level", HandleLogLevel); 129 GC.Collect();
175
176 m_console.Commands.AddCommand("General", false, "show info",
177 "show info",
178 "Show general information about the server", HandleShow);
179
180 m_console.Commands.AddCommand("General", false, "show stats",
181 "show stats",
182 "Show statistics", HandleShow);
183
184 m_console.Commands.AddCommand("General", false, "show threads",
185 "show threads",
186 "Show thread status", HandleShow);
187
188 m_console.Commands.AddCommand("General", false, "show uptime",
189 "show uptime",
190 "Show server uptime", HandleShow);
191
192 m_console.Commands.AddCommand("General", false, "show version",
193 "show version",
194 "Show server version", HandleShow);
195
196 m_console.Commands.AddCommand("General", false, "threads abort",
197 "threads abort <thread-id>",
198 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
199
200 m_console.Commands.AddCommand("General", false, "threads show",
201 "threads show",
202 "Show thread status. Synonym for \"show threads\"",
203 (string module, string[] args) => Notice(GetThreadsReport()));
204 }
205 } 130 }
206 131
207 /// <summary> 132 /// <summary>
@@ -226,12 +151,7 @@ namespace OpenSim.Framework.Servers
226 { 151 {
227 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n"); 152 StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
228 sb.Append(GetUptimeReport()); 153 sb.Append(GetUptimeReport());
229 154 sb.Append(StatsManager.SimExtraStats.Report());
230 if (m_stats != null)
231 {
232 sb.Append(m_stats.Report());
233 }
234
235 sb.Append(Environment.NewLine); 155 sb.Append(Environment.NewLine);
236 sb.Append(GetThreadsReport()); 156 sb.Append(GetThreadsReport());
237 157
@@ -287,26 +207,11 @@ namespace OpenSim.Framework.Servers
287 } 207 }
288 208
289 /// <summary> 209 /// <summary>
290 /// Return a report about the uptime of this server
291 /// </summary>
292 /// <returns></returns>
293 protected string GetUptimeReport()
294 {
295 StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
296 sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
297 sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
298
299 return sb.ToString();
300 }
301
302 /// <summary>
303 /// Performs initialisation of the scene, such as loading configuration from disk. 210 /// Performs initialisation of the scene, such as loading configuration from disk.
304 /// </summary> 211 /// </summary>
305 public virtual void Startup() 212 public virtual void Startup()
306 { 213 {
307 m_log.Info("[STARTUP]: Beginning startup processing"); 214 m_log.Info("[STARTUP]: Beginning startup processing");
308
309 EnhanceVersionInformation();
310 215
311 m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine); 216 m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine);
312 // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and 217 // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
@@ -343,60 +248,10 @@ namespace OpenSim.Framework.Servers
343 Shutdown(); 248 Shutdown();
344 } 249 }
345 250
346 private void HandleLogLevel(string module, string[] cmd) 251 public override void HandleShow(string module, string[] cmd)
347 {
348 if (null == m_consoleAppender)
349 {
350 Notice("No appender named Console found (see the log4net config file for this executable)!");
351 return;
352 }
353
354 if (cmd.Length > 3)
355 {
356 string rawLevel = cmd[3];
357
358 ILoggerRepository repository = LogManager.GetRepository();
359 Level consoleLevel = repository.LevelMap[rawLevel];
360
361 if (consoleLevel != null)
362 m_consoleAppender.Threshold = consoleLevel;
363 else
364 Notice(
365 String.Format(
366 "{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
367 rawLevel));
368 }
369
370 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
371 }
372
373 /// <summary>
374 /// Show help information
375 /// </summary>
376 /// <param name="helpArgs"></param>
377 protected virtual void ShowHelp(string[] helpArgs)
378 { 252 {
379 Notice(""); 253 base.HandleShow(module, cmd);
380
381 if (helpArgs.Length == 0)
382 {
383 Notice("set log level [level] - change the console logging level only. For example, off or debug.");
384 Notice("show info - show server information (e.g. startup path).");
385
386 if (m_stats != null)
387 Notice("show stats - show statistical information for this server");
388
389 Notice("show threads - list tracked threads");
390 Notice("show uptime - show server startup time and uptime.");
391 Notice("show version - show server version.");
392 Notice("");
393 254
394 return;
395 }
396 }
397
398 public virtual void HandleShow(string module, string[] cmd)
399 {
400 List<string> args = new List<string>(cmd); 255 List<string> args = new List<string>(cmd);
401 256
402 args.RemoveAt(0); 257 args.RemoveAt(0);
@@ -405,23 +260,10 @@ namespace OpenSim.Framework.Servers
405 260
406 switch (showParams[0]) 261 switch (showParams[0])
407 { 262 {
408 case "info":
409 ShowInfo();
410 break;
411
412 case "stats":
413 if (m_stats != null)
414 Notice(m_stats.Report());
415 break;
416
417 case "threads": 263 case "threads":
418 Notice(GetThreadsReport()); 264 Notice(GetThreadsReport());
419 break; 265 break;
420 266
421 case "uptime":
422 Notice(GetUptimeReport());
423 break;
424
425 case "version": 267 case "version":
426 Notice(GetVersionText()); 268 Notice(GetVersionText());
427 break; 269 break;
@@ -447,165 +289,11 @@ namespace OpenSim.Framework.Servers
447 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); 289 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
448 else 290 else
449 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); 291 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
450 } 292 }
451
452 protected void ShowInfo()
453 {
454 Notice(GetVersionText());
455 Notice("Startup directory: " + m_startupDirectory);
456 if (null != m_consoleAppender)
457 Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold));
458 }
459
460 protected string GetVersionText()
461 {
462 return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
463 }
464
465 /// <summary>
466 /// Console output is only possible if a console has been established.
467 /// That is something that cannot be determined within this class. So
468 /// all attempts to use the console MUST be verified.
469 /// </summary>
470 /// <param name="msg"></param>
471 protected void Notice(string msg)
472 {
473 if (m_console != null)
474 {
475 m_console.Output(msg);
476 }
477 }
478
479 /// <summary>
480 /// Console output is only possible if a console has been established.
481 /// That is something that cannot be determined within this class. So
482 /// all attempts to use the console MUST be verified.
483 /// </summary>
484 /// <param name="format"></param>
485 /// <param name="components"></param>
486 protected void Notice(string format, params string[] components)
487 {
488 if (m_console != null)
489 m_console.OutputFormat(format, components);
490 }
491
492 /// <summary>
493 /// Enhance the version string with extra information if it's available.
494 /// </summary>
495 protected void EnhanceVersionInformation()
496 {
497 string buildVersion = string.Empty;
498
499 // The subversion information is deprecated and will be removed at a later date
500 // Add subversion revision information if available
501 // Try file "svn_revision" in the current directory first, then the .svn info.
502 // This allows to make the revision available in simulators not running from the source tree.
503 // FIXME: Making an assumption about the directory we're currently in - we do this all over the place
504 // elsewhere as well
505 string gitDir = "../.git/";
506 string gitRefPointerPath = gitDir + "HEAD";
507
508 string svnRevisionFileName = "svn_revision";
509 string svnFileName = ".svn/entries";
510 string manualVersionFileName = ".version";
511 string inputLine;
512 int strcmp;
513
514 if (File.Exists(manualVersionFileName))
515 {
516 using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
517 buildVersion = CommitFile.ReadLine();
518
519 m_version += buildVersion ?? "";
520 }
521 else if (File.Exists(gitRefPointerPath))
522 {
523// m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath);
524
525 string rawPointer = "";
526
527 using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
528 rawPointer = pointerFile.ReadLine();
529
530// m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer);
531
532 Match m = Regex.Match(rawPointer, "^ref: (.+)$");
533
534 if (m.Success)
535 {
536// m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value);
537
538 string gitRef = m.Groups[1].Value;
539 string gitRefPath = gitDir + gitRef;
540 if (File.Exists(gitRefPath))
541 {
542// m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath);
543
544 using (StreamReader refFile = File.OpenText(gitRefPath))
545 {
546 string gitHash = refFile.ReadLine();
547 m_version += gitHash.Substring(0, 7);
548 }
549 }
550 }
551 }
552 else
553 {
554 // Remove the else logic when subversion mirror is no longer used
555 if (File.Exists(svnRevisionFileName))
556 {
557 StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
558 buildVersion = RevisionFile.ReadLine();
559 buildVersion.Trim();
560 RevisionFile.Close();
561 }
562
563 if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
564 {
565 StreamReader EntriesFile = File.OpenText(svnFileName);
566 inputLine = EntriesFile.ReadLine();
567 while (inputLine != null)
568 {
569 // using the dir svn revision at the top of entries file
570 strcmp = String.Compare(inputLine, "dir");
571 if (strcmp == 0)
572 {
573 buildVersion = EntriesFile.ReadLine();
574 break;
575 }
576 else
577 {
578 inputLine = EntriesFile.ReadLine();
579 }
580 }
581 EntriesFile.Close();
582 }
583
584 m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6);
585 }
586 }
587
588 protected void CreatePIDFile(string path)
589 {
590 try
591 {
592 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
593 FileStream fs = File.Create(path);
594
595 Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
596 fs.Write(buf, 0, buf.Length);
597 fs.Close();
598 m_pidFile = path;
599 }
600 catch (Exception)
601 {
602 }
603 }
604 293
605 public string osSecret { 294 public string osSecret {
606 // Secret uuid for the simulator 295 // Secret uuid for the simulator
607 get { return m_osSecret; } 296 get { return m_osSecret; }
608
609 } 297 }
610 298
611 public string StatReport(IOSHttpRequest httpRequest) 299 public string StatReport(IOSHttpRequest httpRequest)
@@ -613,27 +301,12 @@ namespace OpenSim.Framework.Servers
613 // If we catch a request for "callback", wrap the response in the value for jsonp 301 // If we catch a request for "callback", wrap the response in the value for jsonp
614 if (httpRequest.Query.ContainsKey("callback")) 302 if (httpRequest.Query.ContainsKey("callback"))
615 { 303 {
616 return httpRequest.Query["callback"].ToString() + "(" + m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; 304 return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
617 } 305 }
618 else 306 else
619 { 307 {
620 return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); 308 return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
621 }
622 }
623
624 protected void RemovePIDFile()
625 {
626 if (m_pidFile != String.Empty)
627 {
628 try
629 {
630 File.Delete(m_pidFile);
631 m_pidFile = String.Empty;
632 }
633 catch (Exception)
634 {
635 }
636 } 309 }
637 } 310 }
638 } 311 }
639} 312} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 788a0b9..77fce9e 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -54,8 +54,23 @@ namespace OpenSim.Framework.Servers.HttpServer
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); 55 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
56 56
57 /// <summary>
58 /// Gets or sets the debug level.
59 /// </summary>
60 /// <value>
61 /// See MainServer.DebugLevel.
62 /// </value>
57 public int DebugLevel { get; set; } 63 public int DebugLevel { get; set; }
58 64
65 /// <summary>
66 /// Request number for diagnostic purposes.
67 /// </summary>
68 /// <remarks>
69 /// This is an internal number. In some debug situations an external number may also be supplied in the
70 /// opensim-request-id header but we are not currently logging this.
71 /// </remarks>
72 public int RequestNumber { get; private set; }
73
59 private volatile int NotSocketErrors = 0; 74 private volatile int NotSocketErrors = 0;
60 public volatile bool HTTPDRunning = false; 75 public volatile bool HTTPDRunning = false;
61 76
@@ -67,7 +82,7 @@ namespace OpenSim.Framework.Servers.HttpServer
67 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>(); 82 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>();
68 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>(); 83 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
69 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>(); 84 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
70 protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>(); 85// protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
71 protected Dictionary<string, PollServiceEventArgs> m_pollHandlers = 86 protected Dictionary<string, PollServiceEventArgs> m_pollHandlers =
72 new Dictionary<string, PollServiceEventArgs>(); 87 new Dictionary<string, PollServiceEventArgs>();
73 88
@@ -245,29 +260,29 @@ namespace OpenSim.Framework.Servers.HttpServer
245 return new List<string>(m_pollHandlers.Keys); 260 return new List<string>(m_pollHandlers.Keys);
246 } 261 }
247 262
248 // Note that the agent string is provided simply to differentiate 263// // Note that the agent string is provided simply to differentiate
249 // the handlers - it is NOT required to be an actual agent header 264// // the handlers - it is NOT required to be an actual agent header
250 // value. 265// // value.
251 public bool AddAgentHandler(string agent, IHttpAgentHandler handler) 266// public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
252 { 267// {
253 lock (m_agentHandlers) 268// lock (m_agentHandlers)
254 { 269// {
255 if (!m_agentHandlers.ContainsKey(agent)) 270// if (!m_agentHandlers.ContainsKey(agent))
256 { 271// {
257 m_agentHandlers.Add(agent, handler); 272// m_agentHandlers.Add(agent, handler);
258 return true; 273// return true;
259 } 274// }
260 } 275// }
261 276//
262 //must already have a handler for that path so return false 277// //must already have a handler for that path so return false
263 return false; 278// return false;
264 } 279// }
265 280//
266 public List<string> GetAgentHandlerKeys() 281// public List<string> GetAgentHandlerKeys()
267 { 282// {
268 lock (m_agentHandlers) 283// lock (m_agentHandlers)
269 return new List<string>(m_agentHandlers.Keys); 284// return new List<string>(m_agentHandlers.Keys);
270 } 285// }
271 286
272 public bool AddLLSDHandler(string path, LLSDMethod handler) 287 public bool AddLLSDHandler(string path, LLSDMethod handler)
273 { 288 {
@@ -296,6 +311,8 @@ namespace OpenSim.Framework.Servers.HttpServer
296 311
297 private void OnRequest(object source, RequestEventArgs args) 312 private void OnRequest(object source, RequestEventArgs args)
298 { 313 {
314 RequestNumber++;
315
299 try 316 try
300 { 317 {
301 IHttpClientContext context = (IHttpClientContext)source; 318 IHttpClientContext context = (IHttpClientContext)source;
@@ -406,7 +423,6 @@ namespace OpenSim.Framework.Servers.HttpServer
406 string requestMethod = request.HttpMethod; 423 string requestMethod = request.HttpMethod;
407 string uriString = request.RawUrl; 424 string uriString = request.RawUrl;
408 425
409// string reqnum = "unknown";
410 int requestStartTick = Environment.TickCount; 426 int requestStartTick = Environment.TickCount;
411 427
412 // Will be adjusted later on. 428 // Will be adjusted later on.
@@ -423,22 +439,22 @@ namespace OpenSim.Framework.Servers.HttpServer
423 439
424 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); 440 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
425 441
426 // This is the REST agent interface. We require an agent to properly identify 442// // This is the REST agent interface. We require an agent to properly identify
427 // itself. If the REST handler recognizes the prefix it will attempt to 443// // itself. If the REST handler recognizes the prefix it will attempt to
428 // satisfy the request. If it is not recognizable, and no damage has occurred 444// // satisfy the request. If it is not recognizable, and no damage has occurred
429 // the request can be passed through to the other handlers. This is a low 445// // the request can be passed through to the other handlers. This is a low
430 // probability event; if a request is matched it is normally expected to be 446// // probability event; if a request is matched it is normally expected to be
431 // handled 447// // handled
432 IHttpAgentHandler agentHandler; 448// IHttpAgentHandler agentHandler;
433 449//
434 if (TryGetAgentHandler(request, response, out agentHandler)) 450// if (TryGetAgentHandler(request, response, out agentHandler))
435 { 451// {
436 if (HandleAgentRequest(agentHandler, request, response)) 452// if (HandleAgentRequest(agentHandler, request, response))
437 { 453// {
438 requestEndTick = Environment.TickCount; 454// requestEndTick = Environment.TickCount;
439 return; 455// return;
440 } 456// }
441 } 457// }
442 458
443 //response.KeepAlive = true; 459 //response.KeepAlive = true;
444 response.SendChunked = false; 460 response.SendChunked = false;
@@ -450,9 +466,7 @@ namespace OpenSim.Framework.Servers.HttpServer
450 if (TryGetStreamHandler(handlerKey, out requestHandler)) 466 if (TryGetStreamHandler(handlerKey, out requestHandler))
451 { 467 {
452 if (DebugLevel >= 3) 468 if (DebugLevel >= 3)
453 m_log.DebugFormat( 469 LogIncomingToStreamHandler(request, requestHandler);
454 "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
455 request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
456 470
457 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. 471 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
458 472
@@ -529,11 +543,8 @@ namespace OpenSim.Framework.Servers.HttpServer
529 { 543 {
530 case null: 544 case null:
531 case "text/html": 545 case "text/html":
532
533 if (DebugLevel >= 3) 546 if (DebugLevel >= 3)
534 m_log.DebugFormat( 547 LogIncomingToContentTypeHandler(request);
535 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
536 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
537 548
538 buffer = HandleHTTPRequest(request, response); 549 buffer = HandleHTTPRequest(request, response);
539 break; 550 break;
@@ -541,11 +552,8 @@ namespace OpenSim.Framework.Servers.HttpServer
541 case "application/llsd+xml": 552 case "application/llsd+xml":
542 case "application/xml+llsd": 553 case "application/xml+llsd":
543 case "application/llsd+json": 554 case "application/llsd+json":
544
545 if (DebugLevel >= 3) 555 if (DebugLevel >= 3)
546 m_log.DebugFormat( 556 LogIncomingToContentTypeHandler(request);
547 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
548 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
549 557
550 buffer = HandleLLSDRequests(request, response); 558 buffer = HandleLLSDRequests(request, response);
551 break; 559 break;
@@ -564,9 +572,7 @@ namespace OpenSim.Framework.Servers.HttpServer
564 if (DoWeHaveALLSDHandler(request.RawUrl)) 572 if (DoWeHaveALLSDHandler(request.RawUrl))
565 { 573 {
566 if (DebugLevel >= 3) 574 if (DebugLevel >= 3)
567 m_log.DebugFormat( 575 LogIncomingToContentTypeHandler(request);
568 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
569 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
570 576
571 buffer = HandleLLSDRequests(request, response); 577 buffer = HandleLLSDRequests(request, response);
572 } 578 }
@@ -574,18 +580,14 @@ namespace OpenSim.Framework.Servers.HttpServer
574 else if (DoWeHaveAHTTPHandler(request.RawUrl)) 580 else if (DoWeHaveAHTTPHandler(request.RawUrl))
575 { 581 {
576 if (DebugLevel >= 3) 582 if (DebugLevel >= 3)
577 m_log.DebugFormat( 583 LogIncomingToContentTypeHandler(request);
578 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
579 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
580 584
581 buffer = HandleHTTPRequest(request, response); 585 buffer = HandleHTTPRequest(request, response);
582 } 586 }
583 else 587 else
584 { 588 {
585 if (DebugLevel >= 3) 589 if (DebugLevel >= 3)
586 m_log.DebugFormat( 590 LogIncomingToXmlRpcHandler(request);
587 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
588 request.HttpMethod, request.Url.PathAndQuery);
589 591
590 // generic login request. 592 // generic login request.
591 buffer = HandleXmlRpcRequests(request, response); 593 buffer = HandleXmlRpcRequests(request, response);
@@ -629,11 +631,11 @@ namespace OpenSim.Framework.Servers.HttpServer
629 } 631 }
630 catch (IOException e) 632 catch (IOException e)
631 { 633 {
632 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); 634 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
633 } 635 }
634 catch (Exception e) 636 catch (Exception e)
635 { 637 {
636 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); 638 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
637 SendHTML500(response); 639 SendHTML500(response);
638 } 640 }
639 finally 641 finally
@@ -644,17 +646,96 @@ namespace OpenSim.Framework.Servers.HttpServer
644 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture")) 646 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
645 { 647 {
646 m_log.InfoFormat( 648 m_log.InfoFormat(
647 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", 649 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
650 RequestNumber,
648 requestMethod, 651 requestMethod,
649 uriString, 652 uriString,
650 requestHandler != null ? requestHandler.Name : "", 653 requestHandler != null ? requestHandler.Name : "",
651 requestHandler != null ? requestHandler.Description : "", 654 requestHandler != null ? requestHandler.Description : "",
652 request.RemoteIPEndPoint.ToString(), 655 request.RemoteIPEndPoint,
656 tickdiff);
657 }
658 else if (DebugLevel >= 4)
659 {
660 m_log.DebugFormat(
661 "[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms",
662 RequestNumber,
663 Port,
653 tickdiff); 664 tickdiff);
654 } 665 }
655 } 666 }
656 } 667 }
657 668
669 private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
670 {
671 m_log.DebugFormat(
672 "[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
673 RequestNumber,
674 Port,
675 request.HttpMethod,
676 request.Url.PathAndQuery,
677 requestHandler.Name,
678 requestHandler.Description,
679 request.RemoteIPEndPoint);
680
681 if (DebugLevel >= 5)
682 LogIncomingInDetail(request);
683 }
684
685 private void LogIncomingToContentTypeHandler(OSHttpRequest request)
686 {
687 m_log.DebugFormat(
688 "[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
689 RequestNumber,
690 Port,
691 (request.ContentType == null || request.ContentType == "") ? "not set" : request.ContentType,
692 request.HttpMethod,
693 request.Url.PathAndQuery,
694 request.RemoteIPEndPoint);
695
696 if (DebugLevel >= 5)
697 LogIncomingInDetail(request);
698 }
699
700 private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
701 {
702 m_log.DebugFormat(
703 "[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
704 RequestNumber,
705 Port,
706 request.HttpMethod,
707 request.Url.PathAndQuery,
708 request.RemoteIPEndPoint);
709
710 if (DebugLevel >= 5)
711 LogIncomingInDetail(request);
712 }
713
714 private void LogIncomingInDetail(OSHttpRequest request)
715 {
716 using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
717 {
718 string output;
719
720 if (DebugLevel == 5)
721 {
722 const int sampleLength = 80;
723 char[] sampleChars = new char[sampleLength + 3];
724 reader.Read(sampleChars, 0, sampleLength);
725 sampleChars[80] = '.';
726 sampleChars[81] = '.';
727 sampleChars[82] = '.';
728 output = new string(sampleChars);
729 }
730 else
731 {
732 output = reader.ReadToEnd();
733 }
734
735 m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n"));
736 }
737 }
738
658 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) 739 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler)
659 { 740 {
660 string bestMatch = null; 741 string bestMatch = null;
@@ -747,24 +828,24 @@ namespace OpenSim.Framework.Servers.HttpServer
747 } 828 }
748 } 829 }
749 830
750 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) 831// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
751 { 832// {
752 agentHandler = null; 833// agentHandler = null;
753 834//
754 lock (m_agentHandlers) 835// lock (m_agentHandlers)
755 { 836// {
756 foreach (IHttpAgentHandler handler in m_agentHandlers.Values) 837// foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
757 { 838// {
758 if (handler.Match(request, response)) 839// if (handler.Match(request, response))
759 { 840// {
760 agentHandler = handler; 841// agentHandler = handler;
761 return true; 842// return true;
762 } 843// }
763 } 844// }
764 } 845// }
765 846//
766 return false; 847// return false;
767 } 848// }
768 849
769 /// <summary> 850 /// <summary>
770 /// Try all the registered xmlrpc handlers when an xmlrpc request is received. 851 /// Try all the registered xmlrpc handlers when an xmlrpc request is received.
@@ -1737,21 +1818,21 @@ namespace OpenSim.Framework.Servers.HttpServer
1737 m_pollHandlers.Remove(path); 1818 m_pollHandlers.Remove(path);
1738 } 1819 }
1739 1820
1740 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) 1821// public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
1741 { 1822// {
1742 lock (m_agentHandlers) 1823// lock (m_agentHandlers)
1743 { 1824// {
1744 IHttpAgentHandler foundHandler; 1825// IHttpAgentHandler foundHandler;
1745 1826//
1746 if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler) 1827// if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler)
1747 { 1828// {
1748 m_agentHandlers.Remove(agent); 1829// m_agentHandlers.Remove(agent);
1749 return true; 1830// return true;
1750 } 1831// }
1751 } 1832// }
1752 1833//
1753 return false; 1834// return false;
1754 } 1835// }
1755 1836
1756 public void RemoveXmlRPCHandler(string method) 1837 public void RemoveXmlRPCHandler(string method)
1757 { 1838 {
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
index db58f6f..0bd3aae 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
@@ -41,10 +41,10 @@ namespace OpenSim.Framework.Servers.HttpServer
41 uint Port { get; } 41 uint Port { get; }
42 bool UseSSL { get; } 42 bool UseSSL { get; }
43 43
44 // Note that the agent string is provided simply to differentiate 44// // Note that the agent string is provided simply to differentiate
45 // the handlers - it is NOT required to be an actual agent header 45// // the handlers - it is NOT required to be an actual agent header
46 // value. 46// // value.
47 bool AddAgentHandler(string agent, IHttpAgentHandler handler); 47// bool AddAgentHandler(string agent, IHttpAgentHandler handler);
48 48
49 /// <summary> 49 /// <summary>
50 /// Add a handler for an HTTP request. 50 /// Add a handler for an HTTP request.
@@ -106,13 +106,13 @@ namespace OpenSim.Framework.Servers.HttpServer
106 106
107 bool SetDefaultLLSDHandler(DefaultLLSDMethod handler); 107 bool SetDefaultLLSDHandler(DefaultLLSDMethod handler);
108 108
109 /// <summary> 109// /// <summary>
110 /// Remove the agent if it is registered. 110// /// Remove the agent if it is registered.
111 /// </summary> 111// /// </summary>
112 /// <param name="agent"></param> 112// /// <param name="agent"></param>
113 /// <param name="handler"></param> 113// /// <param name="handler"></param>
114 /// <returns></returns> 114// /// <returns></returns>
115 bool RemoveAgentHandler(string agent, IHttpAgentHandler handler); 115// bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
116 116
117 /// <summary> 117 /// <summary>
118 /// Remove an HTTP handler 118 /// Remove an HTTP handler
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index d0a37d0..c19ac32 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -53,7 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer
53 Normal = 0, 53 Normal = 0,
54 LslHttp = 1, 54 LslHttp = 1,
55 Inventory = 2, 55 Inventory = 2,
56 Texture = 3 56 Texture = 3,
57 Mesh = 4
57 } 58 }
58 59
59 public PollServiceEventArgs( 60 public PollServiceEventArgs(
diff --git a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..02ecc25
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Framework.Servers.HttpServer")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("c4ea5baa-81c4-4867-a645-1ec360c1f164")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.7.5.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index 8dc0e3a..ae7d515 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Net; 31using System.Net;
32using System.Text;
32using log4net; 33using log4net;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
@@ -47,9 +48,12 @@ namespace OpenSim.Framework.Servers
47 /// Control the printing of certain debug messages. 48 /// Control the printing of certain debug messages.
48 /// </summary> 49 /// </summary>
49 /// <remarks> 50 /// <remarks>
50 /// If DebugLevel >= 1, then short warnings are logged when receiving bad input data. 51 /// If DebugLevel >= 1 then short warnings are logged when receiving bad input data.
51 /// If DebugLevel >= 2, then long warnings are logged when receiving bad input data. 52 /// If DebugLevel >= 2 then long warnings are logged when receiving bad input data.
52 /// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged. 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.
53 /// </remarks> 57 /// </remarks>
54 public static int DebugLevel 58 public static int DebugLevel
55 { 59 {
@@ -101,17 +105,28 @@ namespace OpenSim.Framework.Servers
101 get { return new Dictionary<uint, BaseHttpServer>(m_Servers); } 105 get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
102 } 106 }
103 107
104
105 public static void RegisterHttpConsoleCommands(ICommandConsole console) 108 public static void RegisterHttpConsoleCommands(ICommandConsole console)
106 { 109 {
107 console.Commands.AddCommand( 110 console.Commands.AddCommand(
108 "Debug", false, "debug http", "debug http [<level>]", 111 "Comms", false, "show http-handlers",
109 "Turn on inbound non-poll http request debugging.", 112 "show http-handlers",
110 "If level <= 0, then no extra logging is done.\n" 113 "Show all registered http handlers", HandleShowHttpHandlersCommand);
111 + "If level >= 1, then short warnings are logged when receiving bad input data.\n" 114
112 + "If level >= 2, then long warnings are logged when receiving bad input data.\n" 115 console.Commands.AddCommand(
113 + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" 116 "Debug", false, "debug http", "debug http <in|out|all> [<level>]",
114 + "If no level is specified then the current level is returned.", 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 incoming data is logged.\n"
125 + " level >= 6 then the entire incoming 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",
115 HandleDebugHttpCommand); 130 HandleDebugHttpCommand);
116 } 131 }
117 132
@@ -119,25 +134,120 @@ namespace OpenSim.Framework.Servers
119 /// Turn on some debugging values for OpenSim. 134 /// Turn on some debugging values for OpenSim.
120 /// </summary> 135 /// </summary>
121 /// <param name="args"></param> 136 /// <param name="args"></param>
122 private static void HandleDebugHttpCommand(string module, string[] args) 137 private static void HandleDebugHttpCommand(string module, string[] cmdparams)
123 { 138 {
124 if (args.Length == 3) 139 if (cmdparams.Length < 3)
140 {
141 MainConsole.Instance.Output("Usage: debug http <in|out|all> 0..6");
142 return;
143 }
144
145 bool inReqs = false;
146 bool outReqs = false;
147 bool allReqs = false;
148
149 string subCommand = cmdparams[2];
150
151 if (subCommand.ToLower() == "in")
152 {
153 inReqs = true;
154 }
155 else if (subCommand.ToLower() == "out")
156 {
157 outReqs = true;
158 }
159 else if (subCommand.ToLower() == "all")
160 {
161 allReqs = true;
162 }
163 else
125 { 164 {
165 MainConsole.Instance.Output("You must specify in, out or all");
166 return;
167 }
168
169 if (cmdparams.Length >= 4)
170 {
171 string rawNewDebug = cmdparams[3];
126 int newDebug; 172 int newDebug;
127 if (int.TryParse(args[2], out newDebug)) 173
174 if (!int.TryParse(rawNewDebug, out newDebug))
175 {
176 MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawNewDebug);
177 return;
178 }
179
180 if (newDebug < 0 || newDebug > 6)
181 {
182 MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0..6", newDebug);
183 return;
184 }
185
186 if (allReqs || inReqs)
128 { 187 {
129 MainServer.DebugLevel = newDebug; 188 MainServer.DebugLevel = newDebug;
130 MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug); 189 MainConsole.Instance.OutputFormat("IN debug level set to {0}", newDebug);
190 }
191
192 if (allReqs || outReqs)
193 {
194 WebUtil.DebugLevel = newDebug;
195 MainConsole.Instance.OutputFormat("OUT debug level set to {0}", newDebug);
131 } 196 }
132 } 197 }
133 else if (args.Length == 2) 198 else
134 { 199 {
135 MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel); 200 if (allReqs || inReqs)
201 MainConsole.Instance.OutputFormat("Current IN debug level is {0}", MainServer.DebugLevel);
202
203 if (allReqs || outReqs)
204 MainConsole.Instance.OutputFormat("Current OUT debug level is {0}", WebUtil.DebugLevel);
136 } 205 }
137 else 206 }
207
208 private static void HandleShowHttpHandlersCommand(string module, string[] args)
209 {
210 if (args.Length != 2)
211 {
212 MainConsole.Instance.Output("Usage: show http-handlers");
213 return;
214 }
215
216 StringBuilder handlers = new StringBuilder();
217
218 lock (m_Servers)
138 { 219 {
139 MainConsole.Instance.Output("Usage: debug http 0..3"); 220 foreach (BaseHttpServer httpServer in m_Servers.Values)
221 {
222 handlers.AppendFormat(
223 "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
224
225 handlers.AppendFormat("* XMLRPC:\n");
226 foreach (String s in httpServer.GetXmlRpcHandlerKeys())
227 handlers.AppendFormat("\t{0}\n", s);
228
229 handlers.AppendFormat("* HTTP:\n");
230 List<String> poll = httpServer.GetPollServiceHandlerKeys();
231 foreach (String s in httpServer.GetHTTPHandlerKeys())
232 handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
233
234// handlers.AppendFormat("* Agent:\n");
235// foreach (String s in httpServer.GetAgentHandlerKeys())
236// handlers.AppendFormat("\t{0}\n", s);
237
238 handlers.AppendFormat("* LLSD:\n");
239 foreach (String s in httpServer.GetLLSDHandlerKeys())
240 handlers.AppendFormat("\t{0}\n", s);
241
242 handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
243 foreach (String s in httpServer.GetStreamHandlerKeys())
244 handlers.AppendFormat("\t{0}\n", s);
245
246 handlers.Append("\n");
247 }
140 } 248 }
249
250 MainConsole.Instance.Output(handlers.ToString());
141 } 251 }
142 252
143 /// <summary> 253 /// <summary>
diff --git a/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..021f63c
--- /dev/null
+++ b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Framework.Servers")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("b48e8b3e-5c5c-4673-b31f-21e13b8e568b")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.7.5.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
new file mode 100644
index 0000000..c182a3a
--- /dev/null
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -0,0 +1,566 @@
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
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using System.Text.RegularExpressions;
34using log4net;
35using log4net.Appender;
36using log4net.Core;
37using log4net.Repository;
38using Nini.Config;
39using OpenSim.Framework.Console;
40
41namespace OpenSim.Framework.Servers
42{
43 public class ServerBase
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 public IConfigSource Config { get; protected set; }
48
49 /// <summary>
50 /// Console to be used for any command line output. Can be null, in which case there should be no output.
51 /// </summary>
52 protected ICommandConsole m_console;
53
54 protected OpenSimAppender m_consoleAppender;
55 protected FileAppender m_logFileAppender;
56
57 protected DateTime m_startuptime;
58 protected string m_startupDirectory = Environment.CurrentDirectory;
59
60 protected string m_pidFile = String.Empty;
61
62 /// <summary>
63 /// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
64 /// </summary>
65 protected string m_version;
66
67 public ServerBase()
68 {
69 m_startuptime = DateTime.Now;
70 m_version = VersionInfo.Version;
71 EnhanceVersionInformation();
72 }
73
74 protected void CreatePIDFile(string path)
75 {
76 try
77 {
78 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
79
80 using (FileStream fs = File.Create(path))
81 {
82 Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
83 fs.Write(buf, 0, buf.Length);
84 }
85
86 m_pidFile = path;
87
88 m_log.InfoFormat("[SERVER BASE]: Created pid file {0}", m_pidFile);
89 }
90 catch (Exception e)
91 {
92 m_log.Warn(string.Format("[SERVER BASE]: Could not create PID file at {0} ", path), e);
93 }
94 }
95
96 protected void RemovePIDFile()
97 {
98 if (m_pidFile != String.Empty)
99 {
100 try
101 {
102 File.Delete(m_pidFile);
103 }
104 catch (Exception e)
105 {
106 m_log.Error(string.Format("[SERVER BASE]: Error whilst removing {0} ", m_pidFile), e);
107 }
108
109 m_pidFile = String.Empty;
110 }
111 }
112
113 public void RegisterCommonAppenders(IConfig startupConfig)
114 {
115 ILoggerRepository repository = LogManager.GetRepository();
116 IAppender[] appenders = repository.GetAppenders();
117
118 foreach (IAppender appender in appenders)
119 {
120 if (appender.Name == "Console")
121 {
122 m_consoleAppender = (OpenSimAppender)appender;
123 }
124 else if (appender.Name == "LogFileAppender")
125 {
126 m_logFileAppender = (FileAppender)appender;
127 }
128 }
129
130 if (null == m_consoleAppender)
131 {
132 Notice("No appender named Console found (see the log4net config file for this executable)!");
133 }
134 else
135 {
136 // FIXME: This should be done through an interface rather than casting.
137 m_consoleAppender.Console = (ConsoleBase)m_console;
138
139 // If there is no threshold set then the threshold is effectively everything.
140 if (null == m_consoleAppender.Threshold)
141 m_consoleAppender.Threshold = Level.All;
142
143 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
144 }
145
146 if (m_logFileAppender != null && startupConfig != null)
147 {
148 string cfgFileName = startupConfig.GetString("LogFile", null);
149 if (cfgFileName != null)
150 {
151 m_logFileAppender.File = cfgFileName;
152 m_logFileAppender.ActivateOptions();
153 }
154
155 m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File);
156 }
157 }
158
159 /// <summary>
160 /// Register common commands once m_console has been set if it is going to be set
161 /// </summary>
162 public void RegisterCommonCommands()
163 {
164 if (m_console == null)
165 return;
166
167 m_console.Commands.AddCommand(
168 "General", false, "show info", "show info", "Show general information about the server", HandleShow);
169
170 m_console.Commands.AddCommand(
171 "General", false, "show uptime", "show uptime", "Show server uptime", HandleShow);
172
173 m_console.Commands.AddCommand(
174 "General", false, "get log level", "get log level", "Get the current console logging level",
175 (mod, cmd) => ShowLogLevel());
176
177 m_console.Commands.AddCommand(
178 "General", false, "set log level", "set log level <level>",
179 "Set the console logging level for this session.", HandleSetLogLevel);
180
181 m_console.Commands.AddCommand(
182 "General", false, "config set",
183 "config set <section> <key> <value>",
184 "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
185
186 m_console.Commands.AddCommand(
187 "General", false, "config get",
188 "config get [<section>] [<key>]",
189 "Synonym for config show",
190 HandleConfig);
191
192 m_console.Commands.AddCommand(
193 "General", false, "config show",
194 "config show [<section>] [<key>]",
195 "Show config information",
196 "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
197 + "If a section is given but not a field, then all fields in that section are printed.",
198 HandleConfig);
199
200 m_console.Commands.AddCommand(
201 "General", false, "config save",
202 "config save <path>",
203 "Save current configuration to a file at the given path", HandleConfig);
204
205 m_console.Commands.AddCommand(
206 "General", false, "command-script",
207 "command-script <script>",
208 "Run a command script from file", HandleScript);
209 }
210
211 public virtual void HandleShow(string module, string[] cmd)
212 {
213 List<string> args = new List<string>(cmd);
214
215 args.RemoveAt(0);
216
217 string[] showParams = args.ToArray();
218
219 switch (showParams[0])
220 {
221 case "info":
222 ShowInfo();
223 break;
224
225 case "uptime":
226 Notice(GetUptimeReport());
227 break;
228 }
229 }
230
231 /// <summary>
232 /// Change and load configuration file data.
233 /// </summary>
234 /// <param name="module"></param>
235 /// <param name="cmd"></param>
236 private void HandleConfig(string module, string[] cmd)
237 {
238 List<string> args = new List<string>(cmd);
239 args.RemoveAt(0);
240 string[] cmdparams = args.ToArray();
241
242 if (cmdparams.Length > 0)
243 {
244 string firstParam = cmdparams[0].ToLower();
245
246 switch (firstParam)
247 {
248 case "set":
249 if (cmdparams.Length < 4)
250 {
251 Notice("Syntax: config set <section> <key> <value>");
252 Notice("Example: config set ScriptEngine.DotNetEngine NumberOfScriptThreads 5");
253 }
254 else
255 {
256 IConfig c;
257 IConfigSource source = new IniConfigSource();
258 c = source.AddConfig(cmdparams[1]);
259 if (c != null)
260 {
261 string _value = String.Join(" ", cmdparams, 3, cmdparams.Length - 3);
262 c.Set(cmdparams[2], _value);
263 Config.Merge(source);
264
265 Notice("In section [{0}], set {1} = {2}", c.Name, cmdparams[2], _value);
266 }
267 }
268 break;
269
270 case "get":
271 case "show":
272 if (cmdparams.Length == 1)
273 {
274 foreach (IConfig config in Config.Configs)
275 {
276 Notice("[{0}]", config.Name);
277 string[] keys = config.GetKeys();
278 foreach (string key in keys)
279 Notice(" {0} = {1}", key, config.GetString(key));
280 }
281 }
282 else if (cmdparams.Length == 2 || cmdparams.Length == 3)
283 {
284 IConfig config = Config.Configs[cmdparams[1]];
285 if (config == null)
286 {
287 Notice("Section \"{0}\" does not exist.",cmdparams[1]);
288 break;
289 }
290 else
291 {
292 if (cmdparams.Length == 2)
293 {
294 Notice("[{0}]", config.Name);
295 foreach (string key in config.GetKeys())
296 Notice(" {0} = {1}", key, config.GetString(key));
297 }
298 else
299 {
300 Notice(
301 "config get {0} {1} : {2}",
302 cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
303 }
304 }
305 }
306 else
307 {
308 Notice("Syntax: config {0} [<section>] [<key>]", firstParam);
309 Notice("Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam);
310 }
311
312 break;
313
314 case "save":
315 if (cmdparams.Length < 2)
316 {
317 Notice("Syntax: config save <path>");
318 return;
319 }
320
321 string path = cmdparams[1];
322 Notice("Saving configuration file: {0}", path);
323
324 if (Config is IniConfigSource)
325 {
326 IniConfigSource iniCon = (IniConfigSource)Config;
327 iniCon.Save(path);
328 }
329 else if (Config is XmlConfigSource)
330 {
331 XmlConfigSource xmlCon = (XmlConfigSource)Config;
332 xmlCon.Save(path);
333 }
334
335 break;
336 }
337 }
338 }
339
340 private void HandleSetLogLevel(string module, string[] cmd)
341 {
342 if (cmd.Length != 4)
343 {
344 Notice("Usage: set log level <level>");
345 return;
346 }
347
348 if (null == m_consoleAppender)
349 {
350 Notice("No appender named Console found (see the log4net config file for this executable)!");
351 return;
352 }
353
354 string rawLevel = cmd[3];
355
356 ILoggerRepository repository = LogManager.GetRepository();
357 Level consoleLevel = repository.LevelMap[rawLevel];
358
359 if (consoleLevel != null)
360 m_consoleAppender.Threshold = consoleLevel;
361 else
362 Notice(
363 "{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
364 rawLevel);
365
366 ShowLogLevel();
367 }
368
369 private void ShowLogLevel()
370 {
371 Notice("Console log level is {0}", m_consoleAppender.Threshold);
372 }
373
374 protected virtual void HandleScript(string module, string[] parms)
375 {
376 if (parms.Length != 2)
377 {
378 Notice("Usage: command-script <path-to-script");
379 return;
380 }
381
382 RunCommandScript(parms[1]);
383 }
384
385 /// <summary>
386 /// Run an optional startup list of commands
387 /// </summary>
388 /// <param name="fileName"></param>
389 protected void RunCommandScript(string fileName)
390 {
391 if (m_console == null)
392 return;
393
394 if (File.Exists(fileName))
395 {
396 m_log.Info("[SERVER BASE]: Running " + fileName);
397
398 using (StreamReader readFile = File.OpenText(fileName))
399 {
400 string currentCommand;
401 while ((currentCommand = readFile.ReadLine()) != null)
402 {
403 currentCommand = currentCommand.Trim();
404 if (!(currentCommand == ""
405 || currentCommand.StartsWith(";")
406 || currentCommand.StartsWith("//")
407 || currentCommand.StartsWith("#")))
408 {
409 m_log.Info("[SERVER BASE]: Running '" + currentCommand + "'");
410 m_console.RunCommand(currentCommand);
411 }
412 }
413 }
414 }
415 }
416
417 /// <summary>
418 /// Return a report about the uptime of this server
419 /// </summary>
420 /// <returns></returns>
421 protected string GetUptimeReport()
422 {
423 StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
424 sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
425 sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
426
427 return sb.ToString();
428 }
429
430 protected void ShowInfo()
431 {
432 Notice(GetVersionText());
433 Notice("Startup directory: " + m_startupDirectory);
434 if (null != m_consoleAppender)
435 Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold));
436 }
437
438 /// <summary>
439 /// Enhance the version string with extra information if it's available.
440 /// </summary>
441 protected void EnhanceVersionInformation()
442 {
443 string buildVersion = string.Empty;
444
445 // The subversion information is deprecated and will be removed at a later date
446 // Add subversion revision information if available
447 // Try file "svn_revision" in the current directory first, then the .svn info.
448 // This allows to make the revision available in simulators not running from the source tree.
449 // FIXME: Making an assumption about the directory we're currently in - we do this all over the place
450 // elsewhere as well
451 string gitDir = "../.git/";
452 string gitRefPointerPath = gitDir + "HEAD";
453
454 string svnRevisionFileName = "svn_revision";
455 string svnFileName = ".svn/entries";
456 string manualVersionFileName = ".version";
457 string inputLine;
458 int strcmp;
459
460 if (File.Exists(manualVersionFileName))
461 {
462 using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
463 buildVersion = CommitFile.ReadLine();
464
465 m_version += buildVersion ?? "";
466 }
467 else if (File.Exists(gitRefPointerPath))
468 {
469// m_log.DebugFormat("[SERVER BASE]: Found {0}", gitRefPointerPath);
470
471 string rawPointer = "";
472
473 using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
474 rawPointer = pointerFile.ReadLine();
475
476// m_log.DebugFormat("[SERVER BASE]: rawPointer [{0}]", rawPointer);
477
478 Match m = Regex.Match(rawPointer, "^ref: (.+)$");
479
480 if (m.Success)
481 {
482// m_log.DebugFormat("[SERVER BASE]: Matched [{0}]", m.Groups[1].Value);
483
484 string gitRef = m.Groups[1].Value;
485 string gitRefPath = gitDir + gitRef;
486 if (File.Exists(gitRefPath))
487 {
488// m_log.DebugFormat("[SERVER BASE]: Found gitRefPath [{0}]", gitRefPath);
489
490 using (StreamReader refFile = File.OpenText(gitRefPath))
491 {
492 string gitHash = refFile.ReadLine();
493 m_version += gitHash.Substring(0, 7);
494 }
495 }
496 }
497 }
498 else
499 {
500 // Remove the else logic when subversion mirror is no longer used
501 if (File.Exists(svnRevisionFileName))
502 {
503 StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
504 buildVersion = RevisionFile.ReadLine();
505 buildVersion.Trim();
506 RevisionFile.Close();
507 }
508
509 if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
510 {
511 StreamReader EntriesFile = File.OpenText(svnFileName);
512 inputLine = EntriesFile.ReadLine();
513 while (inputLine != null)
514 {
515 // using the dir svn revision at the top of entries file
516 strcmp = String.Compare(inputLine, "dir");
517 if (strcmp == 0)
518 {
519 buildVersion = EntriesFile.ReadLine();
520 break;
521 }
522 else
523 {
524 inputLine = EntriesFile.ReadLine();
525 }
526 }
527 EntriesFile.Close();
528 }
529
530 m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6);
531 }
532 }
533
534 protected string GetVersionText()
535 {
536 return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
537 }
538
539 /// <summary>
540 /// Console output is only possible if a console has been established.
541 /// That is something that cannot be determined within this class. So
542 /// all attempts to use the console MUST be verified.
543 /// </summary>
544 /// <param name="msg"></param>
545 protected void Notice(string msg)
546 {
547 if (m_console != null)
548 {
549 m_console.Output(msg);
550 }
551 }
552
553 /// <summary>
554 /// Console output is only possible if a console has been established.
555 /// That is something that cannot be determined within this class. So
556 /// all attempts to use the console MUST be verified.
557 /// </summary>
558 /// <param name="format"></param>
559 /// <param name="components"></param>
560 protected void Notice(string format, params object[] components)
561 {
562 if (m_console != null)
563 m_console.OutputFormat(format, components);
564 }
565 }
566} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index 016a174..bb094ed 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -29,7 +29,7 @@ namespace OpenSim
29{ 29{
30 public class VersionInfo 30 public class VersionInfo
31 { 31 {
32 private const string VERSION_NUMBER = "0.7.4CM"; 32 private const string VERSION_NUMBER = "0.7.5CM";
33 private const Flavour VERSION_FLAVOUR = Flavour.Dev; 33 private const Flavour VERSION_FLAVOUR = Flavour.Dev;
34 34
35 public enum Flavour 35 public enum Flavour