Difference between revisions of "LSL HTTP server/examples/kellys stupid web status updater"

From Second Life Wiki
Jump to navigation Jump to search
m (language tags to <source>)
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== What ==
== What ==
This is a dead stupid, insecure and simple system that will update the floating text above a prim according to what is entered in the web form.  Uses html forms, python and LSL.
This is a dead stupid, insecure and simple system that will update the floating text above a prim according to what is entered in the web form.  Uses html forms, python and LSL.  This is about as simple as it gets, I think.


== index.html ==
== index.html ==
A simple webform that sends the input to our cgi.
A simple webform that sends the input to our cgi.
<html4strict><html>
<source lang="html4strict"><html>
   <body>
   <body>
       <div align="center">
       <div align="center">
Line 15: Line 15:
       </div>
       </div>
   <body>
   <body>
</html></html4strict>
</html></source>
== post.cgi ==
== post.cgi ==
A simple CGI that takes GETs and looks for two parameters:
A simple CGI that takes GETs and looks for two parameters:
Line 22: Line 22:
Bugs:
Bugs:
* Entering no text in the form will cause the cgi to error.
* Entering no text in the form will cause the cgi to error.
<python>
Errata:
* This is probably really insecure.
* You need to create the file 'my_url' (or whatever you set file_name as) in your cgi-bin directory.
* That file needs to be readable and writable by your cgi.  Depending on your setup something like this might work:
: touch my_url
: chmod 600 my_url
* You may need to be more permissive depending on your server configuration, but this worked on my shared hosting system.
 
<source lang="python">
#!/usr/bin/python
#!/usr/bin/python


Line 29: Line 37:
cgitb.enable()
cgitb.enable()


# This file needs to be readable and writable from this cgi
file_name = "my_url"
file_name = "my_url"


form = cgi.FieldStorage()
form = cgi.FieldStorage()
if (form.has_key("Message")):
 
# If we have Message then this is a status update.
if "Message" in form:
        # Redirect back to the form
         print "Status: 302 Moved"
         print "Status: 302 Moved"
         print "Location: http://www.myurl.com/path/to/form"
         print "Location: http://www.myurl.com/path/to/form"
         print
         print


        # Read in the url from the file
         f = open(file_name,'r')
         f = open(file_name,'r')
         base_url = f.read()
         base_url = f.read()
        # Build the complete url with query args.
         message = form["Message"].value
         message = form["Message"].value
         args = "?Message=%s" % urllib.quote(message)
         args = "?Message=%s" % urllib.quote(message)
        # Make the request, giving the status to the script.
         response = urllib2.urlopen(base_url + args)
         response = urllib2.urlopen(base_url + args)


if (form.has_key("URL")):
# If we have URL then this is an URL update
         print form["URL"].value
if "URL" in form:
         # Write the url to the file, overwriting the existing file.
         f = open(file_name,'w')
         f = open(file_name,'w')
         f.write(form["URL"].value)
         f.write(form["URL"].value)
        # Let the caller know it worked.
         print "Content-Type: text/html"
         print "Content-Type: text/html"
         print
         print
         print "OK"
         print "OK"
</python>
</source>
 
== status.lsl ==
== status.lsl ==
<lsl>
<source lang="lsl2">
// Set this to whatever text you want above your status
string header = "My Status:\n";
string header = "My Status:\n";
// This is the url to the post.cgi from above
string updater_url = "http://mywebsite.com/cgi-bin/post.cgi";
string updater_url = "http://mywebsite.com/cgi-bin/post.cgi";
string url;
 
// The magic changed flags to know when to re-request an url
// CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT
integer CHANGED_URL = 1792;
integer CHANGED_URL = 1792;


// Setup run anytime we think our url has been lost.
setup()
setup()
{
{
Line 63: Line 89:
     llRequestURL();
     llRequestURL();
}
}
 
// Debug incoming requests to see all header information.
debug(key id, string method, string body)
debug(key id, string method, string body)
{
{
Line 77: Line 104:
default
default
{
{
    // These events mean we have lost any urls we had and need to run setup()
     state_entry() { setup(); }
     state_entry() { setup(); }
     on_rez(integer n) { setup(); }
     on_rez(integer n) { setup(); }
Line 87: Line 115:
         if (method == URL_REQUEST_GRANTED)
         if (method == URL_REQUEST_GRANTED)
         {
         {
            // Register our url for new status updates.
             llHTTPRequest(updater_url + "?URL=" + body + "/",[],"");
             llHTTPRequest(updater_url + "?URL=" + body + "/",[],"");
         }
         }
         else if (method == URL_REQUEST_DENIED)
         else if (method == URL_REQUEST_DENIED)
         {
         {
            // Might be good to have this email.
             llSay(0, "Something went wrong, no url. " + body);
             llSay(0, "Something went wrong, no url. " + body);
         }
         }
         else if (method == "GET")
         else if (method == "GET")
         {
         {
            // Process a status update by parsing the query string
             string t = llGetHTTPHeader(id,"x-query-string");
             string t = llGetHTTPHeader(id,"x-query-string");
             list l = llParseString2List(t,["?","=","&"],[]);
             list l = llParseString2List(t,["?","=","&"],[]);
            // We want the value after Message
             integer i = llListFindList(l,["Message"]) + 1;
             integer i = llListFindList(l,["Message"]) + 1;


            // If there was no Message argument then i = (-1) + 1 => 0.
            // As long as i > 0 we found Message so put up whatever came next as the status.
             if (i > 0)
             if (i > 0)
             {
             {
Line 115: Line 150:
     }
     }
}
}
</lsl>
</source>

Latest revision as of 16:38, 24 January 2015

What

This is a dead stupid, insecure and simple system that will update the floating text above a prim according to what is entered in the web form. Uses html forms, python and LSL. This is about as simple as it gets, I think.

index.html

A simple webform that sends the input to our cgi.

<html>
   <body>
      <div align="center">
         <br><br><br>
         <form ACTION="cgi-bin/post.cgi" METHOD="GET">
            <textarea name="Message" rows="5" cols="40" onfocus="this.value=''; this.onfocus=null;">Enter your status update here.</textarea>
            <P>
            <INPUT TYPE="submit" title="FOO">
         </form>
      </div>
   <body>
</html>

post.cgi

A simple CGI that takes GETs and looks for two parameters:

  • URL: if found will write the value to a file
  • Message: if found will read from the file and send the contents to the url in the file

Bugs:

  • Entering no text in the form will cause the cgi to error.

Errata:

  • This is probably really insecure.
  • You need to create the file 'my_url' (or whatever you set file_name as) in your cgi-bin directory.
  • That file needs to be readable and writable by your cgi. Depending on your setup something like this might work:
touch my_url
chmod 600 my_url
  • You may need to be more permissive depending on your server configuration, but this worked on my shared hosting system.
#!/usr/bin/python

import cgi, urllib2, urllib
import cgitb
cgitb.enable()

# This file needs to be readable and writable from this cgi
file_name = "my_url"

form = cgi.FieldStorage()

# If we have Message then this is a status update.
if "Message" in form:
        # Redirect back to the form
        print "Status: 302 Moved"
        print "Location: http://www.myurl.com/path/to/form"
        print

        # Read in the url from the file
        f = open(file_name,'r')
        base_url = f.read()

        # Build the complete url with query args.
        message = form["Message"].value
        args = "?Message=%s" % urllib.quote(message)

        # Make the request, giving the status to the script.
        response = urllib2.urlopen(base_url + args)

# If we have URL then this is an URL update
if "URL" in form:
        # Write the url to the file, overwriting the existing file.
        f = open(file_name,'w')
        f.write(form["URL"].value)

        # Let the caller know it worked.
        print "Content-Type: text/html"
        print
        print "OK"

status.lsl

// Set this to whatever text you want above your status
string header = "My Status:\n";
// This is the url to the post.cgi from above
string updater_url = "http://mywebsite.com/cgi-bin/post.cgi";

// The magic changed flags to know when to re-request an url
// CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT
integer CHANGED_URL = 1792;

// Setup run anytime we think our url has been lost.
setup()
{
    llSetObjectName("HTTP Server: Status Updates");
    llRequestURL();
}

// Debug incoming requests to see all header information.
debug(key id, string method, string body)
{
    llOwnerSay(method + ": " + body);
    list headers = ["x-script-url","x-path-info","x-query-string","x-remote-ip","user-agent"];
    integer i;
    for (i=0;i<5;++i)
    {
        llOwnerSay(llList2String(headers,i) + ": " + llGetHTTPHeader(id,llList2String(headers,i)));
    }
}

default
{
    // These events mean we have lost any urls we had and need to run setup()
    state_entry() { setup(); }
    on_rez(integer n) { setup(); }
    changed(integer c) { if (c & (CHANGED_URL) ) setup(); }
 
    http_request(key id, string method, string body)
    {
        // debug(id, method, body);
        
        if (method == URL_REQUEST_GRANTED)
        {
            // Register our url for new status updates.
            llHTTPRequest(updater_url + "?URL=" + body + "/",[],"");
        }
        else if (method == URL_REQUEST_DENIED)
        {
            // Might be good to have this email.
            llSay(0, "Something went wrong, no url. " + body);
        }
        else if (method == "GET")
        {
            // Process a status update by parsing the query string
            string t = llGetHTTPHeader(id,"x-query-string");
            list l = llParseString2List(t,["?","=","&"],[]);

            // We want the value after Message
            integer i = llListFindList(l,["Message"]) + 1;

            // If there was no Message argument then i = (-1) + 1 => 0.
            // As long as i > 0 we found Message so put up whatever came next as the status.
            if (i > 0)
            {
                llSetText(header + llUnescapeURL(llList2String(l,i)),<1,1,0>,1);
                llHTTPResponse(id,200,"OK");
            }
            else
            {
                llHTTPResponse(id,400,"Must Specify a message!");
            }
        }
        else
        {
            llHTTPResponse(id,405,"Method unsupported");
        }
    }
}