Difference between revisions of "LlGetHTTPHeader"

From Second Life Wiki
Jump to navigation Jump to search
m (Added caveats for path/querystring)
(Works fine outside http_request as long as the key is valid)
 
(14 intermediate revisions by 7 users not shown)
Line 2: Line 2:
|func_id=349|func_sleep=0.0|func_energy=10.0|mode
|func_id=349|func_sleep=0.0|func_energy=10.0|mode
|func=llGetHTTPHeader|return_type=string
|func=llGetHTTPHeader|return_type=string
|p1_type=key|p1_name=request_id|p1_desc=A valid HTTP request key.
|p1_type=key|p1_subtype=handle|p1_name=request_id|p1_desc=A valid HTTP request key.
|p2_type=string|p2_name=header|p2_desc=Header value name.
|p2_type=string|p2_name=header|p2_desc=Lower case header value name.
|func_footnote
|func_footnote=Returns an empty string if the header is not found, if the '''request_id''' is not a valid key received through the [[http_request]] event, or if the headers can no longer be accessed. Headers can only be accessed before [[llHTTPResponse]] is called and with-in the first 30 seconds after the [[http_request]] event is queued.
|func_desc
|func_desc
|return_text=that is the value for '''header''' for '''request_id'''.
|return_text=that is the value for '''header''' for '''request_id'''.
Line 49: Line 49:
===[[llHTTPRequest]] Headers===
===[[llHTTPRequest]] Headers===
{{LSL_Constants/HTTP_Headers|lower-case=*}}
{{LSL_Constants/HTTP_Headers|lower-case=*}}
|caveats=* LSL is not a CGI environment
|caveats=
* Header information becomes inaccessible after 30 seconds or if [[llHTTPResponse]] is called.
* Function returns an empty string in any context outside the [[http_request]] event. For instance, it cannot be used in the [[http_response]] event.
* Custom headers are not supported, only the headers listed in the specification are supported.
* LSL is not a CGI environment
** "Content-Type" is an example of a normal header name, in a CGI environment the name would be "HTTP_CONTENT_TYPE".
** "Content-Type" is an example of a normal header name, in a CGI environment the name would be "HTTP_CONTENT_TYPE".
* This header information is valid for 30 seconds, or until [[llHTTPResponse]] is called.
* '''header''' must be lower case (or it will match nothing). All header names are converted to lower case when they are received.
* The header names listed above are incorrect - they should all be fully lower case (i.e. x-secondlife-shard, x-secondlife-object-name, x-secondlife-object-key, x-secondlife-region, etc.
* When making a request...
* A path must be prefixed with a forward slash
** The path part of the URL must be prefixed with a forward slash
** Good: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo
*** Good: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo
** Bad: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322foo
*** Bad: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322foo
* In order to use the query string, you must include path
** In order to use the query string, you must include a path (even if it is just a slash)
** Good: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/?arg=gra
*** Good: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/?arg=gra
** Bad: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322?arg=gra
*** Bad: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322?arg=gra
|constants
|constants
|examples=
|examples=
<lsl>
<source lang="lsl2">
key url_request;
key url_request;
 
default
default
{
{
Line 70: Line 74:
         url_request = llRequestURL();
         url_request = llRequestURL();
     }
     }
     http_request(key id, string method, string body)
     http_request(key id, string method, string body)
     {
     {
         if (url_request == id)
         if (url_request == id)
         {
         {
        //  if you're usually not resetting the query ID
        //  now is a good time to start!
             url_request = "";
             url_request = "";
             if (method == URL_REQUEST_GRANTED)
             if (method == URL_REQUEST_GRANTED)
             {
             {
                 llOwnerSay("URL: " + body);
                 llOwnerSay("URL: " + body);
                 if(llGetAgentSize(llGetOwner()))
 
                     llLoadURL(llGetOwner(), "", body);
                 key owner = llGetOwner();
                vector ownerSize = llGetAgentSize(owner);
 
                if (ownerSize)//  != ZERO_VECTOR
                     llLoadURL(owner, "I got a new URL!", body);
             }
             }
             else if (method == URL_REQUEST_DENIED)
             else if (method == URL_REQUEST_DENIED)
            {
                 llOwnerSay("Something went wrong, no url:\n" + body);
                 llOwnerSay( "Something went wrong, no url. " + body);
            }
         }
         }
         else
         else
         {
         {
             list headers = [ "x-script-url", "x-path-info", "x-query-string", "x-remote-ip", "user-agent" ];
             list headerList = ["x-script-url",
             integer pos = ~llGetListLength(headers);
                            "x-path-info", "x-query-string",
             while( ++pos )
                            "x-remote-ip", "user-agent"];
 
             integer index = -llGetListLength(headerList);
             do
             {
             {
                 string header = llList2String(headers, pos);
                 string header = llList2String(headerList, index);
                 llOwnerSay(header + ": " + llGetHTTPHeader(id, header));
                 llOwnerSay(header + ": " + llGetHTTPHeader(id, header));
             }
             }
             llOwnerSay( "body: " + body);
            while (++index);
 
             llOwnerSay("body:\n" + body);
             llHTTPResponse(id, 200, body);
             llHTTPResponse(id, 200, body);
         }
         }
     }
     }
}
}
</lsl>
</source>
|helpers
|helpers
|also_functions=
|also_functions=

Latest revision as of 17:31, 21 July 2022

Summary

Function: string llGetHTTPHeader( key request_id, string header );

Returns a string that is the value for header for request_id.

• key request_id A valid HTTP request key.
• string header Lower case header value name.

Returns an empty string if the header is not found, if the request_id is not a valid key received through the http_request event, or if the headers can no longer be accessed. Headers can only be accessed before llHTTPResponse is called and with-in the first 30 seconds after the http_request event is queued.

Specification

Generated Headers

These headers are automatically generated by the simulator, they were not actually sent by the requesting client. They supply information about the request to make parsing easier.

Sample URL: https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra

header description example
"x-script-url" The base url, as originally received from llRequestURL/llRequestSecureURL https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322
"x-path-info" Any trailing path information from the requested url /foo/bar
"x-query-string" Any query arguments, the text past the first "?" in the url arg=gra
"x-remote-ip" IP address of the host that made the request

Common Headers

header description example
"user-agent" The user-agent header as reported by the requester

llHTTPRequest Headers

Headers sent by the simulator in the course of calling llHTTPRequest.
Header Description Example data
connection Connection options close
cache-control Maximum response age accepted. max-age=259200
x-forwarded-for Used to show the IP address connected to through proxies. 127.0.0.1
via Shows the recipients and protocols used between the User Agent and the server. 1.1 sim10115.agni.lindenlab.com:3128 (squid/2.7.STABLE9)
content-length The size of the entity-body, in decimal number of octets. 17
pragma The message should be forwarded to the server, even if it has a cached version of the data. no-cache
x-secondlife-shard The environment the object is in. "Production" is the main grid and "Testing" is the preview grid Production
x-secondlife-region The name of the region the object is in, along with the global coordinates of the region's south-west corner Jin Ho (264448, 233984)
x-secondlife-owner-name Legacy name of the owner of the object Zeb Wyler
x-secondlife-owner-key UUID of the owner of the object 01234567-89ab-cdef-0123-456789abcdef
x-secondlife-object-name The name of the object containing the script Object
x-secondlife-object-key The key of the object containing the script 01234567-89ab-cdef-0123-456789abcdef
x-secondlife-local-velocity The velocity of the object 0.000000, 0.000000, 0.000000
x-secondlife-local-rotation The rotation of the object containing the script 0.000000, 0.000000, 0.000000, 1.000000
x-secondlife-local-position The position of the object within the region (173.009827, 75.551231, 60.950001)
user-agent The user-agent header sent by LSL Scripts. Contains Server version. Second Life LSL/16.05.24.315768 (http://secondlife.com)
content-type The media type of the entity body. text/plain; charset=utf-8
accept-charset Acceptable character sets from the server. Q being the quality expected when sending the different character sets. utf-8;q=1.0, *;q=0.5
accept Media types the server will accept. text/*, application/xhtml+xml, application/atom+xml, application/json, application/xml, application/llsd+xml, application/x-javascript, application/javascript, application/x-www-form-urlencoded, application/rss+xml
accept-encoding Acceptable content encodings for the server. deflate, gzip
host The internet host being requested. secondlife.com
  • CGI environments may place the headers into variables by capitalizing the entire name, replacing dashes with underscores, and prefixing the name with "HTTP_", e.g. "x-secondlife-object-name" becomes "HTTP_X_SECONDLIFE_OBJECT_NAME".
  • HTTP header names are case insensitive [1]. Some ISPs may modify the case of header names, as was seen in BUG-5094.

Caveats

All Issues ~ Search JIRA for related Bugs

Examples

key url_request;

default
{
    state_entry()
    {
        url_request = llRequestURL();
    }

    http_request(key id, string method, string body)
    {
        if (url_request == id)
        {
        //  if you're usually not resetting the query ID
        //  now is a good time to start!
            url_request = "";

            if (method == URL_REQUEST_GRANTED)
            {
                llOwnerSay("URL: " + body);

                key owner = llGetOwner();
                vector ownerSize = llGetAgentSize(owner);

                if (ownerSize)//  != ZERO_VECTOR
                    llLoadURL(owner, "I got a new URL!", body);
            }

            else if (method == URL_REQUEST_DENIED)
                llOwnerSay("Something went wrong, no url:\n" + body);
        }

        else
        {
            list headerList = ["x-script-url",
                            "x-path-info", "x-query-string",
                            "x-remote-ip", "user-agent"];

            integer index = -llGetListLength(headerList);
            do
            {
                string header = llList2String(headerList, index);
                llOwnerSay(header + ": " + llGetHTTPHeader(id, header));
            }
            while (++index);

            llOwnerSay("body:\n" + body);
            llHTTPResponse(id, 200, body);
        }
    }
}

See Also

Events

•  http_request

Functions

•  llGetFreeURLs
•  llRequestURL
•  llRequestSecureURL
•  llReleaseURL
•  llHTTPResponse

Articles

•  LSL http server
•  "Wikipedia logo"Wikipedia:List of HTTP headers

Deep Notes

History

Search JIRA for related Issues

Signature

function string llGetHTTPHeader( key request_id, string header );