aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs108
1 files changed, 73 insertions, 35 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 61afc76..5c05500 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -64,17 +64,25 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
64 public string uri; 64 public string uri;
65 } 65 }
66 66
67 /// <summary>
68 /// This module provides external URLs for in-world scripts.
69 /// </summary>
67 public class UrlModule : ISharedRegionModule, IUrlModule 70 public class UrlModule : ISharedRegionModule, IUrlModule
68 { 71 {
69 private static readonly ILog m_log = 72 private static readonly ILog m_log =
70 LogManager.GetLogger( 73 LogManager.GetLogger(
71 MethodBase.GetCurrentMethod().DeclaringType); 74 MethodBase.GetCurrentMethod().DeclaringType);
72 75
73 private Dictionary<UUID, UrlData> m_RequestMap = 76 /// <summary>
74 new Dictionary<UUID, UrlData>(); 77 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID
78 /// randomly generated when a request is received for this URL.
79 /// </summary>
80 private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
75 81
76 private Dictionary<string, UrlData> m_UrlMap = 82 /// <summary>
77 new Dictionary<string, UrlData>(); 83 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL
84 /// </summary>
85 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
78 86
79 /// <summary> 87 /// <summary>
80 /// Maximum number of external urls that can be set up by this module. 88 /// Maximum number of external urls that can be set up by this module.
@@ -224,7 +232,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
224 urlData.urlcode = urlcode; 232 urlData.urlcode = urlcode;
225 urlData.requests = new Dictionary<UUID, RequestData>(); 233 urlData.requests = new Dictionary<UUID, RequestData>();
226 234
227
228 m_UrlMap[url] = urlData; 235 m_UrlMap[url] = urlData;
229 236
230 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 237 string uri = "/lslhttps/" + urlcode.ToString() + "/";
@@ -286,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
286 { 293 {
287 if (m_RequestMap.ContainsKey(requestId)) 294 if (m_RequestMap.ContainsKey(requestId))
288 { 295 {
289 UrlData urlData=m_RequestMap[requestId]; 296 UrlData urlData = m_RequestMap[requestId];
290 string value; 297 string value;
291 if (urlData.requests[requestId].headers.TryGetValue(header,out value)) 298 if (urlData.requests[requestId].headers.TryGetValue(header,out value))
292 return value; 299 return value;
@@ -295,6 +302,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
295 { 302 {
296 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 303 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
297 } 304 }
305
298 return String.Empty; 306 return String.Empty;
299 } 307 }
300 308
@@ -339,6 +347,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
339 { 347 {
340 RemoveUrl(url.Value); 348 RemoveUrl(url.Value);
341 removeURLs.Add(url.Key); 349 removeURLs.Add(url.Key);
350
342 foreach (UUID req in url.Value.requests.Keys) 351 foreach (UUID req in url.Value.requests.Keys)
343 m_RequestMap.Remove(req); 352 m_RequestMap.Remove(req);
344 } 353 }
@@ -349,20 +358,31 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
349 } 358 }
350 } 359 }
351 360
352
353 private void RemoveUrl(UrlData data) 361 private void RemoveUrl(UrlData data)
354 { 362 {
355 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); 363 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/");
356 } 364 }
357 365
358 private Hashtable NoEvents(UUID requestID, UUID sessionID) 366 private Hashtable NoEvents(UUID requestID, UUID sessionID)
359 { 367 {
360 Hashtable response = new Hashtable(); 368 Hashtable response = new Hashtable();
361 UrlData url; 369 UrlData url;
370
362 lock (m_RequestMap) 371 lock (m_RequestMap)
363 { 372 {
373 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
374 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
375 // for the request ID.
364 if (!m_RequestMap.ContainsKey(requestID)) 376 if (!m_RequestMap.ContainsKey(requestID))
377 {
378 response["int_response_code"] = 404;
379 response["str_response_string"] = "";
380 response["keepalive"] = false;
381 response["reusecontext"] = false;
382
365 return response; 383 return response;
384 }
385
366 url = m_RequestMap[requestID]; 386 url = m_RequestMap[requestID];
367 } 387 }
368 388
@@ -384,53 +404,57 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
384 return response; 404 return response;
385 } 405 }
386 406
387
388 return response; 407 return response;
389 } 408 }
390 409
391 private bool HasEvents(UUID requestID, UUID sessionID) 410 private bool HasEvents(UUID requestID, UUID sessionID)
392 { 411 {
393 UrlData url=null; 412 UrlData url = null;
394 413
395 lock (m_RequestMap) 414 lock (m_RequestMap)
396 { 415 {
416 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
417 // can still make it through to HttpRequestHandler(). That will return without setting up a request
418 // when it detects that the URL has been removed. The poller, however, will continue to ask for
419 // events for that request, so here we will signal that there are events and in GetEvents we will
420 // return a 404.
397 if (!m_RequestMap.ContainsKey(requestID)) 421 if (!m_RequestMap.ContainsKey(requestID))
398 { 422 {
399 return false; 423 return true;
400 } 424 }
425
401 url = m_RequestMap[requestID]; 426 url = m_RequestMap[requestID];
402 if (!url.requests.ContainsKey(requestID)) 427 if (!url.requests.ContainsKey(requestID))
403 { 428 {
404 return false; 429 return true;
405 } 430 }
406 } 431 }
407 432
408 if (System.Environment.TickCount-url.requests[requestID].startTime>25000) 433 // Trigger return of timeout response.
434 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
409 { 435 {
410 return true; 436 return true;
411 } 437 }
412 438
413 if (url.requests[requestID].requestDone) 439 return url.requests[requestID].requestDone;
414 return true;
415 else
416 return false;
417
418 } 440 }
441
419 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) 442 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
420 { 443 {
421 UrlData url = null; 444 UrlData url = null;
422 RequestData requestData = null; 445 RequestData requestData = null;
423 446
424 lock (m_RequestMap) 447 lock (m_RequestMap)
425 { 448 {
426 if (!m_RequestMap.ContainsKey(requestID)) 449 if (!m_RequestMap.ContainsKey(requestID))
427 return NoEvents(requestID,sessionID); 450 return NoEvents(requestID, sessionID);
451
428 url = m_RequestMap[requestID]; 452 url = m_RequestMap[requestID];
429 requestData = url.requests[requestID]; 453 requestData = url.requests[requestID];
430 } 454 }
431 455
432 if (!requestData.requestDone) 456 if (!requestData.requestDone)
433 return NoEvents(requestID,sessionID); 457 return NoEvents(requestID, sessionID);
434 458
435 Hashtable response = new Hashtable(); 459 Hashtable response = new Hashtable();
436 460
@@ -443,6 +467,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
443 response["reusecontext"] = false; 467 response["reusecontext"] = false;
444 return response; 468 return response;
445 } 469 }
470
446 //put response 471 //put response
447 response["int_response_code"] = requestData.responseCode; 472 response["int_response_code"] = requestData.responseCode;
448 response["str_response_string"] = requestData.responseBody; 473 response["str_response_string"] = requestData.responseBody;
@@ -459,6 +484,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
459 484
460 return response; 485 return response;
461 } 486 }
487
462 public void HttpRequestHandler(UUID requestID, Hashtable request) 488 public void HttpRequestHandler(UUID requestID, Hashtable request)
463 { 489 {
464 lock (request) 490 lock (request)
@@ -483,11 +509,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
483 509
484 pathInfo = uri.Substring(pos3); 510 pathInfo = uri.Substring(pos3);
485 511
486 UrlData url = null; 512 UrlData urlData = null;
487 if (!is_ssl) 513
488 url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp]; 514 lock (m_UrlMap)
489 else 515 {
490 url = m_UrlMap["https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp]; 516 string url;
517
518 if (is_ssl)
519 url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
520 else
521 url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
522
523 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this
524 // request was being processed.
525 if (!m_UrlMap.TryGetValue(url, out urlData))
526 return;
527 }
491 528
492 //for llGetHttpHeader support we need to store original URI here 529 //for llGetHttpHeader support we need to store original URI here
493 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 530 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -520,11 +557,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
520 queryString = queryString + key + "=" + val + "&"; 557 queryString = queryString + key + "=" + val + "&";
521 } 558 }
522 } 559 }
560
523 if (queryString.Length > 1) 561 if (queryString.Length > 1)
524 queryString = queryString.Substring(0, queryString.Length - 1); 562 queryString = queryString.Substring(0, queryString.Length - 1);
525
526 } 563 }
527
528 } 564 }
529 565
530 //if this machine is behind DNAT/port forwarding, currently this is being 566 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -532,26 +568,28 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
532 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 568 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
533 requestData.headers["x-path-info"] = pathInfo; 569 requestData.headers["x-path-info"] = pathInfo;
534 requestData.headers["x-query-string"] = queryString; 570 requestData.headers["x-query-string"] = queryString;
535 requestData.headers["x-script-url"] = url.url; 571 requestData.headers["x-script-url"] = urlData.url;
536 572
537 //requestData.ev = new ManualResetEvent(false); 573 //requestData.ev = new ManualResetEvent(false);
538 lock (url.requests) 574 lock (urlData.requests)
539 { 575 {
540 url.requests.Add(requestID, requestData); 576 urlData.requests.Add(requestID, requestData);
541 } 577 }
578
542 lock (m_RequestMap) 579 lock (m_RequestMap)
543 { 580 {
544 //add to request map 581 m_RequestMap.Add(requestID, urlData);
545 m_RequestMap.Add(requestID, url);
546 } 582 }
547 583
548 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 584 urlData.engine.PostScriptEvent(
585 urlData.itemID,
586 "http_request",
587 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
549 588
550 //send initial response? 589 //send initial response?
551// Hashtable response = new Hashtable(); 590// Hashtable response = new Hashtable();
552 591
553 return; 592 return;
554
555 } 593 }
556 catch (Exception we) 594 catch (Exception we)
557 { 595 {