OpenSim.Region.ScriptEngine.Shared.Api.LSL_Api.llHTTPRequest C# (CSharp) Method

llHTTPRequest() public method

public llHTTPRequest ( string url, OpenSim.Region.ScriptEngine.Shared.LSL_Types.list parameters, string body ) : OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString
url string
parameters OpenSim.Region.ScriptEngine.Shared.LSL_Types.list
body string
return OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString
        public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
        {
            // Partial implementation: support for parameter flags needed
            //   see http://wiki.secondlife.com/wiki/LlHTTPRequest
            // parameter flags support are implemented in ScriptsHttpRequests.cs
            //   in StartHttpRequest

            m_host.AddScriptLPS(1);
            IHttpRequestModule httpScriptMod =
                m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
            List<string> param = new List<string>();
            bool  ok;
            Int32 flag;

            for (int i = 0; i < parameters.Data.Length; i += 2)
            {
                ok = Int32.TryParse(parameters.Data[i].ToString(), out flag);
                if (!ok || flag < 0 ||
                    flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE)
                {
                    Error("llHTTPRequest", "Parameter " + i.ToString() + " is an invalid flag");
                }

                param.Add(parameters.Data[i].ToString());       //Add parameter flag

                if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER)
                {
                    param.Add(parameters.Data[i+1].ToString()); //Add parameter value
                }
                else
                {
                    //Parameters are in pairs and custom header takes
                    //arguments in pairs so adjust for header marker.
                    ++i;

                    //Maximum of 8 headers are allowed based on the
                    //Second Life documentation for llHTTPRequest.
                    for (int count = 1; count <= 8; ++count)
                    {
                        //Enough parameters remaining for (another) header?
                        if (parameters.Data.Length - i < 2)
                        {
                            //There must be at least one name/value pair for custom header
                            if (count == 1)
                                Error("llHTTPRequest", "Missing name/value for custom header at parameter " + i.ToString());
                            break;
                        }

                        if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase))
                            Error("llHTTPRequest", "Name is invalid as a custom header at parameter " + i.ToString());

                        param.Add(parameters.Data[i].ToString());
                        param.Add(parameters.Data[i+1].ToString());

                        //Have we reached the end of the list of headers?
                        //End is marked by a string with a single digit.
                        if (i+2 >= parameters.Data.Length ||
                            Char.IsDigit(parameters.Data[i].ToString()[0]))
                        {
                            break;
                        }

                        i += 2;
                    }
                }
            }

            Vector3 position = m_host.AbsolutePosition;
            Vector3 velocity = m_host.Velocity;
            Quaternion rotation = m_host.RotationOffset;
            string ownerName = String.Empty;
            ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID);
            if (scenePresence == null)
                ownerName = resolveName(m_host.OwnerID);
            else
                ownerName = scenePresence.Name;

            RegionInfo regionInfo = World.RegionInfo;

            Dictionary<string, string> httpHeaders = new Dictionary<string, string>();

            string shard = "OpenSim";
            IConfigSource config = m_ScriptEngine.ConfigSource;
            if (config.Configs["Network"] != null)
            {
                shard = config.Configs["Network"].GetString("shard", shard);
            }

            httpHeaders["X-SecondLife-Shard"] = shard;
            httpHeaders["X-SecondLife-Object-Name"] = m_host.Name;
            httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString();
            httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.RegionLocX, regionInfo.RegionLocY);
            httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z);
            httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z);
            httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W);
            httpHeaders["X-SecondLife-Owner-Name"] = ownerName;
            httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString();
            string userAgent = config.Configs["Network"].GetString("user_agent", null);
            if (userAgent != null)
                httpHeaders["User-Agent"] = userAgent;

            // See if the URL contains any header hacks
            string[] urlParts = url.Split(new char[] {'\n'});
            if (urlParts.Length > 1)
            {
                // Iterate the passed headers and parse them
                for (int i = 1 ; i < urlParts.Length ; i++ )
                {
                    // The rest of those would be added to the body in SL.
                    // Let's not do that.
                    if (urlParts[i] == String.Empty)
                        break;

                    // See if this could be a valid header
                    string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
                    if (headerParts.Length != 2)
                        continue;

                    string headerName = headerParts[0].Trim();
                    string headerValue = headerParts[1].Trim();

                    // Filter out headers that could be used to abuse
                    // another system or cloak the request
                    if (headerName.ToLower() == "x-secondlife-shard" ||
                        headerName.ToLower() == "x-secondlife-object-name" ||
                        headerName.ToLower() == "x-secondlife-object-key" ||
                        headerName.ToLower() == "x-secondlife-region" ||
                        headerName.ToLower() == "x-secondlife-local-position" ||
                        headerName.ToLower() == "x-secondlife-local-velocity" ||
                        headerName.ToLower() == "x-secondlife-local-rotation" ||
                        headerName.ToLower() == "x-secondlife-owner-name" ||
                        headerName.ToLower() == "x-secondlife-owner-key" ||
                        headerName.ToLower() == "connection" ||
                        headerName.ToLower() == "content-length" ||
                        headerName.ToLower() == "from" ||
                        headerName.ToLower() == "host" ||
                        headerName.ToLower() == "proxy-authorization" ||
                        headerName.ToLower() == "referer" ||
                        headerName.ToLower() == "trailer" ||
                        headerName.ToLower() == "transfer-encoding" ||
                        headerName.ToLower() == "via" ||
                        headerName.ToLower() == "authorization")
                        continue;

                    httpHeaders[headerName] = headerValue;
                }

                // Finally, strip any protocol specifier from the URL
                url = urlParts[0].Trim();
                int idx = url.IndexOf(" HTTP/");
                if (idx != -1)
                    url = url.Substring(0, idx);
            }

            string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
            Regex r = new Regex(authregex);
            int[] gnums = r.GetGroupNumbers();
            Match m = r.Match(url);
            if (m.Success)
            {
                for (int i = 1; i < gnums.Length; i++)
                {
                    //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
                    //CaptureCollection cc = g.Captures;
                }
                if (m.Groups.Count == 5)
                {
                    httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
                    url = m.Groups[1].ToString() + m.Groups[4].ToString();
                }
            }

            HttpInitialRequestStatus status;
            UUID reqID
                = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status);

            if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER)
                Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url));

            if (reqID != UUID.Zero)
                return reqID.ToString();
            else
                return null;
        }
LSL_Api