Overzelous HTTP request filter

Ask technical support questions about other topics
User avatar
Kayaker Magic
Posts: 354
Joined: Sun Dec 01, 2013 8:40 am
Has thanked: 52 times
Been thanked: 393 times

Re: Overzelous HTTP request filter

Post by Kayaker Magic »

Oren Hurvitz wrote:* Script B can now use llHttpRequest() to call Script A.
But this is the step that does not work! Script A and B are in prims in different worlds, probably in different servers, but on the same local area network. So when script B does the llHTTPRequest() call to script A, that is an HTTP request on the local area network and that is blocked by OpenSim.

In my application, the prims would occasionally need to make other requests from the server, and the URLs of the other prims can be returned then. So polling would not be necessary if the prims had a way to talk directly to each other. But since HTTPRequest is blocked for prim-to-prim calls, the only way to get a message from Script B to Script A is for Script B to send it to the server, and have Script A constantly poll the server to ask if there are any messages. That would use a lot of server resources so I'm not doing that in this application.
User avatar
Oren Hurvitz
Posts: 361
Joined: Sun Dec 23, 2012 8:42 am
Has thanked: 19 times
Been thanked: 499 times
Contact:

Re: Overzelous HTTP request filter

Post by Oren Hurvitz »

Ah, I didn't realize that the hostname would resolve to the internal IP even on other servers within the network.

I'll look into having llRequestUrl() return the external IP itself, instead of the hostname.
User avatar
Kayaker Magic
Posts: 354
Joined: Sun Dec 01, 2013 8:40 am
Has thanked: 52 times
Been thanked: 393 times

Re: Overzelous HTTP request filter

Post by Kayaker Magic »

I have to run now, but I will post a little test script to show the problem when I get back.
User avatar
Kayaker Magic
Posts: 354
Joined: Sun Dec 01, 2013 8:40 am
Has thanked: 52 times
Been thanked: 393 times

Re: Overzelous HTTP request filter

Post by Kayaker Magic »

This topic HAS now cycled around until it IS the same now as viewtopic.php?f=11&t=2914
In that post I said "I can't send HTTP requests from one prim to another", Oren's answer: that is disabled in OpenSim for security reasons.
(It works in SL and in IW, it works if script A is in Kitely and script B is in SL or visa versa)
So I tried moving all the HTTP requests to my WEB hosting server, they say "sending HTTP requests to an address with a port number is disabled for security reasons". I'm setting up another server.
In the mean time, Oren says:
* Script B can now use llHttpRequest() to call Script A.
NO! that is the gist of my other thread that Oren said is disabled for security reasons!

To demonstrate this, create two prims, PrimA and PrimB. Put the following script in Prim B. It will dump a URL out to local chat. Cut out that URL and try it in the address line of your browser, you will see Hello World! Then paste the URL into the url string in Script A below. Put Script A in Prim A and click on it. Each click tries to do an HTTP request to the Prim B URL, but gets the following error message:
llHttpRequest: Request to <script b URL> disallowed by filter.

The URLs that llRequestURL returns do not look like requests to the local server, I assume the routers at Amazon notice that they loop back to a local server and optimize them for you, and then OpenSim refuses to accept them. Is there a way to fix the test in OpenSim so it refuses all requests to the local network EXCEPT the ones from prim to prim? Then we would have a way to communicate between prims again.

Code: Select all

        //Script B
        //put this script in Prim B
        //generates a URL and displays it in local chat
        //cut that out of local chat and paste it into the url string of Script A
        //Or paste it into the address line of your brouser to see what is supposed to happen
        //when an HTTP request is sent to that address, you should see messages from this prim
        //and messages at the requesting end.
string urlB="";
key urlRequestID;

default
{
    state_entry()
    {
        llSay(0, "free URLs "+(string)llGetFreeURLs());
        urlRequestID = llRequestURL();  //ask for a URL
    }
    
    http_request(key id, string method, string body)
    {
        integer responseStatus = 400;
        string responseBody = "Unsupported method";
 
        if (method == URL_REQUEST_DENIED)
            llOwnerSay("The following error occurred while attempting to get a free URL for this device:\n" + body);
        else if (method == URL_REQUEST_GRANTED)
        {
            urlB = body;
            llOwnerSay("url is "+urlB);
            return;
        }
        else if (method == "GET")
        {
            string args=llGetHTTPHeader(id,"x-query-string" );
            llOwnerSay("I got a GET\nargs="+args+"\nbody="+body);
            responseStatus = 200;
            responseBody = "Hello world!";
        }
        else if (method == "POST")
        {
            llOwnerSay("I got a POST\nbody="+body);
            responseStatus = 200;
            responseBody = "POST world!";
        }
        else if (method == "PUT")
            llOwnerSay("I got a PUT");
        llHTTPResponse(id, responseStatus, responseBody);
    }
}

Code: Select all

    //Script A 
    //HTTPRequest test
    //Put this script in prim A
    //paste the URL from Script B into the following string:
    //(don't use the address I left there, it has probably expired)
    //then touch the prim
string url=" http://ec2-54-193-199-92.us-west-1.compute.amazonaws.com:9001/lslhttp/d3e857ce-d481-455d-9465-1ce1730bca15/";
default
{
    touch_start(integer num)
    {
        llHTTPRequest(url,[],"");   //make the request
    } //touch_start
            //display the response, easy as 3.14159
    http_response(key request_id, integer status, list metadata, string body)
    {
        llOwnerSay("HTTP Responce status="+(string)status+"\n"+body);
    }

}
User avatar
Oren Hurvitz
Posts: 361
Joined: Sun Dec 23, 2012 8:42 am
Has thanked: 19 times
Been thanked: 499 times
Contact:

Re: Overzelous HTTP request filter

Post by Oren Hurvitz »

I've tested, and using the IP instead of the hostname fixes this problem.

Eventually we'll make this change to the system, but you don't have to wait: with just a small hack, you can start using this solution immediately. The hack is to convert the hostname that you get from llRequestURL() into an IP. This is straightforward because the hostname includes the IP.

E.g.:

http://ec2-54-219-82-196.us-west-1.comp ... fe1ed9e2d/
-> http://54.219.82.196:9000/lslhttp/02778 ... fe1ed9e2d/

(In order to make this future-proof, you should check if the hostname starts with "ec2-". If it doesn't then this means that we've already released the fix, and you're already getting an IP.)
User avatar
Kayaker Magic
Posts: 354
Joined: Sun Dec 01, 2013 8:40 am
Has thanked: 52 times
Been thanked: 393 times

Re: Overzelous HTTP request filter

Post by Kayaker Magic »

Oren Hurvitz wrote:with just a small hack
Haha! I love small hacks! Thank you!

However, this hack will only work on Kitely. Is this a problem only on Kitely? Is it potentially a problem on any grid? I do recall being surprised to find out that prims CAN communicate on OSGrid in some places, but I assumed they had left the security gates wide open on purpose.

Writing a product that depends on prims communicating with llRequestURL is going to be a support problem. You can't use it in the default OSGrid setup unless you set up the ExternalHostNameForLSL line properly in the OpenSim.ini.
User avatar
Kayaker Magic
Posts: 354
Joined: Sun Dec 01, 2013 8:40 am
Has thanked: 52 times
Been thanked: 393 times

Re: Overzelous HTTP request filter

Post by Kayaker Magic »

Well, the small hack turned out to be easy to do with a regexp, but not so fun to do in LSL with the functions we have:

Code: Select all

string myurl="http://ec2-54-177-75-185.us-west-1.compute.amazonaws.com:9002/lslhttp/cf8537b4-3758-4c3c-a2fd-d3fa60242820/";
default
{
    state_entry()
    {
        llOwnerSay(llGetSubString(myurl,0,10));
            if (llGetSubString(myurl,0,10)=="http://ec2-")     //if this is a kitely style URL
            {                       //convert it to an IP number
                list ipl=llParseString2List(myurl,["-","."],[]);    //break on hyphen or dot
                list parts=llParseString2List(myurl,["/",":"],[]);  //break on slash or colon
                            //dig out the 4 parts of the IP address from the first list
                myurl="http://"+llList2String(ipl,1)+"."+llList2String(ipl,2)+"."+llList2String(ipl,3)+"."+llList2String(ipl,4)+":";
                            //dig the port number and the rest out of the second list
                myurl += llList2String(parts,2)+"/"+llList2String(parts,3)+"/"+llList2String(parts,4)+"/";
            }
        llOwnerSay(myurl);
    }
}

User avatar
Oren Hurvitz
Posts: 361
Joined: Sun Dec 23, 2012 8:42 am
Has thanked: 19 times
Been thanked: 499 times
Contact:

Re: Overzelous HTTP request filter

Post by Oren Hurvitz »

That's some heroic string manipulation!

We're going to release the IP fix this week, so soon you won't need this hack.
These users thanked the author Oren Hurvitz for the post (total 2):
Moonrise AzaleeMike Lorrey
Post Reply