aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-04-04 00:36:15 +0100
committerJustin Clark-Casey (justincc)2013-04-04 00:36:15 +0100
commit831e4c38506140e9ece2db4b96b4f0960a0276a8 (patch)
tree8a341213d3da08c85a07c62145db0fcecaedad07 /OpenSim/Region
parentminor: Stop falsely logging that a teleport was being aborted on client logou... (diff)
downloadopensim-SC-831e4c38506140e9ece2db4b96b4f0960a0276a8.zip
opensim-SC-831e4c38506140e9ece2db4b96b4f0960a0276a8.tar.gz
opensim-SC-831e4c38506140e9ece2db4b96b4f0960a0276a8.tar.bz2
opensim-SC-831e4c38506140e9ece2db4b96b4f0960a0276a8.tar.xz
Fix bug where outstanding llHTTPRequests for scripts were not being aborted when they were deleted.
This was because AsyncCommandManager was handing an item ID to IHttpRequestModule.StopHttpRequest() rather than the expected request ID. This commit also makes the http request asynchronous using BeginGetResponse() rather than doing this by launching a new thread so that we can more safely abort it via HttpWebRequest.Abort() rather than aborting the thread itself. This also renames StopHttpRequest() to StopHttpRequestsForScript() since any outstanding requests are now aborted and/or removed.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs92
-rw-r--r--OpenSim/Region/Framework/Interfaces/IHttpRequests.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs8
3 files changed, 76 insertions, 32 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index c2e37c4..1c251b8 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -28,12 +28,15 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Linq;
31using System.Net; 32using System.Net;
32using System.Net.Mail; 33using System.Net.Mail;
33using System.Net.Security; 34using System.Net.Security;
35using System.Reflection;
34using System.Text; 36using System.Text;
35using System.Threading; 37using System.Threading;
36using System.Security.Cryptography.X509Certificates; 38using System.Security.Cryptography.X509Certificates;
39using log4net;
37using Nini.Config; 40using Nini.Config;
38using OpenMetaverse; 41using OpenMetaverse;
39using OpenSim.Framework; 42using OpenSim.Framework;
@@ -250,18 +253,29 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
250 return reqID; 253 return reqID;
251 } 254 }
252 255
253 public void StopHttpRequest(uint m_localID, UUID m_itemID) 256 public void StopHttpRequestsForScript(UUID id)
254 { 257 {
255 if (m_pendingRequests != null) 258 if (m_pendingRequests != null)
256 { 259 {
260 List<UUID> keysToRemove = null;
261
257 lock (HttpListLock) 262 lock (HttpListLock)
258 { 263 {
259 HttpRequestClass tmpReq; 264 foreach (HttpRequestClass req in m_pendingRequests.Values)
260 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
261 { 265 {
262 tmpReq.Stop(); 266 if (req.ItemID == id)
263 m_pendingRequests.Remove(m_itemID); 267 {
268 req.Stop();
269
270 if (keysToRemove == null)
271 keysToRemove = new List<UUID>();
272
273 keysToRemove.Add(req.ReqID);
274 }
264 } 275 }
276
277 if (keysToRemove != null)
278 keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
265 } 279 }
266 } 280 }
267 } 281 }
@@ -362,6 +376,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
362 376
363 public class HttpRequestClass: IServiceRequest 377 public class HttpRequestClass: IServiceRequest
364 { 378 {
379// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
380
365 // Constants for parameters 381 // Constants for parameters
366 // public const int HTTP_BODY_MAXLENGTH = 2; 382 // public const int HTTP_BODY_MAXLENGTH = 2;
367 // public const int HTTP_METHOD = 0; 383 // public const int HTTP_METHOD = 0;
@@ -419,12 +435,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
419 435
420 public void Process() 436 public void Process()
421 { 437 {
422 httpThread = new Thread(SendRequest); 438 SendRequest();
423 httpThread.Name = "HttpRequestThread";
424 httpThread.Priority = ThreadPriority.BelowNormal;
425 httpThread.IsBackground = true;
426 _finished = false;
427 httpThread.Start();
428 } 439 }
429 440
430 /* 441 /*
@@ -435,10 +446,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
435 public void SendRequest() 446 public void SendRequest()
436 { 447 {
437 HttpWebResponse response = null; 448 HttpWebResponse response = null;
438 StringBuilder sb = new StringBuilder();
439 byte[] buf = new byte[8192];
440 string tempString = null;
441 int count = 0;
442 449
443 try 450 try
444 { 451 {
@@ -497,11 +504,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
497 bstream.Close(); 504 bstream.Close();
498 } 505 }
499 506
500 Request.Timeout = HttpTimeout;
501 try 507 try
502 { 508 {
503 // execute the request 509 IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null);
504 response = (HttpWebResponse) Request.GetResponse(); 510
511 ThreadPool.RegisterWaitForSingleObject(
512 result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
505 } 513 }
506 catch (WebException e) 514 catch (WebException e)
507 { 515 {
@@ -510,11 +518,31 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
510 throw; 518 throw;
511 } 519 }
512 response = (HttpWebResponse)e.Response; 520 response = (HttpWebResponse)e.Response;
521 _finished = true;
513 } 522 }
523 }
524 catch (Exception e)
525 {
526 Status = (int)OSHttpStatusCode.ClientErrorJoker;
527 ResponseBody = e.Message;
528 _finished = true;
529 }
530 }
514 531
532 private void ResponseCallback(IAsyncResult ar)
533 {
534 HttpWebResponse response = null;
535
536 try
537 {
538 response = (HttpWebResponse)Request.EndGetResponse(ar);
515 Status = (int)response.StatusCode; 539 Status = (int)response.StatusCode;
516 540
517 Stream resStream = response.GetResponseStream(); 541 Stream resStream = response.GetResponseStream();
542 StringBuilder sb = new StringBuilder();
543 byte[] buf = new byte[8192];
544 string tempString = null;
545 int count = 0;
518 546
519 do 547 do
520 { 548 {
@@ -530,36 +558,40 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
530 // continue building the string 558 // continue building the string
531 sb.Append(tempString); 559 sb.Append(tempString);
532 } 560 }
533 } while (count > 0); // any more data to read? 561 }
562 while (count > 0); // any more data to read?
534 563
535 ResponseBody = sb.ToString(); 564 ResponseBody = sb.ToString();
536 } 565 }
537 catch (Exception e) 566 catch (Exception e)
538 { 567 {
539 Status = (int)OSHttpStatusCode.ClientErrorJoker; 568 Status = (int)OSHttpStatusCode.ClientErrorJoker;
540 ResponseBody = e.Message; 569 ResponseBody = e.Message;
541 570
542 _finished = true; 571// m_log.Debug(
543 return; 572// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on response to {0} for {1} ", Url, ItemID), e);
544 } 573 }
545 finally 574 finally
546 { 575 {
547 if (response != null) 576 if (response != null)
548 response.Close(); 577 response.Close();
578
579 _finished = true;
549 } 580 }
581 }
550 582
551 _finished = true; 583 private void TimeoutCallback(object state, bool timedOut)
584 {
585 if (timedOut)
586 Request.Abort();
552 } 587 }
553 588
554 public void Stop() 589 public void Stop()
555 { 590 {
556 try 591// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID);
557 { 592
558 httpThread.Abort(); 593 if (Request != null)
559 } 594 Request.Abort();
560 catch (Exception)
561 {
562 }
563 } 595 }
564 } 596 }
565} 597}
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
index eb6c5ac..113dcd7 100644
--- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
+++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
@@ -45,7 +45,13 @@ namespace OpenSim.Region.Framework.Interfaces
45 { 45 {
46 UUID MakeHttpRequest(string url, string parameters, string body); 46 UUID MakeHttpRequest(string url, string parameters, string body);
47 UUID StartHttpRequest(uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body); 47 UUID StartHttpRequest(uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body);
48 void StopHttpRequest(uint m_localID, UUID m_itemID); 48
49 /// <summary>
50 /// Stop and remove all http requests for the given script.
51 /// </summary>
52 /// <param name='id'></param>
53 void StopHttpRequestsForScript(UUID id);
54
49 IServiceRequest GetNextCompletedRequest(); 55 IServiceRequest GetNextCompletedRequest();
50 void RemoveCompletedRequest(UUID id); 56 void RemoveCompletedRequest(UUID id);
51 } 57 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..1c59624 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -28,7 +28,9 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
31using System.Threading; 32using System.Threading;
33using log4net;
32using OpenMetaverse; 34using OpenMetaverse;
33using OpenSim.Framework; 35using OpenSim.Framework;
34using OpenSim.Framework.Monitoring; 36using OpenSim.Framework.Monitoring;
@@ -45,6 +47,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
45 /// </summary> 47 /// </summary>
46 public class AsyncCommandManager 48 public class AsyncCommandManager
47 { 49 {
50// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
48 private static Thread cmdHandlerThread; 52 private static Thread cmdHandlerThread;
49 private static int cmdHandlerThreadCycleSleepms; 53 private static int cmdHandlerThreadCycleSleepms;
50 54
@@ -225,6 +229,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
225 /// <param name="itemID"></param> 229 /// <param name="itemID"></param>
226 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID) 230 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID)
227 { 231 {
232// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
233
228 // Remove a specific script 234 // Remove a specific script
229 235
230 // Remove dataserver events 236 // Remove dataserver events
@@ -236,7 +242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 // Remove from: HttpRequest 242 // Remove from: HttpRequest
237 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>(); 243 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
238 if (iHttpReq != null) 244 if (iHttpReq != null)
239 iHttpReq.StopHttpRequest(localID, itemID); 245 iHttpReq.StopHttpRequestsForScript(itemID);
240 246
241 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>(); 247 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
242 if (comms != null) 248 if (comms != null)