diff options
author | Justin Clark-Casey (justincc) | 2013-04-04 00:36:15 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-04-04 00:36:15 +0100 |
commit | 831e4c38506140e9ece2db4b96b4f0960a0276a8 (patch) | |
tree | 8a341213d3da08c85a07c62145db0fcecaedad07 /OpenSim/Region/CoreModules/Scripting/HttpRequest | |
parent | minor: Stop falsely logging that a teleport was being aborted on client logou... (diff) | |
download | opensim-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/CoreModules/Scripting/HttpRequest')
-rw-r--r-- | OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | 92 |
1 files changed, 62 insertions, 30 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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Linq; | ||
31 | using System.Net; | 32 | using System.Net; |
32 | using System.Net.Mail; | 33 | using System.Net.Mail; |
33 | using System.Net.Security; | 34 | using System.Net.Security; |
35 | using System.Reflection; | ||
34 | using System.Text; | 36 | using System.Text; |
35 | using System.Threading; | 37 | using System.Threading; |
36 | using System.Security.Cryptography.X509Certificates; | 38 | using System.Security.Cryptography.X509Certificates; |
39 | using log4net; | ||
37 | using Nini.Config; | 40 | using Nini.Config; |
38 | using OpenMetaverse; | 41 | using OpenMetaverse; |
39 | using OpenSim.Framework; | 42 | using 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 | } |