Difference between revisions of "LSL HTTP server/examples"

From Second Life Wiki
Jump to navigation Jump to search
Line 190: Line 190:


=== Perl/Python Examples Using POST ===
=== Perl/Python Examples Using POST ===
Here are a set of scripts to provide another example. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is used on the outside server to contact the code on the grid.
Here are a set of scripts to provide another example using POST. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.
<lsl>
<lsl>


Line 329: Line 329:
</lsl>
</lsl>


=== Perl/Python Examples Using POST With Argument Parsing ===
Here are a set of scripts to provide another example using POST. In this example the scripts are adapted to handle the parsing of the arguments that are passed. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.


<lsl>
key requestURL;
// ###############################################
// Routine to parse a string sent through the
// http server via post.
//      parsePostData(theMessage)
// Returns a strided list with stride length 2.
// Each set has the key and then its value.
list parsePostData(string message) {
    list postData;        // The list with the data that was passed in.
    list parsedMessage;    // The key/value pairs parsed into one list.
    string currentField;  // Current key/value pair as a string.
    integer pos;          // Position of the "=" in the current field.
    postData = [];                              // Initialize the list
    parsedMessage =                            // Parse the incoming message
        llParseString2List(message,["&"],[]);  // into the component pairs
    while(llGetListLength(parsedMessage)>0) {         
        currentField = llList2String(parsedMessage,0); // Get the current field
        parsedMessage =                                // Delete it from the
            llDeleteSubList(parsedMessage,0,0);        // list.
        pos = llSubStringIndex(currentField,"=");    // Find the "=" sign
        if(pos < 0) {
            // There is only one field in this part of the message.
            postData += [llUnescapeURL(currentField),""]; 
        } else {
            // Break up the field into its key and value then add it
            // to the list.
            postData += [llUnescapeURL(llDeleteSubString(currentField,pos,-1)),
                        llUnescapeURL(llDeleteSubString(currentField,0,pos))];
        }
       
    }
    // Return the strided list.
    return(postData);
}
default
{
    state_entry() {
        requestURL = llRequestURL(); // Request that an URL be assigned to me.
    }
   
   
    http_request(key id, string method, string body) {
        list incomingMessage;
       
        if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){
            // An URL has been assigned to me.
            llOwnerSay("Obtained URL: " + body);
            requestURL = NULL_KEY;
        }
       
       
        else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) {
            // I could not obtain a URL
            llOwnerSay("There was a problem, and an URL was not assigned: " +
                      body);
            requestURL = NULL_KEY;
        }
        else if (method == "POST") {
            // An incoming message was received.
            llOwnerSay("Received information form the outside: " + body);
            incomingMessage = parsePostData(body);
            llOwnerSay(llDumpList2String(incomingMessage,"\n"));
            llHTTPResponse(id,200,"You passed the following:\n" +
                          llDumpList2String(incomingMessage,"\n"));
        }
       
        else {
            // An incoming message has come in using a method that has
            // not been anticipated.
            llHTTPResponse(id,405,"Unsupported Method");
        }
    }
}
</lsl>
Here is the coresponding PERL script for contacting the LSL script on the grid.
<lsl>
#!/usr/bin/perl
# Routine to contact a script on the SL Grid using http server
use LWP;
require HTTP::Request;
use URI::Escape;
use strict;
# #################################################
# Routine to send the information to the prim
#    submitInformation($url,$information)
#
sub submitInformation{
    my $url = shift;                  # First get the arguments.
    my $information = shift;
    my $browser = LWP::UserAgent->new;                # Create the object
    my $request = HTTP::Request->new(POST => $url);  # used to send the
                                                      # HTTP request
    $request->content_type                            # Set the
('application/x-www-form-urlencoded');        # encoding type.
    $request->content(hash2URI($information));        # Set the content to
                                                      # send.
    my $response = $browser->request($request);      # Send the request.
    return($response->content);                      # Return the
      # information that
      # was sent back
}
# #########################################################################
# Convert a hash to a url encoded string
#      hash2URI(%hash)
sub hash2URI {
    my $theHash = shift;            # Get the arguments passed.
    my $encodedString = '';        # The encoded string to return.
    my $lupe;                      # a loop variable.
   
    foreach $lupe (keys %{$theHash}) {                #
$encodedString .= uri_escape($lupe) . '=' .  # Add each item in the
    uri_escape($$theHash{$lupe}) . '&';      # hash to the encoded string.
    }
    $encodedString =~ s/&$//;                        # Remove the trailing "&"
    return($encodedString);                          # Send the encoded string.
}
# Set the URL manually....
my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0';
my $info = submitInformation
    ($url,{'action' => 'send message',
  'value'=> 'Hi there chief!',
  'id'=>'244195d6-c9b7-4fd6-9229-c3a8b2e60e81',
  'name'=>'M Linden'});
print($info,"\n");
</lsl>
Here is the coresponding Python script. It does the same thing as the PERL script above.
<lsl>
#!/usr/bin/python
import urllib
import re
# #################################################
# Routine to send the information to the prim
#    submitInformation(url,information)
#
def submitInformation(url,parameters) :
   
#    encodedParams =  urllib.urlencode(parameters);  # encode the parameters
    encodedParams  = dictionary2URI(parameters);    # encode the parameters
    net = urllib.urlopen(url,encodedParams);        # Post the data.
    return(net.read());                            # return the result.
# ################################################
# Routine to encode a dictionary without using
# "+" for spaces.
#      dictionary2URI(theDictionary)
def dictionary2URI(theDictionary) :
    encoded = '';          # Initialize the string to return
    for key, value in theDictionary.iteritems():
        # Encode each item in the dictionary.
        encoded += urllib.quote(key)+"="+urllib.quote(value)+"&";
    remove = re.compile('&$')            # Remove the trailing ampersand.
    encoded = remove.sub('',encoded);
    return(encoded);
if __name__ == "__main__":
    # Set the URL manually
    url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0';
    # Define the parameters
    parameters = {'id':'244195d6-c9b7-4fd6-9229-c3a8b2e60e81',
                  'name':'M Linden',
                  'action':'send message',
                  'value':'Hey there, hi there, ho there!'};
    # Pass the information along to the prim
    info = submitInformation(url,parameters);
    print(info);
</lsl>
{{LSLC|HTTP}}{{LSLC|Examples}}
{{LSLC|HTTP}}{{LSLC|Examples}}

Revision as of 04:28, 27 May 2009

Hello World!

Classic example, the smallest http_request script possible. <lsl> default {

   state_entry()
   {
       llRequestURL();
   }
   http_request(key id, string method, string body)
   {
       if (method == URL_REQUEST_GRANTED)
       {
           llSay(0,"URL: " + body);
       }
       else if (method == "GET")
       {
           llHTTPResponse(id,200,"Hello World!");
       }
   }

} </lsl> A slightly more robust version: <lsl> default {

   state_entry()
   {
       llRequestURL();
   }
   http_request(key id, string method, string body)
   {
       if (method == URL_REQUEST_GRANTED)
       {
           llSay(0,"URL: " + body);
       }
       else if (method == URL_REQUEST_DENIED)
       {
           llSay(0, "Something went wrong, no url. " + body);
       }
       else if (method == "GET")
       {
           llHTTPResponse(id,200,"Hello World!");
       }
       else
       {
           llHTTPResponse(id,405,"Unsupported Method");
       }
   }

} </lsl>

Visitor List

A list of residents within sensor range of the server.
Notes:

  • This includes a method for handling multiple requests while waiting for asynchronous data requests to come back.

<lsl>integer scanning = FALSE;

list requests;

send_response(string body) {

   integer j;
   for (j = 0; j < llGetListLength(requests); ++j)
   {
       llHTTPResponse(llList2Key(requests,j), 200, body);
   }
   requests = [];

}

default {

   state_entry()
   {
       llRequestURL();
   }

   http_request(key id, string method, string body)
   {
       if (method == URL_REQUEST_GRANTED)
       {
           llSay(0,"URL: " + body);
       }
       else if (method == URL_REQUEST_DENIED)
       {
           llSay(0, "Something went wrong, no url. " + body);
       }
       else if (method == "GET")
       {
           if (!scanning)
           {
               llSensor("",NULL_KEY,AGENT,96,PI);
               scanning = TRUE;
           }
           
           requests += [id];
       }
       else
       {
           llHTTPResponse(id,405,"Unsupported method.");
       }
   }

   no_sensor()
   {
       send_response("There is no one here.");
       scanning = FALSE;
   }

   sensor(integer n)
   {
       string output;
       if (n < 16) output = "There are " + (string)n + " avatars nearby:";
       else output = "There are at least 16 avatars nearby:";
       
       integer i;
       for (i = 0;i<n;++i)
       {
           output += "\n\t" + llDetectedName(i);
       }
       
       send_response(output);
       scanning = FALSE;
   }

} </lsl>

Url Persistence / Visitor Counter

A more complete 'hello world', always has an url and keeps a visitor counter. <lsl> string url; integer hits;

setup() {

   llSetObjectName("HTTP Server");
   url = "";
   llRequestURL();
   hits = (integer)llGetObjectDesc();
   llSetText((string)hits + " visitors.",<1,1,0>,1);

}

default {

   state_entry() { setup(); }
   on_rez(integer n) { setup(); }
   
   changed(integer c)
   {
       if (c & (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )
       {
           setup();
       }
   }
   
   touch_start(integer n)
   {
       llSay(0,"My url is: " + url);
   }

   http_request(key id, string method, string body)
   {
       if (method == URL_REQUEST_GRANTED)
       {
           url = body;
       }
       else if (method == URL_REQUEST_DENIED)
       {
           llSay(0, "Something went wrong, no url. " + body);
       }
       else if (method == "GET")
       {
           ++hits;
           llSetObjectDesc((string)hits);
           llSetText((string)hits + " visitors.",<1,1,0>,1);
           llHTTPResponse(id,200,"Hello!  You are visitor " + (string)hits + ".");
       }
       else
       {
           llHTTPResponse(id,405,"Method unsupported");
       }
   }

} </lsl>


Perl/Python Examples Using POST

Here are a set of scripts to provide another example using POST. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid. <lsl>

key requestURL;

default {

   state_entry() {
       requestURL = llRequestURL();     // Request that an URL be assigned to me.
   }
   
   
    http_request(key id, string method, string body) {
       
       if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){
           // An URL has been assigned to me.
           llOwnerSay("Obtained URL: " + body);
           requestURL = NULL_KEY;
       }
       
       
       else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) {
           // I could not obtain a URL
           llOwnerSay("There was a problem, and an URL was not assigned: " + body);
           requestURL = NULL_KEY;
       }
       else if (method == "POST") {
           // An incoming message was received.
           llOwnerSay("Received information from the outside: " + body);
           llHTTPResponse(id,200,"Thank you for calling. All of our operators are busy.");
       }


       else {
           // An incoming message has come in using a method that has not been anticipated.
           llHTTPResponse(id,405,"Unsupported Method");
       }


   }


}

</lsl>

Here is the PERL script to contact the prim on the grid.

<lsl>

  1. !/usr/bin/perl
  2. Routine to contact a script on the SL Grid using http server

use LWP; require HTTP::Request; use URI::Escape; use strict;


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation($url,$information)

sub submitInformation{

   # First get the arguments.
   my $url = shift;
   my $information = shift;
   # Create the objects to be used to send out the HTTP request
   my $browser = LWP::UserAgent->new;
   my $request = HTTP::Request->new(POST => $url);
   # Set the encoding method and specify the information to be sent.
   $request->content_type('application/x-www-form-urlencoded');
   $request->content(uri_escape($information));
   # Send the request.
   my $response = $browser->request($request);
   # Return the information sent back
   return($response->content);

}


  1. Set the URL manually....

my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48';

my $info = submitInformation

   ($url,'id=244195d6-c9b7-4fd6-9229-c3a8b2e60e81&name=M Linden');

print $info,"\n";


</lsl>

Here is the Python code that does the same thing as the PERL code above.

<lsl>

  1. !/usr/bin/python

import urllib


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation(url,information)

def submitInformation(url,parameters) :

   # Set the parameters to be sent.
   encodedParams =  urllib.urlencode(parameters);
   # Post the data.
   net = urllib.urlopen(url,encodedParams);
   # return the result.
   return(net.read());


if __name__ == "__main__":

   # Set the URL manually
   url = 'http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48';
   # Define the parameters
   parameters = {'id':'244195d6-c9b7-4fd6-9229-c3a8b2e60e81',
                 'name':'M Linden'}
   # Pass the information along to the prim
   info = submitInformation(url,parameters);
   print(info);


</lsl>

Perl/Python Examples Using POST With Argument Parsing

Here are a set of scripts to provide another example using POST. In this example the scripts are adapted to handle the parsing of the arguments that are passed. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.

<lsl>


key requestURL;


// ############################################### // Routine to parse a string sent through the // http server via post. // parsePostData(theMessage) // Returns a strided list with stride length 2. // Each set has the key and then its value. list parsePostData(string message) {

   list postData;         // The list with the data that was passed in.
   list parsedMessage;    // The key/value pairs parsed into one list.
   string currentField;   // Current key/value pair as a string.
   integer pos;           // Position of the "=" in the current field.


   postData = [];                              // Initialize the list 
   parsedMessage =                             // Parse the incoming message
       llParseString2List(message,["&"],[]);   // into the component pairs
   while(llGetListLength(parsedMessage)>0) {          
       currentField = llList2String(parsedMessage,0); // Get the current field
       parsedMessage =                                // Delete it from the
           llDeleteSubList(parsedMessage,0,0);        // list.
       pos = llSubStringIndex(currentField,"=");     // Find the "=" sign
       if(pos < 0) {
           // There is only one field in this part of the message.
           postData += [llUnescapeURL(currentField),""];  
       } else {
           // Break up the field into its key and value then add it
           // to the list.
           postData += [llUnescapeURL(llDeleteSubString(currentField,pos,-1)),
                        llUnescapeURL(llDeleteSubString(currentField,0,pos))];
       }
       
   }
   // Return the strided list.
   return(postData);

}



default {

   state_entry() {
       requestURL = llRequestURL(); // Request that an URL be assigned to me.
   }
   
   
    http_request(key id, string method, string body) {
        list incomingMessage;
       
       if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){
           // An URL has been assigned to me.
           llOwnerSay("Obtained URL: " + body);
           requestURL = NULL_KEY;
       }
       
       
       else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) {
           // I could not obtain a URL
           llOwnerSay("There was a problem, and an URL was not assigned: " + 
                      body);
           requestURL = NULL_KEY;
       }
       else if (method == "POST") {
           // An incoming message was received.
           llOwnerSay("Received information form the outside: " + body);
           incomingMessage = parsePostData(body);
           llOwnerSay(llDumpList2String(incomingMessage,"\n"));
           llHTTPResponse(id,200,"You passed the following:\n" + 
                          llDumpList2String(incomingMessage,"\n"));
       }


       else {
           // An incoming message has come in using a method that has
           // not been anticipated.
           llHTTPResponse(id,405,"Unsupported Method");
       }


   }


}

</lsl>

Here is the coresponding PERL script for contacting the LSL script on the grid.

<lsl>

  1. !/usr/bin/perl
  2. Routine to contact a script on the SL Grid using http server

use LWP; require HTTP::Request; use URI::Escape; use strict;


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation($url,$information)

sub submitInformation{


   my $url = shift;                   # First get the arguments.
   my $information = shift;
   my $browser = LWP::UserAgent->new;                # Create the object
   my $request = HTTP::Request->new(POST => $url);   # used to send the
                                                     # HTTP request
   $request->content_type                            # Set the

('application/x-www-form-urlencoded'); # encoding type.

   $request->content(hash2URI($information));        # Set the content to
                                                     # send.
   my $response = $browser->request($request);       # Send the request.
   return($response->content);                       # Return the

# information that # was sent back }


  1. #########################################################################
  2. Convert a hash to a url encoded string
  3. hash2URI(%hash)

sub hash2URI {

   my $theHash = shift;            # Get the arguments passed.
   my $encodedString = ;         # The encoded string to return.
   my $lupe;                       # a loop variable.


   foreach $lupe (keys %{$theHash}) {                # 

$encodedString .= uri_escape($lupe) . '=' . # Add each item in the uri_escape($$theHash{$lupe}) . '&'; # hash to the encoded string.

   }
   $encodedString =~ s/&$//;                         # Remove the trailing "&"
   return($encodedString);                           # Send the encoded string.

}


  1. Set the URL manually....

my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0';

my $info = submitInformation

   ($url,{'action' => 'send message',

'value'=> 'Hi there chief!', 'id'=>'244195d6-c9b7-4fd6-9229-c3a8b2e60e81', 'name'=>'M Linden'});

print($info,"\n");


</lsl>


Here is the coresponding Python script. It does the same thing as the PERL script above.

<lsl>

  1. !/usr/bin/python

import urllib import re


  1. #################################################
  2. Routine to send the information to the prim
  3. submitInformation(url,information)

def submitInformation(url,parameters) :

  1. encodedParams = urllib.urlencode(parameters); # encode the parameters
   encodedParams  = dictionary2URI(parameters);    # encode the parameters
   net = urllib.urlopen(url,encodedParams);        # Post the data.
   return(net.read());                             # return the result.



  1. ################################################
  2. Routine to encode a dictionary without using
  3. "+" for spaces.
  4. dictionary2URI(theDictionary)

def dictionary2URI(theDictionary) :

   encoded = ;           # Initialize the string to return
   for key, value in theDictionary.iteritems():
       # Encode each item in the dictionary.
       encoded += urllib.quote(key)+"="+urllib.quote(value)+"&";
   remove = re.compile('&$')             # Remove the trailing ampersand.
   encoded = remove.sub(,encoded);
   return(encoded);


if __name__ == "__main__":

   # Set the URL manually
   url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0';
   # Define the parameters
   parameters = {'id':'244195d6-c9b7-4fd6-9229-c3a8b2e60e81',
                 'name':'M Linden',
                 'action':'send message',
                 'value':'Hey there, hi there, ho there!'};
   # Pass the information along to the prim
   info = submitInformation(url,parameters);
   print(info);


</lsl>