| Anonymous | Login | Signup for a new account | 2013-05-23 14:48 UTC | ![]() |
| Main | My View | View Issues | Change Log | Roadmap | Summary | My Account |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | ||||
| 0005993 | opensim | [REGION] OpenSim Core | public | 2012-04-26 13:26 | 2012-05-14 18:27 | ||||
| Reporter | tomhainescciu | ||||||||
| Assigned To | justincc | ||||||||
| Priority | normal | Severity | minor | Reproducibility | always | ||||
| Status | resolved | Resolution | fixed | ||||||
| Platform | Linux | OS | Ubuntu | OS Version | 11.10 | ||||
| Product Version | master (dev code) | ||||||||
| Target Version | Fixed in Version | ||||||||
| Summary | 0005993: In attachment, llRequestURL() immediately after changing regions results in broken HTTP-in URL being returned | ||||||||
| Description | When an attachment requests a new HTTP-in URL in the changed event, the new URL doesn't function properly. $ curl -v http://x.x.x.x:9000/lslhttp/f46bdfa1-885f-48f2-aa58-b802ae001790/ [^] * About to connect() to x.x.x.x port 9000 (#0) * Trying x.x.x.x... connected * Connected to x.x.x.x (x.x.x.x) port 9000 (#0) > GET /lslhttp/f46bdfa1-885f-48f2-aa58-b802ae001790/ HTTP/1.1 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 > Host: x.x.x.x:9000 > Accept: */* > The request just hangs here. | ||||||||
| Steps To Reproduce | add this script to an attachment, and then teleport to a new region. when attempting to connect to the URL granted in the changed event, the HTTP connection hangs after connecting string _httpin_url_request_key; default { changed(integer mask) { if ( mask & CHANGED_REGION ) { _httpin_url_request_key = llRequestURL(); } } http_request(key request_id, string http_method, string body) { integer response_status_code = 200; // check if this is a call back from llRequestURL() llOwnerSay("process_http_request_event() - http_method: " + http_method); if ( request_id == _httpin_url_request_key) { _httpin_url_request_key = ""; if (http_method == URL_REQUEST_GRANTED){ // set the new HTTP-In URL llOwnerSay(body); } else if (http_method == URL_REQUEST_DENIED) { // } } llHTTPResponse(request_id, 200, "GREAT SUCCESS"); } state_entry() { _httpin_url_request_key = llRequestURL(); } } | ||||||||
| Tags | No tags attached. | ||||||||
| Git Revision or version number | f36fe45fa7468dd6e785d523c5df38666140135f | ||||||||
| Run Mode | Grid (Multiple Regions per Sim) | ||||||||
| Physics Engine | ODE | ||||||||
| Environment | Mono / Linux64 | ||||||||
| Mono Version | 2.10 | ||||||||
| Viewer | Second Life Viewer 2 | ||||||||
| Attached Files | |||||||||
Notes |
|
|
(0021309) tomhainescciu (reporter) 2012-04-26 13:26 |
I should note that in my script I'm releasing the URL before generating a new one. |
|
(0021366) justincc (administrator) 2012-05-04 21:15 |
I wasn't able to reproduce this on current git master da4819a1 with this script in a box on my head whilst teleporting between two regions separated by a one region space - I was able to wget the given url output after teleport. I have done some changes to teleport timings very recently. In theory, this shouldn't impact url requests but it's worth checking against really bleeding edge. In da4819a1 I also added some debug log lines which say when an url is requested and released. It might be worth including the url releases in the test script since that may well have an impact on this. Also, your current script has a small weakness where llHTTPResponse(request_id, 200, "GREAT SUCCESS"); is still called even if the script is just being notified about a granted/denied URL. |
|
(0021368) justincc (administrator) 2012-05-04 22:08 |
Also, are the teleport source and target on the same simulator or different simulators? |
|
(0021372) Michelle Argus (reporter) 2012-05-05 11:33 |
Does this only happen were the URL generated uses the hostname instead of the IP? When the hostname is used instead of the IP there is often a connection problem which can be solved by replacing the incorrect hostname with the IP, adjusting the server settings or ajusting the ExternalHostNameForLSL in the opensim.ini . Unfortunatly many hosters have incorrect hostnames set by default, eg. all common german server providers. http://opensimulator.org/mantis/view.php?id=5615 [^] Otherwise, I also could not repruduce the problem. Tip: if the a adress is not reachable, replace the hostname with the IP. My experiance sofar is, that it always works. You then dont need to contact each regionowner to have them change their settings ;) |
|
(0021385) tomhainescciu (reporter) 2012-05-07 16:35 edited on: 2012-05-07 16:39 |
Justin, That script was thrown together for the sake of a quick test. I realize now that I'm not seeing the problem in this script, but am still seeing it in the original. I wanted to break it down to the smallest component that still manages to cause the problem. I will attach in a second note the full text of the original script. The HUD in question contains about 15 prims, each running one script. The script that uses llRequestURL passes linked messages to the other scripts. None of the child scripts use LLRequestURL. I will be upgrading to Git master shortly, and will see if that fixes the issue. Michelle, I am using IP addresses everywhere and not Hostnames, and if the script is reset after landing in a new region, llRequestURL returns a working URL |
|
(0021386) tomhainescciu (reporter) 2012-05-07 16:37 edited on: 2012-05-07 17:51 |
// the host name of the server string server_hostname = "host.name.of.game.server"; integer server_use_ssl = FALSE; // whether we ask for a new httpin url on region changes by llRequestURL() or llResetScript(); // valid values are 'request' or 'reset' // see http://opensimulator.org/mantis/view.php?id=5993 [^] string _new_region_httpin_request_method = "request"; /**** * NO MORE USER CUSTOMIZABLE SETTINGS *****/ float version = 0.5; // the various control groups we can communicate with integer CONTROL_GROUP_COMMUNICATOR = 1; integer CONTROL_GROUP_PAGE_FULL = 2; integer CONTROL_GROUP_PAGE_SMALL = 4; integer CONTROL_GROUP_INVENTORY = 8; integer CONTROL_GROUP_MUSIC = 16; integer CONTROL_GROUP_ALL = 2147483647; // various child methods that can be called integer CHILD_METHOD_SHOW = 1; integer CHILD_METHOD_HIDE = 2; integer CHILD_METHOD_RESET = 4; integer CHILD_METHOD_LOAD_URL = 8; integer CHILD_METHOD_CLEAR_URL = 16; integer CHILD_METHOD_DISPLAY_CHARACTER = 32; integer CHILD_METHOD_DISPLAY_DIALOGUE = 64; integer CHILD_METHOD_SET_INVENTORY_STATE = 128; integer CHILD_METHOD_SHOW_INVENTORY_ITEM = 256; integer CHILD_METHOD_HIDE_INVENTORY_ITEM = 512; integer CHILD_METHOD_CONTROL_MUSIC = 1024; // various inventory items integer INVENTORY_ITEM_CHART = 1; integer INVENTORY_ITEM_HEALTHY_BLUEPRINT = 2; integer INVENTORY_ITEM_HELICASE_ENZYME = 4; integer INVENTORY_ITEM_HEALTHY_DNA = 8; integer INVENTORY_ITEM_POLYMERASE = 16; integer INVENTORY_ITEM_RNA_POLYMERASE = 32; integer INVENTORY_ITEM_MRNA = 64; integer INVENTORY_ITEM_ALL = 2147483647; string _current_httpin_url = ""; // the private var used to identify llRequestURL() and llHTTPRequest() calls key _httpin_url_request_key; key _http_event_trip_key; // the endpoint on the server for event tripping string _server_event_trip_endpoint = "/triggers"; // debug functions integer DEBUG = FALSE; dm(string message) { if ( DEBUG ) llOwnerSay(message); } // boot the HUD _initialize_hud() { // tell the server we've booted trip_server_event("hud_boot", []); // request an httpin url _request_new_httpin_url(); } // this just restarts this script _restart_supervisor() { llResetScript(); } // this function takes the name of an argument and a strided list of args and values (as returned by parse_arguments), // and returns the value string get_argument(string arg_name, list args) { integer index = llListFindList(args, [arg_name]); if ( index == -1 ) { return ""; } else { return ( llList2String(args, index+1)); } } // ############################################### // 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 parse_arguments(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; } // adds a param and value to a strided list and returns the value list append_arguments(string param, string value, list args) { args = args + [param, value]; return args; } // this turns a param, value strided list into ad URL safe param string // e.g. ['firstname','ringo','lastname','starr'] becomes 'firstname=ringo&lastname=starr' // not sure if this handles empty args list properly string build_parameter_string(list args) { integer i; string paramString = ""; integer length = llGetListLength(args); for (i = 0; i < length; i+=2) { // add the param if (i != 0) { paramString += "&";} paramString += llEscapeURL(llList2String(args,i)); paramString += "=" + llEscapeURL(llList2String(args,i+1)); } return paramString; } /* process any state change events that are triggered * Should respond to: CHANGED_REGION, CHANGED_TELEPORT, CHANGED_REGION_START */ process_changed_event(integer change) { // if we moved to a new region, request a new HTTPin url. // also let the server know we've changed to a new region. if ( change & CHANGED_REGION ) { dm("process_changed_event() change: " + change); dm("change & CHANGED_REGION"); /******** We'd like to just get a new httpin_url here, but it looks like an OpenSim bug causes the httpin_url to not function. The only way around it seems to be to restart this script here. A bit kludgy. **********/ if (_new_region_httpin_request_method == "request" ) { // request a new httpin url. _request_new_httpin_url(); // tell the server we've changed regions after we request a new url trip_server_event("region_changed", []); } else { // tell the server we've changed regions before we reset the script trip_server_event("region_changed", []); _restart_supervisor(); } } } process_on_rez_event(integer param) { trip_server_event("hud_rez", []); } process_attach_event(key id) { dm("process_attach_event: id: " + id); if( id ) { // llResetScript(); } else { // state inactive; } } // request a new http in url _request_new_httpin_url() { _httpin_url_request_key = llRequestURL(); } /* handle any incoming http_request events. implemented here to ensure * uniform HTTP request handling across lsl states */ process_http_request_event(key request_id, string http_method, string body) { integer response_status_code = 200; // check if this is a call back from llRequestURL() dm("process_http_request_event(): http_method: " + http_method); dm("process_http_request_event(): body: " + body); if ( request_id == _httpin_url_request_key) { _httpin_url_request_key = ""; if (http_method == URL_REQUEST_GRANTED){ // set the new HTTP-In URL update_httpin_url(body); trip_server_event("httpin_url_changed", ["httpin_url", body]); } else if (http_method == URL_REQUEST_DENIED) { state fatal_error; } // otherwise treat it as a method call from the server } else { // respond affirmatively llHTTPResponse(request_id, response_status_code, ""); list args = parse_arguments(body); string method = get_argument("method", args); if ( method != "" ) { if ( method == "loadPageFull") {_loadPageFull(get_argument("url", args));} if ( method == "hidePageFull") {_hidePageFull();} if ( method == "loadPageSmall") {_loadPageSmall(get_argument("url",args));} if ( method == "hidePageSmall") {_hidePageSmall();} if ( method == "teleportPlayer") {_teleportPlayer(get_argument("region", args), (vector) "<" + get_argument("teleport_x", args) + "," + get_argument("teleport_y", args) + "," +get_argument("teleport_z", args) + ">", (vector) "<" + get_argument("facing_x", args) + "," + get_argument("facing_y", args) + "," +get_argument("facing_z", args) + ">" );} if ( method == "displayDialogue") {_displayDialogue( (key) get_argument("character_texture_id", args), get_argument("dialogue_url", args));} if ( method == "hideDialogue") {_hideDialogue();} if ( method == "setInventoryItemState") {_setInventoryItemState((integer) get_argument("inventory_item_id", args), (integer) get_argument("inventory_item_state", args));} if ( method == "showInventoryItem") {_showInventoryItem((integer) get_argument("inventory_item_id", args));} if ( method == "hideInventoryItem") {_hideInventoryItem((integer) get_argument("inventory_item_id", args));} if ( method == "controlMusic") {_controlMusic( get_argument("music_command", args));} if ( method == "restartHUD") {_restartHUD();} } } } /* handle any incoming http_response event. implemented here to ensure * uniform HTTP request handling across lsl states */ process_http_response_event( key request_id, integer status, list metadata, string body ) { // if this is a call back from an event trip if ( request_id = _http_event_trip_key ) { } } /* This function accepts a new _httpin_url as returned from a call to * llRequestURLand gives passes it to the server * it also must free the old URL in _current_httpin_url */ update_httpin_url(string new_url) { if ( _current_httpin_url != "") { llReleaseURL( new_url );} dm ( new_url ); _current_httpin_url = new_url; } /* This function trips an event on the server. * It is up to the server to decide what to do with the event. * The following parameters are relayed in the headers, so they do not need to be passed as paramaters here: * avatar_id, region_name */ trip_server_event(string event_name, list args) { string protocol; if ( server_use_ssl == TRUE ) { protocol = "https://";} [^] else { protocol = "http://";} [^] string url = protocol + server_hostname + _server_event_trip_endpoint + "/" + event_name; list http_params = [ HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded" ]; // add mandatory arguments to the list args += ["version", version, "avatar_key", llGetOwner()]; string post_params = build_parameter_string(args); dm("trip_server_event: post_params: " + post_params); _http_event_trip_key = llHTTPRequest(url, http_params, post_params); } /* This function calls a method on one of the children prims * by sending a linked message to the entire set. child prims * have a component_group property. The method specifies a * particular control_group or ALL. Prims will respond if they * are in the control_group or ALL is specified. */ call_child_method(integer method, integer control_group, list parameters) { string parameter_string = build_parameter_string(parameters); llMessageLinked(LINK_SET, control_group, (string) method, (key) parameter_string); } // load a URL in the full screen browser _loadPageFull (string url) { call_child_method(CHILD_METHOD_SHOW, CONTROL_GROUP_PAGE_FULL, []); call_child_method(CHILD_METHOD_LOAD_URL, CONTROL_GROUP_PAGE_FULL, ["url",url]); } _hidePageFull () { call_child_method(CHILD_METHOD_HIDE, CONTROL_GROUP_PAGE_FULL, []); call_child_method(CHILD_METHOD_CLEAR_URL, CONTROL_GROUP_PAGE_FULL, []); } _loadPageSmall (string url) { call_child_method(CHILD_METHOD_SHOW, CONTROL_GROUP_PAGE_SMALL, []); call_child_method(CHILD_METHOD_LOAD_URL, CONTROL_GROUP_PAGE_SMALL, ["url",url]); } _hidePageSmall () { call_child_method(CHILD_METHOD_HIDE, CONTROL_GROUP_PAGE_SMALL, []); call_child_method(CHILD_METHOD_CLEAR_URL, CONTROL_GROUP_PAGE_SMALL, []); } _teleportPlayer (string region, vector location, vector facing) { // no idea } _displayDialogue (key character_texture_id, string dialogue_url) { // call the child methods to display the character and dialogue before the show command call_child_method(CHILD_METHOD_DISPLAY_CHARACTER, CONTROL_GROUP_COMMUNICATOR, ["character_texture_id", character_texture_id]); call_child_method(CHILD_METHOD_DISPLAY_DIALOGUE, CONTROL_GROUP_COMMUNICATOR, ["dialogue_url", dialogue_url]); call_child_method(CHILD_METHOD_SHOW, CONTROL_GROUP_COMMUNICATOR, []); } _hideDialogue () { call_child_method(CHILD_METHOD_HIDE, CONTROL_GROUP_COMMUNICATOR, []); } _setInventoryItemState(integer inventory_item_id, integer inventory_item_state) { call_child_method(CHILD_METHOD_SET_INVENTORY_STATE, CONTROL_GROUP_INVENTORY, ["inventory_item_id", inventory_item_id, "inventory_item_state", inventory_item_state]); } _showInventoryItem(integer inventory_item_id) { call_child_method(CHILD_METHOD_SHOW_INVENTORY_ITEM, CONTROL_GROUP_INVENTORY, ["inventory_item_id", inventory_item_id]); } _hideInventoryItem(integer inventory_item_id) { call_child_method(CHILD_METHOD_HIDE_INVENTORY_ITEM, CONTROL_GROUP_INVENTORY, ["inventory_item_id", inventory_item_id]); } _controlMusic(string music_command) { call_child_method(CHILD_METHOD_CONTROL_MUSIC, CONTROL_GROUP_MUSIC, ["music_command", music_command]); } _restartHUD () { call_child_method(CHILD_METHOD_RESET, CONTROL_GROUP_ALL, []); _restart_supervisor(); } _hideAll () { call_child_method(CHILD_METHOD_HIDE, CONTROL_GROUP_ALL, []); } default { state_entry() { _initialize_hud(); } attach(key id) {process_attach_event(id);} changed(integer mask) {process_changed_event(mask);} on_rez(integer param) {process_on_rez_event(param);} http_response( key request_id, integer status, list metadata, string body ) { process_http_response_event( request_id, status, metadata, body );} http_request(key request_id, string http_method, string body) { process_http_request_event(request_id, http_method, body);} } state active_gameplay { state_entry() { } attach(key id) {process_attach_event(id);} changed(integer mask) {process_changed_event(mask);} on_rez(integer param) {process_on_rez_event(param);} http_response( key request_id, integer status, list metadata, string body ) { process_http_response_event( request_id, status, metadata, body );} http_request(key request_id, string http_method, string body) { process_http_request_event(request_id, http_method, body);} } state inactive { state_entry() { } attach(key id) {process_attach_event(id);} changed(integer mask) {process_changed_event(mask);} on_rez(integer param) {process_on_rez_event(param);} http_response( key request_id, integer status, list metadata, string body ) { process_http_response_event( request_id, status, metadata, body );} http_request(key request_id, string http_method, string body) { process_http_request_event(request_id, http_method, body);} } state incorrect_version { state_entry() { } attach(key id) {process_attach_event(id);} changed(integer mask) {process_changed_event(mask);} on_rez(integer param) {process_on_rez_event(param);} http_response( key request_id, integer status, list metadata, string body ) { process_http_response_event( request_id, status, metadata, body );} http_request(key request_id, string http_method, string body) { process_http_request_event(request_id, http_method, body);} } state fatal_error { state_entry() { // TODO: Process error llSay(0, "Aww snap!"); } attach(key id) {process_attach_event(id);} changed(integer mask) {process_changed_event(mask);} on_rez(integer param) {process_on_rez_event(param);} http_response( key request_id, integer status, list metadata, string body ) { process_http_response_event( request_id, status, metadata, body );} http_request(key request_id, string http_method, string body) { process_http_request_event(request_id, http_method, body);} } |
|
(0021405) justincc (administrator) 2012-05-11 02:31 |
Is it possible to cut down this second script to the part that actually causes the failure? Also, it's crucial to know whether source and destination regions are on the same simulator. |
|
(0021420) justincc (administrator) 2012-05-12 02:09 |
In fact, even the posted script will not compile - it has copy/paste errors on line 3 of trip_server_event() |
|
(0021422) BlueWall (administrator) 2012-05-12 02:17 |
Try adding another state to the small test script and switching out of default to it before jumping. See if that will trigger the behavior. |
|
(0021447) tomhainescciu (reporter) 2012-05-12 14:13 edited on: 2012-05-12 14:19 |
@justincc, The script doesn't compile because mantis tries to turn http:// in trip_server_event into a link and inserts characters that throw syntax errors. See above. I will strip it down to smalest breaking part today. And both region and destination are on the same simulator. I will also test today if problem occurs when they are not on the same simulator. @BlueWall, I will try this today. |
|
(0021448) tomhainescciu (reporter) 2012-05-12 16:30 |
In stripping out unnecessary functionality, I found the source of the problem. I have a housekeeping function that fires llReleaseURL on the old url after a new one is obtained, and of course I was executing it upon the newly retrieved url. Sorry for the wasted time. Everything is now working as it should. |
|
(0021458) justincc (administrator) 2012-05-14 18:27 |
No problem, good to hear that you got it working! |
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2012-04-26 13:26 | tomhainescciu | New Issue | |
| 2012-04-26 13:26 | tomhainescciu | Note Added: 0021309 | |
| 2012-04-26 13:30 | tomhainescciu | Steps to Reproduce Updated | View Revisions |
| 2012-04-26 13:30 | tomhainescciu | Steps to Reproduce Updated | View Revisions |
| 2012-05-04 21:15 | justincc | Note Added: 0021366 | |
| 2012-05-04 21:15 | justincc | Assigned To | => justincc |
| 2012-05-04 21:15 | justincc | Status | new => feedback |
| 2012-05-04 22:08 | justincc | Note Added: 0021368 | |
| 2012-05-05 11:33 | Michelle Argus | Note Added: 0021372 | |
| 2012-05-07 16:35 | tomhainescciu | Note Added: 0021385 | |
| 2012-05-07 16:35 | tomhainescciu | Status | feedback => assigned |
| 2012-05-07 16:37 | tomhainescciu | Note Added: 0021386 | |
| 2012-05-07 16:39 | tomhainescciu | Note Edited: 0021385 | View Revisions |
| 2012-05-07 16:48 | tomhainescciu | Note Edited: 0021386 | View Revisions |
| 2012-05-07 16:49 | tomhainescciu | Note Edited: 0021386 | View Revisions |
| 2012-05-07 17:51 | tomhainescciu | Note Edited: 0021386 | View Revisions |
| 2012-05-11 02:31 | justincc | Note Added: 0021405 | |
| 2012-05-12 02:09 | justincc | Note Added: 0021420 | |
| 2012-05-12 02:17 | BlueWall | Note Added: 0021422 | |
| 2012-05-12 14:13 | tomhainescciu | Note Added: 0021447 | |
| 2012-05-12 14:19 | tomhainescciu | Note Edited: 0021447 | View Revisions |
| 2012-05-12 16:30 | tomhainescciu | Note Added: 0021448 | |
| 2012-05-14 18:27 | justincc | Note Added: 0021458 | |
| 2012-05-14 18:27 | justincc | Status | assigned => resolved |
| 2012-05-14 18:27 | justincc | Resolution | open => fixed |
| Copyright © 2000 - 2012 MantisBT Group |