User:Darien Caldwell/HTTP-DNS

From Second Life Wiki
Jump to navigation Jump to search

Dynamic DNS service for HTTP-IN via Google App Engine:

NOTE: While the original version of this code did not provide true DNS service, it has since been updated to do so. Please read the original thread to understand the evolution of the code. A lot of good information and workarounds are also provided in the old thread!

http://forums-archive.secondlife.com/54/33/323981/1.html

One of the big issues with HTTP-IN is the fact that the URLs are dynamic and can change under many conditions. Many have balked at the requirements of having an external server to manage a Dynamic DNS service to keep track of these ever changing URLs. So here's a free solution that anyone can use, and expand with their needs.

Using this DNS, you can have servers register their URL 'service' and allow other in-world (and out of world) applications discover the URL for this service in a consistent manner. The Google App Engine is free and offers resource limits which should be able to support small to mid range applications. Of course, for a small fee you can purchase more resources from Google as well. (Resouce limits: http://developers.google.com/appengine/docs/quotas )


This is the basics, and has no verification or encryption, but should be fairly secure as long as you don't go around giving your service URL to people. Feel free to add on to it as you like. The code is released to the Public Domain. Enjoy.

Setup and Installation

  • First, download the files here:
http://home.comcast.net/~volfin/lsl-dns.zip

Or, you can find the contents of the zip file here:

http://wiki.secondlife.com/w/index.php?title=User:Darien_Caldwell/HTTP-DNS%20Code

Now, what to do with these files:

  • Go here to install Python 2.5 (if you don't already have it)
http://www.python.org/download/releases/2.5.4/
  • Download and install the App Engine SDK:
http://developers.google.com/appengine/downloads

The SDK will be installed into a subdirectory called 'google_appengine'.

  • Create a directory under the 'google_appengine' directory called 'lsl-dns'
  • Place the files from the zip file (dns.py and app.yaml) into this new directory.
  • Edit the app.yaml file to change the name of the application to the name you specified when you signed up for the service:
application: YOUR-APP-NAME-HERE <-- Change this
  • From the 'google_appengine' directory (where the SDK was installed), run this command from the console (DOS Prompt):
appcfg.py update lsl-dns/

This will install the application.

  • You're done.

The API Calls

Once it's installed you can start using it:

  • http://yourappname.appspot.com/?type=add&name=[NAME]&url=[URL]

Adds a new service named [NAME] with the HTTP-IN url [URL]. The URL must be converted to a string using llEscapeURL() first.

if the URL is added, returns the response 'Added', or 'Found' if the service
already exists. 
  • http://yourappname.appspot.com/?type=remove&name=[NAME]

Removes the given service named [NAME].

Returns 'Removed' if successful, or 'None' if the service wasn't found.
  • http://yourappname.appspot.com/?type=update&name=[NAME]&url=[URL]

Updates the service named [NAME] with the HTTP-IN url [URL].

The URL must be converted to a string using llEscapeURL() first.
If the URL is updated the response 'Updated' is returned.
If the service doesn't exist, a new service is added and 'Added' is returned.
  • http://yourappname.appspot.com/?type=retrieve&name=[NAME]

Retrieves the url of the given service named [NAME].

Returns the URL if the service is found, or 'None' if the service wasn't found.
the returned URL must be converted to a URL using llUnescapeURL()
  • http://yourappname.appspot.com/?type=list

Lists the available services currently stored.

Returns a Comma seperated list of service names, ending with the word 'END'.
if no services are defined, 'Empty' is returned.

Optimizing to stay in the Free Quota

Google App Engine is designed for high scalability, so it will try to use as much resources as it can to keep up with the load put on it. However, for someone in the free Quota, you may not want it to do that. :) So, to stay in the free quota you have to sacrifice some scalability and latency. But for SL this is generally okay to do.

The thing to do is make some simple changes to some Application configuration settings. Logging into your application dashboard (https://appengine.google.com/), on the left hand menu find Application Settings under the "Administration" subheading, and go there. Then change the settings shown below to match what you see here:

Application Instance Settings

Using the DNS URL

Once a service has been entered, you can use the serivce name in the URL to do automatic redirection.

Example:

You establish a service named 'Intro1'

The URL for the service is: http://sim3015.aditi.lindenlab.com:12046/cap/3ff4f3f2-ea08-76c1-cef6-a22b4a573a7c

By Navigating to http://yourappname.appspot.com/Intro1 The page will be automatically redirected to the service URL:

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

If the service name used in the URL is invalid, 'None' is returned.

Example LSL Script

<lsl>

string url = ""; string service_name = "Intro1"; key URL_KEY;


setup() {

   llReleaseURL(url);
   URL_KEY=llRequestURL();

}

default {

   state_entry()
   {
       llSetObjectName("HTTP Server");
       setup();
   }
   
   on_rez(integer n)
   {
       setup();
   }
   changed(integer c)
   {
if (c & (CHANGED_REGION

Advanced Version

There is an advanced version that has a very basic admin function, password protection, and verbose logging. Thanks goes to CrystalShard Foo for contributing her time to work with me on this.

The code can be found here:

http://wiki.secondlife.com/w/index.php?title=User:Darien_Caldwell/Advanced%20HTTP-DNS%20Code

Advanced API Calls

The API is much the same, but there are several new *optional* parameters that can be used.

  • wpass: Write protect password. If an entry has a write protect password set, it can't be updated or deleted without specificying this password.
  • rpass: Read Protect password. If an entry has a read protect password set, it can't be retrieved without specificying this password. It also can't be called via a DNS url.
  • hidden: Hidden status. If an entry is marked as hidden, it will not show up in the Entry List. 'list'ing the services with the admin password included will show hidden entries.
  • pass: A generic password parameter, takes the place of rpass, wpass, or both in various situations. If whien adding a service through an update, you specifiy 'pass', it will be set as the read and write passwords. specifying 'rpass' or 'wpass' will override this.
  • admin: Admin Password. The hard-coded Admin password allows global overriding of some actions, regardless of the entry password set. If an Admin password is set, only Add requests that include the admin password will be accepted. 'admin' can also be used to override update,remove,retrieve,and list.
The Admin password is hard coded in the dns.py file:

<python>

       admin_password = "adminpassword"        # This password enables you to have unrestricted access to the DNS

</python>

  • http://yourappname.appspot.com/?type=add&name=[NAME]&url=[URL]&hidden=[0/1]&admin=[ADMIN PASS]&wpass=[WRITE PASS]&rpass=[READ PASS]

Adds a new service named [NAME] with the HTTP-IN url [URL]. Can be 'hidden', 'wpass' protected, and/or 'rpass' protected. The URL must be converted to a string using llEscapeURL() first.

if the URL is added, returns the response 'Added', or 'Found' if the service already exists. 
  • http://yourappname.appspot.com/?type=remove&name=[NAME]&admin=[ADMIN PASS]&pass=[WRITE PASS]

Removes the given service named [NAME]. If 'wpass' was set during creation/update, must be specificed as 'pass'. or overridden by admin=[ADMIN PASS]

Returns 'Removed' if successful, or 'None' if the service wasn't found.
  • http://yourappname.appspot.com/?type=update&name=[NAME]&url=[URL]&hidden=[0/1]&admin=[ADMIN PASS]&wpass=[WRITE PASS]&rpass=[READ PASS]

Updates the service named [NAME] with the HTTP-IN url [URL]. Can be 'hidden', 'wpass' protected, and/or 'rpass' protected. If 'wpass' was set during previous creation/update, must be specificed as 'pass', or overridden by admin=[ADMIN PASS]

The URL must be converted to a string using llEscapeURL() first.
If the URL is updated the response 'Updated' is returned.
If the service doesn't exist, a new service is added and 'Added' is returned.
  • http://yourappname.appspot.com/?type=retrieve&name=[NAME]&pass=[READ PASS]&admin=[ADMIN PASS]

Retrieves the url of the given service named [NAME]. If 'rpass' was set during previous creation/update, must be specificed as 'pass', or overridden by admin=[ADMIN PASS]

Returns the URL if the service is found, or 'None' if the service wasn't found.
the returned URL must be converted to a URL using llUnescapeURL()
  • http://yourappname.appspot.com/?type=list&admin=[ADMIN PASS]

Lists the available services currently stored. Will only show entries not marked as 'hidden', Unless &admin=[ADMIN PASS] is included. then all are shown.

Returns a Comma seperated list of service names, ending with the word 'END'.
If no services are defined, 'Empty' is returned.
Enjoy :)