URLMap API

From Apez

Jump to: navigation, search

virtualID URLMap service

The URLMap service allows you to associate a static URL with a subdomain of your choice and have it automatically redirected to any URL target. That is great for keeping a static URL associated with the dynamic/changing URLs generated by the in-world HTTP server feature of LSL scripted objects.

For example, you might have an object in-world that counts visitors passing by and wish to access its statistics online. You could map the alias URL:

http://my-visitors.obj.virtualid.info

to the object, and keep it updated. Much easier to remember than a URL like:

http://sim3015.aditi.lindenlab.com:12046/cap/3ff4f3f2-ea08-76c1-cef6-a22b4a573a7c

(which changes every time the object crosses a sim, resets, changes owner, etc)

How does it work?

First, we'll show the simplest way to use it - save the details for below.

To create a new alias (or update an existing one), simply make a HTTP request like this in your script:

llHTTPRequest("http://api.virtualid.info/?op=set&a=my-visitors&t=http://sim3015.aditi.lindenlab.com:12046/cap/3ff4f3f2-ea08-76c1-cef6-a22b4a573a7c", [], "");

The part after op= is the operation - set in this case, which is used to create or update a mapping between an alias and a target URL. The alias is the subdomain used to access the object before the .obj.virtualid.info part.

Obviously, the string after a= is the alias - which you can choose. Note that they're global - so you'll need to choose one nobody else has used (alphanumeric or "-" characters, can't start with a digit or "-").

Finally, the string after t= is the target URL - where you wish the alias to be redirected.


Now, when you access http://my-visitors.obj.virtualid.info the service issues a standard HTTP 302 Redirect code to the accesing client. If that is a browser, for example, it will automatically and instantly access the target URL. (Note that if you're using this for inter-object communication in-world, be aware that llHTTPRequest() doesn't handle 302 Redirect, so you'll need to access the location and make an additional request to the supplied target)

Once you've created an alias the first time, you 'own' it and are the only one that can set it to a different value until either you delete it or it expires (see below for details). The default expiry is 30days from the last time is was updated.

If you have an Apez account (free) you can see a list of all your current aliases at any time here: www.apez.biz/urlmap.

There are several other parameters, but that's about it to get started! Copy and paste the example script text below to try it out.

Operations & Parameters

The URL parameters are in standard URL format: name=value pairs, separated by "&", with the first preceded by "?". If issuing a HTTP POST for operations that modify aliases, you can standard form encoding in the body instead. The set and delete operations must be via access to "api.virtualid.info", but others can be via either the api domain or the alias dopmain.

  • op: operation (optional) - one of redirect | lookup | proxy | set | delete. Defaults to redirect.
    • redirect (default) - issues a HTTP 302 Redirect to the target or an appropriate error status (e.g. 404 Not Found).
    • lookup - returns the target URL as the body of the response
    • set - create or update the target for an alias. If the alias already exists, it can only be updated if appropriate authentication or authorization is supplied (see following section). Can optionally create an automatic alias for the device's object key "k"<UUID>.
    • delete - delete alias (and optionally device key alias)
    • proxy - makes a request to the target server and returns its response directly to the client. note that it is only available if the target URL is in in-world object.
  • a: alias - the user defined string for the subdomain of the static URL. Can contain characters [a-z][A-Z][0-9] or "-", but cannot start with a digit or "-" and must have a length of 4-64 characters. For example, if an alias is "myalias1-2-300Z" the static URL created is "http://myalias1-2-300Z.obj.virtualid.info". A required parameter for operations set and delete via access to "api.virtualid.info", but optional when accessing the alias domain itself.
  • t: target - required for set operation. This is the target URL you'd like the alias mapped to. May need to be URL encoded (e.g. with llEscapeURL()).
  • exp: expiry (optional) - expiry period for the alias (in seconds). Defaults to 30days - which means an alias will stop functioning 30days after the last time the set operation was called (except if it is deleted of course). Maximum is one year, but 7-10 days is suggested.
  • aliaskey: alias device/object key (optional; default "0"/false) - if "1" for the set operation, in addition to the URL mapping from <alias>.obj.virtualid.info to the target, a mapping k<key>.obj.virtualid.info is also created (where <key> is the UUID/key of the calling object in-world)
  • gencap: generate capability (optional; default "0"/false) - if "1" then a new capability string is returned by operation set, which can be passed to subsequent set or delete operations to authorize the operation. The string map be up-to 256 bytes in length. Note that HTTP responses to llHTTPRequest() in an LSL script are triggered in all scripts with a http_response event in the same object (so only use this option if you trust all scripts in the object or the alias is sufficiently unguessable).
  • strongauth: strong authorization required - for set and delete operations (see following section).
  • caps: capabilities (optional) - a space separated list of capabilities (e.g. login capability, URLmap set capability - see section below). Note that after URL encoding, caps will actually be "+" or "%20" separated (either will work).
  • dev: device (optional) - device/object key. If supplied for delete operation, "k"<key> alias will be deleted in additional to the supplied alias (typically, this is the key of the device making the request). The 'key' alias must be owned by the authenticated agent.

Authentication & Authorization

Authentication refers to identifying who is making the request, whereas authorization deals with if an operation is authorized or not. No authentication or authorization is required for the operations redirect, lookup or proxy. There are two ways to identify the requesting agent (avatar) for the set and delete operations:

  • Allowing the service to identify the owner of the object making the request from in-world. This is the simplest as you don't need to do anything special.
    • SL passes the owner's avatar key in all HTTP header requests from in-world. A request from in-world can be identified by having these headers and originating from an IP address that belongs to the grid. It should be noted that IP addresses can be spoofed and headers set - so this is not 100% secure, but should serve most purposes - especially in cases where the alias is not public or easy to guess anyway.
    • Obviously, this isn't an option for calls to the service not made from in-world.
    • This authentication method is not supported for set and delete operations on an existing alias for which strongauth=1 was passed when initially set.
  • Supplying a login capability. This is a special string that can be obtained either directly from the general Apez web-services API (see Development) or via some script functions in the Apez.devkit.

There are also two ways to supply proof of authorization to the set and delete operations for updating or deleting an existing alias.

  • Passing a URLMap set capability, as returned by the set operation if gencap=1 was passed.
  • Passing a login capability as described above.

Tip

If your main purpose for static URL mapping is for inter-object communication in-world and/or communication from external servers to objects in-world for which you always know the UUID/key, a good strategy might be to generate difficult-to-guess aliases from a consistient mapping function that only you/your-scripts know. For example, you could use an alias like llMD5String(secret_string+(string)llGetKey(),secret_num) where the secret_string and secret_num are constant in all your scripts and server-side code. If the aliases are never publicly exposed via link messages or plain-text external network requests, then using non-strongauth set request is less of a problem since even in the unlikely event an attacker goes to the trouble of spoofing HTTP requests to the service identifying as you, they won't know which aliases to set in order to disrupt or access your objects anyway.

Example script

The LSL script below demonstrates simple usage.

// Apez Corp Example LSL script 
// This script is hereby placed in the public domain.
//
// {"obj":"Apez DevKit", "ver":"2.3", "src":"devkit/Apez-urlmap-example.lsl"}
// $Revision$


//
// This is an example of how to use the Apez URL mapping Affiliate Services REST API
// The URLmap service is convenient for having a static URL that can be updated in response
//  to a changing target URL - such as those generated by the http_request event.
// For details see http://wiki.apez.biz/Development


// This script creates a HTTP server for this object and maps a static alias which it
//  keeps up-to-date so that the object can always be accessed via the alias URL


key url_req_key;
key map_req_id;
string url;
string alias;
string aliasurl;
integer alias_last_updated; // unixtime
integer expiry_secs;
integer touch_count = 0;


// obtain a URL and update the static alias
setup()
{
        // Request a HTTP URL for this object
        url_req_key = llRequestURL();    
}


setAlias(string alias, string targetURL)
{
    // every alias has an expiry period (in seconds), which cannot be greater than 3 months.
    //  The script needs to update it before then to renew the period
    expiry_secs = 48*60*60; // only going to ask for 48hours for this example
    llSetTimerEvent(expiry_secs-60*60); // set URL again before it expires
    
    map_req_id = llHTTPRequest("http://api.virtualid.info/?op=set&a="+alias
                              +"&t="+llEscapeURL(targetURL)+"&exp="+(string)expiry_secs, [], "");
}


default
{
    state_entry()
    {
        setup();
    }

    on_rez(integer passed)
    {
        setup();
    }  
    
    http_request(key id, string method, string body)
    {
        if (method == URL_REQUEST_GRANTED)
        {
            url = body;
            llOwnerSay("SL assigned us the URL: " + url);
            
            // the user-defined alias/subdomain we want to map to this object
            //  must be a string of alphanumeric characters, can't start with a digit and must be <64 chars in length
            // (for this example we append the first few chars of the object key to make it different for each tester)
            alias = "myalias"+llGetSubString((string)llGetKey(),0,2);
            aliasurl = alias+".obj.virtualid.info";
            
            llOwnerSay("Requesting URL alias \""+aliasurl+"\" ...");
            
            setAlias(alias, url);
                        
        }
        else if (method == URL_REQUEST_DENIED)
        {
            llSay(0, "Something went wrong, no url. " + body);
        }
        else if (method == "GET")
        {
            string rsp = "Hello from object "+llGetObjectName()+"!\n"
                          +" owner: "+llKey2Name(llGetOwner())+"\n"
                          +" key: "+(string)llGetKey()+"\n"
                          +" touch count since reset: "+(string)touch_count;
            
            llHTTPResponse(id,200,rsp);
        }
        else
        {
            llHTTPResponse(id,405,"Unsupported Method");
        }
    }

    http_response(key request_id, integer status, list metadata, string body)
    {
        if (request_id == map_req_id)
        {
            llOwnerSay("Apez URLmap service said:"+body+" (status "+(string)status+")");
            
            if ((status >= 200) && (status < 300)) { // success
                llOwnerSay("You can now access this object via the URL http://"+aliasurl+"  (try it in your browser!)");
                alias_last_updated = llGetUnixTime();
            }
        }
    }

    changed(integer c)
    {
        if (c & (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )
        {
            setup();
        }
    }
    
    timer()
    {
        // set alias again before it expires (1hr early)
        if (llGetUnixTime() - alias_last_updated > expiry_secs - 65*60)
            setAlias(alias, url);
    }
    
    touch(integer num_detected)
    {
        touch_count++;
    }
  
}

FAQ

  • Is it reliable? What if your company goes away?
    • The service itself utilizes our servers and Amazon's cloud computing facilities. For the most part, if you believe Amazon.com is reliable enough then the URLMap service should be reliable enough too. Apez Corp it a real company that has been operating in Second Life since 2005 and we have no plans to go away. After all - Linden Labs could just as well 'go away' too!
  • How much does it cost?
    • It is free. We plan to keep it that way. However, if it is abused by developers or we experience huge volumes of traffic, we reserve the right to charge a small subscription in future just to cover costs (which are low). We promise this: there will always be a free-tier that will satisfy most small-medium sized users. Only very heavy users will ever be charged, if we're ever forced to do that. Mostly likely, we'll only charge for requests to the proxy operation (if you don't know what that is, you may never need worry!). If it comes to that, we'll give plenty of heads-up and lead-time - we're not going to just yank aliases at short notice!
  • Won't people use it for phishing attacks, objectionable content and such?
    • Currently, the SL in-world HTTP service doesn't support responses with type html/text - so it isn't possible to render a web page that could fool someone. Having said that, if you see any objectionable content under a .virtualid.info domain, please report it to us.
    • We are considering providing a proxy operation option to map content to html/text. If we decide to that we'll consider this question carefully. Also note that all created aliases are associated with an avatar.
Personal tools

A d v e r t i s m e n t