aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs542
1 files changed, 326 insertions, 216 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 99a3122..11fc513 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -26,10 +26,11 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
30using System.Collections.Generic; 29using System.Collections.Generic;
31using System.Collections; 30using System.Collections;
32using System.Reflection; 31using System.Reflection;
32using System.Net;
33using System.Net.Sockets;
33using log4net; 34using log4net;
34using Mono.Addins; 35using Mono.Addins;
35using Nini.Config; 36using Nini.Config;
@@ -42,40 +43,17 @@ using OpenSim.Region.Framework.Scenes;
42 43
43namespace OpenSim.Region.CoreModules.Scripting.LSLHttp 44namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
44{ 45{
45 /// <summary>
46 /// Data describing an external URL set up by a script.
47 /// </summary>
48 public class UrlData 46 public class UrlData
49 { 47 {
50 /// <summary>
51 /// Scene object part hosting the script
52 /// </summary>
53 public UUID hostID; 48 public UUID hostID;
54
55 /// <summary>
56 /// The item ID of the script that requested the URL.
57 /// </summary>
58 public UUID itemID; 49 public UUID itemID;
59
60 /// <summary>
61 /// The script engine that runs the script.
62 /// </summary>
63 public IScriptModule engine; 50 public IScriptModule engine;
64
65 /// <summary>
66 /// The generated URL.
67 /// </summary>
68 public string url; 51 public string url;
69
70 /// <summary>
71 /// The random UUID component of the generated URL.
72 /// </summary>
73 public UUID urlcode; 52 public UUID urlcode;
74
75 /// <summary>
76 /// The external requests currently being processed or awaiting retrieval for this URL.
77 /// </summary>
78 public Dictionary<UUID, RequestData> requests; 53 public Dictionary<UUID, RequestData> requests;
54 public bool isSsl;
55 public Scene scene;
56 public bool allowXss;
79 } 57 }
80 58
81 public class RequestData 59 public class RequestData
@@ -89,7 +67,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
89 //public ManualResetEvent ev; 67 //public ManualResetEvent ev;
90 public bool requestDone; 68 public bool requestDone;
91 public int startTime; 69 public int startTime;
70 public bool responseSent;
92 public string uri; 71 public string uri;
72 public bool allowResponseType = false;
73 public UUID hostID;
74 public Scene scene;
93 } 75 }
94 76
95 /// <summary> 77 /// <summary>
@@ -102,40 +84,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
102 LogManager.GetLogger( 84 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 85 MethodBase.GetCurrentMethod().DeclaringType);
104 86
105 /// <summary> 87 protected Dictionary<UUID, UrlData> m_RequestMap =
106 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 88 new Dictionary<UUID, UrlData>();
107 /// randomly generated when a request is received for this URL.
108 /// </summary>
109 /// <remarks>
110 /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
111 /// m_UrlMap
112 /// </remarks>
113 private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
114 89
115 /// <summary> 90 protected Dictionary<string, UrlData> m_UrlMap =
116 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 91 new Dictionary<string, UrlData>();
117 /// </summary>
118 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
119 92
120 private uint m_HttpsPort = 0; 93 protected bool m_enabled = false;
121 private IHttpServer m_HttpServer = null; 94 protected string m_ErrorStr;
122 private IHttpServer m_HttpsServer = null; 95 protected uint m_HttpsPort = 0;
96 protected IHttpServer m_HttpServer = null;
97 protected IHttpServer m_HttpsServer = null;
123 98
124 public string ExternalHostNameForLSL { get; private set; } 99 public string ExternalHostNameForLSL { get; protected set; }
125 100
126 /// <summary> 101 /// <summary>
127 /// The default maximum number of urls 102 /// The default maximum number of urls
128 /// </summary> 103 /// </summary>
129 public const int DefaultTotalUrls = 100; 104 public const int DefaultTotalUrls = 15000;
130 105
131 /// <summary> 106 /// <summary>
132 /// Maximum number of external urls that can be set up by this module. 107 /// Maximum number of external urls that can be set up by this module.
133 /// </summary> 108 /// </summary>
134 public int TotalUrls { get; set; } 109 public int TotalUrls { get; set; }
135 110
136 public Type ReplaceableInterface 111 public Type ReplaceableInterface
137 { 112 {
138 get { return null; } 113 get { return typeof(IUrlModule); }
139 } 114 }
140 115
141 public string Name 116 public string Name
@@ -146,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
146 public void Initialise(IConfigSource config) 121 public void Initialise(IConfigSource config)
147 { 122 {
148 IConfig networkConfig = config.Configs["Network"]; 123 IConfig networkConfig = config.Configs["Network"];
124 m_enabled = false;
149 125
150 if (networkConfig != null) 126 if (networkConfig != null)
151 { 127 {
@@ -156,9 +132,31 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
156 if (ssl_enabled) 132 if (ssl_enabled)
157 m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort); 133 m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort);
158 } 134 }
135 else
136 {
137 m_ErrorStr = "[Network] configuration missing, HTTP listener for LSL disabled";
138 m_log.Warn("[URL MODULE]: " + m_ErrorStr);
139 return;
140 }
159 141
160 if (ExternalHostNameForLSL == null) 142 if (String.IsNullOrWhiteSpace(ExternalHostNameForLSL))
161 ExternalHostNameForLSL = System.Environment.MachineName; 143 {
144 m_ErrorStr = "ExternalHostNameForLSL not defined in configuration, HTTP listener for LSL disabled";
145 m_log.Warn("[URL MODULE]: " + m_ErrorStr);
146 return;
147 }
148
149 IPAddress ia = null;
150 ia = Util.GetHostFromDNS(ExternalHostNameForLSL);
151 if (ia == null)
152 {
153 m_ErrorStr = "Could not resolve ExternalHostNameForLSL, HTTP listener for LSL disabled";
154 m_log.Warn("[URL MODULE]: " + m_ErrorStr);
155 return;
156 }
157
158 m_enabled = true;
159 m_ErrorStr = String.Empty;
162 160
163 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 161 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
164 162
@@ -174,7 +172,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
174 172
175 public void AddRegion(Scene scene) 173 public void AddRegion(Scene scene)
176 { 174 {
177 if (m_HttpServer == null) 175 if (m_enabled && m_HttpServer == null)
178 { 176 {
179 // There can only be one 177 // There can only be one
180 // 178 //
@@ -204,21 +202,39 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
204 202
205 public void RemoveRegion(Scene scene) 203 public void RemoveRegion(Scene scene)
206 { 204 {
205 // Drop references to that scene
206 foreach (KeyValuePair<string, UrlData> kvp in m_UrlMap)
207 {
208 if (kvp.Value.scene == scene)
209 kvp.Value.scene = null;
210 }
211 foreach (KeyValuePair<UUID, UrlData> kvp in m_RequestMap)
212 {
213 if (kvp.Value.scene == scene)
214 kvp.Value.scene = null;
215 }
207 } 216 }
208 217
209 public void Close() 218 public void Close()
210 { 219 {
211 } 220 }
212 221
213 public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) 222 public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID, Hashtable options)
214 { 223 {
215 UUID urlcode = UUID.Random(); 224 UUID urlcode = UUID.Random();
216 225
226 if(!m_enabled)
227 {
228 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", m_ErrorStr });
229 return urlcode;
230 }
231
217 lock (m_UrlMap) 232 lock (m_UrlMap)
218 { 233 {
219 if (m_UrlMap.Count >= TotalUrls) 234 if (m_UrlMap.Count >= TotalUrls)
220 { 235 {
221 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 236 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED",
237 "Too many URLs already open" });
222 return urlcode; 238 return urlcode;
223 } 239 }
224 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 240 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/";
@@ -229,20 +245,26 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
229 urlData.engine = engine; 245 urlData.engine = engine;
230 urlData.url = url; 246 urlData.url = url;
231 urlData.urlcode = urlcode; 247 urlData.urlcode = urlcode;
248 urlData.isSsl = false;
232 urlData.requests = new Dictionary<UUID, RequestData>(); 249 urlData.requests = new Dictionary<UUID, RequestData>();
233 250 urlData.scene = host.ParentGroup.Scene;
251 urlData.allowXss = false;
252
253 if (options != null && options["allowXss"] != null)
254 urlData.allowXss = true;
255
234 m_UrlMap[url] = urlData; 256 m_UrlMap[url] = urlData;
235 257
236 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 258 string uri = "/lslhttp/" + urlcode.ToString() + "/";
237 259
238 PollServiceEventArgs args 260 PollServiceEventArgs args
239 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); 261 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
240 args.Type = PollServiceEventArgs.EventType.LslHttp; 262 args.Type = PollServiceEventArgs.EventType.LslHttp;
241 m_HttpServer.AddPollServiceHTTPHandler(uri, args); 263 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
242 264
243 m_log.DebugFormat( 265// m_log.DebugFormat(
244 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 266// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
245 uri, itemID, host.Name, host.LocalId); 267// uri, itemID, host.Name, host.LocalId);
246 268
247 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 269 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
248 } 270 }
@@ -250,10 +272,16 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
250 return urlcode; 272 return urlcode;
251 } 273 }
252 274
253 public UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID) 275 public UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID, Hashtable options)
254 { 276 {
255 UUID urlcode = UUID.Random(); 277 UUID urlcode = UUID.Random();
256 278
279 if(!m_enabled)
280 {
281 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", m_ErrorStr });
282 return urlcode;
283 }
284
257 if (m_HttpsServer == null) 285 if (m_HttpsServer == null)
258 { 286 {
259 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 287 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
@@ -264,7 +292,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
264 { 292 {
265 if (m_UrlMap.Count >= TotalUrls) 293 if (m_UrlMap.Count >= TotalUrls)
266 { 294 {
267 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 295 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED",
296 "Too many URLs already open" });
268 return urlcode; 297 return urlcode;
269 } 298 }
270 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 299 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/";
@@ -275,20 +304,25 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
275 urlData.engine = engine; 304 urlData.engine = engine;
276 urlData.url = url; 305 urlData.url = url;
277 urlData.urlcode = urlcode; 306 urlData.urlcode = urlcode;
307 urlData.isSsl = true;
278 urlData.requests = new Dictionary<UUID, RequestData>(); 308 urlData.requests = new Dictionary<UUID, RequestData>();
309 urlData.allowXss = false;
310
311 if (options != null && options["allowXss"] != null)
312 urlData.allowXss = true;
279 313
280 m_UrlMap[url] = urlData; 314 m_UrlMap[url] = urlData;
281 315
282 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 316 string uri = "/lslhttps/" + urlcode.ToString() + "/";
283 317
284 PollServiceEventArgs args 318 PollServiceEventArgs args
285 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); 319 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
286 args.Type = PollServiceEventArgs.EventType.LslHttp; 320 args.Type = PollServiceEventArgs.EventType.LslHttp;
287 m_HttpsServer.AddPollServiceHTTPHandler(uri, args); 321 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
288 322
289 m_log.DebugFormat( 323// m_log.DebugFormat(
290 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 324// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
291 uri, itemID, host.Name, host.LocalId); 325// uri, itemID, host.Name, host.LocalId);
292 326
293 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 327 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
294 } 328 }
@@ -307,18 +341,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
307 return; 341 return;
308 } 342 }
309 343
310 foreach (UUID req in data.requests.Keys) 344 lock (m_RequestMap)
311 m_RequestMap.Remove(req); 345 {
346 foreach (UUID req in data.requests.Keys)
347 m_RequestMap.Remove(req);
348 }
312 349
313 m_log.DebugFormat( 350// m_log.DebugFormat(
314 "[URL MODULE]: Releasing url {0} for {1} in {2}", 351// "[URL MODULE]: Releasing url {0} for {1} in {2}",
315 url, data.itemID, data.hostID); 352// url, data.itemID, data.hostID);
316 353
317 RemoveUrl(data); 354 RemoveUrl(data);
318 m_UrlMap.Remove(url); 355 m_UrlMap.Remove(url);
319 } 356 }
320 } 357 }
321 358
322 public void HttpContentType(UUID request, string type) 359 public void HttpContentType(UUID request, string type)
323 { 360 {
324 lock (m_UrlMap) 361 lock (m_UrlMap)
@@ -334,32 +371,42 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
334 } 371 }
335 } 372 }
336 } 373 }
337 374
338 public void HttpResponse(UUID request, int status, string body) 375 public void HttpResponse(UUID request, int status, string body)
339 { 376 {
340 lock (m_UrlMap) 377 lock (m_RequestMap)
341 { 378 {
342 if (m_RequestMap.ContainsKey(request)) 379 if (m_RequestMap.ContainsKey(request))
343 { 380 {
344 UrlData urlData = m_RequestMap[request]; 381 UrlData urlData = m_RequestMap[request];
345 string responseBody = body; 382 if (!urlData.requests[request].responseSent)
346 if (urlData.requests[request].responseType.Equals("text/plain"))
347 { 383 {
348 string value; 384 string responseBody = body;
349 if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) 385
386 // If we have no OpenID from built-in browser, disable this
387 if (!urlData.requests[request].allowResponseType)
388 urlData.requests[request].responseType = "text/plain";
389
390 if (urlData.requests[request].responseType.Equals("text/plain"))
350 { 391 {
351 if (value != null && value.IndexOf("MSIE") >= 0) 392 string value;
393 if (urlData.requests[request].headers.TryGetValue("user-agent", out value))
352 { 394 {
353 // wrap the html escaped response if the target client is IE 395 if (value != null && value.IndexOf("MSIE") >= 0)
354 // It ignores "text/plain" if the body is html 396 {
355 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>"; 397 // wrap the html escaped response if the target client is IE
398 // It ignores "text/plain" if the body is html
399 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>";
400 }
356 } 401 }
357 } 402 }
403
404 urlData.requests[request].responseCode = status;
405 urlData.requests[request].responseBody = responseBody;
406 //urlData.requests[request].ev.Set();
407 urlData.requests[request].requestDone = true;
408 urlData.requests[request].responseSent = true;
358 } 409 }
359 urlData.requests[request].responseCode = status;
360 urlData.requests[request].responseBody = responseBody;
361 //urlData.requests[request].ev.Set();
362 urlData.requests[request].requestDone =true;
363 } 410 }
364 else 411 else
365 { 412 {
@@ -370,7 +417,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
370 417
371 public string GetHttpHeader(UUID requestId, string header) 418 public string GetHttpHeader(UUID requestId, string header)
372 { 419 {
373 lock (m_UrlMap) 420 lock (m_RequestMap)
374 { 421 {
375 if (m_RequestMap.ContainsKey(requestId)) 422 if (m_RequestMap.ContainsKey(requestId))
376 { 423 {
@@ -384,7 +431,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
384 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 431 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
385 } 432 }
386 } 433 }
387
388 return String.Empty; 434 return String.Empty;
389 } 435 }
390 436
@@ -397,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
397 public void ScriptRemoved(UUID itemID) 443 public void ScriptRemoved(UUID itemID)
398 { 444 {
399// m_log.DebugFormat("[URL MODULE]: Removing script {0}", itemID); 445// m_log.DebugFormat("[URL MODULE]: Removing script {0}", itemID);
400 446
401 lock (m_UrlMap) 447 lock (m_UrlMap)
402 { 448 {
403 List<string> removeURLs = new List<string>(); 449 List<string> removeURLs = new List<string>();
@@ -408,8 +454,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
408 { 454 {
409 RemoveUrl(url.Value); 455 RemoveUrl(url.Value);
410 removeURLs.Add(url.Key); 456 removeURLs.Add(url.Key);
411 foreach (UUID req in url.Value.requests.Keys) 457 lock (m_RequestMap)
412 m_RequestMap.Remove(req); 458 {
459 foreach (UUID req in url.Value.requests.Keys)
460 m_RequestMap.Remove(req);
461 }
413 } 462 }
414 } 463 }
415 464
@@ -430,9 +479,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
430 { 479 {
431 RemoveUrl(url.Value); 480 RemoveUrl(url.Value);
432 removeURLs.Add(url.Key); 481 removeURLs.Add(url.Key);
433 482 lock (m_RequestMap)
434 foreach (UUID req in url.Value.requests.Keys) 483 {
435 m_RequestMap.Remove(req); 484 foreach (UUID req in url.Value.requests.Keys)
485 m_RequestMap.Remove(req);
486 }
436 } 487 }
437 } 488 }
438 489
@@ -441,123 +492,131 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
441 } 492 }
442 } 493 }
443 494
444 private void RemoveUrl(UrlData data) 495
496 protected void RemoveUrl(UrlData data)
445 { 497 {
446 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 498 if (data.isSsl)
499 m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
500 else
501 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
447 } 502 }
448 503
449 private Hashtable NoEvents(UUID requestID, UUID sessionID) 504 protected Hashtable NoEvents(UUID requestID, UUID sessionID)
450 { 505 {
451 Hashtable response = new Hashtable(); 506 Hashtable response = new Hashtable();
452 UrlData urlData; 507 UrlData url;
453 508 int startTime = 0;
454 lock (m_UrlMap) 509 lock (m_RequestMap)
455 { 510 {
456 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
457 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
458 // for the request ID.
459 if (!m_RequestMap.ContainsKey(requestID)) 511 if (!m_RequestMap.ContainsKey(requestID))
460 {
461 response["int_response_code"] = 404;
462 response["str_response_string"] = "";
463 response["keepalive"] = false;
464 response["reusecontext"] = false;
465
466 return response; 512 return response;
467 } 513 url = m_RequestMap[requestID];
514 startTime = url.requests[requestID].startTime;
515 }
468 516
469 urlData = m_RequestMap[requestID]; 517 if (System.Environment.TickCount - startTime > 25000)
518 {
519 response["int_response_code"] = 500;
520 response["str_response_string"] = "Script timeout";
521 response["content_type"] = "text/plain";
522 response["keepalive"] = false;
523 response["reusecontext"] = false;
470 524
471 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 525 //remove from map
526 lock (url.requests)
527 {
528 url.requests.Remove(requestID);
529 }
530 lock (m_RequestMap)
472 { 531 {
473 response["int_response_code"] = 500;
474 response["str_response_string"] = "Script timeout";
475 response["content_type"] = "text/plain";
476 response["keepalive"] = false;
477 response["reusecontext"] = false;
478
479 //remove from map
480 urlData.requests.Remove(requestID);
481 m_RequestMap.Remove(requestID); 532 m_RequestMap.Remove(requestID);
482
483 return response;
484 } 533 }
534
535 return response;
485 } 536 }
486 537
538
487 return response; 539 return response;
488 } 540 }
489 541
490 private bool HasEvents(UUID requestID, UUID sessionID) 542 protected bool HasEvents(UUID requestID, UUID sessionID)
491 { 543 {
492 lock (m_UrlMap) 544 UrlData url=null;
545
546 lock (m_RequestMap)
493 { 547 {
494 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
495 // can still make it through to HttpRequestHandler(). That will return without setting up a request
496 // when it detects that the URL has been removed. The poller, however, will continue to ask for
497 // events for that request, so here we will signal that there are events and in GetEvents we will
498 // return a 404.
499 if (!m_RequestMap.ContainsKey(requestID)) 548 if (!m_RequestMap.ContainsKey(requestID))
500 { 549 {
501 return true; 550 return false;
502 } 551 }
503 552 url = m_RequestMap[requestID];
504 UrlData urlData = m_RequestMap[requestID]; 553 }
505 554 lock (url.requests)
506 if (!urlData.requests.ContainsKey(requestID)) 555 {
556 if (!url.requests.ContainsKey(requestID))
507 { 557 {
508 return true; 558 return false;
509 } 559 }
510 560 else
511 // Trigger return of timeout response.
512 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
513 { 561 {
514 return true; 562 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
563 {
564 return true;
565 }
566 if (url.requests[requestID].requestDone)
567 return true;
568 else
569 return false;
515 } 570 }
516
517 return urlData.requests[requestID].requestDone;
518 } 571 }
519 } 572 }
520 573 protected Hashtable GetEvents(UUID requestID, UUID sessionID)
521 private Hashtable GetEvents(UUID requestID, UUID sessionID)
522 { 574 {
523 Hashtable response; 575 UrlData url = null;
576 RequestData requestData = null;
524 577
525 lock (m_UrlMap) 578 lock (m_RequestMap)
526 { 579 {
527 UrlData url = null;
528 RequestData requestData = null;
529
530 if (!m_RequestMap.ContainsKey(requestID)) 580 if (!m_RequestMap.ContainsKey(requestID))
531 return NoEvents(requestID, sessionID); 581 return NoEvents(requestID,sessionID);
532
533 url = m_RequestMap[requestID]; 582 url = m_RequestMap[requestID];
583 }
584 lock (url.requests)
585 {
534 requestData = url.requests[requestID]; 586 requestData = url.requests[requestID];
587 }
535 588
536 if (!requestData.requestDone) 589 if (!requestData.requestDone)
537 return NoEvents(requestID, sessionID); 590 return NoEvents(requestID,sessionID);
538
539 response = new Hashtable();
540 591
541 if (System.Environment.TickCount - requestData.startTime > 25000) 592 Hashtable response = new Hashtable();
542 {
543 response["int_response_code"] = 500;
544 response["str_response_string"] = "Script timeout";
545 response["content_type"] = "text/plain";
546 response["keepalive"] = false;
547 response["reusecontext"] = false;
548 return response;
549 }
550 593
551 //put response 594 if (System.Environment.TickCount - requestData.startTime > 25000)
552 response["int_response_code"] = requestData.responseCode; 595 {
553 response["str_response_string"] = requestData.responseBody; 596 response["int_response_code"] = 500;
554 response["content_type"] = requestData.responseType; 597 response["str_response_string"] = "Script timeout";
555 // response["content_type"] = "text/plain"; 598 response["content_type"] = "text/plain";
556 response["keepalive"] = false; 599 response["keepalive"] = false;
557 response["reusecontext"] = false; 600 response["reusecontext"] = false;
558 601 return response;
559 //remove from map 602 }
603 //put response
604 response["int_response_code"] = requestData.responseCode;
605 response["str_response_string"] = requestData.responseBody;
606 response["content_type"] = requestData.responseType;
607 response["keepalive"] = false;
608 response["reusecontext"] = false;
609
610 if (url.allowXss)
611 response["access_control_allow_origin"] = "*";
612
613 //remove from map
614 lock (url.requests)
615 {
560 url.requests.Remove(requestID); 616 url.requests.Remove(requestID);
617 }
618 lock (m_RequestMap)
619 {
561 m_RequestMap.Remove(requestID); 620 m_RequestMap.Remove(requestID);
562 } 621 }
563 622
@@ -566,44 +625,49 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
566 625
567 public void HttpRequestHandler(UUID requestID, Hashtable request) 626 public void HttpRequestHandler(UUID requestID, Hashtable request)
568 { 627 {
569 string uri = request["uri"].ToString(); 628 lock (request)
570 bool is_ssl = uri.Contains("lslhttps");
571
572 try
573 { 629 {
574 Hashtable headers = (Hashtable)request["headers"]; 630 string uri = request["uri"].ToString();
631 bool is_ssl = uri.Contains("lslhttps");
575 632
576// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; 633 try
634 {
635 Hashtable headers = (Hashtable)request["headers"];
577 636
578 int pos1 = uri.IndexOf("/");// /lslhttp 637// string uri_full = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
579 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
580 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
581 string uri_tmp = uri.Substring(0, pos3 + 1);
582 //HTTP server code doesn't provide us with QueryStrings
583 string pathInfo;
584 string queryString;
585 queryString = "";
586 638
587 pathInfo = uri.Substring(pos3); 639 int pos1 = uri.IndexOf("/");// /lslhttp
640 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
641 int pos3 = uri.IndexOf("/", pos2 + 1); // /lslhttp/urlcode
588 642
589 UrlData urlData = null; 643 string uri_tmp = uri.Substring(0, pos3 + 1);
644 //HTTP server code doesn't provide us with QueryStrings
645 string pathInfo;
646 string queryString;
647 queryString = "";
590 648
591 lock (m_UrlMap) 649 pathInfo = uri.Substring(pos3);
592 {
593 string url;
594 650
595 if (is_ssl) 651 UrlData url = null;
596 url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 652 string urlkey;
653 if (!is_ssl)
654 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
655 //m_UrlMap[];
597 else 656 else
598 url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 657 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
599 658
600 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 659 if (m_UrlMap.ContainsKey(urlkey))
601 // request was being processed. 660 {
602 if (!m_UrlMap.TryGetValue(url, out urlData)) 661 url = m_UrlMap[urlkey];
662 }
663 else
664 {
665 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
603 return; 666 return;
667 }
604 668
605 //for llGetHttpHeader support we need to store original URI here 669 //for llGetHttpHeader support we need to store original URI here
606 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 670 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
607 //as per http://wiki.secondlife.com/wiki/LlGetHTTPHeader 671 //as per http://wiki.secondlife.com/wiki/LlGetHTTPHeader
608 672
609 RequestData requestData = new RequestData(); 673 RequestData requestData = new RequestData();
@@ -611,6 +675,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
611 requestData.requestDone = false; 675 requestData.requestDone = false;
612 requestData.startTime = System.Environment.TickCount; 676 requestData.startTime = System.Environment.TickCount;
613 requestData.uri = uri; 677 requestData.uri = uri;
678 requestData.hostID = url.hostID;
679 requestData.scene = url.scene;
614 if (requestData.headers == null) 680 if (requestData.headers == null)
615 requestData.headers = new Dictionary<string, string>(); 681 requestData.headers = new Dictionary<string, string>();
616 682
@@ -619,8 +685,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
619 string key = (string)header.Key; 685 string key = (string)header.Key;
620 string value = (string)header.Value; 686 string value = (string)header.Value;
621 requestData.headers.Add(key, value); 687 requestData.headers.Add(key, value);
688 if (key == "cookie")
689 {
690 string[] parts = value.Split(new char[] {'='});
691 if (parts[0] == "agni_sl_session_id" && parts.Length > 1)
692 {
693 string cookie = Uri.UnescapeDataString(parts[1]);
694 string[] crumbs = cookie.Split(new char[] {':'});
695 UUID owner;
696 if (crumbs.Length == 2 && UUID.TryParse(crumbs[0], out owner))
697 {
698 if (crumbs[1].Length == 32)
699 {
700 Scene scene = requestData.scene;
701 if (scene != null)
702 {
703 SceneObjectPart host = scene.GetSceneObjectPart(requestData.hostID);
704 if (host != null)
705 {
706 if (host.OwnerID == owner)
707 requestData.allowResponseType = true;
708 }
709 }
710 }
711 }
712 }
713 }
622 } 714 }
623
624 foreach (DictionaryEntry de in request) 715 foreach (DictionaryEntry de in request)
625 { 716 {
626 if (de.Key.ToString() == "querystringkeys") 717 if (de.Key.ToString() == "querystringkeys")
@@ -631,13 +722,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
631 if (request.ContainsKey(key)) 722 if (request.ContainsKey(key))
632 { 723 {
633 string val = (String)request[key]; 724 string val = (String)request[key];
634 queryString = queryString + key + "=" + val + "&"; 725 if (key != "")
726 {
727 queryString = queryString + key + "=" + val + "&";
728 }
729 else
730 {
731 queryString = queryString + val + "&";
732 }
635 } 733 }
636 } 734 }
637
638 if (queryString.Length > 1) 735 if (queryString.Length > 1)
639 queryString = queryString.Substring(0, queryString.Length - 1); 736 queryString = queryString.Substring(0, queryString.Length - 1);
737
640 } 738 }
739
641 } 740 }
642 741
643 //if this machine is behind DNAT/port forwarding, currently this is being 742 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -645,27 +744,38 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
645 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 744 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
646 requestData.headers["x-path-info"] = pathInfo; 745 requestData.headers["x-path-info"] = pathInfo;
647 requestData.headers["x-query-string"] = queryString; 746 requestData.headers["x-query-string"] = queryString;
648 requestData.headers["x-script-url"] = urlData.url; 747 requestData.headers["x-script-url"] = url.url;
649 748
650 urlData.requests.Add(requestID, requestData); 749 //requestData.ev = new ManualResetEvent(false);
651 m_RequestMap.Add(requestID, urlData); 750 lock (url.requests)
652 } 751 {
752 url.requests.Add(requestID, requestData);
753 }
754 lock (m_RequestMap)
755 {
756 //add to request map
757 m_RequestMap.Add(requestID, url);
758 }
653 759
654 urlData.engine.PostScriptEvent( 760 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
655 urlData.itemID, 761
656 "http_request", 762 //send initial response?
657 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 763// Hashtable response = new Hashtable();
658 } 764
659 catch (Exception we) 765 return;
660 { 766
661 //Hashtable response = new Hashtable(); 767 }
662 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 768 catch (Exception we)
663 m_log.Warn(we.Message); 769 {
664 m_log.Warn(we.StackTrace); 770 //Hashtable response = new Hashtable();
771 m_log.Warn("[HttpRequestHandler]: http-in request failed");
772 m_log.Warn(we.Message);
773 m_log.Warn(we.StackTrace);
774 }
665 } 775 }
666 } 776 }
667 777
668 private void OnScriptReset(uint localID, UUID itemID) 778 protected void OnScriptReset(uint localID, UUID itemID)
669 { 779 {
670 ScriptRemoved(itemID); 780 ScriptRemoved(itemID);
671 } 781 }