diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting')
4 files changed, 264 insertions, 235 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index d328eb3..9dac6b9 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -382,6 +382,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
382 | try | 382 | try |
383 | { | 383 | { |
384 | Request = (HttpWebRequest) WebRequest.Create(Url); | 384 | Request = (HttpWebRequest) WebRequest.Create(Url); |
385 | |||
386 | //This works around some buggy HTTP Servers like Lighttpd | ||
387 | Request.ServicePoint.Expect100Continue = false; | ||
388 | |||
385 | Request.Method = HttpMethod; | 389 | Request.Method = HttpMethod; |
386 | Request.ContentType = HttpMIMEType; | 390 | Request.ContentType = HttpMIMEType; |
387 | 391 | ||
@@ -458,15 +462,36 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
458 | 462 | ||
459 | // continue building the string | 463 | // continue building the string |
460 | sb.Append(tempString); | 464 | sb.Append(tempString); |
465 | if (sb.Length > 2048) | ||
466 | break; | ||
461 | } | 467 | } |
462 | } while (count > 0); // any more data to read? | 468 | } while (count > 0); // any more data to read? |
463 | 469 | ||
464 | ResponseBody = sb.ToString(); | 470 | ResponseBody = sb.ToString().Replace("\r", ""); |
465 | } | 471 | } |
466 | catch (Exception e) | 472 | catch (Exception e) |
467 | { | 473 | { |
468 | Status = (int)OSHttpStatusCode.ClientErrorJoker; | 474 | if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) |
469 | ResponseBody = e.Message; | 475 | { |
476 | HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; | ||
477 | Status = (int)webRsp.StatusCode; | ||
478 | try | ||
479 | { | ||
480 | using (Stream responseStream = webRsp.GetResponseStream()) | ||
481 | { | ||
482 | ResponseBody = responseStream.GetStreamString(); | ||
483 | } | ||
484 | } | ||
485 | catch | ||
486 | { | ||
487 | ResponseBody = webRsp.StatusDescription; | ||
488 | } | ||
489 | } | ||
490 | else | ||
491 | { | ||
492 | Status = (int)OSHttpStatusCode.ClientErrorJoker; | ||
493 | ResponseBody = e.Message; | ||
494 | } | ||
470 | 495 | ||
471 | _finished = true; | 496 | _finished = true; |
472 | return; | 497 | return; |
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 53a9679..32a4c88 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | |||
@@ -41,39 +41,13 @@ using OpenSim.Region.Framework.Scenes; | |||
41 | 41 | ||
42 | namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | 42 | namespace OpenSim.Region.CoreModules.Scripting.LSLHttp |
43 | { | 43 | { |
44 | /// <summary> | ||
45 | /// Data describing an external URL set up by a script. | ||
46 | /// </summary> | ||
47 | public class UrlData | 44 | public class UrlData |
48 | { | 45 | { |
49 | /// <summary> | ||
50 | /// Scene object part hosting the script | ||
51 | /// </summary> | ||
52 | public UUID hostID; | 46 | public UUID hostID; |
53 | |||
54 | /// <summary> | ||
55 | /// The item ID of the script that requested the URL. | ||
56 | /// </summary> | ||
57 | public UUID itemID; | 47 | public UUID itemID; |
58 | |||
59 | /// <summary> | ||
60 | /// The script engine that runs the script. | ||
61 | /// </summary> | ||
62 | public IScriptModule engine; | 48 | public IScriptModule engine; |
63 | |||
64 | /// <summary> | ||
65 | /// The generated URL. | ||
66 | /// </summary> | ||
67 | public string url; | 49 | public string url; |
68 | |||
69 | /// <summary> | ||
70 | /// The random UUID component of the generated URL. | ||
71 | /// </summary> | ||
72 | public UUID urlcode; | 50 | public UUID urlcode; |
73 | |||
74 | /// <summary> | ||
75 | /// The external requests currently being processed or awaiting retrieval for this URL. | ||
76 | /// </summary> | ||
77 | public Dictionary<UUID, RequestData> requests; | 51 | public Dictionary<UUID, RequestData> requests; |
78 | } | 52 | } |
79 | 53 | ||
@@ -88,37 +62,26 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
88 | //public ManualResetEvent ev; | 62 | //public ManualResetEvent ev; |
89 | public bool requestDone; | 63 | public bool requestDone; |
90 | public int startTime; | 64 | public int startTime; |
65 | public bool responseSent; | ||
91 | public string uri; | 66 | public string uri; |
92 | } | 67 | } |
93 | 68 | ||
94 | /// <summary> | ||
95 | /// This module provides external URLs for in-world scripts. | ||
96 | /// </summary> | ||
97 | public class UrlModule : ISharedRegionModule, IUrlModule | 69 | public class UrlModule : ISharedRegionModule, IUrlModule |
98 | { | 70 | { |
99 | private static readonly ILog m_log = | 71 | private static readonly ILog m_log = |
100 | LogManager.GetLogger( | 72 | LogManager.GetLogger( |
101 | MethodBase.GetCurrentMethod().DeclaringType); | 73 | MethodBase.GetCurrentMethod().DeclaringType); |
102 | 74 | ||
103 | /// <summary> | 75 | private Dictionary<UUID, UrlData> m_RequestMap = |
104 | /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID | 76 | new Dictionary<UUID, UrlData>(); |
105 | /// randomly generated when a request is received for this URL. | ||
106 | /// </summary> | ||
107 | /// <remarks> | ||
108 | /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with | ||
109 | /// m_UrlMap | ||
110 | /// </remarks> | ||
111 | private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>(); | ||
112 | 77 | ||
113 | /// <summary> | 78 | private Dictionary<string, UrlData> m_UrlMap = |
114 | /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL | 79 | new Dictionary<string, UrlData>(); |
115 | /// </summary> | ||
116 | private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>(); | ||
117 | 80 | ||
118 | /// <summary> | 81 | /// <summary> |
119 | /// Maximum number of external urls that can be set up by this module. | 82 | /// Maximum number of external urls that can be set up by this module. |
120 | /// </summary> | 83 | /// </summary> |
121 | private int m_TotalUrls = 100; | 84 | private int m_TotalUrls = 15000; |
122 | 85 | ||
123 | private uint https_port = 0; | 86 | private uint https_port = 0; |
124 | private IHttpServer m_HttpServer = null; | 87 | private IHttpServer m_HttpServer = null; |
@@ -144,9 +107,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
144 | { | 107 | { |
145 | m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); | 108 | m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); |
146 | bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); | 109 | bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); |
147 | |||
148 | if (ssl_enabled) | 110 | if (ssl_enabled) |
111 | { | ||
149 | https_port = (uint) config.Configs["Network"].GetInt("https_port",0); | 112 | https_port = (uint) config.Configs["Network"].GetInt("https_port",0); |
113 | } | ||
150 | 114 | ||
151 | IConfig llFunctionsConfig = config.Configs["LL-Functions"]; | 115 | IConfig llFunctionsConfig = config.Configs["LL-Functions"]; |
152 | 116 | ||
@@ -207,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
207 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); | 171 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); |
208 | return urlcode; | 172 | return urlcode; |
209 | } | 173 | } |
210 | string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; | 174 | string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString(); |
211 | 175 | ||
212 | UrlData urlData = new UrlData(); | 176 | UrlData urlData = new UrlData(); |
213 | urlData.hostID = host.UUID; | 177 | urlData.hostID = host.UUID; |
@@ -216,14 +180,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
216 | urlData.url = url; | 180 | urlData.url = url; |
217 | urlData.urlcode = urlcode; | 181 | urlData.urlcode = urlcode; |
218 | urlData.requests = new Dictionary<UUID, RequestData>(); | 182 | urlData.requests = new Dictionary<UUID, RequestData>(); |
219 | 183 | ||
220 | m_UrlMap[url] = urlData; | 184 | m_UrlMap[url] = urlData; |
221 | 185 | ||
222 | string uri = "/lslhttp/" + urlcode.ToString() + "/"; | 186 | string uri = "/lslhttp/" + urlcode.ToString(); |
223 | 187 | ||
224 | m_HttpServer.AddPollServiceHTTPHandler( | 188 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); |
225 | uri, | 189 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
226 | new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); | 190 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); |
227 | 191 | ||
228 | m_log.DebugFormat( | 192 | m_log.DebugFormat( |
229 | "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", | 193 | "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", |
@@ -252,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
252 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); | 216 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); |
253 | return urlcode; | 217 | return urlcode; |
254 | } | 218 | } |
255 | string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; | 219 | string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString(); |
256 | 220 | ||
257 | UrlData urlData = new UrlData(); | 221 | UrlData urlData = new UrlData(); |
258 | urlData.hostID = host.UUID; | 222 | urlData.hostID = host.UUID; |
@@ -262,13 +226,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
262 | urlData.urlcode = urlcode; | 226 | urlData.urlcode = urlcode; |
263 | urlData.requests = new Dictionary<UUID, RequestData>(); | 227 | urlData.requests = new Dictionary<UUID, RequestData>(); |
264 | 228 | ||
229 | |||
265 | m_UrlMap[url] = urlData; | 230 | m_UrlMap[url] = urlData; |
266 | 231 | ||
267 | string uri = "/lslhttps/" + urlcode.ToString() + "/"; | 232 | string uri = "/lslhttps/" + urlcode.ToString(); |
268 | 233 | ||
269 | m_HttpsServer.AddPollServiceHTTPHandler( | 234 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); |
270 | uri, | 235 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
271 | new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); | 236 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); |
272 | 237 | ||
273 | m_log.DebugFormat( | 238 | m_log.DebugFormat( |
274 | "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", | 239 | "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", |
@@ -291,12 +256,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
291 | return; | 256 | return; |
292 | } | 257 | } |
293 | 258 | ||
294 | foreach (UUID req in data.requests.Keys) | 259 | lock (m_RequestMap) |
295 | m_RequestMap.Remove(req); | 260 | { |
296 | 261 | foreach (UUID req in data.requests.Keys) | |
297 | m_log.DebugFormat( | 262 | m_RequestMap.Remove(req); |
298 | "[URL MODULE]: Releasing url {0} for {1} in {2}", | 263 | } |
299 | url, data.itemID, data.hostID); | 264 | |
265 | // m_log.DebugFormat( | ||
266 | // "[URL MODULE]: Releasing url {0} for {1} in {2}", | ||
267 | // url, data.itemID, data.hostID); | ||
300 | 268 | ||
301 | RemoveUrl(data); | 269 | RemoveUrl(data); |
302 | m_UrlMap.Remove(url); | 270 | m_UrlMap.Remove(url); |
@@ -321,15 +289,19 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
321 | 289 | ||
322 | public void HttpResponse(UUID request, int status, string body) | 290 | public void HttpResponse(UUID request, int status, string body) |
323 | { | 291 | { |
324 | lock (m_UrlMap) | 292 | lock (m_RequestMap) |
325 | { | 293 | { |
326 | if (m_RequestMap.ContainsKey(request)) | 294 | if (m_RequestMap.ContainsKey(request)) |
327 | { | 295 | { |
328 | UrlData urlData = m_RequestMap[request]; | 296 | UrlData urlData = m_RequestMap[request]; |
329 | urlData.requests[request].responseCode = status; | 297 | if (!urlData.requests[request].responseSent) |
330 | urlData.requests[request].responseBody = body; | 298 | { |
331 | //urlData.requests[request].ev.Set(); | 299 | urlData.requests[request].responseCode = status; |
332 | urlData.requests[request].requestDone =true; | 300 | urlData.requests[request].responseBody = body; |
301 | //urlData.requests[request].ev.Set(); | ||
302 | urlData.requests[request].requestDone = true; | ||
303 | urlData.requests[request].responseSent = true; | ||
304 | } | ||
333 | } | 305 | } |
334 | else | 306 | else |
335 | { | 307 | { |
@@ -340,7 +312,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
340 | 312 | ||
341 | public string GetHttpHeader(UUID requestId, string header) | 313 | public string GetHttpHeader(UUID requestId, string header) |
342 | { | 314 | { |
343 | lock (m_UrlMap) | 315 | lock (m_RequestMap) |
344 | { | 316 | { |
345 | if (m_RequestMap.ContainsKey(requestId)) | 317 | if (m_RequestMap.ContainsKey(requestId)) |
346 | { | 318 | { |
@@ -354,14 +326,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
354 | m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); | 326 | m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); |
355 | } | 327 | } |
356 | } | 328 | } |
357 | |||
358 | return String.Empty; | 329 | return String.Empty; |
359 | } | 330 | } |
360 | 331 | ||
361 | public int GetFreeUrls() | 332 | public int GetFreeUrls() |
362 | { | 333 | { |
363 | lock (m_UrlMap) | 334 | return m_TotalUrls - m_UrlMap.Count; |
364 | return m_TotalUrls - m_UrlMap.Count; | ||
365 | } | 335 | } |
366 | 336 | ||
367 | public void ScriptRemoved(UUID itemID) | 337 | public void ScriptRemoved(UUID itemID) |
@@ -378,8 +348,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
378 | { | 348 | { |
379 | RemoveUrl(url.Value); | 349 | RemoveUrl(url.Value); |
380 | removeURLs.Add(url.Key); | 350 | removeURLs.Add(url.Key); |
381 | foreach (UUID req in url.Value.requests.Keys) | 351 | lock (m_RequestMap) |
382 | m_RequestMap.Remove(req); | 352 | { |
353 | foreach (UUID req in url.Value.requests.Keys) | ||
354 | m_RequestMap.Remove(req); | ||
355 | } | ||
383 | } | 356 | } |
384 | } | 357 | } |
385 | 358 | ||
@@ -400,9 +373,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
400 | { | 373 | { |
401 | RemoveUrl(url.Value); | 374 | RemoveUrl(url.Value); |
402 | removeURLs.Add(url.Key); | 375 | removeURLs.Add(url.Key); |
403 | 376 | lock (m_RequestMap) | |
404 | foreach (UUID req in url.Value.requests.Keys) | 377 | { |
405 | m_RequestMap.Remove(req); | 378 | foreach (UUID req in url.Value.requests.Keys) |
379 | m_RequestMap.Remove(req); | ||
380 | } | ||
406 | } | 381 | } |
407 | } | 382 | } |
408 | 383 | ||
@@ -411,123 +386,125 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
411 | } | 386 | } |
412 | } | 387 | } |
413 | 388 | ||
389 | |||
414 | private void RemoveUrl(UrlData data) | 390 | private void RemoveUrl(UrlData data) |
415 | { | 391 | { |
416 | m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); | 392 | m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); |
417 | } | 393 | } |
418 | 394 | ||
419 | private Hashtable NoEvents(UUID requestID, UUID sessionID) | 395 | private Hashtable NoEvents(UUID requestID, UUID sessionID) |
420 | { | 396 | { |
421 | Hashtable response = new Hashtable(); | 397 | Hashtable response = new Hashtable(); |
422 | UrlData urlData; | 398 | UrlData url; |
423 | 399 | int startTime = 0; | |
424 | lock (m_UrlMap) | 400 | lock (m_RequestMap) |
425 | { | 401 | { |
426 | // We need to return a 404 here in case the request URL was removed at exactly the same time that a | ||
427 | // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling | ||
428 | // for the request ID. | ||
429 | if (!m_RequestMap.ContainsKey(requestID)) | 402 | if (!m_RequestMap.ContainsKey(requestID)) |
430 | { | ||
431 | response["int_response_code"] = 404; | ||
432 | response["str_response_string"] = ""; | ||
433 | response["keepalive"] = false; | ||
434 | response["reusecontext"] = false; | ||
435 | |||
436 | return response; | 403 | return response; |
437 | } | 404 | url = m_RequestMap[requestID]; |
405 | startTime = url.requests[requestID].startTime; | ||
406 | } | ||
438 | 407 | ||
439 | urlData = m_RequestMap[requestID]; | 408 | if (System.Environment.TickCount - startTime > 25000) |
409 | { | ||
410 | response["int_response_code"] = 500; | ||
411 | response["str_response_string"] = "Script timeout"; | ||
412 | response["content_type"] = "text/plain"; | ||
413 | response["keepalive"] = false; | ||
414 | response["reusecontext"] = false; | ||
440 | 415 | ||
441 | if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) | 416 | //remove from map |
417 | lock (url.requests) | ||
418 | { | ||
419 | url.requests.Remove(requestID); | ||
420 | } | ||
421 | lock (m_RequestMap) | ||
442 | { | 422 | { |
443 | response["int_response_code"] = 500; | ||
444 | response["str_response_string"] = "Script timeout"; | ||
445 | response["content_type"] = "text/plain"; | ||
446 | response["keepalive"] = false; | ||
447 | response["reusecontext"] = false; | ||
448 | |||
449 | //remove from map | ||
450 | urlData.requests.Remove(requestID); | ||
451 | m_RequestMap.Remove(requestID); | 423 | m_RequestMap.Remove(requestID); |
452 | |||
453 | return response; | ||
454 | } | 424 | } |
425 | |||
426 | return response; | ||
455 | } | 427 | } |
456 | 428 | ||
429 | |||
457 | return response; | 430 | return response; |
458 | } | 431 | } |
459 | 432 | ||
460 | private bool HasEvents(UUID requestID, UUID sessionID) | 433 | private bool HasEvents(UUID requestID, UUID sessionID) |
461 | { | 434 | { |
462 | lock (m_UrlMap) | 435 | UrlData url=null; |
436 | |||
437 | lock (m_RequestMap) | ||
463 | { | 438 | { |
464 | // We return true here because an external URL request that happened at the same time as an llRemoveURL() | ||
465 | // can still make it through to HttpRequestHandler(). That will return without setting up a request | ||
466 | // when it detects that the URL has been removed. The poller, however, will continue to ask for | ||
467 | // events for that request, so here we will signal that there are events and in GetEvents we will | ||
468 | // return a 404. | ||
469 | if (!m_RequestMap.ContainsKey(requestID)) | 439 | if (!m_RequestMap.ContainsKey(requestID)) |
470 | { | 440 | { |
471 | return true; | 441 | return false; |
472 | } | 442 | } |
473 | 443 | url = m_RequestMap[requestID]; | |
474 | UrlData urlData = m_RequestMap[requestID]; | 444 | } |
475 | 445 | lock (url.requests) | |
476 | if (!urlData.requests.ContainsKey(requestID)) | 446 | { |
447 | if (!url.requests.ContainsKey(requestID)) | ||
477 | { | 448 | { |
478 | return true; | 449 | return false; |
479 | } | 450 | } |
480 | 451 | else | |
481 | // Trigger return of timeout response. | ||
482 | if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) | ||
483 | { | 452 | { |
484 | return true; | 453 | if (System.Environment.TickCount - url.requests[requestID].startTime > 25000) |
454 | { | ||
455 | return true; | ||
456 | } | ||
457 | if (url.requests[requestID].requestDone) | ||
458 | return true; | ||
459 | else | ||
460 | return false; | ||
485 | } | 461 | } |
486 | |||
487 | return urlData.requests[requestID].requestDone; | ||
488 | } | 462 | } |
489 | } | 463 | } |
490 | |||
491 | private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) | 464 | private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) |
492 | { | 465 | { |
493 | Hashtable response; | 466 | UrlData url = null; |
467 | RequestData requestData = null; | ||
494 | 468 | ||
495 | lock (m_UrlMap) | 469 | lock (m_RequestMap) |
496 | { | 470 | { |
497 | UrlData url = null; | ||
498 | RequestData requestData = null; | ||
499 | |||
500 | if (!m_RequestMap.ContainsKey(requestID)) | 471 | if (!m_RequestMap.ContainsKey(requestID)) |
501 | return NoEvents(requestID, sessionID); | 472 | return NoEvents(requestID,sessionID); |
502 | |||
503 | url = m_RequestMap[requestID]; | 473 | url = m_RequestMap[requestID]; |
474 | } | ||
475 | lock (url.requests) | ||
476 | { | ||
504 | requestData = url.requests[requestID]; | 477 | requestData = url.requests[requestID]; |
478 | } | ||
479 | |||
480 | if (!requestData.requestDone) | ||
481 | return NoEvents(requestID,sessionID); | ||
482 | |||
483 | Hashtable response = new Hashtable(); | ||
505 | 484 | ||
506 | if (!requestData.requestDone) | 485 | if (System.Environment.TickCount - requestData.startTime > 25000) |
507 | return NoEvents(requestID, sessionID); | 486 | { |
508 | 487 | response["int_response_code"] = 500; | |
509 | response = new Hashtable(); | 488 | response["str_response_string"] = "Script timeout"; |
510 | 489 | response["content_type"] = "text/plain"; | |
511 | if (System.Environment.TickCount - requestData.startTime > 25000) | ||
512 | { | ||
513 | response["int_response_code"] = 500; | ||
514 | response["str_response_string"] = "Script timeout"; | ||
515 | response["content_type"] = "text/plain"; | ||
516 | response["keepalive"] = false; | ||
517 | response["reusecontext"] = false; | ||
518 | return response; | ||
519 | } | ||
520 | |||
521 | //put response | ||
522 | response["int_response_code"] = requestData.responseCode; | ||
523 | response["str_response_string"] = requestData.responseBody; | ||
524 | response["content_type"] = requestData.responseType; | ||
525 | // response["content_type"] = "text/plain"; | ||
526 | response["keepalive"] = false; | 490 | response["keepalive"] = false; |
527 | response["reusecontext"] = false; | 491 | response["reusecontext"] = false; |
528 | 492 | return response; | |
529 | //remove from map | 493 | } |
494 | //put response | ||
495 | response["int_response_code"] = requestData.responseCode; | ||
496 | response["str_response_string"] = requestData.responseBody; | ||
497 | response["content_type"] = "text/plain"; | ||
498 | response["keepalive"] = false; | ||
499 | response["reusecontext"] = false; | ||
500 | |||
501 | //remove from map | ||
502 | lock (url.requests) | ||
503 | { | ||
530 | url.requests.Remove(requestID); | 504 | url.requests.Remove(requestID); |
505 | } | ||
506 | lock (m_RequestMap) | ||
507 | { | ||
531 | m_RequestMap.Remove(requestID); | 508 | m_RequestMap.Remove(requestID); |
532 | } | 509 | } |
533 | 510 | ||
@@ -536,41 +513,45 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
536 | 513 | ||
537 | public void HttpRequestHandler(UUID requestID, Hashtable request) | 514 | public void HttpRequestHandler(UUID requestID, Hashtable request) |
538 | { | 515 | { |
539 | string uri = request["uri"].ToString(); | 516 | lock (request) |
540 | bool is_ssl = uri.Contains("lslhttps"); | ||
541 | |||
542 | try | ||
543 | { | 517 | { |
544 | Hashtable headers = (Hashtable)request["headers"]; | 518 | string uri = request["uri"].ToString(); |
545 | 519 | bool is_ssl = uri.Contains("lslhttps"); | |
546 | // string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; | ||
547 | 520 | ||
548 | int pos1 = uri.IndexOf("/");// /lslhttp | 521 | try |
549 | int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ | ||
550 | int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/ | ||
551 | string uri_tmp = uri.Substring(0, pos3 + 1); | ||
552 | //HTTP server code doesn't provide us with QueryStrings | ||
553 | string pathInfo; | ||
554 | string queryString; | ||
555 | queryString = ""; | ||
556 | |||
557 | pathInfo = uri.Substring(pos3); | ||
558 | |||
559 | UrlData urlData = null; | ||
560 | |||
561 | lock (m_UrlMap) | ||
562 | { | 522 | { |
563 | string url; | 523 | Hashtable headers = (Hashtable)request["headers"]; |
524 | |||
525 | // string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; | ||
564 | 526 | ||
565 | if (is_ssl) | 527 | int pos1 = uri.IndexOf("/");// /lslhttp |
566 | url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; | 528 | int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ |
529 | int pos3 = pos2 + 37; // /lslhttp/urlcode | ||
530 | string uri_tmp = uri.Substring(0, pos3); | ||
531 | //HTTP server code doesn't provide us with QueryStrings | ||
532 | string pathInfo; | ||
533 | string queryString; | ||
534 | queryString = ""; | ||
535 | |||
536 | pathInfo = uri.Substring(pos3); | ||
537 | |||
538 | UrlData url = null; | ||
539 | string urlkey; | ||
540 | if (!is_ssl) | ||
541 | urlkey = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; | ||
542 | //m_UrlMap[]; | ||
567 | else | 543 | else |
568 | url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; | 544 | urlkey = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; |
569 | 545 | ||
570 | // Avoid a race - the request URL may have been released via llRequestUrl() whilst this | 546 | if (m_UrlMap.ContainsKey(urlkey)) |
571 | // request was being processed. | 547 | { |
572 | if (!m_UrlMap.TryGetValue(url, out urlData)) | 548 | url = m_UrlMap[urlkey]; |
549 | } | ||
550 | else | ||
551 | { | ||
552 | //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString()); | ||
573 | return; | 553 | return; |
554 | } | ||
574 | 555 | ||
575 | //for llGetHttpHeader support we need to store original URI here | 556 | //for llGetHttpHeader support we need to store original URI here |
576 | //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers | 557 | //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers |
@@ -590,7 +571,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
590 | string value = (string)header.Value; | 571 | string value = (string)header.Value; |
591 | requestData.headers.Add(key, value); | 572 | requestData.headers.Add(key, value); |
592 | } | 573 | } |
593 | |||
594 | foreach (DictionaryEntry de in request) | 574 | foreach (DictionaryEntry de in request) |
595 | { | 575 | { |
596 | if (de.Key.ToString() == "querystringkeys") | 576 | if (de.Key.ToString() == "querystringkeys") |
@@ -601,13 +581,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
601 | if (request.ContainsKey(key)) | 581 | if (request.ContainsKey(key)) |
602 | { | 582 | { |
603 | string val = (String)request[key]; | 583 | string val = (String)request[key]; |
604 | queryString = queryString + key + "=" + val + "&"; | 584 | if (key != "") |
585 | { | ||
586 | queryString = queryString + key + "=" + val + "&"; | ||
587 | } | ||
588 | else | ||
589 | { | ||
590 | queryString = queryString + val + "&"; | ||
591 | } | ||
605 | } | 592 | } |
606 | } | 593 | } |
607 | |||
608 | if (queryString.Length > 1) | 594 | if (queryString.Length > 1) |
609 | queryString = queryString.Substring(0, queryString.Length - 1); | 595 | queryString = queryString.Substring(0, queryString.Length - 1); |
596 | |||
610 | } | 597 | } |
598 | |||
611 | } | 599 | } |
612 | 600 | ||
613 | //if this machine is behind DNAT/port forwarding, currently this is being | 601 | //if this machine is behind DNAT/port forwarding, currently this is being |
@@ -615,23 +603,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
615 | requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; | 603 | requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; |
616 | requestData.headers["x-path-info"] = pathInfo; | 604 | requestData.headers["x-path-info"] = pathInfo; |
617 | requestData.headers["x-query-string"] = queryString; | 605 | requestData.headers["x-query-string"] = queryString; |
618 | requestData.headers["x-script-url"] = urlData.url; | 606 | requestData.headers["x-script-url"] = url.url; |
619 | 607 | ||
620 | urlData.requests.Add(requestID, requestData); | 608 | //requestData.ev = new ManualResetEvent(false); |
621 | m_RequestMap.Add(requestID, urlData); | 609 | lock (url.requests) |
622 | } | 610 | { |
611 | url.requests.Add(requestID, requestData); | ||
612 | } | ||
613 | lock (m_RequestMap) | ||
614 | { | ||
615 | //add to request map | ||
616 | m_RequestMap.Add(requestID, url); | ||
617 | } | ||
623 | 618 | ||
624 | urlData.engine.PostScriptEvent( | 619 | url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); |
625 | urlData.itemID, | 620 | |
626 | "http_request", | 621 | //send initial response? |
627 | new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); | 622 | // Hashtable response = new Hashtable(); |
628 | } | 623 | |
629 | catch (Exception we) | 624 | return; |
630 | { | 625 | |
631 | //Hashtable response = new Hashtable(); | 626 | } |
632 | m_log.Warn("[HttpRequestHandler]: http-in request failed"); | 627 | catch (Exception we) |
633 | m_log.Warn(we.Message); | 628 | { |
634 | m_log.Warn(we.StackTrace); | 629 | //Hashtable response = new Hashtable(); |
630 | m_log.Warn("[HttpRequestHandler]: http-in request failed"); | ||
631 | m_log.Warn(we.Message); | ||
632 | m_log.Warn(we.StackTrace); | ||
633 | } | ||
635 | } | 634 | } |
636 | } | 635 | } |
637 | 636 | ||
@@ -640,4 +639,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
640 | ScriptRemoved(itemID); | 639 | ScriptRemoved(itemID); |
641 | } | 640 | } |
642 | } | 641 | } |
643 | } \ No newline at end of file | 642 | } |
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index d82551e..1e17b02 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs | |||
@@ -835,4 +835,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
835 | return null; | 835 | return null; |
836 | } | 836 | } |
837 | } | 837 | } |
838 | } \ No newline at end of file | 838 | } |
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 8358bc0..07bb291 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | |||
@@ -90,6 +90,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
90 | // private static readonly ILog m_log = | 90 | // private static readonly ILog m_log = |
91 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 91 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
92 | 92 | ||
93 | private const int DEBUG_CHANNEL = 2147483647; | ||
94 | |||
93 | private ListenerManager m_listenerManager; | 95 | private ListenerManager m_listenerManager; |
94 | private Queue m_pending; | 96 | private Queue m_pending; |
95 | private Queue m_pendingQ; | 97 | private Queue m_pendingQ; |
@@ -308,56 +310,59 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
308 | /// <param name='msg'> | 310 | /// <param name='msg'> |
309 | /// Message. | 311 | /// Message. |
310 | /// </param> | 312 | /// </param> |
311 | public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg) | 313 | public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error) |
312 | { | 314 | { |
315 | error = null; | ||
316 | |||
317 | if (channel == DEBUG_CHANNEL) | ||
318 | return true; | ||
319 | |||
313 | // Is id an avatar? | 320 | // Is id an avatar? |
314 | ScenePresence sp = m_scene.GetScenePresence(target); | 321 | ScenePresence sp = m_scene.GetScenePresence(target); |
315 | 322 | ||
316 | if (sp != null) | 323 | if (sp != null) |
317 | { | 324 | { |
318 | // ignore if a child agent this is restricted to inside one region | 325 | // Send message to avatar |
319 | if (sp.IsChildAgent) | ||
320 | return; | ||
321 | |||
322 | // Send message to the avatar. | ||
323 | // Channel zero only goes to the avatar | ||
324 | // non zero channel messages only go to the attachments | ||
325 | if (channel == 0) | 326 | if (channel == 0) |
326 | { | 327 | { |
327 | m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false); | 328 | // Channel 0 goes to viewer ONLY |
328 | } | 329 | m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target); |
329 | else | 330 | return true; |
330 | { | 331 | } |
331 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
332 | if (attachments.Count == 0) | ||
333 | return; | ||
334 | 332 | ||
335 | // Get uuid of attachments | 333 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
336 | List<UUID> targets = new List<UUID>(); | ||
337 | foreach (SceneObjectGroup sog in attachments) | ||
338 | { | ||
339 | if (!sog.IsDeleted) | ||
340 | targets.Add(sog.UUID); | ||
341 | } | ||
342 | 334 | ||
343 | // Need to check each attachment | 335 | if (attachments.Count == 0) |
344 | foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) | 336 | return true; |
345 | { | ||
346 | if (li.GetHostID().Equals(id)) | ||
347 | continue; | ||
348 | 337 | ||
349 | if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) | 338 | // Get uuid of attachments |
350 | continue; | 339 | List<UUID> targets = new List<UUID>(); |
340 | foreach (SceneObjectGroup sog in attachments) | ||
341 | { | ||
342 | if (!sog.IsDeleted) | ||
343 | targets.Add(sog.UUID); | ||
344 | } | ||
351 | 345 | ||
352 | if (targets.Contains(li.GetHostID())) | 346 | // Need to check each attachment |
353 | QueueMessage(new ListenerInfo(li, name, id, msg)); | 347 | foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) |
354 | } | 348 | { |
349 | if (li.GetHostID().Equals(id)) | ||
350 | continue; | ||
351 | |||
352 | if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) | ||
353 | continue; | ||
354 | |||
355 | if (targets.Contains(li.GetHostID())) | ||
356 | QueueMessage(new ListenerInfo(li, name, id, msg)); | ||
355 | } | 357 | } |
356 | 358 | ||
357 | return; | 359 | return true; |
358 | } | 360 | } |
359 | 361 | ||
360 | // No avatar found so look for an object | 362 | SceneObjectPart part = m_scene.GetSceneObjectPart(target); |
363 | if (part == null) // Not even an object | ||
364 | return true; // No error | ||
365 | |||
361 | foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) | 366 | foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) |
362 | { | 367 | { |
363 | // Dont process if this message is from yourself! | 368 | // Dont process if this message is from yourself! |
@@ -375,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
375 | } | 380 | } |
376 | } | 381 | } |
377 | 382 | ||
378 | return; | 383 | return true; |
379 | } | 384 | } |
380 | 385 | ||
381 | protected void QueueMessage(ListenerInfo li) | 386 | protected void QueueMessage(ListenerInfo li) |