aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
diff options
context:
space:
mode:
authorSean Dague2008-02-19 19:16:21 +0000
committerSean Dague2008-02-19 19:16:21 +0000
commit530cc2488461a4ef68a06eaba42698fcdc09f459 (patch)
treed2db34a2dcdb10b3b85aaeb200334ee9a27cae91 /OpenSim/Region/Environment/Modules/XMLRPCModule.cs
parentAdded to OpenSim.ini.example: (diff)
downloadopensim-SC_OLD-530cc2488461a4ef68a06eaba42698fcdc09f459.zip
opensim-SC_OLD-530cc2488461a4ef68a06eaba42698fcdc09f459.tar.gz
opensim-SC_OLD-530cc2488461a4ef68a06eaba42698fcdc09f459.tar.bz2
opensim-SC_OLD-530cc2488461a4ef68a06eaba42698fcdc09f459.tar.xz
From: Michael Osias <mosias@us.ibm.com>
This patch implements the llSendRemoteData command and fixes mantis 552, and possibly 586.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/XMLRPCModule.cs482
1 files changed, 366 insertions, 116 deletions
diff --git a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
index edd1df8..48a4c7c 100644
--- a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
+++ b/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
@@ -78,19 +78,20 @@ namespace OpenSim.Region.Environment.Modules
78 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 78 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
79 79
80 private Scene m_scene; 80 private Scene m_scene;
81 private Queue<RPCRequestInfo> rpcQueue = new Queue<RPCRequestInfo>();
82 private object XMLRPCListLock = new object(); 81 private object XMLRPCListLock = new object();
83 private string m_name = "XMLRPCModule"; 82 private string m_name = "XMLRPCModule";
84 private int RemoteReplyScriptWait = 300; 83 private int RemoteReplyScriptWait = 300;
85 private int RemoteReplyScriptTimeout = 900; 84 private int RemoteReplyScriptTimeout = 9000;
86 private int m_remoteDataPort = 0; 85 private int m_remoteDataPort = 0;
87 private List<Scene> m_scenes = new List<Scene>(); 86 private List<Scene> m_scenes = new List<Scene>();
88 87
89 // <channel id, RPCChannelInfo> 88 // <channel id, RPCChannelInfo>
90 private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; 89 private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
91 90
92 // <channel id, RPCRequestInfo> 91 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending;
93 private Dictionary<LLUUID, RPCRequestInfo> m_pendingResponse; 92 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses;
93
94 private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses;
94 95
95 public void Initialise(Scene scene, IConfigSource config) 96 public void Initialise(Scene scene, IConfigSource config)
96 { 97 {
@@ -115,13 +116,15 @@ namespace OpenSim.Region.Environment.Modules
115 if (IsEnabled()) 116 if (IsEnabled())
116 { 117 {
117 m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); 118 m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>();
118 m_pendingResponse = new Dictionary<LLUUID, RPCRequestInfo>(); 119 m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>();
120 m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>();
121 m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>();
119 122
120 // Start http server 123 // Start http server
121 // Attach xmlrpc handlers 124 // Attach xmlrpc handlers
122 m_log.Info("[REMOTE_DATA]: " + 125 m_log.Info("[REMOTE_DATA]: " +
123 "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); 126 "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
124 BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); 127 BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort);
125 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); 128 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
126 httpServer.Start(); 129 httpServer.Start();
127 } 130 }
@@ -188,18 +191,28 @@ namespace OpenSim.Region.Environment.Modules
188 return channel; 191 return channel;
189 } 192 }
190 193
191 public void DeleteChannel(LLUUID itemID) 194 // Delete channels based on itemID
195 // for when a script is deleted
196 public void DeleteChannels(LLUUID itemID)
192 { 197 {
193 198
194 foreach (RPCChannelInfo li in m_openChannels.Values) 199 if (m_openChannels != null)
195 { 200 {
201 ArrayList tmp = new ArrayList();
196 202
197 if (li.GetItemID().Equals(itemID)) 203 lock (XMLRPCListLock)
198 { 204 {
205 foreach (RPCChannelInfo li in m_openChannels.Values)
206 {
207 if (li.GetItemID().Equals(itemID))
208 {
209 tmp.Add(itemID);
210 }
211 }
199 212
200 m_openChannels.Remove(li.GetChannelID()); 213 System.Collections.IEnumerator tmpEnumerator = tmp.GetEnumerator();
201 return; 214 while ( tmpEnumerator.MoveNext() )
202 215 m_openChannels.Remove((LLUUID)tmpEnumerator.Current);
203 } 216 }
204 217
205 } 218 }
@@ -218,15 +231,12 @@ namespace OpenSim.Region.Environment.Modules
218 RPCRequestInfo rpcInfo; 231 RPCRequestInfo rpcInfo;
219 LLUUID message_key = new LLUUID(message_id); 232 LLUUID message_key = new LLUUID(message_id);
220 233
221 if (m_pendingResponse.TryGetValue(message_key, out rpcInfo)) 234 if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo))
222 { 235 {
223 rpcInfo.SetRetval(sdata); 236 rpcInfo.SetStrRetval(sdata);
237 rpcInfo.SetIntRetval(idata);
224 rpcInfo.SetProcessed(true); 238 rpcInfo.SetProcessed(true);
225 239 m_rpcPendingResponses.Remove(message_key);
226 lock (XMLRPCListLock)
227 {
228 m_pendingResponse.Remove(message_key);
229 }
230 } 240 }
231 } 241 }
232 242
@@ -248,18 +258,18 @@ namespace OpenSim.Region.Environment.Modules
248 { 258 {
249 XmlRpcResponse response = new XmlRpcResponse(); 259 XmlRpcResponse response = new XmlRpcResponse();
250 260
251 Hashtable requestData = (Hashtable) request.Params[0]; 261 Hashtable requestData = (Hashtable)request.Params[0];
252 bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && 262 bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") &&
253 requestData.Contains("StringValue")); 263 requestData.Contains("StringValue"));
254 264
255 if (GoodXML) 265 if (GoodXML)
256 { 266 {
257 LLUUID channel = new LLUUID((string) requestData["Channel"]); 267 LLUUID channel = new LLUUID((string)requestData["Channel"]);
258 RPCChannelInfo rpcChanInfo; 268 RPCChannelInfo rpcChanInfo;
259 if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) 269 if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
260 { 270 {
261 string intVal = (string) requestData["IntValue"]; 271 string intVal = (string)requestData["IntValue"];
262 string strVal = (string) requestData["StringValue"]; 272 string strVal = (string)requestData["StringValue"];
263 273
264 RPCRequestInfo rpcInfo; 274 RPCRequestInfo rpcInfo;
265 275
@@ -268,7 +278,7 @@ namespace OpenSim.Region.Environment.Modules
268 rpcInfo = 278 rpcInfo =
269 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, 279 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
270 intVal); 280 intVal);
271 rpcQueue.Enqueue(rpcInfo); 281 m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
272 } 282 }
273 283
274 int timeoutCtr = 0; 284 int timeoutCtr = 0;
@@ -280,16 +290,20 @@ namespace OpenSim.Region.Environment.Modules
280 } 290 }
281 if (rpcInfo.IsProcessed()) 291 if (rpcInfo.IsProcessed())
282 { 292 {
283 response.Value = rpcInfo.GetRetval(); 293 Hashtable param = new Hashtable();
294 param["StringValue"] = rpcInfo.GetStrRetval();
295 param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval());
296
297 ArrayList parameters = new ArrayList();
298 parameters.Add(param);
299
300 response.Value = parameters;
284 rpcInfo = null; 301 rpcInfo = null;
285 } 302 }
286 else 303 else
287 { 304 {
288 response.SetFault(-1, "Script timeout"); 305 response.SetFault(-1, "Script timeout");
289 lock (XMLRPCListLock) 306 rpcInfo = null;
290 {
291 m_pendingResponse.Remove(rpcInfo.GetMessageID());
292 }
293 } 307 }
294 } 308 }
295 else 309 else
@@ -303,129 +317,365 @@ namespace OpenSim.Region.Environment.Modules
303 317
304 public bool hasRequests() 318 public bool hasRequests()
305 { 319 {
306 return (rpcQueue.Count > 0);
307 }
308
309 public RPCRequestInfo GetNextRequest()
310 {
311 lock (XMLRPCListLock) 320 lock (XMLRPCListLock)
312 { 321 {
313 RPCRequestInfo rpcInfo = rpcQueue.Dequeue(); 322 if (m_rpcPending != null)
314 m_pendingResponse.Add(rpcInfo.GetMessageID(), rpcInfo); 323 return (m_rpcPending.Count > 0);
315 return rpcInfo; 324 else
325 return false;
316 } 326 }
317 } 327 }
318 }
319
320 /**************************************************************
321 *
322 * Class RPCRequestInfo
323 *
324 * Holds details about incoming requests until they are picked
325 * from the queue by LSLLongCmdHandler
326 * ***********************************************************/
327 328
328 public class RPCRequestInfo 329 public RPCRequestInfo GetNextCompletedRequest()
329 {
330 private string m_StrVal;
331 private string m_IntVal;
332 private bool m_processed;
333 private string m_resp;
334 private uint m_localID;
335 private LLUUID m_ItemID;
336 private LLUUID m_MessageID;
337 private LLUUID m_ChannelKey;
338
339 public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
340 { 330 {
341 m_localID = localID; 331 if (m_rpcPending != null)
342 m_StrVal = strVal; 332 {
343 m_IntVal = intVal; 333 lock (XMLRPCListLock)
344 m_ItemID = itemID; 334 {
345 m_ChannelKey = channelKey; 335 foreach (LLUUID luid in m_rpcPending.Keys)
346 m_MessageID = LLUUID.Random(); 336 {
347 m_processed = false; 337 RPCRequestInfo tmpReq;
348 m_resp = String.Empty;
349 }
350 338
351 public bool IsProcessed() 339 if (m_rpcPending.TryGetValue(luid, out tmpReq))
352 { 340 {
353 return m_processed;
354 }
355 341
356 public LLUUID GetChannelKey() 342 if (!tmpReq.IsProcessed()) return tmpReq;
357 { 343 }
358 return m_ChannelKey; 344 }
345 }
346 }
347 return null;
359 } 348 }
360 349
361 public void SetProcessed(bool processed) 350 public void RemoveCompletedRequest(LLUUID id)
362 { 351 {
363 m_processed = processed; 352 lock (XMLRPCListLock)
353 {
354 RPCRequestInfo tmp;
355 if (m_rpcPending.TryGetValue(id, out tmp))
356 {
357 m_rpcPending.Remove(id);
358 m_rpcPendingResponses.Add(id, tmp);
359 }
360 else
361 {
362 Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST");
363 }
364 }
364 } 365 }
365 366
366 public void SetRetval(string resp) 367 public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
367 { 368 {
368 m_resp = resp;
369 }
370 369
371 public string GetRetval() 370 SendRemoteDataRequest req = new SendRemoteDataRequest(
372 { 371 localID, itemID, channel, dest, idata, sdata
373 return m_resp; 372 );
374 } 373 m_pendingSRDResponses.Add(req.GetReqID(), req);
374 return req.process();
375 375
376 public uint GetLocalID()
377 {
378 return m_localID;
379 } 376 }
380 377
381 public LLUUID GetItemID() 378 public SendRemoteDataRequest GetNextCompletedSRDRequest()
382 { 379 {
383 return m_ItemID; 380 if (m_pendingSRDResponses != null)
384 } 381 {
382 lock (XMLRPCListLock)
383 {
384 foreach (LLUUID luid in m_pendingSRDResponses.Keys)
385 {
386 SendRemoteDataRequest tmpReq;
385 387
386 public string GetStrVal() 388 if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq))
387 { 389 {
388 return m_StrVal; 390 if (tmpReq.finished)
391 return tmpReq;
392 }
393 }
394 }
395 }
396 return null;
389 } 397 }
390 398
391 public int GetIntValue() 399 public void RemoveCompletedSRDRequest(LLUUID id)
392 { 400 {
393 return int.Parse(m_IntVal); 401 lock (XMLRPCListLock)
402 {
403 SendRemoteDataRequest tmpReq;
404 if (m_pendingSRDResponses.TryGetValue(id, out tmpReq))
405 {
406 m_pendingSRDResponses.Remove(id);
407 }
408 }
394 } 409 }
395 410
396 public LLUUID GetMessageID() 411 public void CancelSRDRequests(LLUUID itemID)
397 { 412 {
398 return m_MessageID; 413 if (m_pendingSRDResponses != null)
414 {
415 lock (XMLRPCListLock)
416 {
417 foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values)
418 {
419 if (li.m_itemID.Equals(itemID))
420 m_pendingSRDResponses.Remove(li.GetReqID());
421 }
422 }
423 }
399 } 424 }
400 } 425 }
426 /**************************************************************
427 *
428 * Class RPCRequestInfo
429 *
430 * Holds details about incoming requests until they are picked
431 * from the queue by LSLLongCmdHandler
432 * ***********************************************************/
401 433
402 public class RPCChannelInfo 434 public class RPCRequestInfo
403 {
404 private LLUUID m_itemID;
405 private uint m_localID;
406 private LLUUID m_ChannelKey;
407
408 public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
409 { 435 {
410 m_ChannelKey = channelID; 436 private string m_StrVal;
411 m_localID = localID; 437 private string m_IntVal;
412 m_itemID = itemID; 438 private bool m_processed;
413 } 439 private string m_respStr;
440 private int m_respInt;
441 private uint m_localID;
442 private LLUUID m_ItemID;
443 private LLUUID m_MessageID;
444 private LLUUID m_ChannelKey;
445
446 public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
447 {
448 m_localID = localID;
449 m_StrVal = strVal;
450 m_IntVal = intVal;
451 m_ItemID = itemID;
452 m_ChannelKey = channelKey;
453 m_MessageID = LLUUID.Random();
454 m_processed = false;
455 m_respStr = String.Empty;
456 m_respInt = 0;
457 }
414 458
415 public LLUUID GetItemID() 459 public bool IsProcessed()
416 { 460 {
417 return m_itemID; 461 return m_processed;
462 }
463
464 public LLUUID GetChannelKey()
465 {
466 return m_ChannelKey;
467 }
468
469 public void SetProcessed(bool processed)
470 {
471 m_processed = processed;
472 }
473
474 public void SetStrRetval(string resp)
475 {
476 m_respStr = resp;
477 }
478
479 public string GetStrRetval()
480 {
481 return m_respStr;
482 }
483 public void SetIntRetval(int resp)
484 {
485 m_respInt = resp;
486 }
487
488 public int GetIntRetval()
489 {
490 return m_respInt;
491 }
492 public uint GetLocalID()
493 {
494 return m_localID;
495 }
496
497 public LLUUID GetItemID()
498 {
499 return m_ItemID;
500 }
501
502 public string GetStrVal()
503 {
504 return m_StrVal;
505 }
506
507 public int GetIntValue()
508 {
509 return int.Parse(m_IntVal);
510 }
511
512 public LLUUID GetMessageID()
513 {
514 return m_MessageID;
515 }
418 } 516 }
419 517
420 public LLUUID GetChannelID() 518 public class RPCChannelInfo
421 { 519 {
422 return m_ChannelKey; 520 private LLUUID m_itemID;
521 private uint m_localID;
522 private LLUUID m_ChannelKey;
523
524 public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
525 {
526 m_ChannelKey = channelID;
527 m_localID = localID;
528 m_itemID = itemID;
529 }
530
531 public LLUUID GetItemID()
532 {
533 return m_itemID;
534 }
535
536 public LLUUID GetChannelID()
537 {
538 return m_ChannelKey;
539 }
540
541 public uint GetLocalID()
542 {
543 return m_localID;
544 }
545
423 } 546 }
424 547
425 public uint GetLocalID() 548 public class SendRemoteDataRequest
426 { 549 {
427 return m_localID; 550
551 public LLUUID reqID;
552 public string destURL;
553 public string channel;
554 public string sdata;
555 public int idata;
556 public bool finished;
557 public string response_sdata;
558 public int response_idata;
559 public XmlRpcRequest request;
560 private Thread httpThread;
561 public LLUUID m_itemID;
562 public uint m_localID;
563 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
564
565 public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
566 {
567
568 this.channel = channel;
569 this.destURL = dest;
570 this.idata = idata;
571 this.sdata = sdata;
572 m_itemID = itemID;
573 m_localID = localID;
574
575 reqID = LLUUID.Random();
576
577 }
578
579 public LLUUID process()
580 {
581 httpThread = new Thread(SendRequest);
582 httpThread.Name = "HttpRequestThread";
583 httpThread.Priority = ThreadPriority.BelowNormal;
584 httpThread.IsBackground = true;
585 finished = false;
586 httpThread.Start();
587
588 return reqID;
589
590 }
591
592 /*
593 * TODO: More work on the response codes. Right now
594 * returning 200 for success or 499 for exception
595 */
596
597 public void SendRequest()
598 {
599
600 Hashtable param = new Hashtable();
601
602 // Check if channel is an LLUUID
603 // if not, use as method name
604 LLUUID parseUID;
605 string mName = "llRemoteData";
606 if( (channel != null) && (channel != "") )
607 if( !LLUUID.TryParse(channel, out parseUID) )
608 mName = channel;
609 else
610 param["Channel"] = channel;
611
612 param["StringValue"] = sdata;
613 param["IntValue"] = Convert.ToString(idata);
614
615 ArrayList parameters = new ArrayList();
616 parameters.Add(param);
617 XmlRpcRequest req = new XmlRpcRequest(mName, parameters);
618 try
619 {
620 XmlRpcResponse resp = req.Send(destURL, 30000);
621 if (resp != null)
622 {
623 Hashtable respParms;
624 if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) {
625 respParms = (Hashtable)resp.Value;
626 }
627 else {
628 ArrayList respData = (ArrayList)resp.Value;
629 respParms = (Hashtable)respData[0];
630 }
631 if (respParms != null)
632 {
633 if (respParms.Contains("StringValue"))
634 {
635 sdata = (string)respParms["StringValue"];
636 }
637 if (respParms.Contains("IntValue"))
638 {
639 idata = Convert.ToInt32((string)respParms["IntValue"]);
640 }
641 if (respParms.Contains("faultString"))
642 {
643 sdata = (string)respParms["faultString"];
644 }
645 if (respParms.Contains("faultCode"))
646 {
647 idata = Convert.ToInt32(respParms["faultCode"]);
648 }
649 }
650 }
651 }
652 catch (System.Net.WebException we)
653 {
654 sdata = we.Message;
655 m_log.Warn("[SendRemoteDataRequest]: Request failed");
656 m_log.Warn(we.StackTrace);
657 }
658
659 finished = true;
660
661 }
662
663 public void Stop()
664 {
665 try
666 {
667 httpThread.Abort();
668 }
669 catch (Exception)
670 {
671 }
672 }
673
674 public LLUUID GetReqID()
675 {
676 return reqID;
677 }
678
428 } 679 }
429 680
430 } 681} \ No newline at end of file
431}