aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Console/RemoteConsole.cs
diff options
context:
space:
mode:
authorMelanie2009-08-17 05:00:30 +0100
committerMelanie2009-08-17 05:00:30 +0100
commit002940dd5dc8a4b5fa23ea6d5183e00431dd48df (patch)
tree793c49a583cd9f59a7d42c01de017a557e0cac5d /OpenSim/Framework/Console/RemoteConsole.cs
parent* handle litjson errors for now. We'll remove this when we hear back from ... (diff)
downloadopensim-SC_OLD-002940dd5dc8a4b5fa23ea6d5183e00431dd48df.zip
opensim-SC_OLD-002940dd5dc8a4b5fa23ea6d5183e00431dd48df.tar.gz
opensim-SC_OLD-002940dd5dc8a4b5fa23ea6d5183e00431dd48df.tar.bz2
opensim-SC_OLD-002940dd5dc8a4b5fa23ea6d5183e00431dd48df.tar.xz
Filling in the blanks: The "meat" of the REST console
Diffstat (limited to 'OpenSim/Framework/Console/RemoteConsole.cs')
-rw-r--r--OpenSim/Framework/Console/RemoteConsole.cs334
1 files changed, 325 insertions, 9 deletions
diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs
index 73209be..dbf8f8c 100644
--- a/OpenSim/Framework/Console/RemoteConsole.cs
+++ b/OpenSim/Framework/Console/RemoteConsole.cs
@@ -26,30 +26,43 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
30using System.Collections;
29using System.Collections.Generic; 31using System.Collections.Generic;
30using System.Diagnostics; 32using System.Diagnostics;
31using System.Reflection; 33using System.Reflection;
32using System.Text; 34using System.Text;
33using System.Threading; 35using System.Threading;
36using OpenMetaverse;
34using Nini.Config; 37using Nini.Config;
35using OpenSim.Framework.Servers.HttpServer; 38using OpenSim.Framework.Servers.HttpServer;
36using log4net; 39using log4net;
37 40
38namespace OpenSim.Framework.Console 41namespace OpenSim.Framework.Console
39{ 42{
43 public class ConsoleConnection
44 {
45 public int last;
46 public long lastLineSeen;
47 }
48
40 // A console that uses REST interfaces 49 // A console that uses REST interfaces
41 // 50 //
42 public class RemoteConsole : CommandConsole 51 public class RemoteConsole : CommandConsole
43 { 52 {
44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 54
46 // private IHttpServer m_Server = null; 55 private IHttpServer m_Server = null;
47 // private IConfigSource m_Config = null; 56 private IConfigSource m_Config = null;
48 57
49 private List<string> m_Scrollback = new List<string>(); 58 private List<string> m_Scrollback = new List<string>();
50 private ManualResetEvent m_DataEvent = new ManualResetEvent(false); 59 private ManualResetEvent m_DataEvent = new ManualResetEvent(false);
51 private List<string> m_InputData = new List<string>(); 60 private List<string> m_InputData = new List<string>();
52 private uint m_LineNumber = 1; 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;
53 66
54 public RemoteConsole(string defaultPrompt) : base(defaultPrompt) 67 public RemoteConsole(string defaultPrompt) : base(defaultPrompt)
55 { 68 {
@@ -57,12 +70,23 @@ namespace OpenSim.Framework.Console
57 70
58 public void ReadConfig(IConfigSource config) 71 public void ReadConfig(IConfigSource config)
59 { 72 {
60 // m_Config = config; 73 m_Config = config;
74
75 IConfig netConfig = m_Config.Configs["Network"];
76 if (netConfig == null)
77 return;
78
79 m_UserName = netConfig.GetString("ConsoleUser", String.Empty);
80 m_Password = netConfig.GetString("ConsolePass", String.Empty);
61 } 81 }
62 82
63 public void SetServer(IHttpServer server) 83 public void SetServer(IHttpServer server)
64 { 84 {
65 // m_Server = server; 85 m_Server = server;
86
87 m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession);
88 m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession);
89 m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand);
66 } 90 }
67 91
68 public override void Output(string text, string level) 92 public override void Output(string text, string level)
@@ -71,16 +95,14 @@ namespace OpenSim.Framework.Console
71 { 95 {
72 while (m_Scrollback.Count >= 1000) 96 while (m_Scrollback.Count >= 1000)
73 m_Scrollback.RemoveAt(0); 97 m_Scrollback.RemoveAt(0);
74 m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
75 m_LineNumber++; 98 m_LineNumber++;
99 m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
76 } 100 }
77 System.Console.Write(text); 101 System.Console.Write(text);
78 } 102 }
79 103
80 public override string ReadLine(string p, bool isCommand, bool e) 104 public override string ReadLine(string p, bool isCommand, bool e)
81 { 105 {
82 System.Console.Write("{0}", prompt);
83
84 m_DataEvent.WaitOne(); 106 m_DataEvent.WaitOne();
85 107
86 lock (m_InputData) 108 lock (m_InputData)
@@ -115,5 +137,299 @@ namespace OpenSim.Framework.Console
115 return cmdinput; 137 return cmdinput;
116 } 138 }
117 } 139 }
140
141 private void DoExpire()
142 {
143 List<UUID> expired = new List<UUID>();
144
145 lock (m_Connections)
146 {
147 foreach (KeyValuePair<UUID, ConsoleConnection> kvp in m_Connections)
148 {
149 if (System.Environment.TickCount - kvp.Value.last > 500000)
150 expired.Add(kvp.Key);
151 }
152
153 foreach (UUID id in expired)
154 {
155 System.Console.WriteLine("Expired {0}", id.ToString());
156 CloseConnection(id);
157 m_Connections.Remove(id);
158 }
159 }
160 }
161
162 private Hashtable HandleHttpStartSession(Hashtable request)
163 {
164 DoExpire();
165
166 Hashtable post = DecodePostString(request["body"].ToString());
167 Hashtable reply = new Hashtable();
168
169 reply["str_response_string"] = "";
170 reply["int_response_code"] = 401;
171 reply["content_type"] = "text/plain";
172
173 if (m_UserName == String.Empty)
174 return reply;
175
176 if (post["USER"] == null || post["PASS"] == null)
177 return reply;
178
179 if (m_UserName != post["USER"].ToString() ||
180 m_Password != post["PASS"].ToString())
181 {
182 return reply;
183 }
184
185 ConsoleConnection c = new ConsoleConnection();
186 c.last = System.Environment.TickCount;
187 c.lastLineSeen = 0;
188
189 UUID sessionID = UUID.Random();
190
191 lock (m_Connections)
192 {
193 m_Connections[sessionID] = c;
194 }
195
196 string uri = "/ReadResponses/" + sessionID.ToString() + "/";
197
198 m_Server.AddPollServiceHTTPHandler(uri, HandleHttpCloseSession,
199 new PollServiceEventArgs(HasEvents, GetEvents, NoEvents,
200 sessionID));
201
202 XmlDocument xmldoc = new XmlDocument();
203 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
204 "", "");
205
206 xmldoc.AppendChild(xmlnode);
207 XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
208 "");
209
210 xmldoc.AppendChild(rootElement);
211
212 XmlElement id = xmldoc.CreateElement("", "SessionID", "");
213 id.AppendChild(xmldoc.CreateTextNode(sessionID.ToString()));
214
215 rootElement.AppendChild(id);
216 rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc));
217
218 reply["str_response_string"] = xmldoc.InnerXml;
219 reply["int_response_code"] = 200;
220 reply["content_type"] = "text/xml";
221
222 return reply;
223 }
224
225 private Hashtable HandleHttpCloseSession(Hashtable request)
226 {
227 DoExpire();
228
229 Hashtable post = DecodePostString(request["body"].ToString());
230 Hashtable reply = new Hashtable();
231
232 reply["str_response_string"] = "";
233 reply["int_response_code"] = 404;
234 reply["content_type"] = "text/plain";
235
236 if (post["ID"] == null)
237 return reply;
238
239 UUID id;
240 if (!UUID.TryParse(post["ID"].ToString(), out id))
241 return reply;
242
243 lock (m_Connections)
244 {
245 if (m_Connections.ContainsKey(id))
246 {
247 CloseConnection(id);
248 m_Connections.Remove(id);
249 }
250 }
251
252 XmlDocument xmldoc = new XmlDocument();
253 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
254 "", "");
255
256 xmldoc.AppendChild(xmlnode);
257 XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
258 "");
259
260 xmldoc.AppendChild(rootElement);
261
262 XmlElement res = xmldoc.CreateElement("", "Result", "");
263 res.AppendChild(xmldoc.CreateTextNode("OK"));
264
265 rootElement.AppendChild(res);
266
267 reply["str_response_string"] = xmldoc.InnerXml;
268 reply["int_response_code"] = 200;
269 reply["content_type"] = "text/plain";
270
271 return reply;
272 }
273
274 private Hashtable HandleHttpSessionCommand(Hashtable request)
275 {
276 DoExpire();
277
278 Hashtable post = DecodePostString(request["body"].ToString());
279 Hashtable reply = new Hashtable();
280
281 reply["str_response_string"] = "";
282 reply["int_response_code"] = 404;
283 reply["content_type"] = "text/plain";
284
285 if (post["ID"] == null)
286 return reply;
287
288 UUID id;
289 if (!UUID.TryParse(post["ID"].ToString(), out id))
290 return reply;
291
292 if (post["COMMAND"] == null || post["COMMAND"].ToString() == String.Empty)
293 return reply;
294
295 lock (m_InputData)
296 {
297 m_DataEvent.Set();
298 m_InputData.Add(post["COMMAND"].ToString());
299 }
300
301 XmlDocument xmldoc = new XmlDocument();
302 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
303 "", "");
304
305 xmldoc.AppendChild(xmlnode);
306 XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
307 "");
308
309 xmldoc.AppendChild(rootElement);
310
311 XmlElement res = xmldoc.CreateElement("", "Result", "");
312 res.AppendChild(xmldoc.CreateTextNode("OK"));
313
314 rootElement.AppendChild(res);
315
316 reply["str_response_string"] = xmldoc.InnerXml;
317 reply["int_response_code"] = 200;
318 reply["content_type"] = "text/plain";
319
320 return reply;
321 }
322
323 private Hashtable DecodePostString(string data)
324 {
325 Hashtable result = new Hashtable();
326
327 string[] terms = data.Split(new char[] {'&'});
328
329 foreach (string term in terms)
330 {
331 string[] elems = term.Split(new char[] {'='});
332 if (elems.Length == 0)
333 continue;
334
335 string name = System.Web.HttpUtility.UrlDecode(elems[0]);
336 string value = String.Empty;
337
338 if (elems.Length > 1)
339 value = System.Web.HttpUtility.UrlDecode(elems[1]);
340
341 result[name] = value;
342 }
343
344 return result;
345 }
346
347 public void CloseConnection(UUID id)
348 {
349 string uri = "/ReadResponses/" + id.ToString() + "/";
350
351 m_Server.RemovePollServiceHTTPHandler("", uri);
352 }
353
354 private bool HasEvents(UUID sessionID)
355 {
356 ConsoleConnection c = null;
357
358 lock (m_Connections)
359 {
360 if (!m_Connections.ContainsKey(sessionID))
361 return false;
362 c = m_Connections[sessionID];
363 }
364 c.last = System.Environment.TickCount;
365 if (c.lastLineSeen < m_LineNumber)
366 return true;
367 return false;
368 }
369
370 private Hashtable GetEvents(UUID sessionID, string request)
371 {
372 ConsoleConnection c = null;
373
374 lock (m_Connections)
375 {
376 if (!m_Connections.ContainsKey(sessionID))
377 return NoEvents();
378 c = m_Connections[sessionID];
379 }
380 c.last = System.Environment.TickCount;
381 if (c.lastLineSeen >= m_LineNumber)
382 return NoEvents();
383
384 Hashtable result = new Hashtable();
385
386 XmlDocument xmldoc = new XmlDocument();
387 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
388 "", "");
389
390 xmldoc.AppendChild(xmlnode);
391 XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
392 "");
393
394 lock (m_Scrollback)
395 {
396 long startLine = m_LineNumber - m_Scrollback.Count;
397
398 for (long i = startLine ; i < m_LineNumber ; i++)
399 {
400 XmlElement res = xmldoc.CreateElement("", "Line", "");
401 long line = i + 1;
402 res.SetAttribute("Number", line.ToString());
403 res.AppendChild(xmldoc.CreateTextNode(m_Scrollback[(int)(i - startLine)]));
404
405 rootElement.AppendChild(res);
406 }
407 }
408 c.lastLineSeen = m_LineNumber;
409
410 xmldoc.AppendChild(rootElement);
411
412 result["str_response_string"] = xmldoc.InnerXml;
413 result["int_response_code"] = 200;
414 result["content_type"] = "application/xml";
415 result["keepalive"] = false;
416 result["reusecontext"] = false;
417
418 return result;
419 }
420
421 private Hashtable NoEvents()
422 {
423 Hashtable result = new Hashtable();
424
425 result["int_response_code"] = 502;
426 result["content_type"] = "text/plain";
427 result["keepalive"] = false;
428 result["reusecontext"] = false;
429 result["str_response_string"] = "Upstream error: ";
430 result["error_status_text"] = "Upstream error:";
431
432 return result;
433 }
118 } 434 }
119} 435}