aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs233
1 files changed, 146 insertions, 87 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index b1f3f9b..235fbbb 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -28,15 +28,12 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Linq;
32using System.Net; 31using System.Net;
33using System.Net.Mail; 32using System.Net.Mail;
34using System.Net.Security; 33using System.Net.Security;
35using System.Reflection;
36using System.Text; 34using System.Text;
37using System.Threading; 35using System.Threading;
38using System.Security.Cryptography.X509Certificates; 36using System.Security.Cryptography.X509Certificates;
39using log4net;
40using Nini.Config; 37using Nini.Config;
41using OpenMetaverse; 38using OpenMetaverse;
42using OpenSim.Framework; 39using OpenSim.Framework;
@@ -46,6 +43,7 @@ using OpenSim.Framework.Servers.HttpServer;
46using OpenSim.Region.Framework.Interfaces; 43using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes; 44using OpenSim.Region.Framework.Scenes;
48using Mono.Addins; 45using Mono.Addins;
46using Amib.Threading;
49 47
50/***************************************************** 48/*****************************************************
51 * 49 *
@@ -109,6 +107,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
109 private Dictionary<UUID, HttpRequestClass> m_pendingRequests; 107 private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
110 private Scene m_scene; 108 private Scene m_scene;
111 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 109 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
110 public static SmartThreadPool ThreadPool = null;
112 111
113 public HttpRequestModule() 112 public HttpRequestModule()
114 { 113 {
@@ -291,29 +290,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
291 return true; 290 return true;
292 } 291 }
293 292
294 public void StopHttpRequestsForScript(UUID id) 293 public void StopHttpRequest(uint m_localID, UUID m_itemID)
295 { 294 {
296 if (m_pendingRequests != null) 295 if (m_pendingRequests != null)
297 { 296 {
298 List<UUID> keysToRemove = null;
299
300 lock (HttpListLock) 297 lock (HttpListLock)
301 { 298 {
302 foreach (HttpRequestClass req in m_pendingRequests.Values) 299 HttpRequestClass tmpReq;
300 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
303 { 301 {
304 if (req.ItemID == id) 302 tmpReq.Stop();
305 { 303 m_pendingRequests.Remove(m_itemID);
306 req.Stop();
307
308 if (keysToRemove == null)
309 keysToRemove = new List<UUID>();
310
311 keysToRemove.Add(req.ReqID);
312 }
313 } 304 }
314
315 if (keysToRemove != null)
316 keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
317 } 305 }
318 } 306 }
319 } 307 }
@@ -331,13 +319,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
331 { 319 {
332 lock (HttpListLock) 320 lock (HttpListLock)
333 { 321 {
334 foreach (HttpRequestClass req in m_pendingRequests.Values) 322 foreach (UUID luid in m_pendingRequests.Keys)
335 { 323 {
336 if (req.Finished) 324 HttpRequestClass tmpReq;
337 return req; 325
326 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
327 {
328 if (tmpReq.Finished)
329 {
330 return tmpReq;
331 }
332 }
338 } 333 }
339 } 334 }
340
341 return null; 335 return null;
342 } 336 }
343 337
@@ -364,9 +358,34 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
364 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 358 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
365 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 359 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
366 360
361<<<<<<< HEAD
367 m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); 362 m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config);
363=======
364 int maxThreads = 15;
365
366 IConfig httpConfig = config.Configs["HttpRequestModule"];
367 if (httpConfig != null)
368 {
369 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
370 }
371>>>>>>> avn/ubitvar
368 372
369 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 373 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
374
375 // First instance sets this up for all sims
376 if (ThreadPool == null)
377 {
378 STPStartInfo startInfo = new STPStartInfo();
379 startInfo.IdleTimeout = 20000;
380 startInfo.MaxWorkerThreads = maxThreads;
381 startInfo.MinWorkerThreads = 1;
382 startInfo.ThreadPriority = ThreadPriority.BelowNormal;
383 startInfo.StartSuspended = true;
384 startInfo.ThreadPoolName = "ScriptsHttpReq";
385
386 ThreadPool = new SmartThreadPool(startInfo);
387 ThreadPool.Start();
388 }
370 } 389 }
371 390
372 public void AddRegion(Scene scene) 391 public void AddRegion(Scene scene)
@@ -410,8 +429,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
410 429
411 public class HttpRequestClass : IServiceRequest 430 public class HttpRequestClass : IServiceRequest
412 { 431 {
413// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
414
415 // Constants for parameters 432 // Constants for parameters
416 // public const int HTTP_BODY_MAXLENGTH = 2; 433 // public const int HTTP_BODY_MAXLENGTH = 2;
417 // public const int HTTP_METHOD = 0; 434 // public const int HTTP_METHOD = 0;
@@ -438,6 +455,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
438 public string HttpMIMEType = "text/plain;charset=utf-8"; 455 public string HttpMIMEType = "text/plain;charset=utf-8";
439 public int HttpTimeout; 456 public int HttpTimeout;
440 public bool HttpVerifyCert = true; 457 public bool HttpVerifyCert = true;
458 public IWorkItemResult WorkItem = null;
459
441 //public bool HttpVerboseThrottle = true; // not implemented 460 //public bool HttpVerboseThrottle = true; // not implemented
442 public List<string> HttpCustomHeaders = null; 461 public List<string> HttpCustomHeaders = null;
443 public bool HttpPragmaNoCache = true; 462 public bool HttpPragmaNoCache = true;
@@ -485,15 +504,44 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
485 504
486 public void Process() 505 public void Process()
487 { 506 {
507 _finished = false;
508
509 lock (HttpRequestModule.ThreadPool)
510 WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
511 }
512
513 private object StpSendWrapper(object o)
514 {
488 SendRequest(); 515 SendRequest();
516 return null;
489 } 517 }
490 518
519 /*
520 * TODO: More work on the response codes. Right now
521 * returning 200 for success or 499 for exception
522 */
523
491 public void SendRequest() 524 public void SendRequest()
492 { 525 {
526 HttpWebResponse response = null;
527 Stream resStream = null;
528 StringBuilder sb = new StringBuilder();
529 byte[] buf = new byte[8192];
530 string tempString = null;
531 int count = 0;
532
493 try 533 try
494 { 534 {
535<<<<<<< HEAD
495 Request = (HttpWebRequest)WebRequest.Create(Url); 536 Request = (HttpWebRequest)WebRequest.Create(Url);
496 Request.AllowAutoRedirect = false; 537 Request.AllowAutoRedirect = false;
538=======
539 Request = (HttpWebRequest) WebRequest.Create(Url);
540
541 //This works around some buggy HTTP Servers like Lighttpd
542 Request.ServicePoint.Expect100Continue = false;
543
544>>>>>>> avn/ubitvar
497 Request.Method = HttpMethod; 545 Request.Method = HttpMethod;
498 Request.ContentType = HttpMIMEType; 546 Request.ContentType = HttpMIMEType;
499 547
@@ -501,7 +549,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
501 { 549 {
502 // We could hijack Connection Group Name to identify 550 // We could hijack Connection Group Name to identify
503 // a desired security exception. But at the moment we'll use a dummy header instead. 551 // a desired security exception. But at the moment we'll use a dummy header instead.
504// Request.ConnectionGroupName = "NoVerify";
505 Request.Headers.Add("NoVerifyCert", "true"); 552 Request.Headers.Add("NoVerifyCert", "true");
506 } 553 }
507// else 554// else
@@ -534,14 +581,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
534 } 581 }
535 } 582 }
536 583
537 if (ResponseHeaders != null) 584 foreach (KeyValuePair<string, string> entry in ResponseHeaders)
538 { 585 if (entry.Key.ToLower().Equals("user-agent"))
539 foreach (KeyValuePair<string, string> entry in ResponseHeaders) 586 Request.UserAgent = entry.Value;
540 if (entry.Key.ToLower().Equals("user-agent") && Request is HttpWebRequest) 587 else
541 ((HttpWebRequest)Request).UserAgent = entry.Value; 588 Request.Headers[entry.Key] = entry.Value;
542 else
543 Request.Headers[entry.Key] = entry.Value;
544 }
545 589
546 // Encode outbound data 590 // Encode outbound data
547 if (!string.IsNullOrEmpty(OutboundBody)) 591 if (!string.IsNullOrEmpty(OutboundBody))
@@ -553,12 +597,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
553 bstream.Write(data, 0, data.Length); 597 bstream.Write(data, 0, data.Length);
554 } 598 }
555 599
600 Request.Timeout = HttpTimeout;
556 try 601 try
557 { 602 {
558 IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null); 603 // execute the request
559 604 response = (HttpWebResponse) Request.GetResponse();
560 ThreadPool.RegisterWaitForSingleObject(
561 result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
562 } 605 }
563 catch (WebException e) 606 catch (WebException e)
564 { 607 {
@@ -566,65 +609,74 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
566 { 609 {
567 throw; 610 throw;
568 } 611 }
612 response = (HttpWebResponse)e.Response;
613 }
569 614
570 HttpWebResponse response = (HttpWebResponse)e.Response; 615 Status = (int)response.StatusCode;
571 616
572 Status = (int)response.StatusCode; 617 resStream = response.GetResponseStream();
573 ResponseBody = response.StatusDescription;
574 _finished = true;
575 }
576 }
577 catch (Exception e)
578 {
579// m_log.Debug(
580// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on request to {0} for {1} ", Url, ItemID), e);
581 618
582 Status = (int)OSHttpStatusCode.ClientErrorJoker; 619 do
583 ResponseBody = e.Message; 620 {
584 _finished = true; 621 // fill the buffer with data
585 } 622 count = resStream.Read(buf, 0, buf.Length);
586 }
587 623
588 private void ResponseCallback(IAsyncResult ar) 624 // make sure we read some data
589 { 625 if (count != 0)
590 HttpWebResponse response = null; 626 {
627 // translate from bytes to ASCII text
628 tempString = Util.UTF8.GetString(buf, 0, count);
591 629
592 try 630 // continue building the string
631 sb.Append(tempString);
632 if (sb.Length > 2048)
633 break;
634 }
635 } while (count > 0); // any more data to read?
636
637 ResponseBody = sb.ToString().Replace("\r", "");
638 }
639 catch (WebException e)
593 { 640 {
594 try 641 if (e.Status == WebExceptionStatus.ProtocolError)
595 {
596 response = (HttpWebResponse)Request.EndGetResponse(ar);
597 }
598 catch (WebException e)
599 { 642 {
600 if (e.Status != WebExceptionStatus.ProtocolError) 643 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
644 Status = (int)webRsp.StatusCode;
645 try
601 { 646 {
602 throw; 647 using (Stream responseStream = webRsp.GetResponseStream())
648 {
649 ResponseBody = responseStream.GetStreamString();
650 }
603 } 651 }
604 652 catch
605 response = (HttpWebResponse)e.Response; 653 {
654 ResponseBody = webRsp.StatusDescription;
655 }
656 }
657 else
658 {
659 Status = (int)OSHttpStatusCode.ClientErrorJoker;
660 ResponseBody = e.Message;
606 } 661 }
607 662
608 Status = (int)response.StatusCode; 663 if (ResponseBody == null)
664 ResponseBody = String.Empty;
609 665
610 using (Stream stream = response.GetResponseStream()) 666 _finished = true;
611 { 667 return;
612 StreamReader reader = new StreamReader(stream, Encoding.UTF8);
613 ResponseBody = reader.ReadToEnd();
614 }
615 } 668 }
616 catch (Exception e) 669 catch (Exception e)
617 { 670 {
618 Status = (int)OSHttpStatusCode.ClientErrorJoker; 671 // Don't crash on anything else
619 ResponseBody = e.Message;
620
621// m_log.Debug(
622// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on response to {0} for {1} ", Url, ItemID), e);
623 } 672 }
624 finally 673 finally
625 { 674 {
675 if (resStream != null)
676 resStream.Close();
626 if (response != null) 677 if (response != null)
627 response.Close(); 678 response.Close();
679<<<<<<< HEAD
628 680
629 // We need to resubmit 681 // We need to resubmit
630 if ( 682 if (
@@ -672,21 +724,28 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
672 { 724 {
673 _finished = true; 725 _finished = true;
674 } 726 }
727=======
728>>>>>>> avn/ubitvar
675 } 729 }
676 }
677 730
678 private void TimeoutCallback(object state, bool timedOut) 731 if (ResponseBody == null)
679 { 732 ResponseBody = String.Empty;
680 if (timedOut) 733
681 Request.Abort(); 734 _finished = true;
682 } 735 }
683 736
684 public void Stop() 737 public void Stop()
685 { 738 {
686// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID); 739 try
687 740 {
688 if (Request != null) 741 if (!WorkItem.Cancel())
689 Request.Abort(); 742 {
743 WorkItem.Cancel(true);
744 }
745 }
746 catch (Exception)
747 {
748 }
690 } 749 }
691 } 750 }
692} \ No newline at end of file 751}