Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.csavinationmerge
commit
ba0819be9e
|
@ -227,9 +227,12 @@ namespace OpenSim.Framework.Servers
|
||||||
handlers.AppendFormat("\t{0}\n", s);
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
handlers.AppendFormat("* HTTP:\n");
|
handlers.AppendFormat("* HTTP:\n");
|
||||||
List<String> poll = httpServer.GetPollServiceHandlerKeys();
|
|
||||||
foreach (String s in httpServer.GetHTTPHandlerKeys())
|
foreach (String s in httpServer.GetHTTPHandlerKeys())
|
||||||
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
|
handlers.AppendFormat("* HTTP (poll):\n");
|
||||||
|
foreach (String s in httpServer.GetPollServiceHandlerKeys())
|
||||||
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
handlers.AppendFormat("* JSONRPC:\n");
|
handlers.AppendFormat("* JSONRPC:\n");
|
||||||
foreach (String s in httpServer.GetJsonRpcHandlerKeys())
|
foreach (String s in httpServer.GetJsonRpcHandlerKeys())
|
||||||
|
|
|
@ -83,17 +83,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
private Dictionary<string, UrlData> m_UrlMap =
|
private Dictionary<string, UrlData> m_UrlMap =
|
||||||
new Dictionary<string, UrlData>();
|
new Dictionary<string, UrlData>();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Maximum number of external urls that can be set up by this module.
|
|
||||||
/// </summary>
|
|
||||||
private int m_TotalUrls = 15000;
|
|
||||||
|
|
||||||
private uint m_HttpsPort = 0;
|
private uint m_HttpsPort = 0;
|
||||||
private IHttpServer m_HttpServer = null;
|
private IHttpServer m_HttpServer = null;
|
||||||
private IHttpServer m_HttpsServer = null;
|
private IHttpServer m_HttpsServer = null;
|
||||||
|
|
||||||
public string ExternalHostNameForLSL { get; private set; }
|
public string ExternalHostNameForLSL { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default maximum number of urls
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultTotalUrls = 15000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum number of external urls that can be set up by this module.
|
||||||
|
/// </summary>
|
||||||
|
public int TotalUrls { get; set; }
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
|
@ -124,7 +129,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
IConfig llFunctionsConfig = config.Configs["LL-Functions"];
|
IConfig llFunctionsConfig = config.Configs["LL-Functions"];
|
||||||
|
|
||||||
if (llFunctionsConfig != null)
|
if (llFunctionsConfig != null)
|
||||||
m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls);
|
TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", DefaultTotalUrls);
|
||||||
|
else
|
||||||
|
TotalUrls = DefaultTotalUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
@ -175,7 +182,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
lock (m_UrlMap)
|
lock (m_UrlMap)
|
||||||
{
|
{
|
||||||
if (m_UrlMap.Count >= m_TotalUrls)
|
if (m_UrlMap.Count >= TotalUrls)
|
||||||
{
|
{
|
||||||
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
|
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
|
||||||
return urlcode;
|
return urlcode;
|
||||||
|
@ -220,7 +227,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
lock (m_UrlMap)
|
lock (m_UrlMap)
|
||||||
{
|
{
|
||||||
if (m_UrlMap.Count >= m_TotalUrls)
|
if (m_UrlMap.Count >= TotalUrls)
|
||||||
{
|
{
|
||||||
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
|
engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
|
||||||
return urlcode;
|
return urlcode;
|
||||||
|
@ -355,7 +362,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
public int GetFreeUrls()
|
public int GetFreeUrls()
|
||||||
{
|
{
|
||||||
return m_TotalUrls - m_UrlMap.Count;
|
lock (m_UrlMap)
|
||||||
|
return TotalUrls - m_UrlMap.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScriptRemoved(UUID itemID)
|
public void ScriptRemoved(UUID itemID)
|
||||||
|
|
|
@ -443,7 +443,6 @@ default
|
||||||
string itemName = "TestNoStop";
|
string itemName = "TestNoStop";
|
||||||
|
|
||||||
SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
|
SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
|
||||||
TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
|
|
||||||
|
|
||||||
// Wait for the script to start the event before we try stopping it.
|
// Wait for the script to start the event before we try stopping it.
|
||||||
m_chatEvent.WaitOne(60000);
|
m_chatEvent.WaitOne(60000);
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Region.CoreModules.Scripting.LSLHttp;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Region.ScriptEngine.Shared;
|
||||||
|
using OpenSim.Region.ScriptEngine.Shared.Api;
|
||||||
|
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tests for HTTP related functions in LSL
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture]
|
||||||
|
public class LSL_ApiHttpTests : OpenSimTestCase
|
||||||
|
{
|
||||||
|
private Scene m_scene;
|
||||||
|
private MockScriptEngine m_engine;
|
||||||
|
private UrlModule m_urlModule;
|
||||||
|
|
||||||
|
private TaskInventoryItem m_scriptItem;
|
||||||
|
private LSL_Api m_lslApi;
|
||||||
|
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public void TestFixtureSetUp()
|
||||||
|
{
|
||||||
|
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||||
|
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestFixtureTearDown]
|
||||||
|
public void TestFixureTearDown()
|
||||||
|
{
|
||||||
|
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||||
|
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
|
||||||
|
// tests really shouldn't).
|
||||||
|
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public override void SetUp()
|
||||||
|
{
|
||||||
|
base.SetUp();
|
||||||
|
|
||||||
|
// This is an unfortunate bit of clean up we have to do because MainServer manages things through static
|
||||||
|
// variables and the VM is not restarted between tests.
|
||||||
|
uint port = 9999;
|
||||||
|
MainServer.RemoveHttpServer(port);
|
||||||
|
|
||||||
|
BaseHttpServer server = new BaseHttpServer(port, false, 0, "");
|
||||||
|
MainServer.AddHttpServer(server);
|
||||||
|
MainServer.Instance = server;
|
||||||
|
|
||||||
|
server.Start();
|
||||||
|
|
||||||
|
m_engine = new MockScriptEngine();
|
||||||
|
m_urlModule = new UrlModule();
|
||||||
|
|
||||||
|
m_scene = new SceneHelpers().SetupScene();
|
||||||
|
SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine, m_urlModule);
|
||||||
|
|
||||||
|
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
|
||||||
|
m_scriptItem = TaskInventoryHelpers.AddScript(m_scene, so.RootPart);
|
||||||
|
|
||||||
|
// This is disconnected from the actual script - the mock engine does not set up any LSL_Api atm.
|
||||||
|
// Possibly this could be done and we could obtain it directly from the MockScriptEngine.
|
||||||
|
m_lslApi = new LSL_Api();
|
||||||
|
m_lslApi.Initialize(m_engine, so.RootPart, m_scriptItem, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
MainServer.Instance.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLlReleaseUrl()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
|
m_lslApi.llRequestURL();
|
||||||
|
string returnedUri = m_engine.PostedEvents[m_scriptItem.ItemID][0].Params[2].ToString();
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check that the initial number of URLs is correct
|
||||||
|
Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check releasing a non-url
|
||||||
|
m_lslApi.llReleaseURL("GARBAGE");
|
||||||
|
Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check releasing a non-existing url
|
||||||
|
m_lslApi.llReleaseURL("http://example.com");
|
||||||
|
Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check URL release
|
||||||
|
m_lslApi.llReleaseURL(returnedUri);
|
||||||
|
Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
|
||||||
|
|
||||||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
|
||||||
|
|
||||||
|
bool gotExpectedException = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
catch (WebException e)
|
||||||
|
{
|
||||||
|
using (HttpWebResponse response = (HttpWebResponse)e.Response)
|
||||||
|
gotExpectedException = response.StatusCode == HttpStatusCode.NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(gotExpectedException, Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check releasing the same URL again
|
||||||
|
m_lslApi.llReleaseURL(returnedUri);
|
||||||
|
Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLlRequestUrl()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
|
string requestId = m_lslApi.llRequestURL();
|
||||||
|
Assert.That(requestId, Is.Not.EqualTo(UUID.Zero.ToString()));
|
||||||
|
string returnedUri;
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check that URL is correctly set up
|
||||||
|
Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
|
||||||
|
|
||||||
|
Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
|
||||||
|
|
||||||
|
List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
|
||||||
|
Assert.That(events.Count, Is.EqualTo(1));
|
||||||
|
EventParams eventParams = events[0];
|
||||||
|
Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
|
||||||
|
|
||||||
|
UUID returnKey;
|
||||||
|
string rawReturnKey = eventParams.Params[0].ToString();
|
||||||
|
string method = eventParams.Params[1].ToString();
|
||||||
|
returnedUri = eventParams.Params[2].ToString();
|
||||||
|
|
||||||
|
Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
|
||||||
|
Assert.That(method, Is.EqualTo(ScriptBaseClass.URL_REQUEST_GRANTED));
|
||||||
|
Assert.That(Uri.IsWellFormedUriString(returnedUri, UriKind.Absolute), Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Check that request to URL works.
|
||||||
|
string testResponse = "Hello World";
|
||||||
|
|
||||||
|
m_engine.ClearPostedEvents();
|
||||||
|
m_engine.PostEventHook
|
||||||
|
+= (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse);
|
||||||
|
|
||||||
|
// Console.WriteLine("Trying {0}", returnedUri);
|
||||||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
|
||||||
|
|
||||||
|
AssertHttpResponse(returnedUri, testResponse);
|
||||||
|
|
||||||
|
Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
|
||||||
|
|
||||||
|
List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
|
||||||
|
Assert.That(events.Count, Is.EqualTo(1));
|
||||||
|
EventParams eventParams = events[0];
|
||||||
|
Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
|
||||||
|
|
||||||
|
UUID returnKey;
|
||||||
|
string rawReturnKey = eventParams.Params[0].ToString();
|
||||||
|
string method = eventParams.Params[1].ToString();
|
||||||
|
string body = eventParams.Params[2].ToString();
|
||||||
|
|
||||||
|
Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
|
||||||
|
Assert.That(method, Is.EqualTo("GET"));
|
||||||
|
Assert.That(body, Is.EqualTo(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AssertHttpResponse(string uri, string expectedResponse)
|
||||||
|
{
|
||||||
|
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
|
||||||
|
|
||||||
|
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
|
||||||
|
{
|
||||||
|
using (Stream stream = webResponse.GetResponseStream())
|
||||||
|
{
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
Assert.That(reader.ReadToEnd(), Is.EqualTo(expectedResponse));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
// Store an avatar with a different height from default in a notecard.
|
// Store an avatar with a different height from default in a notecard.
|
||||||
UUID userId = TestHelpers.ParseTail(0x1);
|
UUID userId = TestHelpers.ParseTail(0x1);
|
||||||
float firstHeight = 1.9f;
|
float firstHeight = 1.9f;
|
||||||
float secondHeight = 2.1f;
|
// float secondHeight = 2.1f;
|
||||||
string firstAppearanceNcName = "appearanceNc1";
|
string firstAppearanceNcName = "appearanceNc1";
|
||||||
string secondAppearanceNcName = "appearanceNc2";
|
string secondAppearanceNcName = "appearanceNc2";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue