diff options
30 files changed, 1048 insertions, 32 deletions
diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h index 289f9995e5..7cd854febd 100644 --- a/indra/llcommon/lllslconstants.h +++ b/indra/llcommon/lllslconstants.h @@ -188,4 +188,18 @@ const S32 OBJECT_CREATOR = 8; // llTextBox() magic token string - yes this is a hack. sue me. const std::string TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!"; +// changed() event flags +const U32 CHANGED_NONE = 0x0; +const U32 CHANGED_INVENTORY = 0x1; +const U32 CHANGED_COLOR = 0x2; +const U32 CHANGED_SHAPE = 0x4; +const U32 CHANGED_SCALE = 0x8; +const U32 CHANGED_TEXTURE = 0x10; +const U32 CHANGED_LINK = 0x20; +const U32 CHANGED_ALLOWED_DROP = 0x40; +const U32 CHANGED_OWNER = 0x80; +const U32 CHANGED_REGION = 0x100; +const U32 CHANGED_TELEPORT = 0x200; +const U32 CHANGED_REGION_START = 0x400; + #endif diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 6e3024908e..12d0fdf1e9 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -243,7 +243,7 @@ public: void setAllParcelFlags(U32 flags); void setParcelFlag(U32 flag, BOOL b); - void setArea(S32 area, S32 sim_object_limit); + virtual void setArea(S32 area, S32 sim_object_limit); void setDiscountRate(F32 rate); void setAllowModify(BOOL b) { setParcelFlag(PF_CREATE_OBJECTS, b); } diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 0114ad0713..2ba900a533 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -36,8 +36,8 @@ #include <boost/tokenizer.hpp> #include "llstl.h" +#include "lliohttpserver.h" // for string constants -static const std::string CONTEXT_REQUEST("request"); static const std::string CONTEXT_WILDCARD("wildcard"); /** @@ -181,7 +181,8 @@ void LLHTTPNode::options(ResponsePtr response, const LLSD& context) const //llinfos << "options context: " << context << llendl; // default implementation constructs an url to the documentation. - std::string host = context[CONTEXT_REQUEST]["headers"]["host"].asString(); + std::string host( + context[CONTEXT_REQUEST][CONTEXT_HEADERS]["host"].asString()); if(host.empty()) { response->status(400, "Bad Request -- need Host header"); @@ -475,6 +476,11 @@ void LLSimpleResponse::result(const LLSD& result) status(200, "OK"); } +void LLSimpleResponse::extendedResult(S32 code, const std::string& body, const LLSD& headers) +{ + status(code,body); +} + void LLSimpleResponse::status(S32 code, const std::string& message) { mCode = code; diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h index a6f14f6545..4f80db47f1 100644 --- a/indra/llmessage/llhttpnode.h +++ b/indra/llmessage/llhttpnode.h @@ -38,7 +38,6 @@ class LLChainIOFactory; - /** * These classes represent the HTTP framework: The URL tree, and the LLSD * REST interface that such nodes implement. @@ -101,6 +100,11 @@ public: virtual void result(const LLSD&) = 0; /** + * @brief return status code and message with headers. + */ + virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) = 0; + + /** * @brief return status code and reason string on http header, * but do not return a payload. */ @@ -218,6 +222,14 @@ public: const LLHTTPNode* rootNode() const; const LLHTTPNode* findNode(const std::string& name) const; + + enum EHTTPNodeContentType + { + CONTENT_TYPE_LLSD, + CONTENT_TYPE_TEXT + }; + + virtual EHTTPNodeContentType getContentType() const { return CONTENT_TYPE_LLSD; } //@} /* @name Description system @@ -277,6 +289,7 @@ public: static LLPointer<LLSimpleResponse> create(); void result(const LLSD& result); + void extendedResult(S32 code, const std::string& body, const LLSD& headers); void status(S32 code, const std::string& message); void print(std::ostream& out) const; diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 6486e5e3e0..0895af091b 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -57,15 +57,15 @@ #include <boost/tokenizer.hpp> static const char HTTP_VERSION_STR[] = "HTTP/1.0"; -static const std::string CONTEXT_REQUEST("request"); -static const std::string CONTEXT_RESPONSE("response"); -static const std::string CONTEXT_VERB("verb"); -static const std::string CONTEXT_HEADERS("headers"); -static const std::string HTTP_VERB_GET("GET"); -static const std::string HTTP_VERB_PUT("PUT"); -static const std::string HTTP_VERB_POST("POST"); -static const std::string HTTP_VERB_DELETE("DELETE"); -static const std::string HTTP_VERB_OPTIONS("OPTIONS"); +const std::string CONTEXT_REQUEST("request"); +const std::string CONTEXT_RESPONSE("response"); +const std::string CONTEXT_VERB("verb"); +const std::string CONTEXT_HEADERS("headers"); +const std::string HTTP_VERB_GET("GET"); +const std::string HTTP_VERB_PUT("PUT"); +const std::string HTTP_VERB_POST("POST"); +const std::string HTTP_VERB_DELETE("DELETE"); +const std::string HTTP_VERB_OPTIONS("OPTIONS"); static LLIOHTTPServer::timing_callback_t sTimingCallback = NULL; static void* sTimingCallbackData = NULL; @@ -104,6 +104,7 @@ private: // from LLHTTPNode::Response virtual void result(const LLSD&); + virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers); virtual void status(S32 code, const std::string& message); void nullPipe(); @@ -122,7 +123,8 @@ private: STATE_DELAYED, STATE_LOCKED, STATE_GOOD_RESULT, - STATE_STATUS_RESULT + STATE_STATUS_RESULT, + STATE_EXTENDED_RESULT }; State mState; @@ -180,14 +182,32 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( { LLPerfBlock putblock("http_put"); LLSD input; - LLSDSerialize::fromXML(input, istr); + if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) + { + LLSDSerialize::fromXML(input, istr); + } + else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) + { + std::stringstream strstrm; + strstrm << istr.rdbuf(); + input = strstrm.str(); + } mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input); } else if(verb == HTTP_VERB_POST) { LLPerfBlock postblock("http_post"); LLSD input; - LLSDSerialize::fromXML(input, istr); + if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) + { + LLSDSerialize::fromXML(input, istr); + } + else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT) + { + std::stringstream strstrm; + strstrm << istr.rdbuf(); + input = strstrm.str(); + } mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input); } else if(verb == HTTP_VERB_DELETE) @@ -262,7 +282,16 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage; LLBufferStream ostr(channels, buffer.get()); - ostr << mStatusMessage << std::ends; + ostr << mStatusMessage; + + return STATUS_DONE; + } + case STATE_EXTENDED_RESULT: + { + context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = mHeaders; + context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; + LLBufferStream ostr(channels, buffer.get()); + ostr << mStatusMessage; return STATUS_DONE; } @@ -309,6 +338,21 @@ void LLHTTPPipe::Response::result(const LLSD& r) mPipe->unlockChain(); } +void LLHTTPPipe::Response::extendedResult(S32 code, const std::string& body, const LLSD& headers) +{ + if(! mPipe) + { + llwarns << "LLHTTPPipe::Response::status: NULL pipe" << llendl; + return; + } + + mPipe->mStatusCode = code; + mPipe->mStatusMessage = body; + mPipe->mHeaders = headers; + mPipe->mState = STATE_EXTENDED_RESULT; + mPipe->unlockChain(); +} + // virtual void LLHTTPPipe::Response::status(S32 code, const std::string& message) { @@ -409,6 +453,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl( } ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n"; + S32 content_length = buffer->countAfter(channels.in(), NULL); if(0 < content_length) { diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h index fef3f9fc77..d1c9bdde85 100644 --- a/indra/llmessage/lliohttpserver.h +++ b/indra/llmessage/lliohttpserver.h @@ -40,6 +40,18 @@ class LLPumpIO; +// common strings use for populating the context. bascally 'request', +// 'wildcard', and 'headers'. +extern const std::string CONTEXT_REQUEST; +extern const std::string CONTEXT_RESPONSE; +extern const std::string CONTEXT_VERB; +extern const std::string CONTEXT_HEADERS; +extern const std::string HTTP_VERB_GET; +extern const std::string HTTP_VERB_PUT; +extern const std::string HTTP_VERB_POST; +extern const std::string HTTP_VERB_DELETE; +extern const std::string HTTP_VERB_OPTIONS; + class LLIOHTTPServer { public: diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp index dcce00c138..3f07147ebc 100644 --- a/indra/llmessage/llservicebuilder.cpp +++ b/indra/llmessage/llservicebuilder.cpp @@ -86,6 +86,14 @@ void LLServiceBuilder::createServiceDefinition( } } +static +bool starts_with(const std::string& text, const char* prefix) +{ + return text.substr(0, strlen(prefix)) == prefix; +} + +// TODO: Build a real services.xml for windows development. +// and remove the base_url logic below. std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) { std::ostringstream service_url; @@ -96,7 +104,19 @@ std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) LLApp* app = LLApp::instance(); if(app) { - LLSD base_url = app->getOption("services-base-url"); + // We define a base-url for some development configurations + // In production neither of these are defined and all services have full urls + LLSD base_url; + + if (starts_with(service_name,"cap")) + { + base_url = app->getOption("cap-base-url"); + } + + if (base_url.asString().empty()) + { + base_url = app->getOption("services-base-url"); + } service_url << base_url.asString(); } service_url << mServiceMap[service_name]; diff --git a/indra/lscript/CMakeLists.txt b/indra/lscript/CMakeLists.txt index c655aef4d9..937e2ec0dc 100644 --- a/indra/lscript/CMakeLists.txt +++ b/indra/lscript/CMakeLists.txt @@ -1,6 +1,9 @@ # -*- cmake -*- set(lscript_HEADER_FILES + llscriptresource.h + llscriptresourceconsumer.h + llscriptresourcepool.h lscript_alloc.h lscript_byteconvert.h lscript_byteformat.h diff --git a/indra/lscript/llscriptresource.h b/indra/lscript/llscriptresource.h new file mode 100644 index 0000000000..2aa0af882d --- /dev/null +++ b/indra/lscript/llscriptresource.h @@ -0,0 +1,64 @@ +/** + * @file llscriptresource.h + * @brief LLScriptResource class definition + * + * $LicenseInfo:firstyear=2008&license=internal$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSCRIPTRESOURCE_H +#define LL_LLSCRIPTRESOURCE_H + +#include "stdtypes.h" + +// An LLScriptResource is a limited resource per ID. +class LLScriptResource +{ +public: + LLScriptResource(); + + // If amount resources are available will mark amount resouces + // used and returns true + // Otherwise returns false and doesn't mark any resources used. + bool request(S32 amount = 1); + + // Release amount resources from use if at least amount resources are used and return true + // If amount is more than currently used no resources are released and return false + bool release(S32 amount = 1); + + // Returns how many resources are available + S32 getAvailable() const; + + // Sets the total amount of available resources + // It is possible to set the amount to less than currently used + // Most likely to happen on parcel ownership change + void setTotal(S32 amount); + + // Get the total amount of available resources + S32 getTotal() const; + + // Get the number of resources used + S32 getUsed() const; + + // true if more resources used than total available + bool isOverLimit() const; + +private: + S32 mTotal; // How many resources have been set aside + S32 mUsed; // How many resources are currently in use +}; + +#endif // LL_LLSCRIPTRESOURCE_H diff --git a/indra/lscript/llscriptresourceconsumer.h b/indra/lscript/llscriptresourceconsumer.h new file mode 100644 index 0000000000..1ec0026996 --- /dev/null +++ b/indra/lscript/llscriptresourceconsumer.h @@ -0,0 +1,56 @@ +/** + * @file llscriptresourceconsumer.h + * @brief An interface for a script resource consumer. + * + * $LicenseInfo:firstyear=2008&license=internal$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSCRIPTRESOURCECONSUMER_H +#define LL_LLSCRIPTRESOURCECONSUMER_H + +#include "linden_common.h" + +class LLScriptResourcePool; + +// Entities that use limited script resources +// should implement this interface + +class LLScriptResourceConsumer +{ +public: + LLScriptResourceConsumer(); + + virtual ~LLScriptResourceConsumer() { } + + // Get the number of public urls used by this consumer. + virtual S32 getUsedPublicURLs() const = 0; + + // Get the resource pool this consumer is currently using. + LLScriptResourcePool& getScriptResourcePool(); + const LLScriptResourcePool& getScriptResourcePool() const; + + bool switchScriptResourcePools(LLScriptResourcePool& new_pool); + bool canUseScriptResourcePool(const LLScriptResourcePool& resource_pool); + bool isInPool(const LLScriptResourcePool& resource_pool); + +protected: + virtual void setScriptResourcePool(LLScriptResourcePool& pool); + + LLScriptResourcePool* mScriptResourcePool; +}; + +#endif // LL_LLSCRIPTRESOURCECONSUMER_H diff --git a/indra/lscript/llscriptresourcepool.h b/indra/lscript/llscriptresourcepool.h new file mode 100644 index 0000000000..ca4afeb3c6 --- /dev/null +++ b/indra/lscript/llscriptresourcepool.h @@ -0,0 +1,46 @@ +/** + * @file llscriptresourcepool.h + * @brief A collection of LLScriptResources + * + * $LicenseInfo:firstyear=2008&license=internal$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLSCRIPTRESOURCEPOOL_H +#define LL_LLSCRIPTRESOURCEPOOL_H + +#include "llscriptresource.h" + +// This is just a holder for LLSimResources +class LLScriptResourcePool +{ +public: + LLScriptResourcePool(); + // ~LLSimResourceMgr(); + + LLScriptResource& getPublicURLResource(); + const LLScriptResource& getPublicURLResource() const; + + // An empty resource pool. + static LLScriptResourcePool null; + +private: + LLScriptResource mLSLPublicURLs; +}; + + + +#endif diff --git a/indra/lscript/lscript_byteformat.h b/indra/lscript/lscript_byteformat.h index 7333d47f15..ba2c46bef2 100644 --- a/indra/lscript/lscript_byteformat.h +++ b/indra/lscript/lscript_byteformat.h @@ -360,6 +360,7 @@ typedef enum e_lscript_state_event_type LSTT_OBJECT_REZ, LSTT_REMOTE_DATA, LSTT_HTTP_RESPONSE, + LSTT_HTTP_REQUEST, LSTT_EOF, LSTT_STATE_BEGIN = LSTT_STATE_ENTRY, @@ -401,7 +402,8 @@ const U64 LSCRIPTStateBitField[LSTT_EOF] = 0x0000000020000000, // LSTT_MOVING_END 0x0000000040000000, // LSTT_OBJECT_REZ 0x0000000080000000, // LSTT_REMOTE_DATA - 0x0000000100000000LL // LSTT_HTTP_RESPOSE + 0x0000000100000000LL, // LSTT_HTTP_RESPOSE + 0x0000000200000000LL // LSTT_HTTP_REQUEST }; inline S32 get_event_handler_jump_position(U64 bit_field, LSCRIPTStateEventType type) @@ -551,5 +553,10 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] = (0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA }; +// http_request string constants +extern const char* URL_REQUEST_GRANTED; +extern const char* URL_REQUEST_DENIED; +extern const U64 LSL_HTTP_REQUEST_TIMEOUT; + #endif diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l index 2616b47c73..ac524326fc 100644 --- a/indra/lscript/lscript_compile/indra.l +++ b/indra/lscript/lscript_compile/indra.l @@ -118,6 +118,7 @@ extern "C" { int yyerror(const char *fmt, ...); } "object_rez" { count(); return(OBJECT_REZ); } "remote_data" { count(); return(REMOTE_DATA); } "http_response" { count(); return(HTTP_RESPONSE); } +"http_request" { count(); return(HTTP_REQUEST); } "." { count(); return(PERIOD); } @@ -221,16 +222,17 @@ extern "C" { int yyerror(const char *fmt, ...); } "INVENTORY_ALL" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); } "INVENTORY_NONE" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); } -"CHANGED_INVENTORY" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); } -"CHANGED_COLOR" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); } -"CHANGED_SHAPE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); } -"CHANGED_SCALE" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); } -"CHANGED_TEXTURE" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); } -"CHANGED_LINK" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); } -"CHANGED_ALLOWED_DROP" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); } -"CHANGED_OWNER" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); } -"CHANGED_REGION" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); } -"CHANGED_TELEPORT" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); } +"CHANGED_INVENTORY" { count(); yylval.ival = CHANGED_INVENTORY; return(INTEGER_CONSTANT); } +"CHANGED_COLOR" { count(); yylval.ival = CHANGED_COLOR; return(INTEGER_CONSTANT); } +"CHANGED_SHAPE" { count(); yylval.ival = CHANGED_SHAPE; return(INTEGER_CONSTANT); } +"CHANGED_SCALE" { count(); yylval.ival = CHANGED_SCALE; return(INTEGER_CONSTANT); } +"CHANGED_TEXTURE" { count(); yylval.ival = CHANGED_TEXTURE; return(INTEGER_CONSTANT); } +"CHANGED_LINK" { count(); yylval.ival = CHANGED_LINK; return(INTEGER_CONSTANT); } +"CHANGED_ALLOWED_DROP" { count(); yylval.ival = CHANGED_ALLOWED_DROP; return(INTEGER_CONSTANT); } +"CHANGED_OWNER" { count(); yylval.ival = CHANGED_OWNER; return(INTEGER_CONSTANT); } +"CHANGED_REGION" { count(); yylval.ival = CHANGED_REGION; return(INTEGER_CONSTANT); } +"CHANGED_TELEPORT" { count(); yylval.ival = CHANGED_TELEPORT; return(INTEGER_CONSTANT); } +"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); } "OBJECT_UNKNOWN_DETAIL" { count(); yylval.ival = OBJECT_UNKNOWN_DETAIL; return(INTEGER_CONSTANT); } "OBJECT_NAME" { count(); yylval.ival = OBJECT_NAME; return(INTEGER_CONSTANT); } @@ -252,6 +254,8 @@ extern "C" { int yyerror(const char *fmt, ...); } "NULL_KEY" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "00000000-0000-0000-0000-000000000000"); return(STRING_CONSTANT); } "EOF" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "\n\n\n"); return(STRING_CONSTANT); } +"URL_REQUEST_GRANTED" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, URL_REQUEST_GRANTED); return(STRING_CONSTANT); } +"URL_REQUEST_DENIED" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, URL_REQUEST_DENIED); return(STRING_CONSTANT); } "PI" { count(); yylval.fval = F_PI; return(FP_CONSTANT); } "TWO_PI" { count(); yylval.fval = F_TWO_PI; return(FP_CONSTANT); } diff --git a/indra/lscript/lscript_compile/indra.y b/indra/lscript/lscript_compile/indra.y index fdc240c772..e4b10ffdd9 100644 --- a/indra/lscript/lscript_compile/indra.y +++ b/indra/lscript/lscript_compile/indra.y @@ -92,6 +92,7 @@ %token LINK_MESSAGE %token REMOTE_DATA %token HTTP_RESPONSE +%token HTTP_REQUEST %token <sval> IDENTIFIER %token <sval> STATE_DEFAULT @@ -195,6 +196,7 @@ %type <event> object_rez %type <event> remote_data %type <event> http_response +%type <event> http_request %type <event> link_message %type <event> timer %type <event> chat @@ -848,6 +850,11 @@ event $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); gAllocationManager->addAllocation($$); } + | http_request compound_statement + { + $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); + gAllocationManager->addAllocation($$); + } ; state_entry @@ -1216,6 +1223,20 @@ http_response } ; +http_request + : HTTP_REQUEST '(' LLKEY IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ')' + { + LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); + gAllocationManager->addAllocation(id1); + LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); + gAllocationManager->addAllocation(id2); + LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); + gAllocationManager->addAllocation(id3); + $$ = new LLScriptHTTPRequestEvent(gLine, gColumn, id1, id2, id3); + gAllocationManager->addAllocation($$); + } + ; + compound_statement : '{' '}' { diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp index 51983bb41b..e291d4c6f8 100644 --- a/indra/lscript/lscript_compile/lscript_tree.cpp +++ b/indra/lscript/lscript_compile/lscript_tree.cpp @@ -3291,6 +3291,110 @@ S32 LLScriptHTTPResponseEvent::getSize() return 16; } +void LLScriptHTTPRequestEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata) +{ + if (gErrorToText.getErrors()) + { + return; + } + switch(pass) + { + case LSCP_PRETTY_PRINT: + case LSCP_EMIT_ASSEMBLY: + fdotabs(fp, tabs, tabsize); + fprintf(fp, "http_request( key "); + mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + fprintf(fp, ", string "); + mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + fprintf(fp, ", string "); + mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + fprintf(fp, " )\n"); + break; + + case LSCP_SCOPE_PASS1: + checkForDuplicateHandler(fp, this, scope, "http_request"); + if (scope->checkEntry(mRequestId->mName)) + { + gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME); + } + else + { + mRequestId->mScopeEntry = scope->addEntry(mRequestId->mName, LIT_VARIABLE, LST_KEY); + } + + if (scope->checkEntry(mMethod->mName)) + { + gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME); + } + else + { + mMethod->mScopeEntry = scope->addEntry(mMethod->mName, LIT_VARIABLE, LST_STRING); + } + + if (scope->checkEntry(mBody->mName)) + { + gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME); + } + else + { + mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING); + } + break; + + case LSCP_RESOURCE: + { + // we're just tryng to determine how much space the variable needs + if (mRequestId->mScopeEntry) + { + mRequestId->mScopeEntry->mOffset = (S32)count; + mRequestId->mScopeEntry->mSize = 4; + count += mRequestId->mScopeEntry->mSize; + + mMethod->mScopeEntry->mOffset = (S32)count; + mMethod->mScopeEntry->mSize = 4; + count += mMethod->mScopeEntry->mSize; + + mBody->mScopeEntry->mOffset = (S32)count; + mBody->mScopeEntry->mSize = 4; + count += mBody->mScopeEntry->mSize; + } + } + break; + + case LSCP_EMIT_BYTE_CODE: + { +#ifdef LSL_INCLUDE_DEBUG_INFO + char name[] = "http_request"; + chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/ + chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1); /*Flawfinder: ignore*/ + chunk->addBytes(mMethod->mName, strlen(mMethod->mName) + 1); /*Flawfinder: ignore*/ + chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1); /*Flawfinder: ignore*/ +#endif + } + break; + case LSCP_EMIT_CIL_ASSEMBLY: + fdotabs(fp, tabs, tabsize); + fprintf(fp, "http_request( valuetype [ScriptTypes]LindenLab.SecondLife.Key "); + mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + fprintf(fp, ", string "); + mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + fprintf(fp, ", string "); + mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + fprintf(fp, " )\n"); + break; + default: + mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL); + break; + } +} + +S32 LLScriptHTTPRequestEvent::getSize() +{ + // key + string + string = 12 + return 12; +} void LLScriptMoneyEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata) { @@ -9658,6 +9762,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom mScopeEntry->mFunctionArgs.addType(LST_LIST); mScopeEntry->mFunctionArgs.addType(LST_STRING); break; + case LSTT_HTTP_REQUEST: + mScopeEntry->mFunctionArgs.addType(LST_KEY); + mScopeEntry->mFunctionArgs.addType(LST_STRING); + mScopeEntry->mFunctionArgs.addType(LST_STRING); + break; default: break; diff --git a/indra/lscript/lscript_compile/lscript_tree.h b/indra/lscript/lscript_compile/lscript_tree.h index 369d775e5d..12c16908af 100644 --- a/indra/lscript/lscript_compile/lscript_tree.h +++ b/indra/lscript/lscript_compile/lscript_tree.h @@ -759,12 +759,12 @@ class LLScriptHTTPResponseEvent : public LLScriptEvent { public: LLScriptHTTPResponseEvent(S32 line, S32 col, - LLScriptIdentifier *reqeust_id, + LLScriptIdentifier *request_id, LLScriptIdentifier *status, LLScriptIdentifier *metadata, LLScriptIdentifier *body) : LLScriptEvent(line, col, LSTT_HTTP_RESPONSE), - mRequestId(reqeust_id), mStatus(status), mMetadata(metadata), mBody(body) + mRequestId(request_id), mStatus(status), mMetadata(metadata), mBody(body) { } @@ -783,6 +783,32 @@ public: LLScriptIdentifier *mBody; }; +class LLScriptHTTPRequestEvent : public LLScriptEvent +{ +public: + LLScriptHTTPRequestEvent(S32 line, S32 col, + LLScriptIdentifier *request_id, + LLScriptIdentifier *method, + LLScriptIdentifier *body) + : LLScriptEvent(line, col, LSTT_HTTP_REQUEST), + mRequestId(request_id), mMethod(method), mBody(body) + { + } + + void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, + LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, + LSCRIPTType &type, LSCRIPTType basetype, U64 &count, + LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, + S32 stacksize, LLScriptScopeEntry *entry, + S32 entrycount, LLScriptLibData **ldata); + + S32 getSize(); + + LLScriptIdentifier *mRequestId; + LLScriptIdentifier *mMethod; + LLScriptIdentifier *mBody; +}; + class LLScriptRezEvent : public LLScriptEvent { public: diff --git a/indra/lscript/lscript_execute/CMakeLists.txt b/indra/lscript/lscript_execute/CMakeLists.txt index f30915bab0..3a16ffdc01 100644 --- a/indra/lscript/lscript_execute/CMakeLists.txt +++ b/indra/lscript/lscript_execute/CMakeLists.txt @@ -12,6 +12,9 @@ include_directories( ) set(lscript_execute_SOURCE_FILES + llscriptresource.cpp + llscriptresourceconsumer.cpp + llscriptresourcepool.cpp lscript_execute.cpp lscript_heapruntime.cpp lscript_readlso.cpp @@ -20,6 +23,9 @@ set(lscript_execute_SOURCE_FILES set(lscript_execute_HEADER_FILES CMakeLists.txt + ../llscriptresource.h + ../llscriptresourceconsumer.h + ../llscriptresourcepool.h ../lscript_execute.h ../lscript_rt_interface.h lscript_heapruntime.h diff --git a/indra/lscript/lscript_execute/llscriptresource.cpp b/indra/lscript/lscript_execute/llscriptresource.cpp new file mode 100644 index 0000000000..cc802987b9 --- /dev/null +++ b/indra/lscript/lscript_execute/llscriptresource.cpp @@ -0,0 +1,86 @@ +/** + * @file llscriptresource.cpp + * @brief LLScriptResource class implementation for managing limited resources + * + * $LicenseInfo:firstyear=2008&license=internal$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llscriptresource.h" +#include "llerror.h" + +LLScriptResource::LLScriptResource() +: mTotal(0), + mUsed(0) +{ +} + +bool LLScriptResource::request(S32 amount /* = 1 */) +{ + if (mUsed + amount <= mTotal) + { + mUsed += amount; + return true; + } + + return false; +} + +bool LLScriptResource::release(S32 amount /* = 1 */) +{ + if (mUsed >= amount) + { + mUsed -= amount; + return true; + } + + return false; +} + +S32 LLScriptResource::getAvailable() const +{ + if (mUsed > mTotal) + { + // It is possible after a parcel ownership change for more than total to be used + // In this case the user of this class just wants to know + // whether or not they can use a resource + return 0; + } + return (mTotal - mUsed); +} + +void LLScriptResource::setTotal(S32 amount) +{ + // This may cause this resource to be over spent + // such that more are in use than total allowed + // Until those resources are released getAvailable will return 0. + mTotal = amount; +} + +S32 LLScriptResource::getTotal() const +{ + return mTotal; +} + +S32 LLScriptResource::getUsed() const +{ + return mUsed; +} + +bool LLScriptResource::isOverLimit() const +{ + return (mUsed > mTotal); +} diff --git a/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp b/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp new file mode 100644 index 0000000000..6a5b28e257 --- /dev/null +++ b/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp @@ -0,0 +1,101 @@ +/** + * @file llscriptresourceconsumer.cpp + * @brief An interface for a script resource consumer. + * + * $LicenseInfo:firstyear=2008&license=internal$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llscriptresourceconsumer.h" + +#include "llscriptresourcepool.h" + +LLScriptResourceConsumer::LLScriptResourceConsumer() + : mScriptResourcePool(&LLScriptResourcePool::null) +{ } + +// Get the resource pool this consumer is currently using. +// virtual +LLScriptResourcePool& LLScriptResourceConsumer::getScriptResourcePool() +{ + return *mScriptResourcePool; +} + +// Get the resource pool this consumer is currently using. +// virtual +const LLScriptResourcePool& LLScriptResourceConsumer::getScriptResourcePool() const +{ + return *mScriptResourcePool; +} + +// virtual +void LLScriptResourceConsumer::setScriptResourcePool(LLScriptResourcePool& new_pool) +{ + mScriptResourcePool = &new_pool; +} + +bool LLScriptResourceConsumer::switchScriptResourcePools(LLScriptResourcePool& new_pool) +{ + if (&new_pool == &LLScriptResourcePool::null) + { + llwarns << "New pool is null" << llendl; + } + + if (isInPool(new_pool)) + { + return true; + } + + if (!canUseScriptResourcePool(new_pool)) + { + return false; + } + + S32 used_urls = getUsedPublicURLs(); + + getScriptResourcePool().getPublicURLResource().release( used_urls ); + setScriptResourcePool(new_pool); + getScriptResourcePool().getPublicURLResource().request( used_urls ); + + return true; +} + +bool LLScriptResourceConsumer::canUseScriptResourcePool(const LLScriptResourcePool& resource_pool) +{ + if (isInPool(resource_pool)) + { + return true; + } + + if (resource_pool.getPublicURLResource().getAvailable() < getUsedPublicURLs()) + { + return false; + } + + return true; +} + +bool LLScriptResourceConsumer::isInPool(const LLScriptResourcePool& resource_pool) +{ + const LLScriptResourcePool& current_pool = getScriptResourcePool(); + if ( &resource_pool == ¤t_pool ) + { + // This consumer is already in this pool + return true; + } + return false; +} + diff --git a/indra/lscript/lscript_execute/llscriptresourcepool.cpp b/indra/lscript/lscript_execute/llscriptresourcepool.cpp new file mode 100644 index 0000000000..2ec67c87dd --- /dev/null +++ b/indra/lscript/lscript_execute/llscriptresourcepool.cpp @@ -0,0 +1,39 @@ +/** + * @file llscriptresourcepool.cpp + * @brief Collection of limited script resources + * + * $LicenseInfo:firstyear=2002&license=internal$ + * + * Copyright (c) 2002-2007, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llscriptresourcepool.h" + +LLScriptResourcePool LLScriptResourcePool::null; + +LLScriptResourcePool::LLScriptResourcePool() +{ + +} + +LLScriptResource& LLScriptResourcePool::getPublicURLResource() +{ + return mLSLPublicURLs; +} + +const LLScriptResource& LLScriptResourcePool::getPublicURLResource() const +{ + return mLSLPublicURLs; +} diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index daa17f371c..b2b54cdd7a 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -68,6 +68,12 @@ const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] = /*Flawfinder: ignore*/ void LLScriptExecuteLSL2::startRunning() {} void LLScriptExecuteLSL2::stopRunning() {} +const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; +const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; + +// HTTP Requests to LSL scripts will time out after 25 seconds. +const U64 LSL_HTTP_REQUEST_TIMEOUT = 25 * USEC_PER_SEC; + LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp) { U8 sizearray[4]; diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp index f45e64e5de..3b10cc67c1 100644 --- a/indra/lscript/lscript_execute/lscript_readlso.cpp +++ b/indra/lscript/lscript_execute/lscript_readlso.cpp @@ -625,6 +625,16 @@ void LLScriptLSOParse::printStates(LLFILE *fp) bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); break; + case LSTT_HTTP_REQUEST: // LSTT_HTTP_REQUEST + bytestream2char(name, mRawData, event_offset, sizeof(name)); + fprintf(fp, "%s\n", name); + bytestream2char(name, mRawData, event_offset, sizeof(name)); + fprintf(fp, "\t\tkey %s\n", name); + bytestream2char(name, mRawData, event_offset, sizeof(name)); + fprintf(fp, "\t\tstring %s\n", name); + bytestream2char(name, mRawData, event_offset, sizeof(name)); + fprintf(fp, "\t\tstring %s\n", name); + break; default: break; } diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp index 55ecbcf2a1..0342c97429 100644 --- a/indra/lscript/lscript_library/lscript_library.cpp +++ b/indra/lscript/lscript_library/lscript_library.cpp @@ -451,6 +451,12 @@ void LLScriptLibrary::init() addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSHA1String", "s", "s", "string llSHA1String(string sr)\nPerforms a SHA1 security Hash. Returns a 40 character hex string.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetFreeURLs", "i", NULL, "integer llGetFreeURLs()\nreturns the available urls for the current script")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestURL", "k", NULL, "key llRequestURL()\nRequests one HTTP:// url for use by this object\nTriggers an http_server event with results.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestSecureURL", "k", NULL, "key llRequestSecureURL()\nRequests one HTTPS:// (SSL) url for use by this object\nTriggers an http_server event with results.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseURL", NULL, "s", "llReleaseURL(string url)\nReleases the specified URL, it will no longer be usable.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis", "llHTTPResponse(key id, integer status, string body)\nResponds to request id with status and body.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks", "string llGetHTTPHeader(key id, string header)\nGet the value for header for request id.")); // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 0ab977d8e9..cd7b533e7a 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -50,6 +50,7 @@ link_message link_message(integer sender_num, integer num, string str, key id):T changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT) remote_data remote_data(integer event_type, key channel, key message_id, string sender,integer idata, string sdata):Triggered by various XML-RPC calls (event_type will be one of REMOTE_DATA_CHANNEL, REMOTE_DATA_REQUEST, REMOTE_DATA_REPLY) http_response http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests +http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL # integer constants [word .1, .1, .5] @@ -317,6 +318,7 @@ CHANGED_ALLOWED_DROP Parameter of changed event handler used to indicate a user CHANGED_OWNER Parameter of changed event handler used to indicate change to task's owner ONLY when an object is sold as original or deeded to group CHANGED_REGION Parameter of changed event handler used to indicate the region has changed CHANGED_TELEPORT Parameter of changed event handler used to indicate teleport has completed +CHANGED_REGION_START Parameter of changed event handler used to indicate the region has been restarted TYPE_INTEGER Indicates that the list entry is holding an integer TYPE_FLOAT Indicates that the list entry is holding an float @@ -519,6 +521,9 @@ TEXTURE_DEFAULT UUID for the "Default Media" texture TEXTURE_PLYWOOD UUID for the default "Plywood" texture TEXTURE_TRANSPARENT UUID for the "White - Transparent" texture +URL_REQUEST_GRANTED Used with http_request when a public URL is successfully granted +URL_REQUEST_DENIED Used with http_request when a public URL is not available + # float constants [word .3, .1, .5] PI 3.1415926535897932384626433832795 diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 16428ce6d1..fa6ba162ec 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -172,6 +172,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) std::string owner_buf; F32 mono_score = 0.f; bool have_extended_data = false; + S32 public_urls = 0; msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block); msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block); @@ -186,6 +187,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) have_extended_data = true; msg->getU32("DataExtended", "TimeStamp", time_stamp, block); msg->getF32("DataExtended", "MonoScore", mono_score, block); + msg->getS32(_PREHASH_ReportData,"PublicURLs",public_urls,block); } LLSD element; @@ -216,6 +218,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) element["columns"][5]["column"] = "mono_time"; element["columns"][5]["value"] = llformat("%0.3f", mono_score); element["columns"][5]["font"] = "SANSSERIF"; + + element["columns"][6]["column"] = "URLs"; + element["columns"][6]["value"] = llformat("%d", public_urls); + element["columns"][6]["font"] = "SANSSERIF"; } list->addElement(element); diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 01c291be7b..0000cc237b 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -10,6 +10,7 @@ include(LLMath) include(LLMessage) include(LLVFS) include(LLXML) +include(LScript) include(Linking) include_directories( @@ -20,6 +21,7 @@ include_directories( ${LLINVENTORY_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} + ${LSCRIPT_INCLUDE_DIRS} ) set(test_SOURCE_FILES @@ -48,6 +50,7 @@ set(test_SOURCE_FILES llquaternion_tut.cpp llrandom_tut.cpp llsaleinfo_tut.cpp + llscriptresource_tut.cpp llsdmessagebuilder_tut.cpp llsdmessagereader_tut.cpp llsd_new_tut.cpp @@ -58,6 +61,7 @@ set(test_SOURCE_FILES llstring_tut.cpp lltemplatemessagebuilder_tut.cpp lltiming_tut.cpp + lltranscode_tut.cpp lltut.cpp lluri_tut.cpp lluuidhashmap_tut.cpp @@ -109,7 +113,9 @@ target_link_libraries(test ${LLMATH_LIBRARIES} ${LLVFS_LIBRARIES} ${LLXML_LIBRARIES} + ${LSCRIPT_LIBRARIES} ${LLCOMMON_LIBRARIES} + ${APRICONV_LIBRARIES} ${PTHREAD_LIBRARY} ${WINDOWS_LIBRARIES} ${DL_LIBRARY} diff --git a/indra/test/llhttpnode_tut.cpp b/indra/test/llhttpnode_tut.cpp index 8654971f9b..e17d1e0f24 100644 --- a/indra/test/llhttpnode_tut.cpp +++ b/indra/test/llhttpnode_tut.cpp @@ -86,7 +86,8 @@ namespace tut void result(const LLSD& result) { mResult = result; } void status(S32 code, const std::string& message) { } - + void extendedResult(S32 code, const std::string& message, const LLSD& headers) { } + private: Response() {;} // Must be accessed through LLPointer. }; diff --git a/indra/test/llscriptresource_tut.cpp b/indra/test/llscriptresource_tut.cpp new file mode 100644 index 0000000000..e384c275a3 --- /dev/null +++ b/indra/test/llscriptresource_tut.cpp @@ -0,0 +1,203 @@ +/** + * @file llscriptresource_tut.cpp + * @brief Test LLScriptResource + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2006-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +//#include <tut/tut.h> +#include "linden_common.h" + +#include "lltut.h" + +#include "llscriptresource.h" +#include "llscriptresourceconsumer.h" +#include "llscriptresourcepool.h" + +class TestConsumer : public LLScriptResourceConsumer +{ +public: + TestConsumer() + : mUsedURLs(0) + { } + + // LLScriptResourceConsumer interface: + S32 getUsedPublicURLs() const + { + return mUsedURLs; + } + + // Test details: + S32 mUsedURLs; +}; + + +namespace tut +{ + class LLScriptResourceTestData + { + }; + + typedef test_group<LLScriptResourceTestData> LLScriptResourceTestGroup; + typedef LLScriptResourceTestGroup::object LLScriptResourceTestObject; + LLScriptResourceTestGroup scriptResourceTestGroup("scriptResource"); + + template<> template<> + void LLScriptResourceTestObject::test<1>() + { + LLScriptResource resource; + U32 total = 42; + + resource.setTotal(total); + ensure_equals("Verify set/get total", resource.getTotal(), total); + ensure_equals("Verify all resources are initially available",resource.getAvailable(),total); + + // Requesting too many, releasing non-allocated + ensure("Request total + 1 resources should fail",!resource.request(total + 1)); + ensure_equals("Verify all resources available after failed request",resource.getAvailable(),total); + + ensure("Releasing resources when none allocated should fail",!resource.release()); + ensure_equals("All resources should be available after failed release",resource.getAvailable(),total); + + ensure("Request one resource", resource.request()); + ensure_equals("Verify available resources after successful request",resource.getAvailable(),total - 1); + + // Is this right? Or should we release all used resources if we try to release more than are currently used? + ensure("Release more resources than allocated",!resource.release(2)); + ensure_equals("Verify resource availability after failed release",resource.getAvailable(),total - 1); + + ensure("Release a resource",resource.release()); + ensure_equals("Verify all resources available after successful release",resource.getAvailable(),total); + } + + + template<> template<> + void LLScriptResourceTestObject::test<2>() + { + LLScriptResource resource; + U32 total = 42; + + resource.setTotal(total); + + S32 resources_to_request = 30; + ensure("Get multiple resources resources",resource.request(resources_to_request)); + ensure_equals("Verify available resources is correct after request of multiple resources",resource.getAvailable(), total - resources_to_request); + + S32 resources_to_release = (resources_to_request / 2); + ensure("Release some resources",resource.release(resources_to_release)); + + S32 expected_available = (total - resources_to_request + resources_to_release); + ensure_equals("Verify available resources after release of some resources",resource.getAvailable(), expected_available); + + resources_to_release = (resources_to_request - resources_to_release); + ensure("Release remaining resources",resource.release(resources_to_release)); + + ensure_equals("Verify available resources after release of remaining resources",resource.getAvailable(), total); + } + + template<> template<> + void LLScriptResourceTestObject::test<3>() + { + LLScriptResource resource; + + U32 total = 42; + resource.setTotal(total); + + ensure("Request all resources",resource.request(total)); + + U32 low_total = 10; + ensure("Release all resources",resource.release(total)); + ensure_equals("Verify all resources available after releasing",resource.getAvailable(),total); + + resource.setTotal(low_total); + ensure_equals("Verify low total resources are available after set",resource.getAvailable(),low_total); + } + + + template<> template<> + void LLScriptResourceTestObject::test<4>() + { + S32 big_resource_total = 100; + S32 small_resource_total = 10; + LLScriptResourcePool big_pool; + big_pool.getPublicURLResource().setTotal(big_resource_total); + LLScriptResourcePool small_pool; + small_pool.getPublicURLResource().setTotal(small_resource_total); + + TestConsumer consumer; + LLScriptResourcePool& initial_pool = consumer.getScriptResourcePool(); + ensure("Initial resource pool is 'null'.", (&initial_pool == &LLScriptResourcePool::null)); + + consumer.switchScriptResourcePools(big_pool); + LLScriptResourcePool& get_pool = consumer.getScriptResourcePool(); + ensure("Get resource that was set.", (&big_pool == &get_pool)); + + ensure_equals("No public urls in use yet.", consumer.getUsedPublicURLs(),0); + + S32 request_urls = 5; + consumer.mUsedURLs = request_urls; + consumer.getScriptResourcePool().getPublicURLResource().request(request_urls); + + ensure_equals("Available urls on big_pool is 5 less than total.", + big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls); + + ensure("Switching from big pool to small pool", + consumer.switchScriptResourcePools(small_pool)); + + ensure_equals("All resources available to big pool again", + big_pool.getPublicURLResource().getAvailable(), big_resource_total); + + ensure_equals("Available urls on small pool is 5 less than total.", + small_pool.getPublicURLResource().getAvailable(), small_resource_total - request_urls); + + ensure("Switching from small pool to big pool", + consumer.switchScriptResourcePools(big_pool)); + + consumer.getScriptResourcePool().getPublicURLResource().release(request_urls); + + request_urls = 50; // Too many for the small_pool + + consumer.mUsedURLs = request_urls; + consumer.getScriptResourcePool().getPublicURLResource().request(request_urls); + + // Verify big pool has them + ensure_equals("Available urls on big pool is 50 less than total.", + big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls); + + // Verify can't switch to small_pool + ensure("Switching to small pool with too many resources", + !consumer.switchScriptResourcePools(small_pool)); + + // Verify big pool still accounting for used resources + ensure_equals("Available urls on big_pool is still 50 less than total.", + big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls); + + // Verify small pool still has all resources available. + ensure_equals("All resources in small pool are still available.", + small_pool.getPublicURLResource().getAvailable(), small_resource_total); + } +} diff --git a/indra/test/lltranscode_tut.cpp b/indra/test/lltranscode_tut.cpp new file mode 100644 index 0000000000..8abf9dc224 --- /dev/null +++ b/indra/test/lltranscode_tut.cpp @@ -0,0 +1,94 @@ +/** + * @file llscriptresource_tut.cpp + * @brief Test LLScriptResource + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2006-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +//#include <tut/tut.h> +#include "linden_common.h" + +#include "lltut.h" + +#include "../newsim/lltranscode.cpp" // include TU to pull in newsim implementation. + +static const char test_utf8[] = "Edelwei\xc3\x9f"; +static const char test_utf7[] = "Edelwei+AN8-"; +static const char test_latin1[] = "Edelwei\xdf"; +static const char test_latin2[] = "Edelwei\xdf"; + +namespace tut +{ + class LLTranscodeTestData + { + }; + + typedef test_group<LLTranscodeTestData> LLTranscodeTestGroup; + typedef LLTranscodeTestGroup::object LLTranscodeTestObject; + LLTranscodeTestGroup transcodeTestGroup("transcode"); + + template<> template<> + void LLTranscodeTestObject::test<1>() + { +#if LL_WINDOWS + skip("Windows APR libs can't transcode."); +#endif + // Test utf8 + std::stringstream input; + std::stringstream output; + + input.str(test_utf7); + output.clear(); + LLTranscode::transcode("charset=UTF-7", input, output); + ensure_equals("UTF-7 to UTF-8 transcoding", output.str(), + std::string(test_utf8)); + + input.str(test_latin1); + output.clear(); + LLTranscode::transcode("", input, output); + ensure_equals("Default (latin_1) to UTF8 transcoding", output.str(), + std::string(test_utf8)); + + input.str(test_latin1); + output.clear(); + LLTranscode::transcode("charset=iso-8859-1", input, output); + ensure_equals("latin_1 (ISO-8859-1) to UTF8 transcoding", output.str(), + std::string(test_utf8)); + + input.str(test_latin2); + output.clear(); + LLTranscode::transcode("charset=iso-8859-2", input, output); + ensure_equals("latin_2 (ISO-8859-2) to UTF8 transcoding", output.str(), + std::string(test_utf8)); + + input.str(test_utf8); + output.clear(); + LLTranscode::transcode("charset=utf-8", input, output); + ensure_equals("UTF8 to UTF8 transcoding", output.str(), + std::string(test_utf8)); + } +} diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp index e632234623..3fede2608c 100644 --- a/indra/test/message_tut.cpp +++ b/indra/test/message_tut.cpp @@ -51,6 +51,7 @@ namespace { mStatus = code; } + virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) { } S32 mStatus; }; } |