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.cs180
1 files changed, 111 insertions, 69 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 6793fc8..6eb25ef 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;
@@ -45,6 +42,7 @@ using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
47using Mono.Addins; 44using Mono.Addins;
45using Amib.Threading;
48 46
49/***************************************************** 47/*****************************************************
50 * 48 *
@@ -105,6 +103,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
105 private Dictionary<UUID, HttpRequestClass> m_pendingRequests; 103 private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
106 private Scene m_scene; 104 private Scene m_scene;
107 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 105 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
106 public static SmartThreadPool ThreadPool = null;
108 107
109 public HttpRequestModule() 108 public HttpRequestModule()
110 { 109 {
@@ -253,29 +252,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
253 return reqID; 252 return reqID;
254 } 253 }
255 254
256 public void StopHttpRequestsForScript(UUID id) 255 public void StopHttpRequest(uint m_localID, UUID m_itemID)
257 { 256 {
258 if (m_pendingRequests != null) 257 if (m_pendingRequests != null)
259 { 258 {
260 List<UUID> keysToRemove = null;
261
262 lock (HttpListLock) 259 lock (HttpListLock)
263 { 260 {
264 foreach (HttpRequestClass req in m_pendingRequests.Values) 261 HttpRequestClass tmpReq;
262 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
265 { 263 {
266 if (req.ItemID == id) 264 tmpReq.Stop();
267 { 265 m_pendingRequests.Remove(m_itemID);
268 req.Stop();
269
270 if (keysToRemove == null)
271 keysToRemove = new List<UUID>();
272
273 keysToRemove.Add(req.ReqID);
274 }
275 } 266 }
276
277 if (keysToRemove != null)
278 keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
279 } 267 }
280 } 268 }
281 } 269 }
@@ -293,13 +281,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
293 { 281 {
294 lock (HttpListLock) 282 lock (HttpListLock)
295 { 283 {
296 foreach (HttpRequestClass req in m_pendingRequests.Values) 284 foreach (UUID luid in m_pendingRequests.Keys)
297 { 285 {
298 if (req.Finished) 286 HttpRequestClass tmpReq;
299 return req; 287
288 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
289 {
290 if (tmpReq.Finished)
291 {
292 return tmpReq;
293 }
294 }
300 } 295 }
301 } 296 }
302
303 return null; 297 return null;
304 } 298 }
305 299
@@ -326,7 +320,30 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
326 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 320 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
327 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 321 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
328 322
323 int maxThreads = 50;
324
325 IConfig httpConfig = config.Configs["HttpRequestModule"];
326 if (httpConfig != null)
327 {
328 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
329 }
330
329 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 331 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
332
333 // First instance sets this up for all sims
334 if (ThreadPool == null)
335 {
336 STPStartInfo startInfo = new STPStartInfo();
337 startInfo.IdleTimeout = 20000;
338 startInfo.MaxWorkerThreads = maxThreads;
339 startInfo.MinWorkerThreads = 5;
340 startInfo.ThreadPriority = ThreadPriority.BelowNormal;
341 startInfo.StartSuspended = true;
342
343 ThreadPool = new SmartThreadPool(startInfo);
344
345 ThreadPool.Start();
346 }
330 } 347 }
331 348
332 public void AddRegion(Scene scene) 349 public void AddRegion(Scene scene)
@@ -370,8 +387,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
370 387
371 public class HttpRequestClass: IServiceRequest 388 public class HttpRequestClass: IServiceRequest
372 { 389 {
373// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
374
375 // Constants for parameters 390 // Constants for parameters
376 // public const int HTTP_BODY_MAXLENGTH = 2; 391 // public const int HTTP_BODY_MAXLENGTH = 2;
377 // public const int HTTP_METHOD = 0; 392 // public const int HTTP_METHOD = 0;
@@ -392,6 +407,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
392 public string HttpMIMEType = "text/plain;charset=utf-8"; 407 public string HttpMIMEType = "text/plain;charset=utf-8";
393 public int HttpTimeout; 408 public int HttpTimeout;
394 public bool HttpVerifyCert = true; 409 public bool HttpVerifyCert = true;
410 public IWorkItemResult WorkItem = null;
411
395 //public bool HttpVerboseThrottle = true; // not implemented 412 //public bool HttpVerboseThrottle = true; // not implemented
396 public List<string> HttpCustomHeaders = null; 413 public List<string> HttpCustomHeaders = null;
397 public bool HttpPragmaNoCache = true; 414 public bool HttpPragmaNoCache = true;
@@ -428,7 +445,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
428 445
429 public void Process() 446 public void Process()
430 { 447 {
448 _finished = false;
449
450 lock (HttpRequestModule.ThreadPool)
451 WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
452 }
453
454 private object StpSendWrapper(object o)
455 {
431 SendRequest(); 456 SendRequest();
457 return null;
432 } 458 }
433 459
434 /* 460 /*
@@ -439,10 +465,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
439 public void SendRequest() 465 public void SendRequest()
440 { 466 {
441 HttpWebResponse response = null; 467 HttpWebResponse response = null;
468 StringBuilder sb = new StringBuilder();
469 byte[] buf = new byte[8192];
470 string tempString = null;
471 int count = 0;
442 472
443 try 473 try
444 { 474 {
445 Request = (HttpWebRequest) WebRequest.Create(Url); 475 Request = (HttpWebRequest) WebRequest.Create(Url);
476
477 //This works around some buggy HTTP Servers like Lighttpd
478 Request.ServicePoint.Expect100Continue = false;
479
446 Request.Method = HttpMethod; 480 Request.Method = HttpMethod;
447 Request.ContentType = HttpMIMEType; 481 Request.ContentType = HttpMIMEType;
448 482
@@ -450,7 +484,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
450 { 484 {
451 // We could hijack Connection Group Name to identify 485 // We could hijack Connection Group Name to identify
452 // a desired security exception. But at the moment we'll use a dummy header instead. 486 // a desired security exception. But at the moment we'll use a dummy header instead.
453// Request.ConnectionGroupName = "NoVerify";
454 Request.Headers.Add("NoVerifyCert", "true"); 487 Request.Headers.Add("NoVerifyCert", "true");
455 } 488 }
456// else 489// else
@@ -497,12 +530,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
497 bstream.Close(); 530 bstream.Close();
498 } 531 }
499 532
533 Request.Timeout = HttpTimeout;
500 try 534 try
501 { 535 {
502 IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null); 536 // execute the request
503 537 response = (HttpWebResponse) Request.GetResponse();
504 ThreadPool.RegisterWaitForSingleObject(
505 result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
506 } 538 }
507 catch (WebException e) 539 catch (WebException e)
508 { 540 {
@@ -511,31 +543,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
511 throw; 543 throw;
512 } 544 }
513 response = (HttpWebResponse)e.Response; 545 response = (HttpWebResponse)e.Response;
514 _finished = true;
515 } 546 }
516 }
517 catch (Exception e)
518 {
519 Status = (int)OSHttpStatusCode.ClientErrorJoker;
520 ResponseBody = e.Message;
521 _finished = true;
522 }
523 }
524 547
525 private void ResponseCallback(IAsyncResult ar)
526 {
527 HttpWebResponse response = null;
528
529 try
530 {
531 response = (HttpWebResponse)Request.EndGetResponse(ar);
532 Status = (int)response.StatusCode; 548 Status = (int)response.StatusCode;
533 549
534 Stream resStream = response.GetResponseStream(); 550 Stream resStream = response.GetResponseStream();
535 StringBuilder sb = new StringBuilder();
536 byte[] buf = new byte[8192];
537 string tempString = null;
538 int count = 0;
539 551
540 do 552 do
541 { 553 {
@@ -550,41 +562,71 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
550 562
551 // continue building the string 563 // continue building the string
552 sb.Append(tempString); 564 sb.Append(tempString);
565 if (sb.Length > 2048)
566 break;
553 } 567 }
554 } 568 } while (count > 0); // any more data to read?
555 while (count > 0); // any more data to read?
556 569
557 ResponseBody = sb.ToString(); 570 ResponseBody = sb.ToString().Replace("\r", "");
558 } 571 }
559 catch (Exception e) 572 catch (WebException e)
560 { 573 {
561 Status = (int)OSHttpStatusCode.ClientErrorJoker; 574 if (e.Status == WebExceptionStatus.ProtocolError)
562 ResponseBody = e.Message; 575 {
576 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
577 Status = (int)webRsp.StatusCode;
578 try
579 {
580 using (Stream responseStream = webRsp.GetResponseStream())
581 {
582 ResponseBody = responseStream.GetStreamString();
583 }
584 }
585 catch
586 {
587 ResponseBody = webRsp.StatusDescription;
588 }
589 }
590 else
591 {
592 Status = (int)OSHttpStatusCode.ClientErrorJoker;
593 ResponseBody = e.Message;
594 }
563 595
564// m_log.Debug( 596 if (ResponseBody == null)
565// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on response to {0} for {1} ", Url, ItemID), e); 597 ResponseBody = String.Empty;
598
599 _finished = true;
600 return;
601 }
602 catch (Exception e)
603 {
604 // Don't crash on anything else
566 } 605 }
567 finally 606 finally
568 { 607 {
569 if (response != null) 608 if (response != null)
570 response.Close(); 609 response.Close();
571
572 _finished = true;
573 } 610 }
574 }
575 611
576 private void TimeoutCallback(object state, bool timedOut) 612 if (ResponseBody == null)
577 { 613 ResponseBody = String.Empty;
578 if (timedOut) 614
579 Request.Abort(); 615 _finished = true;
580 } 616 }
581 617
582 public void Stop() 618 public void Stop()
583 { 619 {
584// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID); 620 try
585 621 {
586 if (Request != null) 622 if (!WorkItem.Cancel())
587 Request.Abort(); 623 {
624 WorkItem.Cancel(true);
625 }
626 }
627 catch (Exception)
628 {
629 }
588 } 630 }
589 } 631 }
590} 632}