LSL HTTP server/examples/ja

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

ユーティリティ・スクリプト

「穴埋め」練習に向いた、とってもとってもシンプルな HTTP サーバは、こちらです。 Utility Script

Hello World!

古典的でシンプルな、可能な範囲でいちばん小さい http_request スクリプトです。

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!");
        }
    }
}

もっと頑丈に作ったバージョン

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))" は "Hello World" をもうちょっと使えるようにしたもので、動的に生成されたデータフィードを返す簡単なサーバのデモンストレーションになっています。Echo World は http_request がどのように GET で渡された変数を受け取るかを示しています。この「動的エコー」を受け取るために、以下のように、ご自分の URL の最後尾にクエリ文字列を追加してください。 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"));
        }        
    }
}

訪問者リスト

サーバのセンサーの範囲内の人のリストです。
注意:

  • このスクリプトには、リクエストしたデータの帰りを非同期で待ちながら、複数のリクエストをさばくメソッドが入っています。
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 固定 / ビジターカウンター

'hello world' をもっと完成に近づけたもので、常に URL をもち、訪問者をカウントし続けます。

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 で POST を使った例

POST を使った他の例を示した一連のスクリプトです。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。(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");
        }
    }
}

グリッド上のプリムと通信する Perl スクリプトです。

#!/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{

    # 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);
}


# 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";

上の Perl コードと同じことをする Python コードです。

#!/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 で POST を使った例

POST を使った他の例を示した一連のスクリプトです。この例では、スクリプトは渡された引数を解釈するようになっています。最初のスクリプトはグリッドの情報を受信する LSL プログラムです。2 番目のスクリプトは Perl スクリプトで、外部サーバに置いてグリッドのプログラムと通信するのに使います。3 番目のスクリプトは Python スクリプトで、同じように外部サーバに置いてグリッドのプログラムと通信するのに使います。 (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");
        }
    }
}

対応する Perl スクリプトです。グリッド上のプリムと通信します。

#!/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");


対応する Python スクリプトです。上の Perl スクリプトと同じことをします。

#!/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);


PHP を通して LSL にデータを送信する簡単なスクリプト

この例は Simba Fuhr が作成しました。

Warning!

プロバイダによっては、fsockopen を標準のポート 80 または 443 でしか許可していないことがあります。このスクリプトはそのようなプロバイダ上で動作しません。

default
{
 state_entry()
 {
  llRequestURL();
 }
 http_request(key id, string method, string body)
 {
  if ((method == URL_REQUEST_GRANTED))
  {
   llOwnerSay("URL: " + body);
  }
  else if (method == "POST")
  {
   llHTTPResponse(id, 200, body + " there !");
  }
 }
}

PHP スクリプトです。 LSL スクリプトに "Hello" と送信し、" there !" を付け加えて返却します。つまり、PHP は "Hello there !" と返すことになります。

<?php
$Data = CallLSLScript("http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0", "Hello");
die($Data);

//Function by Simba Fuhr
//Use under the GPL License
function CallLSLScript($URL, $Data, $Timeout = 10)
{
 //Parse the URL into Server, Path and Port
 $Host = str_ireplace("http://", "", $URL);
 $Path = explode("/", $Host, 2);
 $Host = $Path[0];
 $Path = $Path[1];
 $PrtSplit = explode(":", $Host);
 $Host = $PrtSplit[0];
 $Port = $PrtSplit[1];
 
 //Open Connection
 $Socket = fsockopen($Host, $Port, $Dummy1, $Dummy2, $Timeout);
 if ($Socket)
 {
  //Send Header and Data
  fputs($Socket, "POST /$Path HTTP/1.1\r\n");
  fputs($Socket, "Host: $Host\r\n");
  fputs($Socket, "Content-type: application/x-www-form-urlencoded\r\n");
  fputs($Socket, "User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n");
  fputs($Socket, "Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n");
  fputs($Socket, "Content-length: ".strlen($Data)."\r\n");
  fputs($Socket, "Connection: close\r\n\r\n");
  fputs($Socket, $Data);
   
  //Receive Data
  while(!feof($Socket))
   {$res .= fgets($Socket, 128);}
  fclose($Socket);
 }
  
 //ParseData and return it
 $res = explode("\r\n\r\n", $res);
 return $res[1];
}
?>

Kelly のけったいな Web ステータス更新装置

原文のページにあります: Kelly's Stupid Web Status Updater
Kurai さんが改変したもの: Kurai's Stupid Web Status Updater Mod

グリッド URL 不揮発化のサンプルスクリプト

このスクリプト は、フリーのWeb サービス Grid URL Persister を使って、LSL HTTP サーバの一時的な URL を管理しています。

Web ベースの動的建築

HTTP-in は Web ページからインワールドのオブジェクトに簡単にコマンドを送るのに使用できます。つまり、Web のユーザが建築物をコントロールして情報をやりとりすることができます。Chromutate というインタラクティブな展示物は、このアイデアをもとにしています。フリーのスクリプトと詳細な説明は、 資料サイト を参照してください。

PHP/SQL オブジェクト DNS

PHP で書かれた簡単な DNS サーバです。LSL スクリプトで DNS サービスを扱いやすくします。 PHPDNS