From 06871d51dd47cd59185e2123f8235b4d79aee02c Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 22 Sep 2009 05:13:50 +0100 Subject: [PATCH 1/4] Disable the handler execution for poll services until the ramifications can be studied --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 5d83e34f37..5c9fa9bd0d 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -260,11 +260,11 @@ namespace OpenSim.Framework.Servers.HttpServer PollServiceEventArgs psEvArgs; if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs)) { - OSHttpRequest req = new OSHttpRequest(context, request); +// OSHttpRequest req = new OSHttpRequest(context, request); PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request); - req.Headers["X-PollServiceID"] = psreq.RequestID.ToString(); - HandleRequest(req, null); +// req.Headers["X-PollServiceID"] = psreq.RequestID.ToString(); +// HandleRequest(req, null); m_PollServiceManager.Enqueue(psreq); //DoHTTPGruntWork(psEvArgs.NoEvents(),new OSHttpResponse(new HttpResponse(context, request))); } From c5be401d46dfbb1e47927b4123130c43c6a054b5 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 22 Sep 2009 05:24:22 +0100 Subject: [PATCH 2/4] Remove support for executing a handler on poll. It caused other issues --- .../Servers/HttpServer/BaseHttpServer.cs | 38 ++++++------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 5c9fa9bd0d..0198960498 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -337,24 +337,19 @@ namespace OpenSim.Framework.Servers.HttpServer // handled //m_log.Debug("[BASE HTTP SERVER]: Handling Request" + request.RawUrl); - // If the response is null, then we're not going to respond here. This case - // triggers when we're at the head of a HTTP poll - // - if (response != null) + IHttpAgentHandler agentHandler; + + if (TryGetAgentHandler(request, response, out agentHandler)) { - IHttpAgentHandler agentHandler; - - if (TryGetAgentHandler(request, response, out agentHandler)) + if (HandleAgentRequest(agentHandler, request, response)) { - if (HandleAgentRequest(agentHandler, request, response)) - { - return; - } + return; } - - //response.KeepAlive = true; - response.SendChunked = false; } + + //response.KeepAlive = true; + response.SendChunked = false; + IRequestHandler requestHandler; string path = request.RawUrl; @@ -368,8 +363,7 @@ namespace OpenSim.Framework.Servers.HttpServer // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. byte[] buffer = null; - if (response != null) - response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. + response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. if (requestHandler is IStreamedRequestHandler) @@ -425,12 +419,7 @@ namespace OpenSim.Framework.Servers.HttpServer //m_log.Warn("[HTTP]: " + requestBody); } - // If we're not responding, we dont' care about the reply - // - if (response == null) - HTTPRequestHandler.Handle(path, keysvals); - else - DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); + DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); return; } else @@ -445,11 +434,6 @@ namespace OpenSim.Framework.Servers.HttpServer } } - // The handler has run and we're not yet ready to respond, bail - // - if (response == null) - return; - request.InputStream.Close(); // HTTP IN support. The script engine taes it from here From dafe5bf05f6d85d4140a0b733f0fbf9a5c43cf37 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 22 Sep 2009 06:19:02 +0100 Subject: [PATCH 3/4] Completely remove the prior implementation of the request event handling on poll handlers. Introduce a new delegate on the PollServiceEventArgs that allow access to the request headers and body. --- OpenSim/Framework/Console/RemoteConsole.cs | 2 +- .../Servers/HttpServer/BaseHttpServer.cs | 78 ++++++++++--------- .../HttpServer/PollServiceEventArgs.cs | 5 +- .../EventQueue/EventQueueGetModule.cs | 2 +- 4 files changed, 46 insertions(+), 41 deletions(-) diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 76276a5cb2..c27072c2c4 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -198,7 +198,7 @@ namespace OpenSim.Framework.Console string uri = "/ReadResponses/" + sessionID.ToString() + "/"; m_Server.AddPollServiceHTTPHandler(uri, HandleHttpPoll, - new PollServiceEventArgs(HasEvents, GetEvents, NoEvents, + new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID)); XmlDocument xmldoc = new XmlDocument(); diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 0198960498..db87958733 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -256,17 +256,51 @@ namespace OpenSim.Framework.Servers.HttpServer IHttpClientContext context = (IHttpClientContext)source; IHttpRequest request = args.Request; - PollServiceEventArgs psEvArgs; + if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs)) { -// OSHttpRequest req = new OSHttpRequest(context, request); - PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request); -// req.Headers["X-PollServiceID"] = psreq.RequestID.ToString(); -// HandleRequest(req, null); + + if (psEvArgs.Request != null) + { + OSHttpRequest req = new OSHttpRequest(context, request); + + Stream requestStream = req.InputStream; + + Encoding encoding = Encoding.UTF8; + StreamReader reader = new StreamReader(requestStream, encoding); + + string requestBody = reader.ReadToEnd(); + + Hashtable keysvals = new Hashtable(); + Hashtable headervals = new Hashtable(); + + string[] querystringkeys = req.QueryString.AllKeys; + string[] rHeaders = req.Headers.AllKeys; + + keysvals.Add("body", requestBody); + keysvals.Add("uri", req.RawUrl); + keysvals.Add("content-type", req.ContentType); + keysvals.Add("http-method", req.HttpMethod); + + foreach (string queryname in querystringkeys) + { + keysvals.Add(queryname, req.QueryString[queryname]); + } + + foreach (string headername in rHeaders) + { + headervals[headername] = req.Headers[headername]; + } + + keysvals.Add("headers",headervals); + keysvals.Add("querystringkeys", querystringkeys); + + psEvArgs.Request(psreq.RequestID, keysvals); + } + m_PollServiceManager.Enqueue(psreq); - //DoHTTPGruntWork(psEvArgs.NoEvents(),new OSHttpResponse(new HttpResponse(context, request))); } else { @@ -279,48 +313,16 @@ namespace OpenSim.Framework.Servers.HttpServer { OSHttpRequest req = new OSHttpRequest(context, request); OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); - //resp.KeepAlive = req.KeepAlive; - //m_log.Info("[Debug BASE HTTP SERVER]: Got Request"); - //HttpServerContextObj objstate= new HttpServerContextObj(req,resp); - //ThreadPool.QueueUserWorkItem(new WaitCallback(ConvertIHttpClientContextToOSHttp), (object)objstate); HandleRequest(req, resp); } public void ConvertIHttpClientContextToOSHttp(object stateinfo) { HttpServerContextObj objstate = (HttpServerContextObj)stateinfo; - //OSHttpRequest request = new OSHttpRequest(objstate.context,objstate.req); - //OSHttpResponse resp = new OSHttpResponse(new HttpServer.HttpResponse(objstate.context, objstate.req)); OSHttpRequest request = objstate.oreq; OSHttpResponse resp = objstate.oresp; - //OSHttpResponse resp = new OSHttpResponse(new HttpServer.HttpResponse(objstate.context, objstate.req)); - /* - request.AcceptTypes = objstate.req.AcceptTypes; - request.ContentLength = (long)objstate.req.ContentLength; - request.Headers = objstate.req.Headers; - request.HttpMethod = objstate.req.Method; - request.InputStream = objstate.req.Body; - foreach (string str in request.Headers) - { - if (str.ToLower().Contains("content-type: ")) - { - request.ContentType = str.Substring(13, str.Length - 13); - break; - } - } - //request.KeepAlive = objstate.req. - foreach (HttpServer.HttpInput httpinput in objstate.req.QueryString) - { - request.QueryString.Add(httpinput.Name, httpinput[httpinput.Name]); - } - - //request.Query = objstate.req.//objstate.req.QueryString; - //foreach ( - //request.QueryString = objstate.req.QueryString; - - */ HandleRequest(request,resp); } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 61cb8aaab1..7ed9e5ce95 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -30,6 +30,7 @@ using System.Collections; using OpenMetaverse; namespace OpenSim.Framework.Servers.HttpServer { + public delegate void RequestMethod(UUID requestID, Hashtable request); public delegate bool HasEventsMethod(UUID requestID, UUID pId); public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId, string request); @@ -41,9 +42,11 @@ namespace OpenSim.Framework.Servers.HttpServer public HasEventsMethod HasEvents; public GetEventsMethod GetEvents; public NoEventsMethod NoEvents; + public RequestMethod Request; public UUID Id; - public PollServiceEventArgs(HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId) + public PollServiceEventArgs(RequestMethod Request, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId) { + Request = Request; HasEvents = pHasEvents; GetEvents = pGetEvents; NoEvents = pNoEvents; diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs index 57c5198fb5..0cdd9a8e31 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs @@ -316,7 +316,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue // This will persist this beyond the expiry of the caps handlers MainServer.Instance.AddPollServiceHTTPHandler( - capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(HasEvents, GetEvents, NoEvents, agentID)); + capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); Random rnd = new Random(Environment.TickCount); lock (m_ids) From 97c18caa766e2dd72b152b78827ef554f2054f8c Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 22 Sep 2009 17:04:34 +0100 Subject: [PATCH 4/4] Thank you, Intari, for a patch that implements the missing pieces of Http-in and makes the host name for URL generation configurable. Applied with changes: llGetSimulatorHostname was not changed, because the change breaks existing behavior and carries a data exposure risk. That value needs to be configurable, the proposed fixed change is not acceptable. --- .../HttpServer/PollServiceEventArgs.cs | 4 +- .../Scripting/LSLHttp/UrlModule.cs | 306 +++++++++++++++--- .../Shared/Api/Implementation/LSL_Api.cs | 14 +- .../Shared/Api/Interface/ILSL_Api.cs | 2 +- .../Shared/Api/Runtime/LSL_Stub.cs | 4 +- bin/OpenSim.ini.example | 4 + 6 files changed, 287 insertions(+), 47 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 7ed9e5ce95..9d512c6249 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -44,9 +44,9 @@ namespace OpenSim.Framework.Servers.HttpServer public NoEventsMethod NoEvents; public RequestMethod Request; public UUID Id; - public PollServiceEventArgs(RequestMethod Request, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId) + public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId) { - Request = Request; + Request = pRequest; HasEvents = pHasEvents; GetEvents = pGetEvents; NoEvents = pNoEvents; diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 6a2a6c8728..2d81e4c191 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -54,29 +54,42 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { public UUID requestID; public Dictionary headers; - public string body; - public ManualResetEvent ev; + public string body; + public int responseCode; + public string responseBody; + public ManualResetEvent ev; + public bool requestDone; + public int startTime; + public string uri; } public class UrlModule : ISharedRegionModule, IUrlModule { -// private static readonly ILog m_log = -// LogManager.GetLogger( -// MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); private Dictionary m_RequestMap = new Dictionary(); private Dictionary m_UrlMap = - new Dictionary(); + new Dictionary(); + private int m_TotalUrls = 100; - private IHttpServer m_HttpServer = null; + private IHttpServer m_HttpServer = null; + + private string m_ExternalHostNameForLSL = ""; public Type ReplaceableInterface { get { return null; } + } + + private Hashtable HandleHttpPoll(Hashtable request) + { + return new Hashtable(); } public string Name @@ -85,7 +98,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } public void Initialise(IConfigSource config) - { + { + m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); } public void PostInitialise() @@ -116,8 +130,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void Close() { - } - + } public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) { UUID urlcode = UUID.Random(); @@ -128,8 +141,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; - } - string url = "http://"+System.Environment.MachineName+":"+m_HttpServer.Port.ToString()+"/lslhttp/"+urlcode.ToString()+"/"; + } + string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; UrlData urlData = new UrlData(); urlData.hostID = host.UUID; @@ -139,9 +152,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp urlData.urlcode = urlcode; urlData.requests = new Dictionary(); - m_UrlMap[url] = urlData; - - m_HttpServer.AddHTTPHandler("/lslhttp/"+urlcode.ToString()+"/", HttpRequestHandler); + + m_UrlMap[url] = urlData; + + string uri = "/lslhttp/" + urlcode.ToString() + "/"; + + m_HttpServer.AddPollServiceHTTPHandler(uri,HandleHttpPoll, + new PollServiceEventArgs(HttpRequestHandler,HasEvents, GetEvents, NoEvents, + urlcode)); engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); } @@ -162,10 +180,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { lock (m_UrlMap) { - UrlData data; - - if (!m_UrlMap.TryGetValue(url, out data)) - return; + UrlData data; + + if (!m_UrlMap.TryGetValue(url, out data)) + { + return; + } foreach (UUID req in data.requests.Keys) m_RequestMap.Remove(req); @@ -174,14 +194,38 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_UrlMap.Remove(url); } } - + public void HttpResponse(UUID request, int status, string body) - { + { + if (m_RequestMap.ContainsKey(request)) + { + UrlData urlData = m_RequestMap[request]; + RequestData requestData=urlData.requests[request]; + urlData.requests[request].responseCode = status; + urlData.requests[request].responseBody = body; + //urlData.requests[request].ev.Set(); + urlData.requests[request].requestDone=true; + } + else + { + m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); + } } - public string GetHttpHeader(UUID request, string header) - { - return String.Empty; + public string GetHttpHeader(UUID requestId, string header) + { + if (m_RequestMap.ContainsKey(requestId)) + { + UrlData urlData=m_RequestMap[requestId]; + string value; + if (urlData.requests[requestId].headers.TryGetValue(header,out value)) + return value; + } + else + { + m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); + } + return String.Empty; } public int GetFreeUrls() @@ -231,27 +275,215 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp foreach (string urlname in removeURLs) m_UrlMap.Remove(urlname); } - } + } + private void RemoveUrl(UrlData data) { - m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); - } + m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/"); + } + + private Hashtable NoEvents(UUID requestID, UUID sessionID) + { + Hashtable response = new Hashtable(); + UrlData url; + lock (m_RequestMap) + { + if (!m_RequestMap.ContainsKey(requestID)) + return response; + url = m_RequestMap[requestID]; + } + + if (System.Environment.TickCount - url.requests[requestID].startTime > 25000) + { + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + //remove from map + lock (url) + { + url.requests.Remove(requestID); + m_RequestMap.Remove(requestID); + } + + return response; + } - private Hashtable HttpRequestHandler(Hashtable request) + + return response; + } + + private bool HasEvents(UUID requestID, UUID sessionID) { - string uri = request["uri"].ToString(); - //A solution to this ugly mess would be to use only the /lslhttp// part of the URI as the key. - UrlData url = m_UrlMap["http://"+System.Environment.MachineName+":"+m_HttpServer.Port.ToString()+uri]; + UrlData url=null; - //UUID.Random() below is a hack! Eventually we will do HTTP requests and responses properly. - url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { UUID.Random().ToString(), request["http-method"].ToString(), request["body"].ToString() }); + lock (m_RequestMap) + { + if (!m_RequestMap.ContainsKey(requestID)) + { + return false; + } + url = m_RequestMap[requestID]; + if (!url.requests.ContainsKey(requestID)) + { + return false; + } + } - Hashtable response = new Hashtable(); - response["int_response_code"] = 200; - response["str_response_string"] = "This is a generic response as OpenSim does not yet support proper responses. Your request has been passed to the object."; + if (System.Environment.TickCount-url.requests[requestID].startTime>25000) + { + return true; + } - return response; + if (url.requests[requestID].requestDone) + return true; + else + return false; + + } + private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) + { + UrlData url = null; + RequestData requestData = null; + + lock (m_RequestMap) + { + if (!m_RequestMap.ContainsKey(requestID)) + return NoEvents(requestID,sessionID); + url = m_RequestMap[requestID]; + requestData = url.requests[requestID]; + } + + if (!requestData.requestDone) + return NoEvents(requestID,sessionID); + + Hashtable response = new Hashtable(); + + if (System.Environment.TickCount - requestData.startTime > 25000) + { + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + return response; + } + //put response + response["int_response_code"] = requestData.responseCode; + response["str_response_string"] = requestData.responseBody; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + + //remove from map + lock (url) + { + url.requests.Remove(requestID); + m_RequestMap.Remove(requestID); + } + + return response; + } + public void HttpRequestHandler(UUID requestID, Hashtable request) + { + lock (request) + { + string uri = request["uri"].ToString(); + + try + { + Hashtable headers = (Hashtable)request["headers"]; + + string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; + + int pos1 = uri.IndexOf("/");// /lslhttp + int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ + int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp// + string uri_tmp = uri.Substring(0, pos3 + 1); + //HTTP server code doesn't provide us with QueryStrings + string pathInfo; + string queryString; + queryString = ""; + + pathInfo = uri.Substring(pos3); + + UrlData url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp]; + + //for llGetHttpHeader support we need to store original URI here + //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers + //as per http://wiki.secondlife.com/wiki/LlGetHTTPHeader + + RequestData requestData = new RequestData(); + requestData.requestID = requestID; + requestData.requestDone = false; + requestData.startTime = System.Environment.TickCount; + requestData.uri = uri; + if (requestData.headers == null) + requestData.headers = new Dictionary(); + + foreach (DictionaryEntry header in headers) + { + string key = (string)header.Key; + string value = (string)header.Value; + requestData.headers.Add(key, value); + } + foreach (DictionaryEntry de in request) + { + if (de.Key.ToString() == "querystringkeys") + { + System.String[] keys = (System.String[])de.Value; + foreach (String key in keys) + { + if (request.ContainsKey(key)) + { + string val = (String)request[key]; + queryString = queryString + key + "=" + val + "&"; + } + } + if (queryString.Length > 1) + queryString = queryString.Substring(0, queryString.Length - 1); + + } + + } + + //if this machine is behind DNAT/port forwarding, currently this is being + //set to address of port forwarding router + requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; + requestData.headers["x-path-info"] = pathInfo; + requestData.headers["x-query-string"] = queryString; + requestData.headers["x-script-url"] = url.url; + + requestData.ev = new ManualResetEvent(false); + lock (url.requests) + { + url.requests.Add(requestID, requestData); + } + lock (m_RequestMap) + { + //add to request map + m_RequestMap.Add(requestID, url); + } + + url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); + + //send initial response? + Hashtable response = new Hashtable(); + + return; + + } + catch (Exception we) + { + //Hashtable response = new Hashtable(); + m_log.Warn("[HttpRequestHandler]: http-in request failed"); + m_log.Warn(we.Message); + m_log.Warn(we.StackTrace); + } + } } private void OnScriptReset(uint localID, UUID itemID) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 02be98305d..b63147860f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7838,8 +7838,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llGetHTTPHeader(LSL_Key request_id, string header) { m_host.AddScriptLPS(1); - NotImplemented("llGetHTTPHeader"); - return String.Empty; + + if (m_UrlModule != null) + return m_UrlModule.GetHttpHeader(new UUID(request_id), header); + return String.Empty; } @@ -9117,13 +9119,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - public void llHTTPResponse(string url, int status, string body) + public void llHTTPResponse(LSL_Key id, int status, string body) { // Partial implementation: support for parameter flags needed // see http://wiki.secondlife.com/wiki/llHTTPResponse - m_host.AddScriptLPS(1); - NotImplemented("llHTTPResponse"); + m_host.AddScriptLPS(1); + + if (m_UrlModule != null) + m_UrlModule.HttpResponse(new UUID(id), status,body); } public void llResetLandBanList() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 41358e5f6b..a74e8dadc2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -201,7 +201,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llGroundRepel(double height, int water, double tau); LSL_Vector llGroundSlope(LSL_Vector offset); LSL_String llHTTPRequest(string url, LSL_List parameters, string body); - void llHTTPResponse(string url, int status, string body); + void llHTTPResponse(LSL_Key id, int status, string body); LSL_String llInsertString(string dst, int position, string src); void llInstantMessage(string user, string message); LSL_String llIntegerToBase64(int number); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 02ae28131f..a28e97bea6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -864,9 +864,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llHTTPRequest(url, parameters, body); } - public void llHTTPResponse(string url, int status, string body) + public void llHTTPResponse(LSL_Key id, int status, string body) { - m_LSL_Functions.llHTTPResponse(url, status, body); + m_LSL_Functions.llHTTPResponse(id, status, body); } public LSL_String llInsertString(string dst, int position, string src) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index d38c511ba2..e34378c545 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -305,6 +305,10 @@ http_listener_sslport = 9001 ; Use this port for SSL connections http_listener_ssl_cert = "" ; Currently unused, but will be used for OSHttpServer + ; Hostname to use in llRequestURL/llRequestSecureURL + ; if not defined - default machine name is being used + ; (on Windows this mean NETBIOS name - useably only inside local network) + ; ExternalHostNameForLSL=127.0.0.1 ; Uncomment below to enable llRemoteData/remote channels ; remoteDataPort = 20800