30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Diagnostics;
33 using System.Reflection;
35 using System.Text.RegularExpressions;
36 using System.Threading;
39 using OpenSim.Framework.Servers.HttpServer;
42 namespace OpenSim.Framework.Console
48 public bool newConnection =
true;
56 private IConfigSource m_Config = null;
58 private List<string> m_Scrollback =
new List<string>();
59 private ManualResetEvent m_DataEvent =
new ManualResetEvent(
false);
60 private List<string> m_InputData =
new List<string>();
61 private long m_LineNumber = 0;
62 private Dictionary<UUID, ConsoleConnection> m_Connections =
63 new Dictionary<UUID, ConsoleConnection>();
64 private string m_UserName = String.Empty;
65 private string m_Password = String.Empty;
66 private string m_AllowedOrigin = String.Empty;
76 IConfig netConfig = m_Config.Configs[
"Network"];
77 if (netConfig == null)
80 m_UserName = netConfig.GetString(
"ConsoleUser", String.Empty);
81 m_Password = netConfig.GetString(
"ConsolePass", String.Empty);
82 m_AllowedOrigin = netConfig.GetString(
"ConsoleAllowedOrigin", String.Empty);
89 m_Server.AddHTTPHandler(
"/StartSession/", HandleHttpStartSession);
90 m_Server.AddHTTPHandler(
"/CloseSession/", HandleHttpCloseSession);
91 m_Server.AddHTTPHandler(
"/SessionCommand/", HandleHttpSessionCommand);
94 public override void Output(
string text,
string level)
98 while (m_Scrollback.Count >= 1000)
99 m_Scrollback.RemoveAt(0);
101 m_Scrollback.Add(String.Format(
"{0}", m_LineNumber)+
":"+level+
":"+text);
103 FireOnOutput(text.Trim());
104 System.Console.WriteLine(text.Trim());
109 Output(text,
"normal");
112 public override string ReadLine(
string p,
bool isCommand,
bool e)
119 m_DataEvent.WaitOne();
125 if (m_InputData.Count == 0)
131 cmdinput = m_InputData[0];
132 m_InputData.RemoveAt(0);
133 if (m_InputData.Count == 0)
140 string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
146 for (i=0 ; i < cmd.Length ; i++)
148 if (cmd[i].Contains(
" "))
149 cmd[i] =
"\"" + cmd[i] +
"\"";
157 private Hashtable CheckOrigin(Hashtable result)
159 if (!
string.IsNullOrEmpty(m_AllowedOrigin))
160 result[
"access_control_allow_origin"] = m_AllowedOrigin;
180 private void DoExpire()
182 List<UUID> expired =
new List<UUID>();
186 foreach (KeyValuePair<UUID, ConsoleConnection> kvp
in m_Connections)
188 if (System.Environment.TickCount - kvp.Value.last > 500000)
189 expired.Add(kvp.Key);
192 foreach (UUID
id in expired)
194 m_Connections.Remove(id);
200 private Hashtable HandleHttpStartSession(Hashtable request)
204 Hashtable post = DecodePostString(request[
"body"].ToString());
205 Hashtable reply =
new Hashtable();
207 reply[
"str_response_string"] =
"";
208 reply[
"int_response_code"] = 401;
209 reply[
"content_type"] =
"text/plain";
211 if (m_UserName ==
String.Empty)
214 if (post[
"USER"] == null || post[
"PASS"] == null)
217 if (m_UserName != post[
"USER"].ToString() ||
218 m_Password != post[
"PASS"].ToString())
223 ConsoleConnection c =
new ConsoleConnection();
224 c.last = System.Environment.TickCount;
227 UUID sessionID = UUID.Random();
231 m_Connections[sessionID] = c;
234 string uri =
"/ReadResponses/" + sessionID.ToString() +
"/";
236 m_Server.AddPollServiceHTTPHandler(
239 XmlDocument xmldoc =
new XmlDocument();
240 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
243 xmldoc.AppendChild(xmlnode);
244 XmlElement rootElement = xmldoc.CreateElement(
"",
"ConsoleSession",
247 xmldoc.AppendChild(rootElement);
249 XmlElement
id = xmldoc.CreateElement(
"",
"SessionID",
"");
250 id.AppendChild(xmldoc.CreateTextNode(sessionID.ToString()));
252 rootElement.AppendChild(id);
254 XmlElement prompt = xmldoc.CreateElement(
"",
"Prompt",
"");
255 prompt.AppendChild(xmldoc.CreateTextNode(DefaultPrompt));
257 rootElement.AppendChild(prompt);
259 rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc));
261 reply[
"str_response_string"] = xmldoc.InnerXml;
262 reply[
"int_response_code"] = 200;
263 reply[
"content_type"] =
"text/xml";
264 reply = CheckOrigin(reply);
269 private Hashtable HandleHttpCloseSession(Hashtable request)
273 Hashtable post = DecodePostString(request[
"body"].ToString());
274 Hashtable reply =
new Hashtable();
276 reply[
"str_response_string"] =
"";
277 reply[
"int_response_code"] = 404;
278 reply[
"content_type"] =
"text/plain";
280 if (post[
"ID"] == null)
284 if (!
UUID.TryParse(post[
"ID"].ToString(), out id))
289 if (m_Connections.ContainsKey(
id))
291 m_Connections.Remove(id);
296 XmlDocument xmldoc =
new XmlDocument();
297 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
300 xmldoc.AppendChild(xmlnode);
301 XmlElement rootElement = xmldoc.CreateElement(
"",
"ConsoleSession",
304 xmldoc.AppendChild(rootElement);
306 XmlElement res = xmldoc.CreateElement(
"",
"Result",
"");
307 res.AppendChild(xmldoc.CreateTextNode(
"OK"));
309 rootElement.AppendChild(res);
311 reply[
"str_response_string"] = xmldoc.InnerXml;
312 reply[
"int_response_code"] = 200;
313 reply[
"content_type"] =
"text/xml";
314 reply = CheckOrigin(reply);
319 private Hashtable HandleHttpSessionCommand(Hashtable request)
323 Hashtable post = DecodePostString(request[
"body"].ToString());
324 Hashtable reply =
new Hashtable();
326 reply[
"str_response_string"] =
"";
327 reply[
"int_response_code"] = 404;
328 reply[
"content_type"] =
"text/plain";
330 if (post[
"ID"] == null)
334 if (!
UUID.TryParse(post[
"ID"].ToString(), out id))
339 if (!m_Connections.ContainsKey(
id))
343 if (post[
"COMMAND"] == null)
349 m_InputData.Add(post[
"COMMAND"].ToString());
352 XmlDocument xmldoc =
new XmlDocument();
353 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
356 xmldoc.AppendChild(xmlnode);
357 XmlElement rootElement = xmldoc.CreateElement(
"",
"ConsoleSession",
360 xmldoc.AppendChild(rootElement);
362 XmlElement res = xmldoc.CreateElement(
"",
"Result",
"");
363 res.AppendChild(xmldoc.CreateTextNode(
"OK"));
365 rootElement.AppendChild(res);
367 reply[
"str_response_string"] = xmldoc.InnerXml;
368 reply[
"int_response_code"] = 200;
369 reply[
"content_type"] =
"text/xml";
370 reply = CheckOrigin(reply);
375 private Hashtable DecodePostString(
string data)
377 Hashtable result =
new Hashtable();
379 string[] terms = data.Split(
new char[] {
'&'});
381 foreach (
string term
in terms)
383 string[] elems = term.Split(
new char[] {
'='});
384 if (elems.Length == 0)
387 string name = System.Web.HttpUtility.UrlDecode(elems[0]);
388 string value = String.Empty;
390 if (elems.Length > 1)
391 value = System.Web.HttpUtility.UrlDecode(elems[1]);
393 result[name] = value;
403 string uri =
"/ReadResponses/" + id.ToString() +
"/";
405 m_Server.RemovePollServiceHTTPHandler(
"", uri);
412 private bool HasEvents(UUID RequestID, UUID sessionID)
418 if (!m_Connections.ContainsKey(sessionID))
420 c = m_Connections[sessionID];
422 c.last = System.Environment.TickCount;
428 private Hashtable GetEvents(UUID RequestID, UUID sessionID)
430 ConsoleConnection c = null;
434 if (!m_Connections.ContainsKey(sessionID))
435 return NoEvents(RequestID, UUID.Zero);
436 c = m_Connections[sessionID];
438 c.last = System.Environment.TickCount;
439 if (c.lastLineSeen >= m_LineNumber)
440 return NoEvents(RequestID, UUID.Zero);
442 Hashtable result =
new Hashtable();
444 XmlDocument xmldoc =
new XmlDocument();
445 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
448 xmldoc.AppendChild(xmlnode);
449 XmlElement rootElement = xmldoc.CreateElement(
"",
"ConsoleSession",
454 c.newConnection =
false;
455 Output(
"+++" + DefaultPrompt);
460 long startLine = m_LineNumber - m_Scrollback.Count;
461 long sendStart = startLine;
462 if (sendStart < c.lastLineSeen)
463 sendStart = c.lastLineSeen;
465 for (
long i = sendStart ; i < m_LineNumber ; i++)
467 XmlElement res = xmldoc.CreateElement(
"",
"Line",
"");
469 res.SetAttribute(
"Number", line.ToString());
470 res.AppendChild(xmldoc.CreateTextNode(m_Scrollback[(int)(i - startLine)]));
472 rootElement.AppendChild(res);
475 c.lastLineSeen = m_LineNumber;
477 xmldoc.AppendChild(rootElement);
479 result[
"str_response_string"] = xmldoc.InnerXml;
480 result[
"int_response_code"] = 200;
481 result[
"content_type"] =
"application/xml";
482 result[
"keepalive"] =
false;
483 result[
"reusecontext"] =
false;
484 result = CheckOrigin(result);
489 private Hashtable NoEvents(UUID RequestID, UUID
id)
491 Hashtable result =
new Hashtable();
493 XmlDocument xmldoc =
new XmlDocument();
494 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
497 xmldoc.AppendChild(xmlnode);
498 XmlElement rootElement = xmldoc.CreateElement(
"",
"ConsoleSession",
501 xmldoc.AppendChild(rootElement);
503 result[
"str_response_string"] = xmldoc.InnerXml;
504 result[
"int_response_code"] = 200;
505 result[
"content_type"] =
"text/xml";
506 result[
"keepalive"] =
false;
507 result[
"reusecontext"] =
false;
508 result = CheckOrigin(result);
void ReadConfig(IConfigSource config)
void SetServer(IHttpServer server)
Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.) for given URLs.
override void Output(string text)
override string ReadLine(string p, bool isCommand, bool e)
void CloseConnection(UUID id)
RemoteConsole(string defaultPrompt)
override void Output(string text, string level)
A console that processes commands internally