Difference between revisions of "LSL HTTP server/examples"
m (→Visitor List) |
|||
(36 intermediate revisions by 17 users not shown) | |||
Line 1: | Line 1: | ||
{{LSL Header|ml=*}} | {{LSL Header|ml=*}} | ||
=== Utility Script === | |||
A script intended as a 'fill in the blank' exercise for very, very simple HTTP servers is here: [[LSL_http_server/examples/utility_script | Utility Script]] | |||
=== Hello World! === | === Hello World! === | ||
Classic example, the smallest http_request script possible. | Classic example, the smallest http_request script possible. | ||
< | <source lang="lsl2"> | ||
default | default | ||
{ | { | ||
Line 22: | Line 24: | ||
} | } | ||
} | } | ||
</ | </source> | ||
A slightly more robust version: | A slightly more robust version: | ||
< | <source lang="lsl2"> | ||
default | default | ||
{ | { | ||
Line 52: | Line 54: | ||
} | } | ||
} | } | ||
</ | </source> | ||
=== Echo World === | |||
"Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))" is a slightly more useful "Hello World", demonstrating a basic server that echos back dynamic data fed. Echo World shows how http_request receives GET variables. To receive this "dynamic echo", append your cap url with a query string, such as https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra | |||
<source lang="lsl2"> | |||
string url; | |||
default | |||
{ | |||
state_entry() | |||
{ | |||
llRequestURL(); | |||
} | |||
http_request(key id, string method, string body) | |||
{ | |||
if (method == URL_REQUEST_GRANTED) | |||
{ | |||
url=body; | |||
llOwnerSay(url); | |||
} | |||
else if(method=="GET") | |||
{ | |||
if(llGetHTTPHeader(id,"x-query-string")=="") | |||
llHTTPResponse(id,200,"I ECHO when you append some GET variables to me, e.g., /?var=foo"); | |||
else | |||
llHTTPResponse(id,200,llGetHTTPHeader(id,"x-query-string")); | |||
} | |||
} | |||
} | |||
</source> | |||
=== HTTP Server URL Registration === | |||
[[HTTP Server URL Registration]] shows how to obtain the URL for your HTTP service and register it externally, and how to do proper backoff and retry as an HTTP Client. | |||
=== Visitor List === | === Visitor List === | ||
Line 58: | Line 93: | ||
<br>Notes: | <br>Notes: | ||
* This includes a method for handling multiple requests while waiting for asynchronous data requests to come back. | * This includes a method for handling multiple requests while waiting for asynchronous data requests to come back. | ||
< | <source lang="lsl2">integer scanning = FALSE; | ||
list requests; | list requests; | ||
Line 128: | Line 163: | ||
} | } | ||
} | } | ||
</ | </source> | ||
=== Url Persistence / Visitor Counter === | === Url Persistence / Visitor Counter === | ||
A more complete 'hello world', always has an url and keeps a visitor counter. | A more complete 'hello world', always has an url and keeps a visitor counter. | ||
< | <source lang="lsl2"> | ||
string url; | string url; | ||
integer hits; | integer hits; | ||
Line 186: | Line 221: | ||
} | } | ||
} | } | ||
</ | </source> | ||
=== Perl/Python Examples Using POST === | === 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 | 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. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC)) | ||
< | <source lang="lsl2"> | ||
key requestURL; | key requestURL; | ||
Line 198: | Line 232: | ||
{ | { | ||
state_entry() { | state_entry() | ||
{ | |||
requestURL = llRequestURL(); // Request that an URL be assigned to me. | requestURL = llRequestURL(); // Request that an URL be assigned to me. | ||
} | } | ||
http_request(key id, string method, string body) | |||
http_request(key id, string method, string body) { | { | ||
if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ) | |||
if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){ | { | ||
// An URL has been assigned to me. | // An URL has been assigned to me. | ||
llOwnerSay("Obtained URL: " + body); | llOwnerSay("Obtained URL: " + body); | ||
requestURL = NULL_KEY; | requestURL = NULL_KEY; | ||
} | } | ||
else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) | |||
{ | |||
else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) { | |||
// I could not obtain a URL | // I could not obtain a URL | ||
llOwnerSay("There was a problem, and an URL was not assigned: " + body); | llOwnerSay("There was a problem, and an URL was not assigned: " + body); | ||
Line 218: | Line 252: | ||
} | } | ||
else if (method == "POST") { | else if (method == "POST") | ||
{ | |||
// An incoming message was received. | // An incoming message was received. | ||
llOwnerSay("Received information from the outside: " + body); | llOwnerSay("Received information from the outside: " + body); | ||
llHTTPResponse(id,200,"Thank you for calling. All of our operators are busy."); | 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. | // An incoming message has come in using a method that has not been anticipated. | ||
llHTTPResponse(id,405,"Unsupported Method"); | llHTTPResponse(id,405,"Unsupported Method"); | ||
} | } | ||
} | } | ||
} | } | ||
</source> | |||
Here is the Perl script to contact the prim on the grid. | |||
<source lang="perl"> | |||
< | |||
#!/usr/bin/perl | #!/usr/bin/perl | ||
# Routine to contact a script on the SL Grid using http server | # Routine to contact a script on the SL Grid using http server | ||
use strict; | |||
use warnings; | |||
use LWP; | use LWP; | ||
my $browser = LWP::UserAgent->new; | |||
sub submitInformation) { | |||
return($ | my( $url, $params ) = @_; | ||
return $browser->post( $url, $params )->content; | |||
} | } | ||
# Set the URL manually.... | # Set the URL manually.... | ||
my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48'; | my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48'; | ||
my $info = submitInformation | my $info = submitInformation( $url, { | ||
id => '244195d6-c9b7-4fd6-9229-c3a8b2e60e81', | |||
name => 'M Linden', | |||
} ); | |||
print $info,"\n"; | print $info,"\n"; | ||
</source> | |||
</ | |||
Here is the Python code that does the same thing as the PERL code above. | Here is the Python code that does the same thing as the PERL code above. | ||
< | <source lang="python"> | ||
#!/usr/bin/python | #!/usr/bin/python | ||
Line 324: | Line 330: | ||
info = submitInformation(url,parameters); | info = submitInformation(url,parameters); | ||
print(info); | print(info); | ||
</source> | |||
</ | |||
=== Perl/Python Examples Using POST With Argument Parsing === | === 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. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC)) | 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. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC)) | ||
< | <source lang="lsl2"> | ||
key requestURL; | key requestURL; | ||
// ############################################### | // ############################################### | ||
Line 347: | Line 345: | ||
// Each set has the key and then its value. | // Each set has the key and then its value. | ||
list parsePostData(string message) { | list parsePostData(string message) { | ||
list postData; // The list with the data that was passed in. | list postData = []; // The list with the data that was passed in. | ||
list parsedMessage; // The key/value pairs parsed into one list | list parsedMessage = llParseString2List(message,["&"],[]); // The key/value pairs parsed into one list. | ||
integer len = ~llGetListLength(parsedMessage); | |||
integer | |||
while( | while(++len) { | ||
currentField = llList2String(parsedMessage, | string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string. | ||
integer split = llSubStringIndex(currentField,"="); // Find the "=" sign | |||
if( | if(split == -1) { // There is only one field in this part of the message. | ||
postData += [llUnescapeURL(currentField),""]; | postData += [llUnescapeURL(currentField),""]; | ||
} else { | } else { | ||
postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))]; | |||
postData += [llUnescapeURL(llDeleteSubString(currentField, | |||
} | } | ||
} | } | ||
// Return the strided list. | // Return the strided list. | ||
return | return postData ; | ||
} | } | ||
default { | |||
default | |||
{ | |||
state_entry() { | state_entry() { | ||
Line 391: | Line 369: | ||
} | } | ||
http_request(key id, string method, string body) { | |||
list incomingMessage; | list incomingMessage; | ||
Line 400: | Line 377: | ||
requestURL = NULL_KEY; | requestURL = NULL_KEY; | ||
} | } | ||
else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) { | else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) { | ||
// I could not obtain a URL | // I could not obtain a URL | ||
Line 408: | Line 383: | ||
requestURL = NULL_KEY; | requestURL = NULL_KEY; | ||
} | } | ||
else if (method == "POST") { | else if (method == "POST") { | ||
// An incoming message was received. | // An incoming message was received. | ||
Line 419: | Line 393: | ||
} | } | ||
else { | else { | ||
// An incoming message has come in using a method that has | // An incoming message has come in using a method that has | ||
Line 426: | Line 398: | ||
llHTTPResponse(id,405,"Unsupported Method"); | llHTTPResponse(id,405,"Unsupported Method"); | ||
} | } | ||
} | } | ||
} | } | ||
</source> | |||
</ | |||
Here is the coresponding PERL script for contacting the LSL script on the grid. | Here is the coresponding PERL script for contacting the LSL script on the grid. | ||
< | <source lang="perl"> | ||
#!/usr/bin/perl | #!/usr/bin/perl | ||
# Routine to contact a script on the SL Grid using http server | # Routine to contact a script on the SL Grid using http server | ||
use strict; | |||
use warnings; | |||
use LWP; | use LWP; | ||
my $browser = LWP::UserAgent->new; | |||
my $ | sub submitInformation) { | ||
my( $url, $params ) = @_; | |||
return $browser->post( $url, $params )->content; | |||
} | } | ||
# Set the URL manually.... | # Set the URL manually.... | ||
my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0'; | my $url = 'http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0'; | ||
my $info = submitInformation | my $info = submitInformation( $url, { | ||
'action' => 'send message', | |||
'value' => 'Hi there chief!', | |||
'id' => '244195d6-c9b7-4fd6-9229-c3a8b2e60e81', | |||
'name' => 'M Linden', | |||
}); | |||
print($info,"\n"); | print($info,"\n"); | ||
Line 505: | Line 433: | ||
</ | </source> | ||
Here is the coresponding Python script. It does the same thing as the | Here is the coresponding Python script. It does the same thing as the Perl script above. | ||
< | <source lang="python"> | ||
#!/usr/bin/python | #!/usr/bin/python | ||
import urllib | import urllib | ||
import re | import re | ||
# ################################################# | # ################################################# | ||
Line 564: | Line 490: | ||
info = submitInformation(url,parameters); | info = submitInformation(url,parameters); | ||
print(info); | print(info); | ||
</source> | |||
<div style="display:none;"><source lang="lsl2"></source></div> | |||
=== Simple script for sending data to an LSL via PHP === | |||
This example by Simba Fuhr '''UPDATE September 2, 2013'''NO LONGER WORKS PORTS 12046,12043 will not except incoming info from POST... | |||
{{Warning|Some hosting providers only allow fsockopen on the standard 80 and 443 ports. This script will not work on those providers. If your provider is willing to open some ports for you, HTTP-in uses port 12046, and HTTPS-in uses port 12043.}} | |||
'''Note:''' | |||
To use SSL encrypted sockets, you need to have SSL activated on your server. If you run your own server, you need to import the ssl support to your server (apache => apache.conf +"LoadModule ssl_module modules/mod_ssl.so")(normaly based on openssl). | |||
Secure URL Request with LSL. | |||
Script returns the URL to the chat. Please put the URL into the PHP below. | |||
<source lang="lsl2"> | |||
default | |||
{ | |||
state_entry() | |||
{ | |||
llRequestSecureURL(); | |||
} | |||
http_request(key id, string method, string body) | |||
{ | |||
if ((method == URL_REQUEST_GRANTED)) | |||
{ | |||
llOwnerSay("URL: " + body); | |||
} | |||
else if (method == "POST") | |||
{ | |||
llOwnerSay("PHP script sent: {" + body + "}"); | |||
llHTTPResponse(id, 200, "PHP script sent: {" + body + "}"); | |||
} | |||
} | |||
} | |||
</source> | |||
Here the PHP. | |||
A more advanced php function which supports complete url structures and automatical GET and POST types. | |||
Just don't submit any post Data to make a GET request. | |||
The Function supports any kind of url as secure and not secure (https and http). | |||
If you dont submit a port in the url, the default port for http (80) and https (443) will be used. | |||
(An example is shown on the top of the script.) | |||
<source lang="php"> | |||
<?php | |||
echo "LSL Script answered:<br>"; | |||
echo Advanced_HTTP_Request("https://sim20557.agni.lindenlab.com:12043/cap/5851e666-b0c6-f0a0-758a-9e8156765215", "Hello script, how are you ?"); | |||
</ | function Advanced_HTTP_Request($Host, $PostData = "") | ||
{ | |||
$Method = "POST"; | |||
if (empty($PostData)) | |||
{$Method = "GET";} | |||
$Port = 80; | |||
if (strtolower(substr($Host, 0, 5)) == "https") | |||
{$Port = 443;} | |||
$Host = explode("//", $Host, 2); | |||
if (count($Host) < 2) | |||
{$Host[1] = $Host[0];} | |||
$Host = explode("/", $Host[1], 2); | |||
if ($Port == 443) | |||
{$SSLAdd = "ssl://";} | |||
$Host[0] = explode(":", $Host[0]); | |||
if (count($Host[0]) > 1) | |||
{ | |||
$Port = $Host[0][1]; | |||
$Host[0] = $Host[0][0]; | |||
} | |||
else | |||
{$Host[0] = $Host[0][0];} | |||
$Socket = fsockopen($SSLAdd.$Host[0], $Port, $Dummy1, $Dummy2, 10); | |||
if ($Socket) | |||
{ | |||
fputs($Socket, "$Method /$Host[1] HTTP/1.1\r\n". | |||
"Host: $Host[0]\r\n". | |||
"Content-type: application/x-www-form-urlencoded\r\n". | |||
"User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n". | |||
"Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n". | |||
"Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n". | |||
"Content-length: ".strlen($PostData)."\r\n". | |||
"Connection: close\r\n". | |||
"\r\n". | |||
$PostData); | |||
$Tme = time(); | |||
while(!feof($Socket) && $Tme + 30 > time()) | |||
{$Res = $Res.fgets($Socket, 256);} | |||
fclose($Socket); | |||
} | |||
$Res = explode("\r\n\r\n", $Res, 2); | |||
return $Res[1]; | |||
} | |||
?> | |||
</source> | |||
Here is the simplest possible PHP persistant URL script, it could even be run on an old PC set up as a Linux web server from home. | |||
make a text file on the server, then call the page and write to the text file from the LSL script in your prim. | |||
reading the page will give you the SL URL for the prim. | |||
<source lang="php"> | |||
<?php | |||
$myfile = fopen("yourfile.txt", "w") or die("Unable to open file!"); | |||
$txt = $_POST['url']; | |||
fwrite($myfile, $txt); | |||
fclose($myfile); | |||
?> | |||
</source> | |||
=== Kelly's Stupid Web Status Updater === | |||
Is actually on its own page: [[LSL_http_server/examples/kellys_stupid_web_status_updater | Kelly's Stupid Web Status Updater]]<br> | |||
Kurai's mod from Kelly's stupid thing: [[LSL_http_server/examples/kurais_stupid_web_status_updater| Kurai's Stupid Web Status Updater Mod]] | |||
{{LSLC|HTTP}}{{LSLC|Examples}} | {{LSLC|HTTP}}{{LSLC|Examples}} | ||
=== Web-based dynamic buildings === | |||
HTTP-in may be used to easily send commands from a web page to an in-world object, so that web users can control and interact with buildings. The interactive installation ''Chromutate'' is based upon this idea: see its [[User:Opensource_Obscure/Chromutate|documentation page]] for free scripts and more details. | |||
=== PHP/SQL Object DNS === | |||
Simple DNS server written in PHP to facilitate a DNS service for LSL scripts: [[LSL_http_server/examples/phpdns|PHPDNS]] | |||
=== HyperMedia (LSL Web Server) === | |||
An LSL web server that uses HTTP-In and Shared Media to serve and render a webpage (with working forms) on a prim: [[LSL_http_server/examples/hypermedia|HyperMedia]] | |||
=== Object to object HTTP communication === | |||
Go to [[Object to object HTTP communication]] for an example of inworld HTTP communication model. |
Latest revision as of 10:02, 29 April 2019
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Utility Script
A script intended as a 'fill in the blank' exercise for very, very simple HTTP servers is here: Utility Script
Hello World!
Classic example, the smallest http_request script possible.
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!");
}
}
}
A slightly more robust version:
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");
}
}
}
Echo World
"Echo World (Byrd Sciavo 04:19, 7 October 2009 (UTC))" is a slightly more useful "Hello World", demonstrating a basic server that echos back dynamic data fed. Echo World shows how http_request receives GET variables. To receive this "dynamic echo", append your cap url with a query string, such as https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra
string url;
default
{
state_entry()
{
llRequestURL();
}
http_request(key id, string method, string body)
{
if (method == URL_REQUEST_GRANTED)
{
url=body;
llOwnerSay(url);
}
else if(method=="GET")
{
if(llGetHTTPHeader(id,"x-query-string")=="")
llHTTPResponse(id,200,"I ECHO when you append some GET variables to me, e.g., /?var=foo");
else
llHTTPResponse(id,200,llGetHTTPHeader(id,"x-query-string"));
}
}
}
HTTP Server URL Registration
HTTP Server URL Registration shows how to obtain the URL for your HTTP service and register it externally, and how to do proper backoff and retry as an HTTP Client.
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.
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;
}
}
Url Persistence / Visitor Counter
A more complete 'hello world', always has an url and keeps a visitor counter.
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");
}
}
}
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. (Grandma Bates 12:42, 27 May 2009 (UTC))
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");
}
}
}
Here is the Perl script to contact the prim on the grid.
#!/usr/bin/perl
# Routine to contact a script on the SL Grid using http server
use strict;
use warnings;
use LWP;
my $browser = LWP::UserAgent->new;
sub submitInformation) {
my( $url, $params ) = @_;
return $browser->post( $url, $params )->content;
}
# 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";
Here is the Python code that does the same thing as the PERL code above.
#!/usr/bin/python
import urllib
# #################################################
# Routine to send the information to the prim
# 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);
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. (Grandma Bates 12:42, 27 May 2009 (UTC))
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 = llParseString2List(message,["&"],[]); // The key/value pairs parsed into one list.
integer len = ~llGetListLength(parsedMessage);
while(++len) {
string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.
integer split = llSubStringIndex(currentField,"="); // Find the "=" sign
if(split == -1) { // There is only one field in this part of the message.
postData += [llUnescapeURL(currentField),""];
} else {
postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];
}
}
// 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");
}
}
}
Here is the coresponding PERL script for contacting the LSL script on the grid.
#!/usr/bin/perl
# Routine to contact a script on the SL Grid using http server
use strict;
use warnings;
use LWP;
my $browser = LWP::UserAgent->new;
sub submitInformation) {
my( $url, $params ) = @_;
return $browser->post( $url, $params )->content;
}
# 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");
Here is the coresponding Python script. It does the same thing as the Perl script above.
#!/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);
Simple script for sending data to an LSL via PHP
This example by Simba Fuhr UPDATE September 2, 2013NO LONGER WORKS PORTS 12046,12043 will not except incoming info from POST...
Some hosting providers only allow fsockopen on the standard 80 and 443 ports. This script will not work on those providers. If your provider is willing to open some ports for you, HTTP-in uses port 12046, and HTTPS-in uses port 12043.
Note:
To use SSL encrypted sockets, you need to have SSL activated on your server. If you run your own server, you need to import the ssl support to your server (apache => apache.conf +"LoadModule ssl_module modules/mod_ssl.so")(normaly based on openssl).
Secure URL Request with LSL.
Script returns the URL to the chat. Please put the URL into the PHP below.
default
{
state_entry()
{
llRequestSecureURL();
}
http_request(key id, string method, string body)
{
if ((method == URL_REQUEST_GRANTED))
{
llOwnerSay("URL: " + body);
}
else if (method == "POST")
{
llOwnerSay("PHP script sent: {" + body + "}");
llHTTPResponse(id, 200, "PHP script sent: {" + body + "}");
}
}
}
Here the PHP. A more advanced php function which supports complete url structures and automatical GET and POST types. Just don't submit any post Data to make a GET request. The Function supports any kind of url as secure and not secure (https and http). If you dont submit a port in the url, the default port for http (80) and https (443) will be used. (An example is shown on the top of the script.)
<?php
echo "LSL Script answered:<br>";
echo Advanced_HTTP_Request("https://sim20557.agni.lindenlab.com:12043/cap/5851e666-b0c6-f0a0-758a-9e8156765215", "Hello script, how are you ?");
function Advanced_HTTP_Request($Host, $PostData = "")
{
$Method = "POST";
if (empty($PostData))
{$Method = "GET";}
$Port = 80;
if (strtolower(substr($Host, 0, 5)) == "https")
{$Port = 443;}
$Host = explode("//", $Host, 2);
if (count($Host) < 2)
{$Host[1] = $Host[0];}
$Host = explode("/", $Host[1], 2);
if ($Port == 443)
{$SSLAdd = "ssl://";}
$Host[0] = explode(":", $Host[0]);
if (count($Host[0]) > 1)
{
$Port = $Host[0][1];
$Host[0] = $Host[0][0];
}
else
{$Host[0] = $Host[0][0];}
$Socket = fsockopen($SSLAdd.$Host[0], $Port, $Dummy1, $Dummy2, 10);
if ($Socket)
{
fputs($Socket, "$Method /$Host[1] HTTP/1.1\r\n".
"Host: $Host[0]\r\n".
"Content-type: application/x-www-form-urlencoded\r\n".
"User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n".
"Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n".
"Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n".
"Content-length: ".strlen($PostData)."\r\n".
"Connection: close\r\n".
"\r\n".
$PostData);
$Tme = time();
while(!feof($Socket) && $Tme + 30 > time())
{$Res = $Res.fgets($Socket, 256);}
fclose($Socket);
}
$Res = explode("\r\n\r\n", $Res, 2);
return $Res[1];
}
?>
Here is the simplest possible PHP persistant URL script, it could even be run on an old PC set up as a Linux web server from home. make a text file on the server, then call the page and write to the text file from the LSL script in your prim. reading the page will give you the SL URL for the prim.
<?php
$myfile = fopen("yourfile.txt", "w") or die("Unable to open file!");
$txt = $_POST['url'];
fwrite($myfile, $txt);
fclose($myfile);
?>
Kelly's Stupid Web Status Updater
Is actually on its own page: Kelly's Stupid Web Status Updater
Kurai's mod from Kelly's stupid thing: Kurai's Stupid Web Status Updater Mod
Web-based dynamic buildings
HTTP-in may be used to easily send commands from a web page to an in-world object, so that web users can control and interact with buildings. The interactive installation Chromutate is based upon this idea: see its documentation page for free scripts and more details.
PHP/SQL Object DNS
Simple DNS server written in PHP to facilitate a DNS service for LSL scripts: PHPDNS
HyperMedia (LSL Web Server)
An LSL web server that uses HTTP-In and Shared Media to serve and render a webpage (with working forms) on a prim: HyperMedia
Object to object HTTP communication
Go to Object to object HTTP communication for an example of inworld HTTP communication model.