diff options
Diffstat (limited to 'indra')
54 files changed, 2792 insertions, 1062 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 610aa99dc9..0edacac7a9 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -181,7 +181,7 @@ endif (DARWIN)  if (LINUX OR DARWIN) -  set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") +  set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor")    if (NOT GCC_DISABLE_FATAL_WARNINGS)      set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 7cfdead32e..3557a99248 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -69,8 +69,13 @@ MACRO(ADD_SIMULATOR_BUILD_TEST name parent)  ENDMACRO(ADD_SIMULATOR_BUILD_TEST name parent)  MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files) -         -    ADD_EXECUTABLE(${name}_test ${source_files}) +    SET(TEST_SOURCE_FILES ${source_files}) +    SET(HEADER "${name}.h") +    set_source_files_properties(${HEADER} +                            PROPERTIES HEADER_FILE_ONLY TRUE) +    LIST(APPEND TEST_SOURCE_FILES ${HEADER}) +    INCLUDE_DIRECTORIES("${LIBS_OPEN_DIR}/test") +    ADD_EXECUTABLE(${name}_test ${TEST_SOURCE_FILES})      TARGET_LINK_LIBRARIES(${name}_test          ${libraries}          ) @@ -80,11 +85,11 @@ MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files)      ADD_CUSTOM_COMMAND(          OUTPUT ${TEST_OUTPUT}          COMMAND ${TEST_EXE} -        ARGS --touch=${TEST_OUTPUT} +        ARGS --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}          DEPENDS ${name}_test          WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}          )      ADD_CUSTOM_TARGET(${name}_test_ok ALL DEPENDS ${TEST_OUTPUT})      ADD_DEPENDENCIES(${parent} ${name}_test_ok) -ENDMACRO(ADD_BUILD_TEST_INTERNAL name parent libraries)
\ No newline at end of file +ENDMACRO(ADD_BUILD_TEST_INTERNAL name parent libraries) diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index f1094a8fd2..4109eade19 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -118,6 +118,7 @@ const	char* const	DEFAULT_AGNI_DATA_SERVER	= "63.211.139.100";  const	char* const	DEFAULT_AGNI_ASSET_SERVER	= "http://asset.agni.lindenlab.com:80";  // Information about what ports are for what services is in the wiki Name Space Ports page +// https://wiki.lindenlab.com/wiki/Name_Space_Ports  const	char* const DEFAULT_LOCAL_ASSET_SERVER	= "http://localhost:12041/asset/tmp";  const	char* const	LOCAL_ASSET_URL_FORMAT		= "http://%s:12041/asset"; @@ -138,6 +139,10 @@ const   U32		DEFAULT_CAP_PROXY_PORT			= 12043;  const   U32		DEFAULT_INV_DATA_SERVER_PORT	= 12044;  const	U32		DEFAULT_CGI_SERVICES_PORT		= 12045; +// Mapserver uses ports 12124 - 12139 to allow multiple mapservers to run +// on a single host for map tile generation. JC +const	U32		DEFAULT_MAPSERVER_PORT			= 12124; +  // For automatic port discovery when running multiple viewers on one host  const	U32		PORT_DISCOVERY_RANGE_MIN		= 13000;  const	U32		PORT_DISCOVERY_RANGE_MAX		= PORT_DISCOVERY_RANGE_MIN + 50; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 1a1dbd40b6..8915890e18 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -33,6 +33,8 @@  #ifndef LL_LLSTRING_H  #define LL_LLSTRING_H +#include <string> +  #if LL_LINUX || LL_SOLARIS  #include <wctype.h>  #include <wchar.h> diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index f68d86ff7c..2e93b2a3a7 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -300,19 +300,22 @@ U32 LLOSInfo::getProcessVirtualSizeKB()  #endif  #if LL_LINUX  	LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); -	S32 numRead = 0;		 -	char buff[STATUS_SIZE];		/* Flawfinder: ignore */ +	if (status_filep) +	{ +		S32 numRead = 0;		 +		char buff[STATUS_SIZE];		/* Flawfinder: ignore */ -	size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); -	buff[nbytes] = '\0'; +		size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); +		buff[nbytes] = '\0'; -	// All these guys return numbers in KB -	char *memp = strstr(buff, "VmSize:"); -	if (memp) -	{ -		numRead += sscanf(memp, "%*s %u", &virtual_size); +		// All these guys return numbers in KB +		char *memp = strstr(buff, "VmSize:"); +		if (memp) +		{ +			numRead += sscanf(memp, "%*s %u", &virtual_size); +		} +		fclose(status_filep);  	} -	fclose(status_filep);  #elif LL_SOLARIS  	char proc_ps[LL_MAX_PATH];  	sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid()); diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index 7593eeae37..f9b84dd6bd 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -36,7 +36,7 @@  const S32 LL_VERSION_MAJOR = 1;  const S32 LL_VERSION_MINOR = 27;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 109809; +const S32 LL_VERSION_BUILD = 112940;  const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 37c276096e..be6b6c817b 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -58,26 +58,42 @@ void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)  	impl = NULL;  } +// Return string from message, eliminating final \n if present +static std::string chomp(const char* msg) +{ +	// stomp trailing \n +	std::string message = msg; +	if (!message.empty()) +	{ +		size_t last = message.size() - 1; +		if (message[last] == '\n') +		{ +			message.resize( last ); +		} +	} +	return message; +} +  /**  sample error callback expecting a LLFILE* client object  */  void error_callback(const char* msg, void*)  { -	lldebugs << "LLImageJ2CImpl error_callback: " << msg << llendl; +	lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;  }  /**  sample warning callback expecting a LLFILE* client object  */  void warning_callback(const char* msg, void*)  { -	lldebugs << "LLImageJ2CImpl warning_callback: " << msg << llendl; +	lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;  }  /**  sample debug callback expecting no client object  */  void info_callback(const char* msg, void*)  { -	lldebugs << "LLImageJ2CImpl info_callback: " << msg << llendl; +	lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl;  } diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 6fa5c9076e..2689ada80c 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -110,37 +110,11 @@ static const std::string PARCEL_ACTION_STRING[LLParcel::A_COUNT + 1] =      "unknown"  }; -// Timeouts for parcels -// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 -const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); -// ***** TESTING is 10 minutes -//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000); -// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 -const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); -// ***** TESTING is 10 minutes -//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000); -// default sale timeout is 2 days -> 172800000000 -const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); -// ***** TESTING is 10 minutes -//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000); - -// more grace period extensions. -const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); - -// if more than 100,000s before sale revert, and no extra extension -// has been given, go ahead and extend it more. That's about 1.2 days. -const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; - - -const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status); -LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s);  //const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action);  //LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s); -const std::string& category_to_string(LLParcel::ECategory category);  const std::string& category_to_ui_string(LLParcel::ECategory category); -LLParcel::ECategory category_string_to_category(const std::string& s);  LLParcel::ECategory category_ui_string_to_category(const std::string& s);  LLParcel::LLParcel() @@ -548,500 +522,6 @@ void LLParcel::setDiscountRate(F32 rate)  // File input and output  //----------------------------------------------------------- - -// WARNING: Area will be wrong until you calculate it. -BOOL LLParcel::importStream(std::istream& input_stream) -{ -	U32 setting; -	S32 secs_until_revert = 0; - -	skip_to_end_of_next_keyword("{", input_stream); -	if (!input_stream.good())  -	{ -		llwarns << "LLParcel::importStream() - bad input_stream" << llendl; -		return FALSE; -	} - -	while (input_stream.good()) -	{ -		skip_comments_and_emptyspace(input_stream); -		std::string line, keyword, value; -		get_line(line, input_stream, MAX_STRING); -		get_keyword_and_value(keyword, value, line); - -		if ("}" == keyword) -		{ -			break; -		} -		else if ("parcel_id" == keyword) -		{ -			mID.set(value); -		} -		else if ("status" == keyword) -		{ -			mStatus = ownership_string_to_status(value); -		} -		else if ("category" == keyword) -		{ -			mCategory = category_string_to_category(value); -		} -		else if ("local_id" == keyword) -		{ -			LLStringUtil::convertToS32(value, mLocalID); -		} -		else if ("name" == keyword) -		{ -			setName( value ); -		} -		else if ("desc" == keyword) -		{ -			setDesc( value ); -		} -		else if ("music_url" == keyword) -		{ -			setMusicURL( value ); -		} -		else if ("media_url" == keyword) -		{ -			setMediaURL( value ); -		} -		else if ("media_desc" == keyword) -		{ -			setMediaDesc( value ); -		} -		else if ("media_type" == keyword) -		{ -			setMediaType( value ); -		} -		else if ("media_width" == keyword) -		{ -			S32 width; -			LLStringUtil::convertToS32(value, width); -			setMediaWidth( width ); -		} -		else if ("media_height" == keyword) -		{ -			S32 height; -			LLStringUtil::convertToS32(value, height); -			setMediaHeight( height ); -		} -		else if ("media_id" == keyword) -		{ -			mMediaID.set( value ); -		} -		else if ("media_auto_scale" == keyword) -		{ -			LLStringUtil::convertToU8(value, mMediaAutoScale); -		} -		else if ("media_loop" == keyword) -		{ -			LLStringUtil::convertToU8(value, mMediaLoop); -		} -		else if ("obscure_media" == keyword) -		{ -			LLStringUtil::convertToU8(value, mObscureMedia); -		}		 -		else if ("obscure_music" == keyword) -		{ -			LLStringUtil::convertToU8(value, mObscureMusic); -		}		 -		else if ("owner_id" == keyword) -		{ -			mOwnerID.set( value ); -		} -		else if ("group_owned" == keyword) -		{ -			LLStringUtil::convertToBOOL(value, mGroupOwned); -		} -		else if ("clean_other_time" == keyword) -		{ -			S32 time; -			LLStringUtil::convertToS32(value, time); -			setCleanOtherTime(time); -		} -		else if ("auth_buyer_id" == keyword) -		{ -			mAuthBuyerID.set(value); -		} -		else if ("snapshot_id" == keyword) -		{ -			mSnapshotID.set(value); -		} -		else if ("user_location" == keyword) -		{ -			sscanf(value.c_str(), "%f %f %f", -				&mUserLocation.mV[VX], -				&mUserLocation.mV[VY], -				&mUserLocation.mV[VZ]); -		} -		else if ("user_look_at" == keyword) -		{ -			sscanf(value.c_str(), "%f %f %f", -				&mUserLookAt.mV[VX], -				&mUserLookAt.mV[VY], -				&mUserLookAt.mV[VZ]); -		} -		else if ("landing_type" == keyword) -		{ -			S32 landing_type = 0; -			LLStringUtil::convertToS32(value, landing_type); -			mLandingType = (ELandingType) landing_type; -		} -		else if ("join_neighbors" == keyword) -		{ -			llinfos << "found deprecated keyword join_neighbors" << llendl; -		} -		else if ("revert_sale" == keyword) -		{ -			LLStringUtil::convertToS32(value, secs_until_revert); -			if (secs_until_revert > 0) -			{ -				mSaleTimerExpires.start(); -				mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert); -			} -		} -		else if("extended_grace" == keyword) -		{ -			LLStringUtil::convertToS32(value, mGraceExtension); -		} -		else if ("user_list_type" == keyword) -		{ -			// deprecated -		} -		else if("auction_id" == keyword) -		{ -			LLStringUtil::convertToU32(value, mAuctionID); -		} -		else if ("allow_modify" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_CREATE_OBJECTS, setting); -		} -		else if ("allow_group_modify" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting); -		} -		else if ("allow_all_object_entry" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting); -		} -		else if ("allow_group_object_entry" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting); -		} -		else if ("allow_deed_to_group" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting); -		} -		else if("contribute_with_deed" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting); -		} -		else if ("allow_terraform" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_TERRAFORM, setting); -		} -		else if ("allow_damage" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_DAMAGE, setting); -		} -		else if ("allow_fly" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_FLY, setting); -		} -		else if ("allow_landmark" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_LANDMARK, setting); -		} -		else if ("sound_local" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_SOUND_LOCAL, setting); -		} -		else if ("allow_group_scripts" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting); -		} -		else if ("allow_voice_chat" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); -		} -		else if ("use_estate_voice_chan" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); -		} -		else if ("allow_scripts" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting); -		} -		else if ("for_sale" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_FOR_SALE, setting); -		} -		else if ("sell_w_objects" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting); -		} -		else if ("use_pass_list" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_USE_PASS_LIST, setting); -		} -		else if ("show_directory" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_SHOW_DIRECTORY, setting); -		} -		else if ("allow_publish" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_ALLOW_PUBLISH, setting); -		} -		else if ("mature_publish" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_MATURE_PUBLISH, setting); -		} -		else if ("claim_date" == keyword) -		{ -			// BUG: This will fail when time rolls over in 2038. -			S32 time; -			LLStringUtil::convertToS32(value, time); -			mClaimDate = time; -		} -		else if ("claim_price" == keyword) -		{ -			LLStringUtil::convertToS32(value, mClaimPricePerMeter); -		} -		else if ("rent_price" == keyword) -		{ -			LLStringUtil::convertToS32(value, mRentPricePerMeter); -		} -		else if ("discount_rate" == keyword) -		{ -			LLStringUtil::convertToF32(value, mDiscountRate); -		} -		else if ("draw_distance" == keyword) -		{ -			LLStringUtil::convertToF32(value, mDrawDistance); -		} -		else if ("sale_price" == keyword) -		{ -			LLStringUtil::convertToS32(value, mSalePrice); -		} -		else if ("pass_price" == keyword) -		{ -			LLStringUtil::convertToS32(value, mPassPrice); -		} -		else if ("pass_hours" == keyword) -		{ -			LLStringUtil::convertToF32(value, mPassHours); -		} -		else if ("box" == keyword) -		{ -			// deprecated -		} -		else if ("aabb_min" == keyword) -		{ -			sscanf(value.c_str(), "%f %f %f",  -				&mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]); -		} -		else if ("use_access_group" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_USE_ACCESS_GROUP, setting); -		} -		else if ("use_access_list" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_USE_ACCESS_LIST, setting); -		} -		else if ("use_ban_list" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_USE_BAN_LIST, setting); -		} -		else if ("group_name" == keyword) -		{ -			llinfos << "found deprecated keyword group_name" << llendl; -		} -		else if ("group_id" == keyword) -		{ -			mGroupID.set( value ); -		} -		// TODO: DEPRECATED FLAG -		// Flag removed from simstate files in 1.11.1 -		// Remove at some point where we have guarenteed this flag -		// no longer exists anywhere in simstate files. -		else if ("require_identified" == keyword) -		{ -			// LLStringUtil::convertToU32(value, setting); -			// setParcelFlag(PF_DENY_ANONYMOUS, setting); -		} -		// TODO: DEPRECATED FLAG -		// Flag removed from simstate files in 1.11.1 -		// Remove at some point where we have guarenteed this flag -		// no longer exists anywhere in simstate files. -		else if ("require_transacted" == keyword) -		{ -			// LLStringUtil::convertToU32(value, setting); -			// setParcelFlag(PF_DENY_ANONYMOUS, setting); -			// setParcelFlag(PF_DENY_IDENTIFIED, setting); -		} -		else if ("restrict_pushobject" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting); -		} -		else if ("deny_anonymous" == keyword) -		{ -			LLStringUtil::convertToU32(value, setting); -			setParcelFlag(PF_DENY_ANONYMOUS, setting); -		} -		else if ("deny_identified" == keyword) -		{ -// 			LLStringUtil::convertToU32(value, setting); -// 			setParcelFlag(PF_DENY_IDENTIFIED, setting); -		} -		else if ("deny_transacted" == keyword) -		{ -// 			LLStringUtil::convertToU32(value, setting); -// 			setParcelFlag(PF_DENY_TRANSACTED, setting); -		} -        else if ("deny_age_unverified" == keyword) -        { -            LLStringUtil::convertToU32(value, setting); -            setParcelFlag(PF_DENY_AGEUNVERIFIED, setting); -        } -        else if ("access_list" == keyword) -        { -            S32 entry_count = 0; -            LLStringUtil::convertToS32(value, entry_count); -            for (S32 i = 0; i < entry_count; i++) -            { -                LLAccessEntry entry; -                if (importAccessEntry(input_stream, &entry)) -                { -                    mAccessList[entry.mID] = entry; -                } -            } -        } -        else if ("ban_list" == keyword) -        { -            S32 entry_count = 0; -            LLStringUtil::convertToS32(value, entry_count); -            for (S32 i = 0; i < entry_count; i++) -            { -                LLAccessEntry entry; -                if (importAccessEntry(input_stream, &entry)) -                { -                    mBanList[entry.mID] = entry; -                } -            } -        } -        else if ("renter_list" == keyword) -        { -            /* -             S32 entry_count = 0; -             LLStringUtil::convertToS32(value, entry_count); -             for (S32 i = 0; i < entry_count; i++) -             { -                 LLAccessEntry entry; -                 if (importAccessEntry(input_stream, &entry)) -                 { -                     mRenterList.put(entry); -                 } -             }*/ -        } -        else if ("pass_list" == keyword) -        { -            // legacy - put into access list -            S32 entry_count = 0; -            LLStringUtil::convertToS32(value, entry_count); -            for (S32 i = 0; i < entry_count; i++) -            { -                LLAccessEntry entry; -                if (importAccessEntry(input_stream, &entry)) -                { -                    mAccessList[entry.mID] = entry; -                } -            } -        } -         -        else -        { -            llwarns << "Unknown keyword in parcel section: <"  -            << keyword << ">" << llendl; -        } -    } -     -    // this code block detects if we have loaded a 1.1 simstate file, -    // and follows the conversion rules specified in -    // design_docs/land/pay_for_parcel.txt. -    F32 time_to_expire = 0.0f; -    if(mID.isNull()) -    { -        mID.generate(); -        mStatus = OS_LEASE_PENDING; -        //mBuyerID = mOwnerID; -        if(getIsGroupOwned()) -        { -            time_to_expire += GROUP_USEC_CONVERSION_TIMEOUT / SEC_TO_MICROSEC; -        } -        else -        { -            time_to_expire += DEFAULT_USEC_CONVERSION_TIMEOUT / SEC_TO_MICROSEC; -        } -        //mExpireAction = STEA_PUBLIC; -        mRecordTransaction = TRUE; -    } -     -    // this code block deals with giving an extension to pending -    // parcels to the midday of 2004-01-19 if they were originally set -    // for some time on 2004-01-12. -    if((0 == mGraceExtension) -       && (EXTEND_GRACE_IF_MORE_THAN_SEC < secs_until_revert)) -    { -        const S32 NEW_CONVERSION_DATE = 1074538800; // 2004-01-19T11:00:00 -        time_t now = time(NULL); // now in epoch -        secs_until_revert = (S32)(NEW_CONVERSION_DATE - now); -        time_to_expire = (F32)secs_until_revert; -        mGraceExtension = 1; -    } -     -    // This code block adds yet another week to the deadline. :( -    if(1 == mGraceExtension) -    { -        time_to_expire += SEVEN_DAYS_IN_USEC / SEC_TO_MICROSEC; -        mGraceExtension = 2; -    } -     -    if (time_to_expire > 0) -    { -        mSaleTimerExpires.setTimerExpirySec(time_to_expire); -        mSaleTimerExpires.start(); -    } -     -    // successful import -    return TRUE; -} - -  BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entry)  {      skip_to_end_of_next_keyword("{", input_stream); @@ -1085,230 +565,6 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr      return input_stream.good();  } -BOOL LLParcel::exportStream(std::ostream& output_stream) -{ -	S32 setting; -	std::string id_string; - -	std::ios::fmtflags old_flags = output_stream.flags(); -	output_stream.setf(std::ios::showpoint); -	output_stream << "\t{\n"; - -	mID.toString(id_string); -	output_stream << "\t\t parcel_id        " << id_string << "\n"; -	output_stream << "\t\t status           " << ownership_status_to_string(mStatus) << "\n"; -	output_stream << "\t\t category         " << category_to_string(mCategory) << "\n"; - -	output_stream << "\t\t local_id         " << mLocalID  << "\n"; - -	const char* name = (mName.empty() ? "" : mName.c_str() ); -	output_stream << "\t\t name             " << name << "\n"; - -	const char* desc = (mDesc.empty() ? "" : mDesc.c_str() ); -	output_stream << "\t\t desc             " << desc << "\n"; - -	const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() ); -	output_stream << "\t\t music_url        " << music_url << "\n"; - -	const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() ); -	output_stream << "\t\t media_url        " << media_url << "\n"; - -	const char* media_type = (mMediaType.empty() ? "" : mMediaType.c_str() ); -	output_stream << "\t\t media_type             " << media_type << "\n"; - -	const char* media_desc = (mMediaDesc.empty() ? "" : mMediaDesc.c_str() ); -	output_stream << "\t\t media_desc             " << media_desc << "\n"; - -	output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0)  << "\n"; -	output_stream << "\t\t media_loop " << (mMediaLoop ? 1 : 0)  << "\n"; -	output_stream << "\t\t obscure_media " << (mObscureMedia ? 1 : 0)  << "\n"; -	output_stream << "\t\t obscure_music " << (mObscureMusic ? 1 : 0)  << "\n"; - -	mMediaID.toString(id_string); -	output_stream << "\t\t media_id         " << id_string  << "\n"; - -	output_stream << "\t\t media_width     " << mMediaWidth  << "\n"; -	output_stream << "\t\t media_height     " << mMediaHeight  << "\n"; - -	mOwnerID.toString(id_string); -	output_stream << "\t\t owner_id         " << id_string  << "\n"; -	output_stream << "\t\t group_owned	   " << (mGroupOwned ? 1 : 0)  << "\n"; -	output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n"; - -	if(!mAuthBuyerID.isNull()) -	{ -		mAuthBuyerID.toString(id_string); -		output_stream << "\t\t auth_buyer_id    " << id_string << "\n"; -	} -	if (!mSnapshotID.isNull()) -	{ -		mSnapshotID.toString(id_string); -		output_stream << "\t\t snapshot_id      " << id_string << "\n"; -	} -	if (!mUserLocation.isExactlyZero()) -	{ -		output_stream << "\t\t user_location "  -			<< (F64)mUserLocation.mV[VX] -			<< " " << (F64)mUserLocation.mV[VY] -			<< " " << (F64)mUserLocation.mV[VZ] << "\n"; -		output_stream << "\t\t user_look_at "  -			<< (F64)mUserLookAt.mV[VX] -			<< " " << (F64)mUserLookAt.mV[VY] -			<< " " << (F64)mUserLookAt.mV[VZ] << "\n"; -	} -	output_stream << "\t\t landing_type " << mLandingType << "\n"; -	//if(mJoinNeighbors) -	//{ -	//	output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n"; -	//} -	if(mSaleTimerExpires.getStarted()) -	{ -		S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions -		output_stream << "\t\t revert_sale      " << dt_sec << "\n"; -		//output_stream << "\t\t revert_action    " << revert_action_to_string(mExpireAction) << "\n"; -		output_stream << "\t\t extended_grace   " << mGraceExtension << "\n"; -	} - -	if(0 != mAuctionID) -	{ -		output_stream << "\t\t auction_id       " << mAuctionID << "\n"; -	} - -	output_stream << "\t\t allow_modify     " << getAllowModify()  << "\n"; -	output_stream << "\t\t allow_group_modify     " << getAllowGroupModify()  << "\n"; -	output_stream << "\t\t allow_all_object_entry     " << getAllowAllObjectEntry()  << "\n"; -	output_stream << "\t\t allow_group_object_entry     " << getAllowGroupObjectEntry()  << "\n"; -	output_stream << "\t\t allow_terraform  " << getAllowTerraform()  << "\n"; -	output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup()  << "\n"; -	output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n"; -	output_stream << "\t\t allow_damage     " << getAllowDamage()  << "\n"; -	output_stream << "\t\t claim_date       " << (S32)mClaimDate  << "\n"; -	output_stream << "\t\t claim_price      " << mClaimPricePerMeter  << "\n"; -	output_stream << "\t\t rent_price       " << mRentPricePerMeter  << "\n"; -	output_stream << "\t\t discount_rate    " << mDiscountRate  << "\n"; -	output_stream << "\t\t allow_fly        " << (getAllowFly()      ? 1 : 0)  << "\n"; -	output_stream << "\t\t allow_landmark   " << (getAllowLandmark() ? 1 : 0)  << "\n"; -	output_stream << "\t\t sound_local	   " << (getSoundLocal() ? 1 : 0)  << "\n"; -	output_stream << "\t\t allow_scripts    " << (getAllowOtherScripts()  ? 1 : 0)  << "\n"; -	output_stream << "\t\t allow_group_scripts    " << (getAllowGroupScripts()  ? 1 : 0)  << "\n"; -	output_stream << "\t\t use_estate_voice_chan		 " << (getParcelFlagUseEstateVoiceChannel() ? 1 : 0) << "\n"; - -	output_stream << "\t\t allow_voice_chat    " << (getParcelFlagAllowVoice() ? 1 : 0) << "\n"; -	output_stream << "\t\t use_estate_voice_chan   " << (getParcelFlagUseEstateVoiceChannel() ? 1 : 0) << "\n"; -	output_stream << "\t\t for_sale         " << (getForSale()       ? 1 : 0)  << "\n"; -	output_stream << "\t\t sell_w_objects   " << (getSellWithObjects()	? 1 : 0)  << "\n"; -	output_stream << "\t\t draw_distance    " << mDrawDistance  << "\n"; -	output_stream << "\t\t sale_price       " << mSalePrice  << "\n"; - -	setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0); -	output_stream << "\t\t use_access_group " << setting  << "\n"; - -	setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0); -	output_stream << "\t\t use_access_list  " << setting  << "\n"; - -	setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0); -	output_stream << "\t\t use_ban_list     " << setting  << "\n"; - -	mGroupID.toString(id_string); -	output_stream << "\t\t group_id  " << id_string  << "\n"; - -	//const char* group_name -	//	= (mGroupName.isEmpty() ? "" : mGroupName.c_str() ); -	//output_stream << "\t\t group_name " << group_name << "\n"; - -	setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0); -	output_stream << "\t\t use_pass_list    " << setting  << "\n"; - -	output_stream << "\t\t pass_price       " << mPassPrice  << "\n"; -	output_stream << "\t\t pass_hours       " << mPassHours  << "\n"; - -	setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0); -	output_stream << "\t\t show_directory   " << setting  << "\n"; - -	setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0); -	output_stream << "\t\t allow_publish     " << setting  << "\n"; - -	setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0); -	output_stream << "\t\t mature_publish     " << setting  << "\n"; - -	setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0); -	output_stream << "\t\t deny_anonymous     " << setting  << "\n"; - -//	setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0); -//	output_stream << "\t\t deny_identified     " << setting  << "\n"; - -//	setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0); -//	output_stream << "\t\t deny_transacted     " << setting  << "\n"; - -	setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0); -	output_stream << "\t\t deny_age_unverified			 " << setting  << "\n"; - -	setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0); -	output_stream << "\t\t restrict_pushobject " << setting  << "\n"; - -	output_stream << "\t\t aabb_min         "  -		<< mAABBMin.mV[VX] -		<< " " << mAABBMin.mV[VY] -		<< " " << mAABBMin.mV[VZ] << "\n"; - -	if (!mAccessList.empty()) -	{ -		output_stream << "\t\t access_list " << mAccessList.size()  << "\n"; -		access_map_const_iterator cit = mAccessList.begin(); -		access_map_const_iterator end = mAccessList.end(); - -		for ( ; cit != end; ++cit) -		{ -			output_stream << "\t\t{\n"; -			const LLAccessEntry& entry = (*cit).second; -			entry.mID.toString(id_string); -			output_stream << "\t\t\tid " << id_string << "\n"; -			output_stream << "\t\t\ttime " << entry.mTime  << "\n"; -			output_stream << "\t\t\tflags " << entry.mFlags  << "\n"; -			output_stream << "\t\t}\n"; -		} -	} - -	if (!mBanList.empty()) -	{ -		output_stream << "\t\t ban_list " << mBanList.size()  << "\n"; -		access_map_const_iterator cit = mBanList.begin(); -		access_map_const_iterator end = mBanList.end(); - -		for ( ; cit != end; ++cit) -		{ -			output_stream << "\t\t{\n"; -			const LLAccessEntry& entry = (*cit).second; -			entry.mID.toString(id_string); -			output_stream << "\t\t\tid " << id_string << "\n"; -			output_stream << "\t\t\ttime " << entry.mTime  << "\n"; -			output_stream << "\t\t\tflags " << entry.mFlags  << "\n"; -			output_stream << "\t\t}\n"; -		} -	} - -	/*if (mRenterList.count() > 0) -	{ -		output_stream << "\t\t renter_list " << mRenterList.count()  << "\n"; -		for (i = 0; i < mRenterList.count(); i++) -		{ -			output_stream << "\t\t{\n"; -			const LLAccessEntry& entry = mRenterList.get(i); -			entry.mID.toString(id_string); -			output_stream << "\t\t\tid " << id_string << "\n"; -			output_stream << "\t\t\ttime " << entry.mTime  << "\n"; -			output_stream << "\t\t\tflags " << entry.mFlags  << "\n"; -			output_stream << "\t\t}\n"; -		} -	}*/ - -	output_stream << "\t}\n"; -	output_stream.flags(old_flags); - -	return TRUE; -} - -  // Assumes we are in a block "ParcelData"  void LLParcel::packMessage(LLMessageSystem* msg)  { diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 12d0fdf1e9..6f5ae87ebd 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -103,6 +103,32 @@ const U32 RT_OTHER	= 0x1 << 3;  const U32 RT_LIST	= 0x1 << 4;  const U32 RT_SELL	= 0x1 << 5; + +// Timeouts for parcels +// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 +const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); +// ***** TESTING is 10 minutes +//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000); + +// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 +const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); +// ***** TESTING is 10 minutes +//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000); + +// default sale timeout is 2 days -> 172800000000 +const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); +// ***** TESTING is 10 minutes +//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000); + +// more grace period extensions. +const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); + +// if more than 100,000s before sale revert, and no extra extension +// has been given, go ahead and extend it more. That's about 1.2 days. +const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; + + +  class LLMessageSystem;  class LLSD; @@ -271,9 +297,9 @@ public:  	void	setPassPrice(S32 price)				{ mPassPrice = price; }  	void	setPassHours(F32 hours)				{ mPassHours = hours; } -	BOOL	importStream(std::istream& input_stream); +//	BOOL	importStream(std::istream& input_stream);  	BOOL	importAccessEntry(std::istream& input_stream, LLAccessEntry* entry); -	BOOL	exportStream(std::ostream& output_stream); +//	BOOL	exportStream(std::ostream& output_stream);  	void	packMessage(LLMessageSystem* msg);  	void	packMessage(LLSD& msg); @@ -633,4 +659,10 @@ public:  }; +const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status); +LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s); +LLParcel::ECategory category_string_to_category(const std::string& s); +const std::string& category_to_string(LLParcel::ECategory category); + +  #endif diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 101e9d075a..d4031796ad 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -134,6 +134,7 @@ BOOL LLVector3::clampLength( F32 length_limit )  			mV[0] *= length_limit;  			mV[1] *= length_limit;  			mV[2] *= length_limit; +			changed = TRUE;  		}  	} diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index fd22de9399..4fb0187412 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -7,6 +7,7 @@ include(LLCommon)  include(LLMath)  include(LLMessage)  include(LLVFS) +include(LLAddBuildTest)  include_directories (${CMAKE_CURRENT_SOURCE_DIR}) @@ -34,6 +35,7 @@ set(llmessage_SOURCE_FILES      llhost.cpp      llhttpassetstorage.cpp      llhttpclient.cpp +    llhttpclientadapter.cpp      llhttpnode.cpp      llhttpsender.cpp      llinstantmessage.cpp @@ -57,6 +59,7 @@ set(llmessage_SOURCE_FILES      llpacketring.cpp      llpartdata.cpp      llpumpio.cpp +    llregionpresenceverifier.cpp      llsdappservices.cpp      llsdhttpserver.cpp      llsdmessagebuilder.cpp @@ -65,7 +68,9 @@ set(llmessage_SOURCE_FILES      llsdrpcserver.cpp      llservicebuilder.cpp      llservice.cpp +    llstoredmessage.cpp      lltemplatemessagebuilder.cpp +    lltemplatemessagedispatcher.cpp      lltemplatemessagereader.cpp      llthrottle.cpp      lltransfermanager.cpp @@ -73,6 +78,7 @@ set(llmessage_SOURCE_FILES      lltransfersourcefile.cpp      lltransfertargetfile.cpp      lltransfertargetvfile.cpp +    lltrustedmessageservice.cpp      llurlrequest.cpp      lluseroperation.cpp      llxfer.cpp @@ -85,7 +91,6 @@ set(llmessage_SOURCE_FILES      message_prehash.cpp      message_string_table.cpp      net.cpp -    network.cpp      partsyspacket.cpp      patch_code.cpp      patch_dct.cpp @@ -115,7 +120,10 @@ set(llmessage_HEADER_FILES      llhost.h      llhttpassetstorage.h      llhttpclient.h +    llhttpclientinterface.h +    llhttpclientadapter.h      llhttpnode.h +    llhttpnodeadapter.h      llhttpsender.h      llinstantmessage.h      llinvite.h @@ -144,6 +152,7 @@ set(llmessage_HEADER_FILES      llqueryflags.h      llregionflags.h      llregionhandle.h +    llregionpresenceverifier.h      llsdappservices.h      llsdhttpserver.h      llsdmessagebuilder.h @@ -152,9 +161,11 @@ set(llmessage_HEADER_FILES      llsdrpcserver.h      llservice.h      llservicebuilder.h +    llstoredmessage.h      lltaskname.h      llteleportflags.h      lltemplatemessagebuilder.h +    lltemplatemessagedispatcher.h      lltemplatemessagereader.h      llthrottle.h      lltransfermanager.h @@ -162,6 +173,7 @@ set(llmessage_HEADER_FILES      lltransfersourcefile.h      lltransfertargetfile.h      lltransfertargetvfile.h +    lltrustedmessageservice.h      llurlrequest.h      lluseroperation.h      llvehicleparams.h @@ -176,7 +188,6 @@ set(llmessage_HEADER_FILES      message.h      message_prehash.h      net.h -    network.h      partsyspacket.h      patch_code.h      patch_dct.h @@ -197,3 +208,13 @@ target_link_libraries(      ${CRYPTO_LIBRARIES}      ${XMLRPCEPI_LIBRARIES}      ) + +IF (NOT LINUX AND VIEWER) +    # When building the viewer the tests links against the shared objects.  +    # These can not be found when we try to run the tests, so we had to disable them, for the viewer build. +    # TODO: Can someone with viewer knowledge figure out how to make these find the correct so. +    #ADD_BUILD_TEST(llhttpclientadapter llmessage) +    ADD_BUILD_TEST(lltrustedmessageservice llmessage) +    ADD_BUILD_TEST(lltemplatemessagedispatcher llmessage) +ENDIF (NOT LINUX AND VIEWER) + diff --git a/indra/llmessage/lldispatcher.cpp b/indra/llmessage/lldispatcher.cpp index bb7c833b49..7ce3d11be4 100644 --- a/indra/llmessage/lldispatcher.cpp +++ b/indra/llmessage/lldispatcher.cpp @@ -111,40 +111,14 @@ bool LLDispatcher::unpackMessage(  		LLUUID& invoice,  		LLDispatcher::sparam_t& parameters)  { -	char buf[MAX_STRING];	/*Flawfinder: ignore*/  	msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);  	msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice); -	S32 size;  	S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);  	for (S32 i = 0; i < count; ++i)  	{ -		// we treat the SParam as binary data (since it might be an  -		// LLUUID in compressed form which may have embedded \0's,) -		size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter); -		msg->getBinaryDataFast( -			_PREHASH_ParamList, _PREHASH_Parameter, -			buf, size, i, MAX_STRING-1); - -		// If the last byte of the data is 0x0, this is either a normally -		// packed string, or a binary packed UUID (which for these messages -		// are packed with a 17th byte 0x0).  Unpack into a std::string -		// without the trailing \0, so "abc\0" becomes std::string("abc", 3) -		// which matches const char* "abc". -		if (size > 0 -			&& buf[size-1] == 0x0) -		{ -			// special char*/size constructor because UUIDs may have embedded -			// 0x0 bytes. -			std::string binary_data(buf, size-1); -			parameters.push_back(binary_data); -		} -		else -		{ -			// This is either a NULL string, or a string that was packed  -			// incorrectly as binary data, without the usual trailing '\0'. -			std::string string_data(buf, size); -			parameters.push_back(string_data); -		} +		std::string parameter; +		msg->getStringFast(_PREHASH_ParamList,_PREHASH_Parameter, parameter, i); +		parameters.push_back(parameter);  	}  	return true;  } diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 2438539049..dfdad59e2a 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -235,6 +235,7 @@ LLSD LLHTTPAssetRequest::getFullDetails() const  void LLHTTPAssetRequest::setupCurlHandle()  { +	// *NOTE: Similar code exists in mapserver/llcurlutil.cpp  JC  	mCurlHandle = curl_easy_init();  	curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);  	curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1); diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp new file mode 100644 index 0000000000..f0e7654646 --- /dev/null +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -0,0 +1,53 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2001-2009, 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 "llhttpclientadapter.h" +#include "llhttpclient.h" + +LLHTTPClientAdapter::~LLHTTPClientAdapter()  +{ +} + +void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder)  +{ +	LLHTTPClient::get(url, responder); +} + +void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)  +{ +	LLHTTPClient::get(url, responder, headers); +} + +void LLHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)  +{ +	LLHTTPClient::put(url, body, responder); +} + diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h new file mode 100644 index 0000000000..d5f3aeaf2c --- /dev/null +++ b/indra/llmessage/llhttpclientadapter.h @@ -0,0 +1,48 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, 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$ + */ + +#ifndef LL_HTTPCLIENTADAPTER_H +#define LL_HTTPCLIENTADAPTER_H + +#include "llhttpclientinterface.h" +#include "llmemory.h"	// LLSingleton<> + +class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLHTTPClientAdapter> +{ +public: +	virtual ~LLHTTPClientAdapter(); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers); +	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder); +}; + +#endif + diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h new file mode 100644 index 0000000000..1f13d46447 --- /dev/null +++ b/indra/llmessage/llhttpclientinterface.h @@ -0,0 +1,50 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, 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$ + */ + +#ifndef LL_LLHTTPCLIENTINTERFACE_H +#define LL_LLHTTPCLIENTINTERFACE_H + +#include "linden_common.h" +#include "llcurl.h" + +#include <string> + +class LLHTTPClientInterface +{ +public: +	virtual ~LLHTTPClientInterface() {} +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0; +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0; +	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0; +}; + +#endif // LL_LLHTTPCLIENTINTERFACE_H + diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h index 4f80db47f1..17ffd66e8f 100644 --- a/indra/llmessage/llhttpnode.h +++ b/indra/llmessage/llhttpnode.h @@ -88,6 +88,9 @@ public:  	virtual LLSD post(const LLSD& input) const;  	virtual LLSD del(const LLSD& context) const; +	/** +	* @brief Abstract Base Class declaring Response interface. +	*/  	class Response : public LLRefCount  	{  	protected: @@ -95,8 +98,8 @@ public:  	public:  		/** -		 * @brief Return the LLSD content and a 200 OK. -		 */ +		* @brief Return the LLSD content and a 200 OK. +		*/  		virtual void result(const LLSD&) = 0;  		/** @@ -111,42 +114,41 @@ public:  		virtual void status(S32 code, const std::string& message) = 0;  		/** -		 * @brief Return no body, just status code and 'UNKNOWN ERROR'. -		 */ -		void status(S32 code); +		* @brief Return no body, just status code and 'UNKNOWN ERROR'. +		*/ +		virtual void status(S32 code); -		void notFound(const std::string& message); -		void notFound(); -		void methodNotAllowed(); +		virtual void notFound(const std::string& message); +		virtual void notFound(); +		virtual void methodNotAllowed();  		/** -		 * @breif Add a name: value http header. -		 * -		 * No effort is made to ensure the response is a valid http -		 * header. -		 * The headers are stored as a map of header name : value. -		 * Though HTTP allows the same header name to be transmitted -		 * more than once, this implementation only stores a header -		 * name once. -		 * @param name The name of the header, eg, "Content-Encoding" -		 * @param value The value of the header, eg, "gzip" -		 */ -		void addHeader(const std::string& name, const std::string& value); +		* @breif Add a name: value http header. +		* +		* No effort is made to ensure the response is a valid http +		* header. +		* The headers are stored as a map of header name : value. +		* Though HTTP allows the same header name to be transmitted +		* more than once, this implementation only stores a header +		* name once. +		* @param name The name of the header, eg, "Content-Encoding" +		* @param value The value of the header, eg, "gzip" +		*/ +		virtual void addHeader(const std::string& name, const std::string& value);  	protected:  		/** -		 * @brief Headers to be sent back with the HTTP response. -		 * -		 * Protected class membership since derived classes are -		 * expected to use it and there is no use case yet for other -		 * uses. If such a use case arises, I suggest making a -		 * headers() public method, and moving this member data into -		 * private. -		 */ +		* @brief Headers to be sent back with the HTTP response. +		* +		* Protected class membership since derived classes are +		* expected to use it and there is no use case yet for other +		* uses. If such a use case arises, I suggest making a +		* headers() public method, and moving this member data into +		* private. +		*/  		LLSD mHeaders;  	}; -  	typedef LLPointer<Response> ResponsePtr;  	virtual void get(ResponsePtr, const LLSD& context) const; diff --git a/indra/llmessage/llhttpnodeadapter.h b/indra/llmessage/llhttpnodeadapter.h new file mode 100644 index 0000000000..08b5664162 --- /dev/null +++ b/indra/llmessage/llhttpnodeadapter.h @@ -0,0 +1,57 @@ +/** + * @file llhttpnodeadapter.h + * @brief Declaration of llhttpnode adapter classes + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, 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$ + */ + +#ifndef LL_HTTP_NODE_ADAPTER_H +#define LL_HTTP_NODE_ADAPTER_H + +#include "llhttpnode.h" + +template<typename T> +class LLHTTPNodeAdapter : public LLHTTPNode +{ +public: + +	virtual bool validate(const std::string& name, LLSD& context) const +	{ +		T node; +		return node.validate(name, context); +	} +	 +	virtual void post(LLHTTPNode::ResponsePtr response, +					  const LLSD& context, +					  const LLSD& input) const +	{ +		T node; +		return node.post(response, context, input); +	} +}; + +#endif // LL_HTTP_NODE_ADAPTER_H diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 0895af091b..83dfa94f00 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -844,6 +844,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  				= node->getProtocolHandler();  			if (protocolHandler)  			{ +				lldebugs << "HTTP context: " << context << llendl;  				protocolHandler->build(chain, context);  			}  			else diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h new file mode 100644 index 0000000000..4082666339 --- /dev/null +++ b/indra/llmessage/llmessagesenderinterface.h @@ -0,0 +1,49 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, 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$ + */ + +#ifndef LL_LLMESSAGESENDERINTERFACE_H +#define LL_LLMESSAGESENDERINTERFACE_H + +#include "linden_common.h" +#include "llstoredmessage.h" +class LLHost; +class LLSD; + +class LLMessageSenderInterface +{ +public: +	virtual ~LLMessageSenderInterface() {} +	virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message) = 0; + +}; + +#endif // LL_LLMESSAGESENDERINTERFACE_H + diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp new file mode 100644 index 0000000000..b3fabddd3e --- /dev/null +++ b/indra/llmessage/llregionpresenceverifier.cpp @@ -0,0 +1,87 @@ +/**  + * @file  + * @brief  + * + * $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 "llregionpresenceverifier.h" +#include "llhttpclientinterface.h" +#include <sstream> +#include "net.h" +#include "message.h" + + +LLRegionPresenceVerifier::RegionResponder::RegionResponder(ResponsePtr data) : mSharedData(data) +{ +} + + +void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content) +{ +	std::string host = content["private_host"].asString(); +	U32 port = content["private_port"].asInteger(); +	LLHost destination(host, port); +	LLUUID id = content["region_id"]; + +	llinfos << "Verifying " << destination.getString() << " is region " << id << llendl; + +	std::stringstream uri; +	uri << "http://" << destination.getString() << "/state/basic"; +	mSharedData->getHttpClient().get(uri.str(), new VerifiedDestinationResponder(mSharedData, content)); +} + +void LLRegionPresenceVerifier::RegionResponder::completed( +	U32 status, +	const std::string& reason, +	const LLSD& content) +{ +	LLHTTPClient::Responder::completed(status, reason, content); +	 +	mSharedData->onCompletedRegionRequest(); +} + + +LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(ResponsePtr data, const LLSD& content) : mSharedData(data), mContent(content) +{ +} + + + + +void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD& content) +{ +	LLUUID actual_region_id = content["region_id"]; +	LLUUID expected_region_id = mContent["region_id"]; + +	if (mSharedData->checkValidity(content)) +	{ +		mSharedData->onRegionVerified(mContent); +	} +	else if ((mSharedData->shouldRetry()) && (actual_region_id != expected_region_id)) // If the region is correct, then it means we've deliberately changed the data +	{ +		LLSD headers; +		headers["Cache-Control"] = "no-cache, max-age=0"; +		llinfos << "Requesting region information, get uncached for region " << mSharedData->getRegionUri() << llendl; +		mSharedData->decrementRetries(); +		mSharedData->getHttpClient().get(mSharedData->getRegionUri(), new RegionResponder(mSharedData), headers); +	} +	else +	{ +		llwarns << "Could not correctly look up region from region presence service. Region: " << mSharedData->getRegionUri() << llendl; +	} +} diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h new file mode 100644 index 0000000000..a0f08f12fe --- /dev/null +++ b/indra/llmessage/llregionpresenceverifier.h @@ -0,0 +1,81 @@ +/**  + * @file  + * @brief  + * + * $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$ + */ + +/* Macro Definitions */ +#ifndef LL_LLREGIONPRESENCEVERIFIER_H +#define LL_LLREGIONPRESENCEVERIFIER_H + +#include "llhttpclient.h" +#include <string> +#include "llsd.h" +#include <boost/shared_ptr.hpp> + +class LLHTTPClientInterface; + +class LLRegionPresenceVerifier +{ +public: +	class Response +	{ +	public: +		virtual ~Response() {} + +		virtual bool checkValidity(const LLSD& content) const = 0; +		virtual void onRegionVerified(const LLSD& region_details) = 0; + +		virtual void decrementRetries() = 0; + +		virtual LLHTTPClientInterface& getHttpClient() = 0; +		virtual std::string getRegionUri() const = 0; +		virtual bool shouldRetry() const = 0; + +		virtual void onCompletedRegionRequest() {} +	}; + +	typedef boost::shared_ptr<Response> ResponsePtr; + +	class RegionResponder : public LLHTTPClient::Responder +	{ +	public: +		RegionResponder(ResponsePtr data); +		virtual void result(const LLSD& content); +		virtual void completed( +			U32 status, +			const std::string& reason, +			const LLSD& content); + +	private: +		ResponsePtr mSharedData; +	}; + +	class VerifiedDestinationResponder : public LLHTTPClient::Responder +	{ +	public: +		VerifiedDestinationResponder(ResponsePtr data, const LLSD& content); +		virtual void result(const LLSD& content); +	private: +		ResponsePtr mSharedData; +		LLSD mContent; +	}; +}; + + +#endif //LL_LLREGIONPRESENCEVERIFIER_H diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp index a62dd04560..21937f022f 100755 --- a/indra/llmessage/llsdmessagebuilder.cpp +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -268,10 +268,125 @@ void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)  		for(; dit != dend; ++dit)  		{ -			//const LLMsgVarData& mvci = *dit; - -			// TODO: Copy mvci data in to block: -			// (*mCurrentBlock)[varname] = v; +			const LLMsgVarData& mvci = *dit; +			const char* varname = mvci.getName(); + +			switch(mvci.getType()) +			{ +			case MVT_FIXED: +				addBinaryData(varname, mvci.getData(), mvci.getSize()); +				break; + +			case MVT_VARIABLE: +				{ +					const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated +					if (mvci.getDataSize() == 1 && end == 0)  +					{ +						addString(varname, (const char*)mvci.getData()); +					} +					else +					{ +						addBinaryData(varname, mvci.getData(), mvci.getSize()); +					} +					break; +				} + +			case MVT_U8: +				addU8(varname, *(U8*)mvci.getData()); +				break; + +			case MVT_U16: +				addU16(varname, *(U16*)mvci.getData()); +				break; + +			case MVT_U32: +				addU32(varname, *(U32*)mvci.getData()); +				break; + +			case MVT_U64: +				addU64(varname, *(U64*)mvci.getData()); +				break; + +			case MVT_S8: +				addS8(varname, *(S8*)mvci.getData()); +				break; + +			case MVT_S16: +				addS16(varname, *(S16*)mvci.getData()); +				break; + +			case MVT_S32: +				addS32(varname, *(S32*)mvci.getData()); +				break; + +			// S64 not supported in LLSD so we just truncate it +			case MVT_S64: +				addS32(varname, *(S64*)mvci.getData()); +				break; + +			case MVT_F32: +				addF32(varname, *(F32*)mvci.getData()); +				break; + +			case MVT_F64: +				addF64(varname, *(F64*)mvci.getData()); +				break; + +			case MVT_LLVector3: +				addVector3(varname, *(LLVector3*)mvci.getData()); +				break; + +			case MVT_LLVector3d: +				addVector3d(varname, *(LLVector3d*)mvci.getData()); +				break; + +			case MVT_LLVector4: +				addVector4(varname, *(LLVector4*)mvci.getData()); +				break; + +			case MVT_LLQuaternion: +				{ +					LLVector3 v = *(LLVector3*)mvci.getData(); +					LLQuaternion q; +					q.unpackFromVector3(v); +					addQuat(varname, q); +					break; +				} + +			case MVT_LLUUID: +				addUUID(varname, *(LLUUID*)mvci.getData()); +				break;	 + +			case MVT_BOOL: +				addBOOL(varname, *(BOOL*)mvci.getData()); +				break; + +			case MVT_IP_ADDR: +				addIPAddr(varname, *(U32*)mvci.getData()); +				break; + +			case MVT_IP_PORT: +				addIPPort(varname, *(U16*)mvci.getData()); +				break; + +			case MVT_U16Vec3: +				//treated as an array of 6 bytes +				addBinaryData(varname, mvci.getData(), 6); +				break; + +			case MVT_U16Quat: +				//treated as an array of 8 bytes +				addBinaryData(varname, mvci.getData(), 8); +				break; + +			case MVT_S16Array: +				addBinaryData(varname, mvci.getData(), mvci.getSize()); +				break; + +			default: +				llwarns << "Unknown type in conversion of message to LLSD" << llendl; +				break; +			}  		}  	}  } diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp new file mode 100644 index 0000000000..615eff405d --- /dev/null +++ b/indra/llmessage/llstoredmessage.cpp @@ -0,0 +1,38 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2001-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 "llstoredmessage.h" + +LLStoredMessage::LLStoredMessage(const std::string& name, const LLSD& message) : mMessage(message), mName(name) +{ +} + diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h new file mode 100644 index 0000000000..e817f19bd2 --- /dev/null +++ b/indra/llmessage/llstoredmessage.h @@ -0,0 +1,58 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2001-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$ + */ + +#ifndef LL_STOREDMESSAGE_H +#define LL_STOREDMESSAGE_H + +#include "linden_common.h" +#include "llsd.h" +#include <boost/shared_ptr.hpp> +#include <string> + + +class LLMessageSystem; + +class LLStoredMessage +{ +public: +	LLStoredMessage(const std::string& name, const LLSD& message); +private: +	friend class LLMessageSystem; + +	LLSD mMessage; +	std::string mName; +}; + +typedef boost::shared_ptr<LLStoredMessage> LLStoredMessagePtr; + + +#endif // LL_STOREDMESSAGE_H diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index c153c81372..e6419807ff 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -41,7 +41,7 @@  #include "v3math.h"  #include "v4math.h" -LLTemplateMessageBuilder::LLTemplateMessageBuilder(message_template_name_map_t& name_template_map) : +LLTemplateMessageBuilder::LLTemplateMessageBuilder(const message_template_name_map_t& name_template_map) :  	mCurrentSMessageData(NULL),  	mCurrentSMessageTemplate(NULL),  	mCurrentSDataBlock(NULL), @@ -75,14 +75,14 @@ void LLTemplateMessageBuilder::newMessage(const char *name)  	char* namep = (char*)name;   	if (mMessageTemplates.count(namep) > 0)  	{ -		mCurrentSMessageTemplate = mMessageTemplates[namep]; +		mCurrentSMessageTemplate = mMessageTemplates.find(name)->second;  		mCurrentSMessageData = new LLMsgData(namep);  		mCurrentSMessageName = namep;  		mCurrentSDataBlock = NULL;  		mCurrentSBlockName = NULL;  		// add at one of each block -		const LLMessageTemplate* msg_template = mMessageTemplates[namep]; +		const LLMessageTemplate* msg_template = mMessageTemplates.find(name)->second;  		if (msg_template->getDeprecation() != MD_NOTDEPRECATED)  		{ diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h index bcdf722b1b..96e7ae1a86 100644 --- a/indra/llmessage/lltemplatemessagebuilder.h +++ b/indra/llmessage/lltemplatemessagebuilder.h @@ -49,7 +49,7 @@ public:  	typedef std::map<const char* , LLMessageTemplate*> message_template_name_map_t; -	LLTemplateMessageBuilder(message_template_name_map_t&); +	LLTemplateMessageBuilder(const message_template_name_map_t&);  	virtual ~LLTemplateMessageBuilder();  	virtual void newMessage(const char* name); @@ -99,6 +99,7 @@ public:  	virtual void copyFromMessageData(const LLMsgData& data);  	virtual void copyFromLLSD(const LLSD&); +	LLMsgData* getCurrentMessage() const { return mCurrentSMessageData; }  private:  	void addData(const char* varname, const void* data,   					 EMsgVariableType type, S32 size); @@ -114,7 +115,7 @@ private:  	BOOL mbSBuilt;  	BOOL mbSClear;  	S32	 mCurrentSendTotal; -	message_template_name_map_t& mMessageTemplates; +	const message_template_name_map_t& mMessageTemplates;  };  #endif // LL_LLTEMPLATEMESSAGEBUILDER_H diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp new file mode 100644 index 0000000000..3bbf3a058d --- /dev/null +++ b/indra/llmessage/lltemplatemessagedispatcher.cpp @@ -0,0 +1,72 @@ +/** + * @file lltemplatemessagedispatcher.h + * @brief LLTemplateMessageDispatcher class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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 "lltemplatemessagedispatcher.h" + +#include "llhttpnode.h" +#include "llhost.h" +#include "message.h" +#include "llsd.h" +#include "lltemplatemessagereader.h" + + +LLTemplateMessageDispatcher::LLTemplateMessageDispatcher(LLTemplateMessageReader &template_message_reader) : +	mTemplateMessageReader(template_message_reader) +{ +} + +void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name, +										   const LLSD& message, +										   LLHTTPNode::ResponsePtr responsep) +{ +	std::vector<U8> data = message["body"]["binary-template-data"].asBinary(); +	U32 size = data.size(); +	if(size == 0) +	{ +		return; +	} + +	LLHost host; +	host = gMessageSystem->getSender(); + +	bool validate_message = mTemplateMessageReader.validateMessage(&(data[0]), data.size(), host, true); + +	if (validate_message) +	{ +		mTemplateMessageReader.readMessage(&(data[0]),host); +	}  +	else  +	{ +		gMessageSystem->clearReceiveState(); +	} +} + diff --git a/indra/llmessage/lltemplatemessagedispatcher.h b/indra/llmessage/lltemplatemessagedispatcher.h new file mode 100644 index 0000000000..b1e74f47bb --- /dev/null +++ b/indra/llmessage/lltemplatemessagedispatcher.h @@ -0,0 +1,53 @@ +/** + * @file lltemplatemessagedispatcher.h + * @brief LLTemplateMessageDispatcher class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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$ + */ + +#ifndef LLTEMPLATEMESSAGEDISPATCHER_H +#define LLTEMPLATEMESSAGEDISPATCHER_H + +#include "linden_common.h" +#include "llsd.h" +#include "llhttpnode.h" +#include "lltemplatemessagereader.h" + + +class LLTemplateMessageDispatcher +{ +public: +	LLTemplateMessageDispatcher(LLTemplateMessageReader& template_message_reader); +	void dispatch(const std::string& msg_name, +				  const LLSD& message, +				  LLHTTPNode::ResponsePtr responsep); + +private: +	LLTemplateMessageReader &mTemplateMessageReader; +}; + +#endif // LLTEMPLATEMESSAGEDISPATCHER_H diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index f64a096b3e..d635844ee5 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -755,18 +755,38 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender  BOOL LLTemplateMessageReader::validateMessage(const U8* buffer,   											  S32 buffer_size,  -											  const LLHost& sender) +											  const LLHost& sender, +											  bool trusted)  {  	mReceiveSize = buffer_size; -	BOOL result = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); -	if(result) +	BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); +	if(valid)  	{  		mCurrentRMessageTemplate->mReceiveCount++; -		//lldebugs << "MessageRecvd:"  +		//lldebugs << "MessageRecvd:"  		//						 << mCurrentRMessageTemplate->mName   		//						 << " from " << sender << llendl;  	} -	return result; + +	if (valid && isBanned(trusted)) +	{ +		LL_WARNS("Messaging") << "LLMessageSystem::checkMessages " +			<< "received banned message " +			<< getMessageName() +			<< " from " +			<< ((trusted) ? "trusted " : "untrusted ") +			<< sender << llendl; +		valid = FALSE; +	} + +	if(valid && isUdpBanned()) +	{ +		llwarns << "Received UDP black listed message " +				<<  getMessageName() +				<< " from " << sender << llendl; +		valid = FALSE; +	} +	return valid;  }  BOOL LLTemplateMessageReader::readMessage(const U8* buffer,  diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h index e1062de88f..ab06ab433d 100644 --- a/indra/llmessage/lltemplatemessagereader.h +++ b/indra/llmessage/lltemplatemessagereader.h @@ -105,7 +105,7 @@ public:  	virtual void copyToBuilder(LLMessageBuilder&) const;  	BOOL validateMessage(const U8* buffer, S32 buffer_size,  -						 const LLHost& sender); +						 const LLHost& sender, bool trusted = false);  	BOOL readMessage(const U8* buffer, const LLHost& sender);  	bool isTrusted() const; diff --git a/indra/llmessage/lltrustedmessageservice.cpp b/indra/llmessage/lltrustedmessageservice.cpp new file mode 100644 index 0000000000..c1a6c437a7 --- /dev/null +++ b/indra/llmessage/lltrustedmessageservice.cpp @@ -0,0 +1,89 @@ +/** + * @file lltrustedmessageservice.cpp + * @brief LLTrustedMessageService implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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 "linden_common.h" + +#include "lltrustedmessageservice.h" +#include "llhost.h" +#include "llmessageconfig.h" +#include "message.h" + + +bool LLTrustedMessageService::validate(const std::string& name, LLSD& context) +const +{ +	return true; +} + +void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response, +								   const LLSD& context, +								   const LLSD& input) const +{ +	std::string name = context["request"]["wildcard"]["message-name"]; +	std::string senderIP = context["request"]["remote-host"]; +	std::string senderPort = context["request"]["headers"] +		["x-secondlife-udp-listen-port"]; + +	LLSD message_data; +	std::string sender = senderIP + ":" + senderPort; +	message_data["sender"] = sender; +	message_data["body"] = input; +	 +	// untrusted senders should not have access to the trusted message +	// service, but this can happen in development, so check and warn +	LLMessageConfig::SenderTrust trust = +		LLMessageConfig::getSenderTrustedness(name); +	if ((trust == LLMessageConfig::TRUSTED || +		 (trust == LLMessageConfig::NOT_SET && +		  gMessageSystem->isTrustedMessage(name))) +		 && !gMessageSystem->isTrustedSender(LLHost(sender))) +	{ +		LL_WARNS("Messaging") << "trusted message POST to /trusted-message/"  +				<< name << " from unknown or untrusted sender " +				<< sender << llendl; +		response->status(403, "Unknown or untrusted sender"); +	} +	else +	{ +		gMessageSystem->receivedMessageFromTrustedSender(); +		if (input.has("binary-template-data")) +		{ +			llinfos << "Dispatching template: " << input << llendl; +			// try and send this message using udp dispatch +			LLMessageSystem::dispatchTemplate(name, message_data, response); +		} +		else +		{ +			llinfos << "Dispatching without template: " << input << llendl; +			LLMessageSystem::dispatch(name, message_data, response); +		} +	} +} diff --git a/indra/llmessage/lltrustedmessageservice.h b/indra/llmessage/lltrustedmessageservice.h new file mode 100644 index 0000000000..bc824565f1 --- /dev/null +++ b/indra/llmessage/lltrustedmessageservice.h @@ -0,0 +1,51 @@ +/** + * @file lltrustedmessageservice.h + * @brief LLTrustedMessageService class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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$ + */ + +#ifndef LLTRUSTEDMESSAGESERVICE_H +#define LLTRUSTEDMESSAGESERVICE_H + +#include "linden_common.h" +#include "llhttpnode.h" + +class LLSD; + +class LLTrustedMessageService +{ +public: + +	bool validate(const std::string& name, LLSD& context) const; +	 +	void post(LLHTTPNode::ResponsePtr response, +			  const LLSD& context, +			  const LLSD& input) const; +}; + +#endif // LLTRUSTEDMESSAGESERVICE_H diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 4e6cda2880..8ab12ce991 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -59,13 +59,16 @@  #include "llerrorlegacy.h"  #include "llfasttimer.h"  #include "llhttpclient.h" +#include "llhttpnodeadapter.h"  #include "llhttpsender.h"  #include "llmd5.h"  #include "llmessagebuilder.h"  #include "llmessageconfig.h" +#include "lltemplatemessagedispatcher.h"  #include "llpumpio.h"  #include "lltemplatemessagebuilder.h"  #include "lltemplatemessagereader.h" +#include "lltrustedmessageservice.h"  #include "llmessagetemplate.h"  #include "llmessagetemplateparser.h"  #include "llsd.h" @@ -142,52 +145,6 @@ namespace  	};  } - -class LLTrustedMessageService : public LLHTTPNode -{ -	virtual bool validate(const std::string& name, LLSD& context) const -		{ return true; } - -	virtual void post(LLHTTPNode::ResponsePtr response, -					  const LLSD& context, -					  const LLSD& input) const; -}; - -//virtual -void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response, -								   const LLSD& context, -								   const LLSD& input) const -{ -	std::string name = context["request"]["wildcard"]["message-name"]; -	std::string senderIP = context["request"]["remote-host"]; -	std::string senderPort = context["request"]["headers"] -		["x-secondlife-udp-listen-port"]; - -	LLSD message_data; -	std::string sender = senderIP + ":" + senderPort; -	message_data["sender"] = sender; -	message_data["body"] = input; -	 -	// untrusted senders should not have access to the trusted message -	// service, but this can happen in development, so check and warn -	LLMessageConfig::SenderTrust trust = -		LLMessageConfig::getSenderTrustedness(name); -	if ((trust == LLMessageConfig::TRUSTED || -		 (trust == LLMessageConfig::NOT_SET && -		  gMessageSystem->isTrustedMessage(name))) -		 && !gMessageSystem->isTrustedSender(LLHost(sender))) -	{ -		LL_WARNS("Messaging") << "trusted message POST to /trusted-message/"  -				<< name << " from unknown or untrusted sender " -				<< sender << llendl; -		response->status(403, "Unknown or untrusted sender"); -	} -	else -	{ -		LLMessageSystem::dispatch(name, message_data, response); -	} -} -  class LLMessageHandlerBridge : public LLHTTPNode  {  	virtual bool validate(const std::string& name, LLSD& context) const @@ -223,9 +180,6 @@ void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,  LLHTTPRegistration<LLMessageHandlerBridge>  	gHTTPRegistrationMessageWildcard("/message/<message-name>"); -LLHTTPRegistration<LLTrustedMessageService> -	gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); -  //virtual  LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()  { @@ -293,7 +247,8 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,  								 S32 version_patch,  								 bool failure_is_fatal,  								 const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : -	mCircuitInfo(circuit_heartbeat_interval, circuit_timeout) +	mCircuitInfo(circuit_heartbeat_interval, circuit_timeout), +	mLastMessageFromTrustedMessageService(false)  {  	init(); @@ -445,6 +400,7 @@ void LLMessageSystem::clearReceiveState()  	mLastSender.invalidate();  	mLastReceivingIF.invalidate();  	mMessageReader->clearMessage(); +	mLastMessageFromTrustedMessageService = false;  } @@ -477,6 +433,17 @@ bool LLMessageSystem::isTrustedSender(const LLHost& host) const  	return cdp->getTrusted();  } +void LLMessageSystem::receivedMessageFromTrustedSender() +{ +	mLastMessageFromTrustedMessageService = true; +} + +bool LLMessageSystem::isTrustedSender() const +{	 +	return mLastMessageFromTrustedMessageService || +		isTrustedSender(getSender()); +} +  static LLMessageSystem::message_template_name_map_t::const_iterator   findTemplate(const LLMessageSystem::message_template_name_map_t& templates,   			 std::string name) @@ -717,11 +684,16 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			// UseCircuitCode can be a valid, off-circuit packet.  			// But we don't want to acknowledge UseCircuitCode until the circuit is  			// available, which is why the acknowledgement test is done above.  JC - +			bool trusted = cdp && cdp->getTrusted();  			valid_packet = mTemplateMessageReader->validateMessage(  				buffer,  				receive_size, -				host); +				host, +				trusted); +			if (!valid_packet) +			{ +				clearReceiveState(); +			}  			// UseCircuitCode is allowed in even from an invalid circuit, so that  			// we can toss circuits around. @@ -749,29 +721,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  				valid_packet = FALSE;  			} -			if ( -				valid_packet && -				mTemplateMessageReader->isBanned(cdp && cdp->getTrusted())) -			{ -				LL_WARNS("Messaging") << "LLMessageSystem::checkMessages " -					<< "received banned message " -					<< mTemplateMessageReader->getMessageName() -					<< " from " -					<< ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ") -					<< host << llendl; -				clearReceiveState(); -				valid_packet = FALSE; -			} - -			if( valid_packet && mTemplateMessageReader->isUdpBanned()) -			{ -				llwarns << "Received UDP black listed message " -						<<  mTemplateMessageReader->getMessageName() -						<< " from " << host << llendl; -				clearReceiveState(); -				valid_packet = FALSE; -			} -  			if( valid_packet )  			{  				logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); @@ -784,94 +733,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			if (valid_packet)  			{ -				// enable this for output of message names -				//LL_INFOS("Messaging") << "< \"" << mTemplateMessageReader->getMessageName() -						//<< "\"" << llendl; - -				/* Code for dumping the complete contents of a message.  Keep for future use in optimizing messages. -				if( 1 ) -				{ -					static char* object_update = LLMessageStringTable::getInstance()->getString("ObjectUpdate"); -					if(object_update == mTemplateMessageReader->getMessageName() ) -					{ -						LL_INFOS("Messaging") << "ObjectUpdate:" << llendl; -						U32 i; -						LL_INFOS("Messaging") << "    Zero Encoded: " << zero_unexpanded_size << llendl; -						for( i = 0; i<zero_unexpanded_size; i++ ) -						{ -							LL_INFOS("Messaging") << "     " << i << ": " << (U32) zero_unexpanded_buffer[i] << llendl; -						} -						LL_INFOS("Messaging") << "" << llendl; - -						LL_INFOS("Messaging") << "    Zero Unencoded: " << receive_size << llendl; -						for( i = 0; i<receive_size; i++ ) -						{ -							LL_INFOS("Messaging") << "     " << i << ": " << (U32) buffer[i] << llendl; -						} -						LL_INFOS("Messaging") << "" << llendl; - -						LL_INFOS("Messaging") << "    Blocks and variables: " << llendl; -						S32 byte_count = 0; -						for (LLMessageTemplate::message_block_map_t::iterator -								 iter = mCurrentRMessageTemplate->mMemberBlocks.begin(), -								 end = mCurrentRMessageTemplate->mMemberBlocks.end(); -							 iter != end; iter++) -						{ -							LLMessageBlock* block = iter->second; -							const char* block_name = block->mName; -							for (LLMsgBlkData::msg_var_data_map_t::iterator -									 iter = block->mMemberVariables.begin(), -									 end = block->mMemberVariables.end(); -								 iter != end; iter++) -							{ -								const char* var_name = iter->first; -								 -								if( getNumberOfBlocksFast( block_name ) < 1 ) -								{ -									LL_INFOS("Messaging") << var_name << " has no blocks" << llendl; -								} -								for( S32 blocknum = 0; blocknum < getNumberOfBlocksFast( block_name ); blocknum++ ) -								{ -									char *bnamep = (char *)block_name + blocknum; // this works because it's just a hash.  The bnamep is never derefference -									char *vnamep = (char *)var_name;  - -									LLMsgBlkData *msg_block_data = mCurrentRMessageData->mMemberBlocks[bnamep]; - -									if (!msg_block_data) -									{ -										std::string errmsg = llformat("Block %s #%d not in message %s", block_name, blocknum, mCurrentRMessageData->mName); -										LL_ERRS("Messaging") << errmsg << llendl; -									} - -									LLMsgVarData vardata = msg_block_data->mMemberVarData[vnamep]; - -									if (!vardata.getName()) -									{ -										std::string errmsg = llformat("Variable %s not in message %s block %s", vnamep, mCurrentRMessageData->mName, bnamep); -										LL_ERRS("Messaging") << errmsg << llendl; -									} - -									const S32 vardata_size = vardata.getSize(); -									if( vardata_size ) -									{ -										for( i = 0; i < vardata_size; i++ ) -										{ -											byte_count++; -											LL_INFOS("Messaging") << block_name << " " << var_name << " [" << blocknum << "][" << i << "]= " << (U32)(((U8*)vardata.getData())[i]) << llendl; -										} -									} -									else -									{ -										LL_INFOS("Messaging") << block_name << " " << var_name << " [" << blocknum << "] 0 bytes" << llendl; -									} -								} -							} -						} -						LL_INFOS("Messaging") << "Byte count =" << byte_count << llendl; -					} -				} -				*/ -  				mPacketsIn++;  				mBytesIn += mTrueReceiveSize; @@ -899,9 +760,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  					mInvalidOnCircuitPackets++;  				}  			} - -			// Code for dumping the complete contents of a message  -			// delete [] zero_unexpanded_buffer;  		}  	} while (!valid_packet && receive_size > 0); @@ -1004,7 +862,7 @@ void LLMessageSystem::processAcks()  	}  } -void LLMessageSystem::copyMessageRtoS() +void LLMessageSystem::copyMessageReceivedToSend()  {  	// NOTE: babbage: switch builder to match reader to avoid  	// converting message format @@ -1021,6 +879,72 @@ void LLMessageSystem::copyMessageRtoS()  	mMessageReader->copyToBuilder(*mMessageBuilder);  } +LLSD LLMessageSystem::getReceivedMessageLLSD() const +{ +	LLSDMessageBuilder builder; +	mMessageReader->copyToBuilder(builder); +	return builder.getMessage(); +} + +LLSD LLMessageSystem::getBuiltMessageLLSD() const  +{ +	LLSD result; +	if (mLLSDMessageBuilder == mMessageBuilder) +	{ +		 result = mLLSDMessageBuilder->getMessage(); +	} +	else +	{ +		// TODO: implement as below? +		llerrs << "Message not built as LLSD." << llendl;  +	} +	return result; +} + +LLSD LLMessageSystem::wrapReceivedTemplateData() const +{ +	if(mMessageReader == mTemplateMessageReader) +	{ +		LLTemplateMessageBuilder builder(mMessageTemplates); +		builder.newMessage(mMessageReader->getMessageName()); +		mMessageReader->copyToBuilder(builder); +		U8 buffer[MAX_BUFFER_SIZE]; +		const U8 offset_to_data = 0; +		U32 size = builder.buildMessage(buffer, MAX_BUFFER_SIZE, +										offset_to_data); +		std::vector<U8> binary_data(buffer, buffer+size); +		LLSD wrapped_data = LLSD::emptyMap(); +		wrapped_data["binary-template-data"] = binary_data; +		return wrapped_data; +	} +	else +	{ +		return getReceivedMessageLLSD(); +	} +} + +LLStoredMessagePtr LLMessageSystem::getReceivedMessage() const +{ +	const std::string& name = mMessageReader->getMessageName(); +	LLSD message = wrapReceivedTemplateData(); + +	return LLStoredMessagePtr(new LLStoredMessage(name, message)); +} + +LLStoredMessagePtr LLMessageSystem::getBuiltMessage() const +{ +	const std::string& name = mMessageBuilder->getMessageName(); +	LLSD message = getBuiltMessageLLSD(); + +	return LLStoredMessagePtr(new LLStoredMessage(name, message)); +} + +S32 LLMessageSystem::sendMessage(const LLHost &host, LLStoredMessagePtr message) +{ +	return sendMessage(host, message->mName.c_str(), message->mMessage); +} + +  void LLMessageSystem::clearMessage()  {  	mSendReliable = FALSE; @@ -1033,6 +957,11 @@ void LLMessageSystem::nextBlockFast(const char *blockname)  	mMessageBuilder->nextBlock(blockname);  } +void LLMessageSystem::nextBlock(const char *blockname) +{ +	nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname)); +} +  BOOL LLMessageSystem::isSendFull(const char* blockname)  {  	char* stringTableName = NULL; @@ -1112,19 +1041,19 @@ S32 LLMessageSystem::sendReliable(	const LLHost &host,  void LLMessageSystem::forwardMessage(const LLHost &host)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	sendMessage(host);  }  void LLMessageSystem::forwardReliable(const LLHost &host)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	sendReliable(host);  }  void LLMessageSystem::forwardReliable(const U32 circuit_code)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	sendReliable(findHost(circuit_code));  } @@ -1135,7 +1064,7 @@ S32 LLMessageSystem::forwardReliable(	const LLHost &host,  										void (*callback)(void **,S32),   										void ** callback_data)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);  } @@ -1463,13 +1392,6 @@ S32 LLMessageSystem::sendMessage(  		LL_WARNS("Messaging") << "trying to send message to invalid host"	<< llendl;  		return 0;  	} -	newMessage(name);	 -	if (mMessageBuilder != mLLSDMessageBuilder) -	{ -		LL_WARNS("Messaging") << "trying to send llsd message when builder is not LLSD!" -				<< llendl; -		return 0; -	}  	const LLHTTPSender& sender = LLHTTPSender::getSender(host);  	sender.send(host, name, message, createResponder(name)); @@ -2178,6 +2100,15 @@ void LLMessageSystem::dispatch(  	handler->post(responsep, context, message);  } +//static  +void LLMessageSystem::dispatchTemplate(const std::string& msg_name, +										const LLSD& message, +										LLHTTPNode::ResponsePtr responsep) +{ +	LLTemplateMessageDispatcher dispatcher(*(gMessageSystem->mTemplateMessageReader)); +	dispatcher.dispatch(msg_name, message, responsep); +} +  static void check_for_unrecognized_messages(  		const char* type,  		const LLSD& map, @@ -2730,7 +2661,7 @@ void LLMessageSystem::summarizeLogs(std::ostream& str)  	str << "END MESSAGE LOG SUMMARY" << std::endl;  } -void end_messaging_system() +void end_messaging_system(bool print_summary)  {  	gTransferManager.cleanup();  	LLTransferTargetVFile::updateQueue(true); // shutdown LLTransferTargetVFile @@ -2738,9 +2669,12 @@ void end_messaging_system()  	{  		gMessageSystem->stopLogging(); -		std::ostringstream str; -		gMessageSystem->summarizeLogs(str); -		LL_INFOS("Messaging") << str.str().c_str() << llendl; +		if (print_summary) +		{ +			std::ostringstream str; +			gMessageSystem->summarizeLogs(str); +			LL_INFOS("Messaging") << str.str().c_str() << llendl; +		}  		delete gMessageSystem;  		gMessageSystem = NULL; @@ -4088,3 +4022,11 @@ void LLMessageSystem::banUdpMessage(const std::string& name)  		llwarns << "Attempted to ban an unknown message: " << name << "." << llendl;  	}  } +const LLHost& LLMessageSystem::getSender() const +{ +	return mLastSender; +} + +LLHTTPRegistration<LLHTTPNodeAdapter<LLTrustedMessageService> > +	gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); + diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 25eeb85323..4fda8f01d7 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -63,6 +63,9 @@  #include "llstl.h"  #include "llmsgvariabletype.h"  #include "llmsgvariabletype.h" +#include "llmessagesenderinterface.h" + +#include "llstoredmessage.h"  const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;  const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; @@ -206,7 +209,7 @@ public:  	virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;  }; -class LLMessageSystem +class LLMessageSystem : public LLMessageSenderInterface  {   private:  	U8					mSendBuffer[MAX_BUFFER_SIZE]; @@ -373,14 +376,33 @@ public:  	void newMessageFast(const char *name);  	void newMessage(const char *name); -	void	copyMessageRtoS(); -	void	clearMessage(); + +public: +	LLStoredMessagePtr getReceivedMessage() const;  +	LLStoredMessagePtr getBuiltMessage() const; +	S32 sendMessage(const LLHost &host, LLStoredMessagePtr message); + +private: +	LLSD getReceivedMessageLLSD() const; +	LLSD getBuiltMessageLLSD() const; + +	// NOTE: babbage: Only use to support legacy misuse of the +	// LLMessageSystem API where values are dangerously written +	// as one type and read as another. LLSD does not support +	// dangerous conversions and so converting the message to an +	// LLSD would result in the reads failing. All code which +	// misuses the message system in this way should be made safe +	// but while the unsafe code is run in old processes, this +	// method should be used to forward unsafe messages. +	LLSD wrapReceivedTemplateData() const; + +public: + +	void copyMessageReceivedToSend(); +	void clearMessage();  	void nextBlockFast(const char *blockname); -	void	nextBlock(const char *blockname) -	{ -		nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname)); -	} +	void nextBlock(const char *blockname);  public:  	void addBinaryDataFast(const char *varname, const void *data, S32 size); @@ -461,14 +483,14 @@ public:  							void (*callback)(void **,S32), void ** callback_data);  	// flush sends a message only if data's been pushed on it. -	S32		flushSemiReliable(	const LLHost &host,  +	S32	 flushSemiReliable(	const LLHost &host,   								void (*callback)(void **,S32), void ** callback_data); -	S32		flushReliable(	const LLHost &host ); +	S32	flushReliable(	const LLHost &host ); -	void    forwardMessage(const LLHost &host); -	void    forwardReliable(const LLHost &host); -	void    forwardReliable(const U32 circuit_code); +	void forwardMessage(const LLHost &host); +	void forwardReliable(const LLHost &host); +	void forwardReliable(const U32 circuit_code);  	S32 forwardReliable(  		const LLHost &host,   		S32 retries,  @@ -480,9 +502,10 @@ public:  	LLHTTPClient::ResponderPtr createResponder(const std::string& name);  	S32		sendMessage(const LLHost &host);  	S32		sendMessage(const U32 circuit); +private:  	S32		sendMessage(const LLHost &host, const char* name,  						const LLSD& message); - +public:  	// BOOL	decodeData(const U8 *buffer, const LLHost &host);  	void	getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); @@ -561,8 +584,12 @@ public:  	void	sendDenyTrustedCircuit(const LLHost &host);  	/** Return false if host is unknown or untrusted */ +	// Note:DaveH/Babbage some trusted messages can be received without a circuit  	bool isTrustedSender(const LLHost& host) const; +	/** Return true if current message is from trusted source */ +	bool isTrustedSender() const; +  	/** Return false true if name is unknown or untrusted */  	bool isTrustedMessage(const std::string& name) const; @@ -578,6 +605,7 @@ public:  	// Change this message to be UDP black listed.  	void banUdpMessage(const std::string& name); +  private:  	// A list of the circuits that need to be sent DenyTrustedCircuit messages.  	typedef std::set<LLHost> host_set_t; @@ -594,6 +622,7 @@ public:  	void	establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0);  	// returns whether the given host is on a trusted circuit +	// Note:DaveH/Babbage some trusted messages can be received without a circuit  	BOOL    getCircuitTrust(const LLHost &host);  	void	setCircuitAllowTimeout(const LLHost &host, BOOL allow); @@ -663,6 +692,12 @@ public:  						 const LLSD& message,  						 LLHTTPNode::ResponsePtr responsep); +	// this is added to support specific legacy messages and is +	// ***not intended for general use*** Si, Gabriel, 2009 +	static void dispatchTemplate(const std::string& msg_name, +						 const LLSD& message, +						 LLHTTPNode::ResponsePtr responsep); +  	void setMessageBans(const LLSD& trusted, const LLSD& untrusted);  	/** @@ -690,9 +725,18 @@ public:  	// Check UDP messages and pump http_pump to receive HTTP messages.  	bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump); + +	// Moved to allow access from LLTemplateMessageDispatcher +	void clearReceiveState(); + +	// This will cause all trust queries to return true until the next message +	// is read: use with caution! +	void receivedMessageFromTrustedSender();  private: +	bool mLastMessageFromTrustedMessageService; +	  	// The mCircuitCodes is a map from circuit codes to session  	// ids. This allows us to verify sessions on connect.  	typedef std::map<U32, LLUUID> code_session_map_t; @@ -703,7 +747,6 @@ private:  	LLUUID mSessionID;  	void	addTemplate(LLMessageTemplate *templatep); -	void		clearReceiveState();  	BOOL		decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );  	void		logMsgFromInvalidCircuit( const LLHost& sender, BOOL recv_reliable ); @@ -799,7 +842,7 @@ bool start_messaging_system(  	const F32 circuit_heartbeat_interval,   	const F32 circuit_timeout); -void end_messaging_system(); +void end_messaging_system(bool print_summary = true);  void null_message_callback(LLMessageSystem *msg, void **data); @@ -976,8 +1019,6 @@ inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n  	return(htonmemcpy(s,ct,type, n));  } - -inline const LLHost& LLMessageSystem::getSender() const {return mLastSender;}  inline const LLHost& LLMessageSystem::getReceivingInterface() const {return mLastReceivingIF;}  inline U32 LLMessageSystem::getSenderIP() const  diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index 8cbd9f63f1..f63faa511a 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -51,7 +51,6 @@  #endif  // linden library includes -#include "network.h"  #include "llerror.h"  #include "llhost.h"  #include "lltimer.h" @@ -395,11 +394,30 @@ S32 start_net(S32& socket_out, int& nPort)  		return 1;  	} -	// Don't bind() if we want the operating system to assign our ports for  -	// us.  	if (NET_USE_OS_ASSIGNED_PORT == nPort)  	{ -		// Do nothing; the operating system will do it for us. +		// Although bind is not required it will tell us which port we were +		// assigned to. +		stLclAddr.sin_family      = AF_INET; +		stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); +		stLclAddr.sin_port        = htons(0); +		llinfos << "attempting to connect on OS assigned port" << llendl; +		nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); +		if (nRet < 0) +		{ +			llwarns << "Failed to bind on an OS assigned port error: " +					<< nRet << llendl; +		} +		else +		{ +			sockaddr_in socket_info; +			socklen_t len = sizeof(sockaddr_in); +			int err = getsockname(hSocket, (sockaddr*)&socket_info, &len); +			llinfos << "Get socket returned: " << err << " length " << len << llendl; +			nPort = ntohs(socket_info.sin_port); +			llinfos << "Assigned port: " << nPort << llendl; +			 +		}  	}  	else  	{ diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp new file mode 100644 index 0000000000..9d1d3fa221 --- /dev/null +++ b/indra/llmessage/tests/llcurl_stub.cpp @@ -0,0 +1,88 @@ +/** + * @file llcurl_stub.cpp + * @brief stub class to allow unit testing + * + * $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") { } + * 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 "linden_common.h" + +LLCurl::Responder::Responder() +{ +} + +void LLCurl::Responder::completed(U32 status, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const &reason, +								  LLSD const& mContent) +{ +	if (isGoodStatus(status)) +	{ +		result(mContent); +	} +	else +	{ +		error(status, reason, mContent); +	} +} + +void LLCurl::Responder::completedHeader(unsigned, +										std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, +										LLSD const&) +{ +} + +void LLCurl::Responder::completedRaw(unsigned, +									 std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, +									 LLChannelDescriptors const&, +									 boost::shared_ptr<LLBufferArray> const&) +{ +} + +void LLCurl::Responder::error(unsigned, +							  std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, +							  LLSD const&) +{ +} + +LLCurl::Responder::~Responder () +{ +} + +void LLCurl::Responder::error(unsigned, +							  std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) +{ +} + +void LLCurl::Responder::result(LLSD const&) +{ +} + +namespace boost +{ +	void intrusive_ptr_add_ref(LLCurl::Responder* p) +	{ +		++p->mReferenceCount; +	} + +	void intrusive_ptr_release(LLCurl::Responder* p) +	{ +		if(p && 0 == --p->mReferenceCount) +		{ +			delete p; +		} +	} +}; + diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp new file mode 100644 index 0000000000..bde76db08b --- /dev/null +++ b/indra/llmessage/tests/llhttpclientadapter_test.cpp @@ -0,0 +1,169 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, 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 "llhttpclientadapter.h" + +#include "../test/lltut.h" +#include "llhttpclient.h" +#include "llcurl_stub.cpp" + +float const HTTP_REQUEST_EXPIRY_SECS = 1.0F; + +std::vector<std::string> get_urls; +std::vector<boost::intrusive_ptr<LLCurl::Responder> > get_responders; +void LLHTTPClient::get(const std::string& url, boost::intrusive_ptr<LLCurl::Responder> responder, const LLSD& headers, const F32 timeout) +{ +	get_urls.push_back(url); +	get_responders.push_back(responder); +} + +std::vector<std::string> put_urls; +std::vector<LLSD> put_body; +std::vector<boost::intrusive_ptr<LLCurl::Responder> > put_responders; + +void LLHTTPClient::put(std::string const &url, LLSD const &body, boost::intrusive_ptr<LLCurl::Responder> responder,float)  +{ +	put_urls.push_back(url); +	put_responders.push_back(responder); +	put_body.push_back(body); + +} + + +namespace tut +{ +	struct LLHTTPClientAdapterData +	{ +		LLHTTPClientAdapterData() +		{ +			get_urls.clear(); +			get_responders.clear(); +			put_urls.clear(); +			put_responders.clear(); +			put_body.clear(); +		} +	}; + +	typedef test_group<LLHTTPClientAdapterData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLHTTPClientAdapterData test"); +} + +namespace tut +{ +	// Ensure we can create the object +	template<> template<> +	void object::test<1>() +	{ +		LLHTTPClientAdapter adapter; +	} + +	// Does the get pass the appropriate arguments to the LLHTTPClient +	template<> template<> +	void object::test<2>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		adapter.get("Made up URL", responder); +		ensure_equals(get_urls.size(), 1); +		ensure_equals(get_urls[0], "Made up URL"); +	} + +	// Ensure the responder matches the one passed to get +	template<> template<> +	void object::test<3>() +	{ +		LLHTTPClientAdapter adapter; +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		adapter.get("Made up URL", responder); + +		ensure_equals(get_responders.size(), 1); +		ensure_equals(get_responders[0].get(), responder.get()); +	} +	 +	// Ensure the correct url is used in the put +	template<> template<> +	void object::test<4>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		LLSD body; +		body["TestBody"] = "Foobar"; + +		adapter.put("Made up URL", body, responder); +		ensure_equals(put_urls.size(), 1); +		ensure_equals(put_urls[0], "Made up URL"); +	} + +	// Ensure the correct responder is used by put +	template<> template<> +	void object::test<5>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		LLSD body; +		body["TestBody"] = "Foobar"; + +		adapter.put("Made up URL", body, responder); + +		ensure_equals(put_responders.size(), 1); +		ensure_equals(put_responders[0].get(), responder.get()); +	} + +	// Ensure the message body is passed through the put properly +	template<> template<> +	void object::test<6>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		LLSD body; +		body["TestBody"] = "Foobar"; + +		adapter.put("Made up URL", body, responder); + +		ensure_equals(put_body.size(), 1); +		ensure_equals(put_body[0]["TestBody"].asString(), "Foobar"); +	} +} + diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp new file mode 100644 index 0000000000..a6f5659352 --- /dev/null +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -0,0 +1,164 @@ +/** + * @file lltrustedmessageservice_test.cpp + * @brief LLTrustedMessageService unit tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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 "lltemplatemessagedispatcher.h" +#include "lltut.h" + +#include "llhttpnode.h" +#include "llhost.h" +#include "message.h" +#include "llsd.h" + +#include "llhost.cpp" // Needed for copy operator +#include "net.cpp" // Needed by LLHost. + +LLMessageSystem * gMessageSystem = NULL; + +// sensor test doubles +bool gClearRecvWasCalled = false; +void LLMessageSystem::clearReceiveState(void)  +{  +	gClearRecvWasCalled = true;  +} + +char gUdpDispatchedData[MAX_BUFFER_SIZE]; +bool gUdpDispatchWasCalled = false; +BOOL LLTemplateMessageReader::readMessage(const U8* data,class LLHost const &)  +{  +	gUdpDispatchWasCalled = true; +	strcpy(gUdpDispatchedData, reinterpret_cast<const char*>(data)); +	return  true; +} + +BOOL gValidateMessage = FALSE; +BOOL LLTemplateMessageReader::validateMessage(const U8*, S32 buffer_size, LLHost const &sender, bool trusted)  +{  +	return gValidateMessage; +} + +LLHost host; +const LLHost& LLMessageSystem::getSender() const  +{  +	return host;  +} + +const char* gBinaryTemplateData = "BINARYTEMPLATEDATA"; +void fillVector(std::vector<U8>& vector_data, const char* data) +{ +	vector_data.resize(strlen(data) + 1); +	strcpy(reinterpret_cast<char*>(&vector_data[0]), data); +} + +namespace tut +{ +		static LLTemplateMessageReader::message_template_number_map_t numberMap; + +		struct LLTemplateMessageDispatcherData +		{ +			LLTemplateMessageDispatcherData() +			{ +				mMessageName = "MessageName"; +				gUdpDispatchWasCalled = false; +				gClearRecvWasCalled = false; +				gValidateMessage = FALSE; +				mMessage["body"]["binary-template-data"] = std::vector<U8>(); +			} + +			LLSD mMessage; +			LLHTTPNode::ResponsePtr mResponsePtr; +			std::string mMessageName; +		}; + +	typedef test_group<LLTemplateMessageDispatcherData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLTemplateMessageDispatcher test"); +} + +namespace tut +{ +	// does an empty message stop processing? +	template<> template<> +	void object::test<1>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure(! gUdpDispatchWasCalled); +		ensure(! gClearRecvWasCalled); +	} + +	// does the disaptch invoke the udp send method? +	template<> template<> +	void object::test<2>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		gValidateMessage = TRUE; +		std::vector<U8> vector_data; +		fillVector(vector_data, gBinaryTemplateData);		 +		mMessage["body"]["binary-template-data"] = vector_data; +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure("udp dispatch was called", gUdpDispatchWasCalled); +	} + +	// what if the message wasn't valid? We would hope the message gets cleared! +	template<> template<> +	void object::test<3>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		std::vector<U8> vector_data; +		fillVector(vector_data, gBinaryTemplateData); +		mMessage["body"]["binary-template-data"] = vector_data; +		gValidateMessage = FALSE; +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure("clear received message was called", gClearRecvWasCalled); +	} + +	// is the binary data passed through correctly? +	template<> template<> +	void object::test<4>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		gValidateMessage = TRUE; +		std::vector<U8> vector_data; +		fillVector(vector_data, gBinaryTemplateData); +		mMessage["body"]["binary-template-data"] = vector_data; +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure("data couriered correctly", strcmp(gBinaryTemplateData, gUdpDispatchedData) == 0); +	} +} + diff --git a/indra/llmessage/tests/lltesthttpclientadapter.cpp b/indra/llmessage/tests/lltesthttpclientadapter.cpp new file mode 100644 index 0000000000..1140458918 --- /dev/null +++ b/indra/llmessage/tests/lltesthttpclientadapter.cpp @@ -0,0 +1,56 @@ +/**  + * @file  + * @brief  + * + * $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 "lltesthttpclientadapter.h" + +LLTestHTTPClientAdapter::LLTestHTTPClientAdapter() +{ +} + +LLTestHTTPClientAdapter::~LLTestHTTPClientAdapter() +{ +} + +void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder) +{ +	mGetUrl.push_back(url); +	mGetResponder.push_back(responder); +} + +void LLTestHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) +{ +	mPutUrl.push_back(url); +	mPutBody.push_back(body); +	mPutResponder.push_back(responder); +} + +U32 LLTestHTTPClientAdapter::putCalls() const  +{  +	return mPutUrl.size();  +} + +void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) +{ +	mGetUrl.push_back(url); +	mGetHeaders.push_back(headers); +	mGetResponder.push_back(responder); +} + + diff --git a/indra/llmessage/tests/lltesthttpclientadapter.h b/indra/llmessage/tests/lltesthttpclientadapter.h new file mode 100644 index 0000000000..d032503685 --- /dev/null +++ b/indra/llmessage/tests/lltesthttpclientadapter.h @@ -0,0 +1,52 @@ +/**  + * @file  + * @brief  + * + * $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$ + */ + +/* Macro Definitions */ +#ifndef LL_LLTESTHTTPCLIENTADAPTER_H +#define LL_LLTESTHTTPCLIENTADAPTER_H + + +#include "linden_common.h" +#include "llhttpclientinterface.h" + +class LLTestHTTPClientAdapter : public LLHTTPClientInterface +{ +public: +	LLTestHTTPClientAdapter(); +	virtual ~LLTestHTTPClientAdapter(); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers); + +	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder); +	U32 putCalls() const; + +	std::vector<LLSD> mPutBody; +	std::vector<LLSD> mGetHeaders; +	std::vector<std::string> mPutUrl; +	std::vector<std::string> mGetUrl; +	std::vector<LLCurl::ResponderPtr> mPutResponder; +	std::vector<LLCurl::ResponderPtr> mGetResponder; +}; + + + +#endif //LL_LLSIMULATORPRESENCESENDER_H + diff --git a/indra/llmessage/tests/lltestmessagesender.cpp b/indra/llmessage/tests/lltestmessagesender.cpp new file mode 100644 index 0000000000..a37aa4c566 --- /dev/null +++ b/indra/llmessage/tests/lltestmessagesender.cpp @@ -0,0 +1,33 @@ +/**  + * @file  + * @brief  + * + * $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 "lltestmessagesender.h" + +LLTestMessageSender::~LLTestMessageSender() +{ +} + + +S32 LLTestMessageSender::sendMessage(const LLHost& host, LLStoredMessagePtr message) +{ +	mSendHosts.push_back(host); +	mSendMessages.push_back(message); +	return 0; +} diff --git a/indra/llmessage/tests/lltestmessagesender.h b/indra/llmessage/tests/lltestmessagesender.h new file mode 100644 index 0000000000..83c0eff4d3 --- /dev/null +++ b/indra/llmessage/tests/lltestmessagesender.h @@ -0,0 +1,46 @@ +/**  + * @file  + * @brief  + * + * $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$ + */ + +/* Macro Definitions */ +#ifndef LL_LLTESTMESSAGESENDER_H +#define LL_LLTESTMESSAGESENDER_H + + +#include "linden_common.h" +#include "llmessagesenderinterface.h" +#include <vector> + + + +class LLTestMessageSender : public LLMessageSenderInterface +{ +public: +	virtual ~LLTestMessageSender(); +	virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message); + +	std::vector<LLHost> mSendHosts; +	std::vector<LLStoredMessagePtr> mSendMessages; +}; + + + +#endif //LL_LLTESTMESSAGESENDER_H + diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp new file mode 100644 index 0000000000..44595391df --- /dev/null +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -0,0 +1,145 @@ +/** + * @file lltrustedmessageservice_test.cpp + * @brief LLTrustedMessageService unit tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, 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 "lltrustedmessageservice.h" +#include "../test/lltut.h" + +#include "llhost.cpp" // LLHost is a value type for test purposes. +#include "net.cpp" // Needed by LLHost. + +#include "message.h" +#include "llmessageconfig.h" + +LLMessageSystem* gMessageSystem = NULL; + +LLMessageConfig::SenderTrust +LLMessageConfig::getSenderTrustedness(const std::string& msg_name) +{ +	return LLMessageConfig::NOT_SET; +} + +void LLMessageSystem::receivedMessageFromTrustedSender() +{ +} + +bool LLMessageSystem::isTrustedSender(const LLHost& host) const +{ +	return false; +} + +bool LLMessageSystem::isTrustedMessage(const std::string& name) const +{ +	return false; +} + +bool messageDispatched = false; +bool messageDispatchedAsBinary = false; +LLSD lastLLSD; +std::string lastMessageName; + +void LLMessageSystem::dispatch(const std::string& msg_name, +							   const LLSD& message, +							   LLHTTPNode::ResponsePtr responsep) +{ +	messageDispatched = true; +	lastLLSD = message; +	lastMessageName = msg_name; +} + +void LLMessageSystem::dispatchTemplate(const std::string& msg_name, +						 const LLSD& message, +						 LLHTTPNode::ResponsePtr responsep) +{ +	lastLLSD = message; +	lastMessageName = msg_name; +	messageDispatchedAsBinary = true; +} + +namespace tut +{ +	    struct LLTrustedMessageServiceData +		{ +			LLTrustedMessageServiceData() +			{ +				LLSD emptyLLSD; +				lastLLSD = emptyLLSD; +				lastMessageName = "uninitialised message name"; +				messageDispatched = false; +				messageDispatchedAsBinary = false; +			} +		}; + +	typedef test_group<LLTrustedMessageServiceData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLTrustedMessageServiceData test"); +} + +namespace tut +{ +	// characterisation tests + +	// 1) test that messages get forwarded with names etc. as current behaviour (something like LLMessageSystem::dispatch(name, data...) + +	// test llsd messages are sent as normal using LLMessageSystem::dispatch() (eventually) +	template<> template<> +	void object::test<1>() +	{ +		LLHTTPNode::ResponsePtr response; +		LLSD input; +		LLSD context; +		LLTrustedMessageService adapter; +		adapter.post(response, context, input); +		// test original ting got called wit nowt, ya get me blood? +		ensure_equals(messageDispatched, true); +		ensure(lastLLSD.has("body")); +	} + +	// test that llsd wrapped binary-template-data messages are  +	// sent via LLMessageSystem::binaryDispatch() or similar +	template<> template<> +	void object::test<2>() +	{ +		LLHTTPNode::ResponsePtr response; +		LLSD input; +		input["binary-template-data"] = "10001010110"; //make me a message here. +		LLSD context; +		LLTrustedMessageService adapter; + +		adapter.post(response, context, input); +		ensure("check template-binary-data message was dispatched as binary", messageDispatchedAsBinary); +		ensure_equals(lastLLSD["body"]["binary-template-data"].asString(),  "10001010110"); +		// test somit got called with "10001010110" (something like LLMessageSystem::dispatchTemplate(blah)) +	} +} diff --git a/indra/llprimitive/llprimlinkinfo.h b/indra/llprimitive/llprimlinkinfo.h index 7f1840303b..946fa75bfa 100644 --- a/indra/llprimitive/llprimlinkinfo.h +++ b/indra/llprimitive/llprimlinkinfo.h @@ -50,7 +50,7 @@  const F32 MAX_OBJECT_SPAN = 54.f;		// max distance from outside edge of an object to the farthest edge  const F32 OBJECT_SPAN_BONUS = 2.f;		// infinitesimally small prims can always link up to this distance -const S32 MAX_PRIMS_PER_OBJECT = 255; +const S32 MAX_PRIMS_PER_OBJECT = 256;  template < typename DATA_TYPE > diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 85b64a8788..cfd333f618 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,6 +1,7 @@  /* Localized versions of Info.plist keys */  CFBundleName = "Second Life"; +  CFBundleShortVersionString = "Second Life version 1.23.0.0";  CFBundleGetInfoString = "Second Life version 1.23.0.0, Copyright 2004-2008 Linden Research, Inc."; diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 0000cc237b..b9e0e3dbdd 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -60,6 +60,7 @@ set(test_SOURCE_FILES      llstreamtools_tut.cpp      llstring_tut.cpp      lltemplatemessagebuilder_tut.cpp +    lltimestampcache_tut.cpp      lltiming_tut.cpp      lltranscode_tut.cpp      lltut.cpp diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp index 5146bb6b97..4a128a8984 100644 --- a/indra/test/llblowfish_tut.cpp +++ b/indra/test/llblowfish_tut.cpp @@ -94,7 +94,6 @@ namespace tut  	template<> template<>  	void blowfish_object::test<1>()  	{ -#if LL_LINUX  		LLUUID blank;  		LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -107,15 +106,11 @@ namespace tut  		dst_len = cipher.requiredEncryptionSpace(8);  		ensure("encryption space 8",  				(dst_len == 16)  ); -#else -		skip("Blowfish only supported on Linux."); -#endif // LL_LINUX  	}  	template<> template<>  	void blowfish_object::test<2>()  	{ -#if LL_LINUX  		LLUUID blank;  		LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -129,15 +124,11 @@ namespace tut  		result.resize(count);  		ensure("encrypt null key", matchFile("blowfish.1.bin", result)); -#else -		skip("Blowfish only supported on Linux."); -#endif // LL_LINUX  	}  	template<> template<>  	void blowfish_object::test<3>()  	{ -#if LL_LINUX          // same as base64 test id  		LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e");  		LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES); @@ -152,8 +143,5 @@ namespace tut  		result.resize(count);  		ensure("encrypt real key", matchFile("blowfish.2.bin", result)); -#else -        skip("Blowfish only supported on Linux."); -#endif // LL_LINUX  	}  } diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp index 60a50cf75f..27ab127772 100755 --- a/indra/test/llsdmessagebuilder_tut.cpp +++ b/indra/test/llsdmessagebuilder_tut.cpp @@ -35,6 +35,7 @@  #include "linden_common.h"  #include "lltut.h" +#include "llmessagetemplate.h"  #include "llsdmessagebuilder.h"  #include "llsdmessagereader.h"  #include "llsdtraits.h" @@ -43,10 +44,24 @@  #include "v3dmath.h"  #include "v3math.h"  #include "v4math.h" +#include "llsdutil_math.cpp" +#include "lltemplatemessagebuilder.h"  namespace tut  {	 +	static LLTemplateMessageBuilder::message_template_name_map_t templateNameMap; + +    LLMsgData* messageData = NULL; +    LLMsgBlkData* messageBlockData = NULL; +  	struct LLSDMessageBuilderTestData { + +		LLSDMessageBuilderTestData() +		{ +			messageData = new LLMsgData("testMessage"); +			messageBlockData = new LLMsgBlkData("testBlock", 0); +		} +  		static LLSDMessageBuilder defaultBuilder()  		{  			LLSDMessageBuilder builder; @@ -61,6 +76,43 @@ namespace tut  			reader.setMessage("name", builder.getMessage());  			return reader;  		} + +		static void addValue(LLMsgBlkData* mbd, char* name, void* v, EMsgVariableType type, int size, int data_size = -1) +		{ +			LLMsgVarData tmp(name, type); +			tmp.addData(v, size, type, data_size); +			mbd->mMemberVarData[name] = tmp; +		} + + +		static LLMessageBlock* defaultTemplateBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) +		{ +			return createTemplateBlock(_PREHASH_Test0, type, size, block); +		} + +		static LLMessageBlock* createTemplateBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) +		{ +			LLMessageBlock* result = new LLMessageBlock(name, block); +			if(type != MVT_NULL) +			{ +				result->addVariable(_PREHASH_Test0, type, size); +			} +			return result; +		} + +		static LLTemplateMessageBuilder* defaultTemplateBuilder(LLMessageTemplate& messageTemplate, char* name = _PREHASH_Test0) +		{ +			templateNameMap[_PREHASH_TestMessage] = &messageTemplate; +			LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(templateNameMap); +			builder->newMessage(_PREHASH_TestMessage); +			builder->nextBlock(name); +			return builder; +		} + +		static LLMessageTemplate defaultTemplate() +		{ +			return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH); +		}  	};  	typedef test_group<LLSDMessageBuilderTestData>	LLSDMessageBuilderTestGroup; @@ -280,5 +332,509 @@ namespace tut  	  outValue = buffer;  	  ensure_equals("Ensure String", inValue, outValue);  	} + +	template<> template<> +	void LLSDMessageBuilderTestObject::test<19>() +	{ +	  LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); +	  LLMsgData* md = new LLMsgData("testMessage"); +	  md->addBlock(mbd); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*md); +	  LLSD output = builder.getMessage(); + +	  ensure("Ensure message block created when copied from legacy message to llsd", output["testBlock"].isDefined()); +	} + +	// MVT_FIXED +	template<> template<> +	void LLSDMessageBuilderTestObject::test<20>() +	{ +	  char binData[] = "abcdefghijklmnop"; + +	  addValue(messageBlockData, "testBinData", &binData, MVT_FIXED, sizeof(binData)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure fixed binary data works in a message copied from legacy to llsd", +		  &v[0], sizeof(binData), binData, sizeof(binData)); +	} + +	// MVT_VARIABLE data_size 1 (U8's) +	template<> template<> +	void LLSDMessageBuilderTestObject::test<21>() +	{ +	 /* U8 binData[] = "abcdefghijklmnop"; + +	  addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData), 1); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure MVT_VARIABLE U8 binary data works in a message copied from legacy to llsd", +		  &v[0], sizeof(binData), binData, sizeof(binData));*/ +	} + +	// MVT_VARIABLE data_size 2 (U16's) +	template<> template<> +	void LLSDMessageBuilderTestObject::test<22>() +	{ +	  U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts + +	  addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure MVT_VARIABLE U16 binary data works in a message copied from legacy to llsd", +		  &v[0], sizeof(binData) >> 1, binData, sizeof(binData) >> 1); +	} + +	// MVT_VARIABLE data_size 4 (S32's) +	template<> template<> +	void LLSDMessageBuilderTestObject::test<23>() +	{ +	  U32 binData[] = {9,8,7,6,5,4,3,2,1}; + +	  addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure MVT_VARIABLE S32 binary data works in a message copied from legacy to llsd", +		  &v[0], sizeof(binData) >> 2, binData, sizeof(binData) >> 2); +	} + +	// MVT_U8 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<24>() +	{ +	  U8 data = 0xa5; + +	  addValue(messageBlockData, "testBinData", &data, MVT_U8, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_U8 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), data); +	} + +	// MVT_U16 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<25>() +	{ +	  U16 data = 0xa55a; + +	  addValue(messageBlockData, "testBinData", &data, MVT_U16, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_U16 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), data); +	} + +	// MVT_U32 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<26>() +	{ +	  U32 data = 0xa55a7117; + +	  addValue(messageBlockData, "testBinData", &data, MVT_U32, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_U32 data works in a message copied from legacy to llsd", +		  ll_U32_from_sd(output["testBlock"][0]["testBinData"]), data); +	} + +	// MVT_U64 - crush into an s32: LLSD does not support 64 bit values +	template<> template<> +	void LLSDMessageBuilderTestObject::test<27>() +	{ +	  U64 data = U64L(0xa55a711711223344); +	  addValue(messageBlockData, "testBinData", &data, MVT_U64, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_U64 data works in a message copied from legacy to llsd", +		  ll_U64_from_sd(output["testBlock"][0]["testBinData"]), data); +	} + +	// MVT_S8 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<28>() +	{ +	  S8 data = -31; + +	  addValue(messageBlockData, "testBinData", &data, MVT_S8, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_S8 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), data); +	} + +	// MVT_S16 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<29>() +	{ +	  S16 data = -31; + +	  addValue(messageBlockData, "testBinData", &data, MVT_S16, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_S16 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), data); +	} + +	// MVT_S32 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<30>() +	{ +	  S32 data = -3100; + +	  addValue(messageBlockData, "testBinData", &data, MVT_S32, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_S32 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), data); +	} + +	// MVT_S64 - crush into an s32: LLSD does not support 64 bit values +	template<> template<> +	void LLSDMessageBuilderTestObject::test<31>() +	{ +	  S64 data = -31003100; + +	  addValue(messageBlockData, "testBinData", &data, MVT_S64, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_S64 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), (S32)data); +	} + +	// MVT_F32 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<32>() +	{ +	  F32 data = 1234.1234f; + +	  addValue(messageBlockData, "testBinData", &data, MVT_F32, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_F32 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asReal(), data); +	} + +	// MVT_F64 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<33>() +	{ +	  F64 data = 1234.1234; + +	  addValue(messageBlockData, "testBinData", &data, MVT_F64, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_F64 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asReal(), data); +	} + +	// MVT_LLVector3 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<34>() +	{ +	  LLVector3 data(1,2,3); + +	  addValue(messageBlockData, "testBinData", &data, MVT_LLVector3, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd", +		  ll_vector3_from_sd(output["testBlock"][0]["testBinData"]), data); +	} + +	// MVT_LLVector3d +	template<> template<> +	void LLSDMessageBuilderTestObject::test<35>() +	{ +	  LLVector3d data(1,2,3); + +	  addValue(messageBlockData, "testBinData", &data, MVT_LLVector3d, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd", +		  ll_vector3d_from_sd(output["testBlock"][0]["testBinData"]), data); +	} + +	// MVT_LLVector4 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<36>() +	{ +	  LLVector4 data(1,2,3,4); +	  LLSD v = ll_sd_from_vector4(data); + +	  addValue(messageBlockData, "testBinData", &data, MVT_LLVector4, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_LLVector4 data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"], v); +	} + +	// MVT_LLQuaternion +	template<> template<> +	void LLSDMessageBuilderTestObject::test<37>() +	{ +	  LLQuaternion data(1,2,3,0); + +	  //we send a quaternion packed into a vec3 (w is infered) - so sizeof(vec) == 12 bytes not 16. +	  LLVector3 vec = data.packToVector3(); + +	  addValue(messageBlockData, "testBinData", &vec, MVT_LLQuaternion, sizeof(vec)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_LLQuaternion data works in a message copied from legacy to llsd", +		  ll_quaternion_from_sd(output["testBlock"][0]["testBinData"]), data); +	} + +	// MVT_LLUUID +	template<> template<> +	void LLSDMessageBuilderTestObject::test<38>() +	{ +	  LLUUID data("01234567-0123-0123-0123-234567abcdef"); + +	  addValue(messageBlockData, "testBinData", &data, MVT_LLUUID, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); +	  +	  std::string v = output["testBlock"][0]["testBinData"].asUUID().asString(); + +	  ensure_equals("Ensure MVT_LLUUID data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asUUID(), data); +	} + +	// MVT_BOOL +	template<> template<> +	void LLSDMessageBuilderTestObject::test<39>() +	{ +	  BOOL valueTrue = true; +	  BOOL valueFalse = false; + +	  LLMsgData* md = new LLMsgData("testMessage"); +	  LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); +	  addValue(mbd, "testBoolFalse", &valueFalse, MVT_BOOL, sizeof(BOOL)); +	  addValue(mbd, "testBoolTrue", &valueTrue, MVT_BOOL, sizeof(BOOL)); +	  md->addBlock(mbd); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*md); +	  LLSD output = builder.getMessage(); + +	  ensure("Ensure bools work in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBoolTrue"].asBoolean() && !output["testBlock"][0]["testBoolFalse"].asBoolean()); +	} + +	// MVT_IP_ADDR +	template<> template<> +	void LLSDMessageBuilderTestObject::test<40>() +	{ +	  U32 data(0xff887766); +	  LLSD v = ll_sd_from_ipaddr(data); + +	  addValue(messageBlockData, "testBinData", &data, MVT_IP_ADDR, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_IP_ADDR data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"], v); +	} + +	// MVT_IP_PORT +	template<> template<> +	void LLSDMessageBuilderTestObject::test<41>() +	{ +	  U16 data = 0xff88; + +	  addValue(messageBlockData, "testBinData", &data, MVT_IP_PORT, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  ensure_equals("Ensure MVT_IP_PORT data works in a message copied from legacy to llsd", +		  output["testBlock"][0]["testBinData"].asInteger(), data); +	} + +	// MVT_U16Vec3 +	template<> template<> +	void LLSDMessageBuilderTestObject::test<42>() +	{ +	  U16 data[3] = {0,1,2}; + +	  addValue(messageBlockData, "testBinData", &data, MVT_U16Vec3, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_U16Vec3 data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure MVT_U16Vec3 data works in a message copied from legacy to llsd", +		  (U16*)&v[0], 6, data, 6); +	} + +	// MVT_U16Quat +	template<> template<> +	void LLSDMessageBuilderTestObject::test<43>() +	{ +	  U16 data[4] = {0,1,2,4}; + +	  addValue(messageBlockData, "testBinData", &data, MVT_U16Quat, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_U16Quat data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure MVT_U16Quat data works in a message copied from legacy to llsd", +		  (U16*)&v[0], 8, data, 8); +	} + +	// MVT_S16Array +	template<> template<> +	void LLSDMessageBuilderTestObject::test<44>() +	{ +	  S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18}; + +	  addValue(messageBlockData, "testBinData", &data, MVT_S16Array, sizeof(data)); +	  messageData->addBlock(messageBlockData); +	  LLSDMessageBuilder builder = defaultBuilder(); +	   +	  builder.copyFromMessageData(*messageData); +	  LLSD output = builder.getMessage(); + +	  std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); +	  ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + +	  ensure_memory_matches("Ensure MVT_S16Array data works in a message copied from legacy to llsd", +		  (U16*)&v[0], 19, data, 19); +	} + +	template<> template<> +	void LLSDMessageBuilderTestObject::test<45>() +	{ +		LLMessageTemplate messageTemplate = defaultTemplate(); +		messageTemplate.addBlock(defaultTemplateBlock(MVT_U8, 1)); +		U8 inValue = 2; +		LLTemplateMessageBuilder* template_builder = defaultTemplateBuilder(messageTemplate); +		template_builder->addU8(_PREHASH_Test0, inValue); + +		LLSDMessageBuilder builder; +		builder.copyFromMessageData(*template_builder->getCurrentMessage()); +		LLSD output = builder.getMessage(); +		 +		ensure_equals(output["Test0"][0]["Test0"].asInteger(), 2); + +	} + +	template<> template<> +	void LLSDMessageBuilderTestObject::test<46>() +	{ +		LLMessageTemplate messageTemplate = defaultTemplate(); +		messageTemplate.addBlock(defaultTemplateBlock(MVT_VARIABLE, 1)); +		std::string inValue = "testing"; +		LLTemplateMessageBuilder* builder = defaultTemplateBuilder(messageTemplate); +		builder->addString(_PREHASH_Test0, inValue.c_str()); + +		LLSDMessageBuilder sd_builder; +		sd_builder.copyFromMessageData(*builder->getCurrentMessage()); +		LLSD output = sd_builder.getMessage(); +		 +		ensure_equals(output["Test0"][0]["Test0"].asString(), std::string("testing")); +	} +  } diff --git a/indra/test/lltimestampcache_tut.cpp b/indra/test/lltimestampcache_tut.cpp new file mode 100644 index 0000000000..9e0de0fe60 --- /dev/null +++ b/indra/test/lltimestampcache_tut.cpp @@ -0,0 +1,129 @@ +/** + * @file lltimestampcache_tut.cpp + * @author James Tess + * @date 2008-12-03 + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2008, 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.hpp> + +#include "linden_common.h" +#include "../mapserver/lltimestampcache.h" +#include "lltut.h" + + +namespace tut +{ +	struct LLTimestampCacheTestData +	{ +	}; + +	typedef test_group<LLTimestampCacheTestData> LLTimestampCacheTestGroup; +	typedef LLTimestampCacheTestGroup::object LLTimestampCacheTestObject; + +	LLTimestampCacheTestGroup timestampCacheTestGroup("LLTimestampCache"); + +	// Most common usage +	template<> template<> +		void LLTimestampCacheTestObject::test<1>() +		{ +			LLTimestampCache<std::string, std::string> cache; +			// put in some data +			cache.insert("key1", "val1", 1); +			cache.insert("key2", "val2", 2); +			cache.insert("key3", "val3", 3); +			ensure_equals("size is 3", cache.size(), 3); +			// check some items +			ensure("has key1", cache.has("key1")); +			ensure("no invalid key", !cache.has("invalid key")); +			// get some items +			ensure_equals("get key1", cache.get("key1", 4), "val1"); +			ensure_equals("get invalid key",  +					cache.get("invalid key", 4), std::string() ); +			// timestamps +			ensure_equals("key1 timestamp updated", cache.getTimestamp("key1"), 4); +			ensure_equals("invalid key timestamp",  +					cache.getTimestamp("invalid key"), 0); +		} + +	// New empty cache shouldn't have any entries +	template<> template<> +		void LLTimestampCacheTestObject::test<2>() +		{ +			LLTimestampCache<std::string, std::string> cache; +			ensure_equals("starts empty",   cache.size(), 0); +			ensure_equals("has nothing",    cache.has("foo"), false); +			ensure_equals("gets nothing",   cache.get("foo", 0), std::string() ); +			U32 max_time = 0xFFFFFFFF; +			ensure_equals("erases nothing", cache.eraseBefore(max_time), 0); +		} + +	// Non empty cache +	template<> template<> +		void LLTimestampCacheTestObject::test<3>() +		{ +			LLTimestampCache<std::string, std::string> cache; +			cache.insert("foo", "bar", 123); +			ensure_equals("size one", cache.size(), 1); +			ensure_equals("has it", cache.has("foo"), true); +			ensure_equals("timestamp correct", cache.getTimestamp("foo"), 123); +			std::string value = cache.get("foo", 456); +			ensure_equals("get value", value, "bar"); +			ensure_equals("timestamp updated", cache.getTimestamp("foo"), 456); +			ensure_equals("erase nothing", cache.eraseBefore(0), 0); +			ensure_equals("erase one", cache.eraseBefore(789), 1); +			ensure_equals("empty after erase", cache.size(), 0); +		} + +	// Recache of item should update timestamp +	template<> template<> +		void LLTimestampCacheTestObject::test<4>() +		{ +			LLTimestampCache<std::string, std::string> cache; +			cache.insert("foo", "bar", 123); +			cache.insert("foo", "bar", 456); +			ensure_equals("duplicate suppressed", cache.size(), 1); +			ensure_equals("timestamp replaced", cache.getTimestamp("foo"), 456); +		} + +	// Erasing some items +	template<> template<> +		void LLTimestampCacheTestObject::test<5>() +		{ +			LLTimestampCache<std::string, std::string> cache; +			cache.insert("key1", "val1", 1); +			cache.insert("key2", "val2", 2); +			cache.insert("key3", "val3", 3); +			cache.insert("key4", "val4", 4); +			size_t erased = cache.eraseBefore(3); +			ensure_equals("erase range", erased, 2); +			ensure_equals("cache post erase", cache.size(), 2); +			ensure_equals("has key3", cache.has("key3"), true); +			ensure_equals("not has key2", cache.has("key2"), false); +		} +} diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp index 64861c3115..201e174f9c 100644 --- a/indra/test/lltut.cpp +++ b/indra/test/lltut.cpp @@ -33,10 +33,13 @@   */  #include "linden_common.h" +  #include "lltut.h" +#include "lldate.h"  #include "llformat.h"  #include "llsd.h" +#include "lluri.h"  namespace tut  { @@ -74,7 +77,7 @@ namespace tut  	void ensure_equals(const char* m, const LLSD& actual,  		const LLSD& expected)  	{ -		const std::string& msg = m; +		const std::string& msg = m ? m : "";  		ensure_equals(msg + " type", actual.type(), expected.type());  		switch (actual.type()) @@ -196,3 +199,4 @@ namespace tut  		}  	}  } + diff --git a/indra/test/lltut.h b/indra/test/lltut.h index 51e2ee2709..6d50ebad33 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -35,13 +35,13 @@  #ifndef LL_LLTUT_H  #define LL_LLTUT_H -#include <tut/tut.hpp> - -#include "lldate.h" -#include "lluri.h"  #include "llmath.h" +#include <tut/tut.hpp> + +class LLDate;  class LLSD; +class LLURI;  namespace tut  { diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 566459ee90..ba81c6e49e 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -54,9 +54,10 @@  #	include "ctype_workaround.h"  #endif -  namespace tut  { +	std::string sSourceDir; +      test_runner_singleton runner;  } @@ -184,6 +185,7 @@ static const apr_getopt_option_t TEST_CL_OPTIONS[] =  	{"verbose", 'v', 0, "Verbose output."},  	{"group", 'g', 1, "Run test group specified by option argument."},  	{"output", 'o', 1, "Write output to the named file."}, +	{"sourcedir", 's', 1, "Project source file directory from CMake."},  	{"touch", 't', 1, "Touch the given file if all tests succeed"},  	{"wait", 'w', 0, "Wait for input before exit."},  	{"debug", 'd', 0, "Emit full debug logs."}, @@ -302,6 +304,11 @@ int main(int argc, char **argv)  			output = new std::ofstream;  			output->open(opt_arg);  			break; +		case 's':	// --sourcedir +			tut::sSourceDir = opt_arg; +			// For convenience, so you can use tut::sSourceDir + "myfile" +			tut::sSourceDir += '/'; +			break;  		case 't':  			touch = opt_arg;  			break; diff --git a/indra/test/test.h b/indra/test/test.h new file mode 100644 index 0000000000..16ec4effcf --- /dev/null +++ b/indra/test/test.h @@ -0,0 +1,49 @@ +/**  + * @file test.h + * @author James + * @date 2009-01-12 + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, 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$ + */ +#ifndef TEST_H +#define TEST_H + +#include <string> + +namespace tut +{ +	// Source code directory from CMake, used for loading test data and +	// configuration.  For example: +	// +	// loadMyConfig( sSourceDir + "config.dat" ); +	// +	// Use sparingly, as hitting the file system slows down test execution +	// and hence every compile. JC +	extern std::string sSourceDir; +} + +#endif  | 
