diff options
| author | Glenn Glazer <coyot@lindenlab.com> | 2016-04-07 12:10:13 -0700 | 
|---|---|---|
| committer | Glenn Glazer <coyot@lindenlab.com> | 2016-04-07 12:10:13 -0700 | 
| commit | 369cefd5b3f2f52ae0dd203fcd45a4618f74b0f3 (patch) | |
| tree | 941d27a32099abaf71bae8a2865002e2b25a3512 /indra/viewer_components | |
| parent | 0494a502aafac73800352dc26c4eb3a27b02a8ce (diff) | |
| parent | 18928ea6c6f2830a0d45ec412c915eceff1b76b0 (diff) | |
pull from viewer-release
Diffstat (limited to 'indra/viewer_components')
| -rwxr-xr-x | indra/viewer_components/login/CMakeLists.txt | 8 | ||||
| -rwxr-xr-x | indra/viewer_components/login/lllogin.cpp | 251 | ||||
| -rwxr-xr-x | indra/viewer_components/login/tests/lllogin_test.cpp | 191 | ||||
| -rwxr-xr-x | indra/viewer_components/updater/CMakeLists.txt | 28 | ||||
| -rwxr-xr-x | indra/viewer_components/updater/llupdatechecker.cpp | 89 | ||||
| -rwxr-xr-x | indra/viewer_components/updater/llupdatechecker.h | 121 | ||||
| -rwxr-xr-x | indra/viewer_components/updater/llupdatedownloader.cpp | 77 | 
7 files changed, 263 insertions, 502 deletions
| diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index c152f7c0a6..3bedeb7292 100755 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -10,6 +10,8 @@ include(LLCommon)  include(LLMath)  include(LLXML)  include(Boost) +include(LLCoreHttp) +include(LLMessage)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} @@ -42,12 +44,14 @@ add_library(lllogin              )  target_link_libraries(lllogin +    ${LLMESSAGE_LIBRARIES} +    ${LLCOREHTTP_LIBRARIES}      ${LLCOMMON_LIBRARIES}      ${LLMATH_LIBRARIES}      ${LLXML_LIBRARIES} -    ${BOOST_CONTEXT_LIBRARY}      ${BOOST_THREAD_LIBRARY}      ${BOOST_COROUTINE_LIBRARY} +    ${BOOST_CONTEXT_LIBRARY}      ${BOOST_SYSTEM_LIBRARY}      ) @@ -58,7 +62,7 @@ if(LL_TESTS)    set_source_files_properties(      lllogin.cpp      PROPERTIES -    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_COROUTINE_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}" +    LL_TEST_ADDITIONAL_LIBRARIES "${LLMESSAGE_LIBRARIES};${LLCOREHTTP_LIBRARIES};${LLCOMMON_LIBRARIES};${BOOST_COROUTINE_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}"      )    LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}") diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index b8408a6fb4..53d4acc9e0 100755 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -107,9 +107,8 @@ private:      }      // In a coroutine's top-level function args, do NOT NOT NOT accept -    // references (const or otherwise) to anything but the self argument! Pass -    // by value only! -    void login_(LLCoros::self& self, std::string uri, LLSD credentials); +    // references (const or otherwise) to anything! Pass by value only! +    void loginCoro(std::string uri, LLSD credentials);      LLEventStream mPump;  	LLSD mAuthResponse, mValidAuthResponse; @@ -123,11 +122,11 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)      // its first wait; at that point, return here.      std::string coroname =           LLCoros::instance().launch("LLLogin::Impl::login_", -                                   boost::bind(&Impl::login_, this, _1, uri, login_params)); +                                   boost::bind(&Impl::loginCoro, this, uri, login_params));      LL_DEBUGS("LLLogin") << " connected with  uri '" << uri << "', login_params " << login_params << LL_ENDL;	  } -void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_params) +void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)  {  	try  	{ @@ -137,50 +136,13 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para  	//{  	//	printable_params["params"]["passwd"] = "*******";  	//} -	LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self) +	LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName()                          << " with uri '" << uri << "', parameters " << printable_params << LL_ENDL;  	// Arriving in SRVRequest state      LLEventStream replyPump("SRVreply", true);      // Should be an array of one or more uri strings. -    LLSD rewrittenURIs; -    { -		LLEventTimeout filter(replyPump); -		sendProgressEvent("offline", "srvrequest"); - -      // Request SRV record. -		LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL; - -      // *NOTE:Mani - Completely arbitrary default timeout value for SRV request. -		F32 seconds_to_timeout = 5.0f; -		if(login_params.has("cfg_srv_timeout")) -		{ -			seconds_to_timeout = login_params["cfg_srv_timeout"].asReal(); -		} - -		// If the SRV request times out (e.g. EXT-3934), simulate response: an -		// array containing our original URI. -		LLSD fakeResponse(LLSD::emptyArray()); -		fakeResponse.append(uri); -		filter.eventAfter(seconds_to_timeout, fakeResponse); - -		std::string srv_pump_name = "LLAres"; -		if(login_params.has("cfg_srv_pump")) -		{ -			srv_pump_name = login_params["cfg_srv_pump"].asString(); -		} - -		// Make request -		LLSD request; -		request["op"] = "rewriteURI"; -		request["uri"] = uri; -		request["reply"] = replyPump.getName(); -		rewrittenURIs = postAndWait(self, request, srv_pump_name, filter); -		// EXP-772: If rewrittenURIs fail, try original URI as a fallback. -		rewrittenURIs.append(uri); -    } // we no longer need the filter -      LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));      // EXT-4193: use a DIFFERENT reply pump than for the SRV request. We used      // to share them -- but the EXT-3934 fix made it possible for an abandoned @@ -191,107 +153,103 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para      // Because of possible redirect responses, we may make more than one      // attempt per rewrittenURIs entry.      LLSD::Integer attempts = 0; -    for (LLSD::array_const_iterator urit(rewrittenURIs.beginArray()), -             urend(rewrittenURIs.endArray()); -         urit != urend; ++urit) + +    LLSD request(login_params); +    request["reply"] = loginReplyPump.getName(); +    request["uri"] = uri; +    std::string status; + +    // Loop back to here if login attempt redirects to a different +    // request["uri"] +    for (;;)      { -        LLSD request(login_params); -        request["reply"] = loginReplyPump.getName(); -        request["uri"] = *urit; -        std::string status; - -        // Loop back to here if login attempt redirects to a different -        // request["uri"] -        for (;;) +        ++attempts; +        LLSD progress_data; +        progress_data["attempt"] = attempts; +        progress_data["request"] = request; +		if(progress_data["request"].has("params") +			&& progress_data["request"]["params"].has("passwd")) +		{ +			progress_data["request"]["params"]["passwd"] = "*******"; +		} +        sendProgressEvent("offline", "authenticating", progress_data); + +        // We expect zero or more "Downloading" status events, followed by +        // exactly one event with some other status. Use postAndSuspend() the +        // first time, because -- at least in unit-test land -- it's +        // possible for the reply to arrive before the post() call +        // returns. Subsequent responses, of course, must be awaited +        // without posting again. +        for (mAuthResponse = validateResponse(loginReplyPump.getName(), +                    llcoro::postAndSuspend(request, xmlrpcPump, loginReplyPump, "reply")); +                mAuthResponse["status"].asString() == "Downloading"; +                mAuthResponse = validateResponse(loginReplyPump.getName(), +                                                llcoro::suspendUntilEventOn(loginReplyPump)))          { -            ++attempts; -            LLSD progress_data; -            progress_data["attempt"] = attempts; -            progress_data["request"] = request; -			if(progress_data["request"].has("params") -				&& progress_data["request"]["params"].has("passwd")) -			{ -				progress_data["request"]["params"]["passwd"] = "*******"; -			} -            sendProgressEvent("offline", "authenticating", progress_data); - -            // We expect zero or more "Downloading" status events, followed by -            // exactly one event with some other status. Use postAndWait() the -            // first time, because -- at least in unit-test land -- it's -            // possible for the reply to arrive before the post() call -            // returns. Subsequent responses, of course, must be awaited -            // without posting again. -            for (mAuthResponse = validateResponse(loginReplyPump.getName(), -                                 postAndWait(self, request, xmlrpcPump, loginReplyPump, "reply")); -                 mAuthResponse["status"].asString() == "Downloading"; -                 mAuthResponse = validateResponse(loginReplyPump.getName(), -                                     waitForEventOn(self, loginReplyPump))) -            { -                // Still Downloading -- send progress update. -                sendProgressEvent("offline", "downloading"); -            } +            // Still Downloading -- send progress update. +            sendProgressEvent("offline", "downloading"); +        } -			LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL; -            status = mAuthResponse["status"].asString(); - -            // Okay, we've received our final status event for this -            // request. Unless we got a redirect response, break the retry -            // loop for the current rewrittenURIs entry. -            if (!(status == "Complete" && -                  mAuthResponse["responses"]["login"].asString() == "indeterminate")) -            { -                break; -            } - -			sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]); - -            // Here the login service at the current URI is redirecting us -            // to some other URI ("indeterminate" -- why not "redirect"?). -            // The response should contain another uri to try, with its -            // own auth method. -            request["uri"] = mAuthResponse["responses"]["next_url"].asString(); -            request["method"] = mAuthResponse["responses"]["next_method"].asString(); -        } // loop back to try the redirected URI - -        // Here we're done with redirects for the current rewrittenURIs -        // entry. -        if (status == "Complete") +		LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL; +        status = mAuthResponse["status"].asString(); + +        // Okay, we've received our final status event for this +        // request. Unless we got a redirect response, break the retry +        // loop for the current rewrittenURIs entry. +        if (!(status == "Complete" && +                mAuthResponse["responses"]["login"].asString() == "indeterminate"))          { -            // StatusComplete does not imply auth success. Check the -            // actual outcome of the request. We've already handled the -            // "indeterminate" case in the loop above. -            if (mAuthResponse["responses"]["login"].asString() == "true") -            { -                sendProgressEvent("online", "connect", mAuthResponse["responses"]); -            } -            else -            { -                sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]); -            } -            return;             // Done! +            break;          } -		/* Sometimes we end with "Started" here. Slightly slow server? -		 * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. -		 */ -		if( status == "Started") -		{ -			LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; -			continue; -		} +		sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]); -        // If we don't recognize status at all, trouble -        if (! (status == "CURLError" -               || status == "XMLRPCError" -               || status == "OtherError")) +        // Here the login service at the current URI is redirecting us +        // to some other URI ("indeterminate" -- why not "redirect"?). +        // The response should contain another uri to try, with its +        // own auth method. +        request["uri"] = mAuthResponse["responses"]["next_url"].asString(); +        request["method"] = mAuthResponse["responses"]["next_method"].asString(); +    } // loop back to try the redirected URI + +    // Here we're done with redirects for the current rewrittenURIs +    // entry. +    if (status == "Complete") +    { +        // StatusComplete does not imply auth success. Check the +        // actual outcome of the request. We've already handled the +        // "indeterminate" case in the loop above. +        if (mAuthResponse["responses"]["login"].asString() == "true") +        { +            sendProgressEvent("online", "connect", mAuthResponse["responses"]); +        } +        else          { -            LL_ERRS("LLLogin") << "Unexpected status from " << xmlrpcPump.getName() << " pump: " -                               << mAuthResponse << LL_ENDL; -            return; +            sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);          } +        return;             // Done! +    } -        // Here status IS one of the errors tested above. -    } // Retry if there are any more rewrittenURIs. +// 	/* Sometimes we end with "Started" here. Slightly slow server? +// 		* Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. +// 		*/ +// 	if( status == "Started") +// 	{ +// 		LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; +// 		continue; +// 	} + +    // If we don't recognize status at all, trouble +    if (! (status == "CURLError" +            || status == "XMLRPCError" +            || status == "OtherError")) +    { +        LL_ERRS("LLLogin") << "Unexpected status from " << xmlrpcPump.getName() << " pump: " +                            << mAuthResponse << LL_ENDL; +        return; +    } + +    // Here status IS one of the errors tested above.      // Here we got through all the rewrittenURIs without succeeding. Tell      // caller this didn't work out so well. Of course, the only failure data @@ -352,29 +310,8 @@ LLEventPump& LLLogin::getEventPump()  // The list associates to event with the original idle_startup() 'STATE'. -// Rewrite URIs - // State_LOGIN_AUTH_INIT -// Given a vector of login uris (usually just one), perform a dns lookup for the  -// SRV record from each URI. I think this is used to distribute login requests to  -// a single URI to multiple hosts. -// This is currently a synchronous action. (See LLSRV::rewriteURI() implementation) -// On dns lookup error the output uris == the input uris. -// -// Input: A vector of login uris -// Output: A vector of login uris -// -// Code: -// std::vector<std::string> uris; -// LLViewerLogin::getInstance()->getLoginURIs(uris); -// std::vector<std::string>::const_iterator iter, end; -// for (iter = uris.begin(), end = uris.end(); iter != end; ++iter) -// { -//	std::vector<std::string> rewritten; -//	rewritten = LLSRV::rewriteURI(*iter); -//	sAuthUris.insert(sAuthUris.end(), -//					 rewritten.begin(), rewritten.end()); -// } -// sAuthUriNum = 0; +// Setup login +// State_LOGIN_AUTH_INIT  // Authenticate   // STATE_LOGIN_AUTHENTICATE diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp index 58bf371a04..e96c495446 100755 --- a/indra/viewer_components/login/tests/lllogin_test.cpp +++ b/indra/viewer_components/login/tests/lllogin_test.cpp @@ -96,61 +96,6 @@ public:      }  }; -class LLAresListener: public LLEventTrackable -{ -	std::string mName; -	LLSD mEvent; -	bool mImmediateResponse; -	bool mMultipleURIResponse; -    Debug mDebug; -	 -public: -	LLAresListener(const std::string& name,  -				   bool i = false, -				   bool m = false -				   ) :  -		mName(name), -		mImmediateResponse(i), -		mMultipleURIResponse(m), -        mDebug(stringize(*this)) -	{} - -	bool handle_event(const LLSD& event) -	{ -		mDebug(STRINGIZE("LLAresListener called!: " << event)); -		mEvent = event; -		if(mImmediateResponse) -		{ -			sendReply(); -		} -		return false; -	} - -	void sendReply() -	{ -		if(mEvent["op"].asString() == "rewriteURI") -		{ -			LLSD result; -			if(mMultipleURIResponse) -			{ -				result.append(LLSD("login.foo.com")); -			} -			result.append(mEvent["uri"]); -			LLEventPumps::instance().obtain(mEvent["reply"]).post(result); -		} -	} - -	LLBoundListener listenTo(LLEventPump& pump) -    { -        return pump.listen(mName, boost::bind(&LLAresListener::handle_event, this, _1)); -	} - -    friend std::ostream& operator<<(std::ostream& out, const LLAresListener& listener) -    { -        return out << "LLAresListener(" << listener.mName << ')'; -    } -}; -  class LLXMLRPCListener: public LLEventTrackable  {  	std::string mName; @@ -232,16 +177,12 @@ namespace tut      void llviewerlogin_object::test<1>()      {          DEBUG; -		// Testing login with immediate responses from Ares and XMLPRC -		// The response from both requests will come before the post request exits. +		// Testing login with an immediate response from XMLPRC +		// The response will come before the post request exits.  		// This tests an edge case of the login state handling. -		LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.  		LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump  		bool respond_immediately = true; -		// Have 'dummy ares' respond immediately.  -		LLAresListener dummyLLAres("dummy_llares", respond_immediately); -		dummyLLAres.listenTo(llaresPump);  		// Have dummy XMLRPC respond immediately.  		LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc", respond_immediately); @@ -266,109 +207,12 @@ namespace tut      void llviewerlogin_object::test<2>()      {          DEBUG; -		// Tests a successful login in with delayed responses.  -		// Also includes 'failure' that cause the login module -		// to re-attempt connection, once from a basic failure -		// and once from the 'indeterminate' response. - -		set_test_name("LLLogin multiple srv uris w/ success"); - -		// Testing normal login procedure. -		LLEventStream llaresPump("LLAres"); // Dummy LLAres pump. -		LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump - -		bool respond_immediately = false; -		bool multiple_addresses = true; -		LLAresListener dummyLLAres("dummy_llares", respond_immediately, multiple_addresses); -		dummyLLAres.listenTo(llaresPump); - -		LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc"); -		dummyXMLRPC.listenTo(xmlrpcPump); - -		LLLogin login; - -		LoginListener listener("test_ear"); -		listener.listenTo(login.getEventPump()); - -		LLSD credentials; -		credentials["first"] = "foo"; -		credentials["last"] = "bar"; -		credentials["passwd"] = "secret"; - -		login.connect("login.bar.com", credentials); - -		ensure_equals("SRV state", listener.lastEvent()["change"].asString(), "srvrequest");  - -		dummyLLAres.sendReply(); - -		// Test Authenticating State prior to first response. -		ensure_equals("Auth state 1", listener.lastEvent()["change"].asString(), "authenticating");  -		ensure_equals("Attempt 1", listener.lastEvent()["data"]["attempt"].asInteger(), 1);  -		ensure_equals("URI 1", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.foo.com");  - -		// First send emulated LLXMLRPCListener failure, -		// this should return login to the authenticating step and increase the attempt  -		// count. -		LLSD data; -		data["status"] = "OtherError";  -		data["errorcode"] = 0; -		data["error"] = "dummy response"; -		data["transfer_rate"] = 0; -		dummyXMLRPC.setResponse(data); -		dummyXMLRPC.sendReply(); - -		ensure_equals("Fail back to authenticate 1", listener.lastEvent()["change"].asString(), "authenticating");  -		ensure_equals("Attempt 2", listener.lastEvent()["data"]["attempt"].asInteger(), 2);  -		ensure_equals("URI 2", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.bar.com");  - -		// Now send the 'indeterminate' response. -		data.clear(); -		data["status"] = "Complete"; // StatusComplete -		data["errorcode"] = 0; -		data["error"] = "dummy response"; -		data["transfer_rate"] = 0; -		data["responses"]["login"] = "indeterminate"; -		data["responses"]["next_url"] = "login.indeterminate.com";			 -		data["responses"]["next_method"] = "test_login_method"; 			 -		dummyXMLRPC.setResponse(data); -		dummyXMLRPC.sendReply(); - -		ensure_equals("Fail back to authenticate 2", listener.lastEvent()["change"].asString(), "authenticating");  -		ensure_equals("Attempt 3", listener.lastEvent()["data"]["attempt"].asInteger(), 3);  -		ensure_equals("URI 3", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.indeterminate.com");  -		ensure_equals("Method 3", listener.lastEvent()["data"]["request"]["method"].asString(), "test_login_method");  - -		// Finally let the auth succeed. -		data.clear(); -		data["status"] = "Complete"; // StatusComplete -		data["errorcode"] = 0; -		data["error"] = "dummy response"; -		data["transfer_rate"] = 0; -		data["responses"]["login"] = "true"; -		dummyXMLRPC.setResponse(data); -		dummyXMLRPC.sendReply(); - -		ensure_equals("Success state", listener.lastEvent()["state"].asString(), "online"); - -		login.disconnect(); - -		ensure_equals("Disconnected state", listener.lastEvent()["state"].asString(), "offline"); -	} - -    template<> template<> -    void llviewerlogin_object::test<3>() -    { -        DEBUG;  		// Test completed response, that fails to login.  		set_test_name("LLLogin valid response, failure (eg. bad credentials)");  		// Testing normal login procedure. -		LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.  		LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump -		LLAresListener dummyLLAres("dummy_llares"); -		dummyLLAres.listenTo(llaresPump); -  		LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc");  		dummyXMLRPC.listenTo(xmlrpcPump); @@ -383,10 +227,6 @@ namespace tut  		login.connect("login.bar.com", credentials); -		ensure_equals("SRV state", listener.lastEvent()["change"].asString(), "srvrequest");  - -		dummyLLAres.sendReply(); -  		ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating");   		// Send the failed auth request reponse @@ -403,19 +243,15 @@ namespace tut  	}      template<> template<> -    void llviewerlogin_object::test<4>() +    void llviewerlogin_object::test<3>()      {          DEBUG;  		// Test incomplete response, that end the attempt.  		set_test_name("LLLogin valid response, failure (eg. bad credentials)");  		// Testing normal login procedure. -		LLEventStream llaresPump("LLAres"); // Dummy LLAres pump.  		LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump -		LLAresListener dummyLLAres("dummy_llares"); -		dummyLLAres.listenTo(llaresPump); -  		LLXMLRPCListener dummyXMLRPC("dummy_xmlrpc");  		dummyXMLRPC.listenTo(xmlrpcPump); @@ -430,10 +266,6 @@ namespace tut  		login.connect("login.bar.com", credentials); -		ensure_equals("SRV state", listener.lastEvent()["change"].asString(), "srvrequest");  - -		dummyLLAres.sendReply(); -  		ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating");   		// Send the failed auth request reponse @@ -449,17 +281,13 @@ namespace tut  	}  	template<> template<> -    void llviewerlogin_object::test<5>() +    void llviewerlogin_object::test<4>()      {          DEBUG;  		// Test SRV request timeout.  		set_test_name("LLLogin SRV timeout testing");  		// Testing normal login procedure. -		LLEventStream llaresPump("LLAres"); // Dummy LLAres pump. - -		LLAresListener dummyLLAres("dummy_llares"); -		dummyLLAres.listenTo(llaresPump);  		LLLogin login;  		LoginListener listener("test_ear"); @@ -473,26 +301,15 @@ namespace tut  		login.connect("login.bar.com", credentials); -		ensure_equals("SRV State", listener.lastEvent()["change"].asString(), "srvrequest");  -  		// Get the mainloop eventpump, which needs a pinging in order to drive the   		// SRV timeout.  		LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));  		LLSD frame_event;  		mainloop.post(frame_event); -		// In this state we have NOT sent a reply from LLAresListener -- in -		// fact there's no such object. Nonetheless, we expect the timeout to -		// have stepped the login module forward to try to authenticate with -		// the original URI.  		ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating");   		ensure_equals("Attempt", listener.lastEvent()["data"]["attempt"].asInteger(), 1);   		ensure_equals("URI", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.bar.com"); -		// EXT-4193: if the SRV reply isn't lost but merely late, and if it -		// arrives just at the moment we're expecting the XMLRPC reply, the -		// original code got confused and crashed. Drive that case here. We -		// observe that without the fix, this call DOES repro. -		dummyLLAres.sendReply();  	}  } diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt index 61fd4220e0..73e18aacb3 100755 --- a/indra/viewer_components/updater/CMakeLists.txt +++ b/indra/viewer_components/updater/CMakeLists.txt @@ -6,15 +6,18 @@ include(00-Common)  if(LL_TESTS)    include(LLAddBuildTest)  endif(LL_TESTS) +include(Boost)  include(CMakeCopyIfDifferent)  include(CURL)  include(LLCommon) +include(LLCoreHttp)  include(LLMessage)  include(LLPlugin)  include(LLVFS)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} +    ${LLCOREHTTP_INCLUDE_DIRS}      ${LLMESSAGE_INCLUDE_DIRS}      ${LLPLUGIN_INCLUDE_DIRS}      ${LLVFS_INCLUDE_DIRS} @@ -60,25 +63,36 @@ add_library(llupdaterservice  target_link_libraries(llupdaterservice      ${LLCOMMON_LIBRARIES}      ${LLMESSAGE_LIBRARIES} +    ${LLCOREHTTP_LIBRARIES}      ${LLPLUGIN_LIBRARIES}      ${LLVFS_LIBRARIES}      )  if(LL_TESTS) +if (NOT LINUX)    SET(llupdater_service_TEST_SOURCE_FILES        llupdaterservice.cpp        ) +set(test_libs +    ${LLCOMMON_LIBRARIES} +    ${BOOST_COROUTINE_LIBRARY}  +    ${BOOST_CONTEXT_LIBRARY}  +    ${BOOST_THREAD_LIBRARY}  +    ${BOOST_SYSTEM_LIBRARY}) + +set_source_files_properties( +    llupdaterservice.cpp +    PROPERTIES +      LL_TEST_ADDITIONAL_LIBRARIES ${test_libs}  # *NOTE:Mani - I was trying to use the preprocessor seam to mock out -#              llifstream (and other) llcommon classes. I didn't work +#              llifstream (and other) llcommon classes. It didn't work  #              because of the windows declspec(dllimport)attribute. -#set_source_files_properties( -#    llupdaterservice.cpp -#    PROPERTIES -#      LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream" -#    ) +#     LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream" +    ) -  LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}") +  LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}" ${test_libs}) +endif (NOT LINUX)  endif(LL_TESTS)  set(UPDATER_INCLUDE_DIRS  diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 8da4f88905..1bb5e95740 100755 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -26,10 +26,10 @@  #include "linden_common.h"  #include <stdexcept>  #include <boost/format.hpp> -#include "llhttpclient.h"  #include "llsd.h"  #include "llupdatechecker.h"  #include "lluri.h" +#include "llcorehttputil.h"  #if LL_DARWIN  #include <CoreServices/CoreServices.h>  #endif @@ -53,15 +53,12 @@ public:  // LLUpdateChecker  //----------------------------------------------------------------------------- - -  LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):  	mImplementation(new LLUpdateChecker::Implementation(client))  {  	; // No op.  } -  void LLUpdateChecker::checkVersion(std::string const & urlBase,   								   std::string const & channel,  								   std::string const & version, @@ -74,11 +71,8 @@ void LLUpdateChecker::checkVersion(std::string const & urlBase,  } -  // LLUpdateChecker::Implementation  //----------------------------------------------------------------------------- - -  const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1"; @@ -121,57 +115,58 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase,  		std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);  		LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL; -	 -		mHttpClient.get(checkUrl, this); -	} -	else -	{ -		LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL; -	} -} -void LLUpdateChecker::Implementation::httpCompleted() -{ -	mInProgress = false;	 +        LLCoros::instance().launch("LLUpdateChecker::Implementation::checkVersionCoro", +            boost::bind(&Implementation::checkVersionCoro, this, checkUrl)); -	S32 status = getStatus(); -	const LLSD& content = getContent(); -	const std::string& reason = getReason(); -	if(status != 200) -	{ -		std::string server_error; -		if ( content.has("error_code") ) -		{ -			server_error += content["error_code"].asString(); -		} -		if ( content.has("error_text") ) -		{ -			server_error += server_error.empty() ? "" : ": "; -			server_error += content["error_text"].asString(); -		} - -		LL_WARNS("UpdaterService") << "response error " << status -								   << " " << reason -								   << " (" << server_error << ")" -								   << LL_ENDL; -		mClient.error(reason);  	}  	else  	{ -		mClient.response(content); +		LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL;  	}  } - -void LLUpdateChecker::Implementation::httpFailure() +void LLUpdateChecker::Implementation::checkVersionCoro(std::string url)  { -	const std::string& reason = getReason(); -	mInProgress = false; -	LL_WARNS("UpdaterService") << "update check failed; " << reason << LL_ENDL; -	mClient.error(reason); +    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); +    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t +        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("checkVersionCoro", httpPolicy)); +    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + +    LL_INFOS("checkVersionCoro") << "Getting update information from " << url << LL_ENDL; + +    LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + +    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + +    mInProgress = false; + +    if (status != LLCore::HttpStatus(HTTP_OK)) +    { +        std::string server_error; +        if (result.has("error_code")) +        { +            server_error += result["error_code"].asString(); +        } +        if (result.has("error_text")) +        { +            server_error += server_error.empty() ? "" : ": "; +            server_error += result["error_text"].asString(); +        } + +        LL_WARNS("UpdaterService") << "response error " << status.getStatus() +            << " " << status.toString() +            << " (" << server_error << ")" +            << LL_ENDL; +        mClient.error(status.toString()); +        return; +    } + +    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); +    mClient.response(result);  } -  std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase,   													  std::string const & channel,  													  std::string const & version, diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index 3163a6d53c..d10ea4cf42 100755 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -30,61 +30,27 @@  #include <boost/shared_ptr.hpp>  #include "llmd5.h" -#include "llhttpclient.h" +#include "lleventcoro.h" +#include "llcoros.h"  //  // Implements asynchronous checking for updates.  //  class LLUpdateChecker {  public: -	class Client; -	class Implementation: public LLHTTPClient::Responder -	{ -	public: -		Implementation(Client & client); -		~Implementation(); -		void checkVersion(std::string const & urlBase,  -						  std::string const & channel, -						  std::string const & version, -						  std::string const & platform, -						  std::string const & platform_version, -						  unsigned char       uniqueid[MD5HEX_STR_SIZE], -						  bool                willing_to_test -						  ); -	 -    protected: -		// Responder: -		virtual void httpCompleted(); -		virtual void httpFailure(); -	 -	private:	 -		static const char * sLegacyProtocolVersion; -		static const char * sProtocolVersion; -		const char* mProtocol; -		 -		Client & mClient; -		LLHTTPClient mHttpClient; -		bool         mInProgress; -		std::string   mVersion; -		std::string   mUrlBase; -		std::string   mChannel; -		std::string   mPlatform; -		std::string   mPlatformVersion; -		unsigned char mUniqueId[MD5HEX_STR_SIZE]; -		bool          mWillingToTest; -		 -		std::string buildUrl(std::string const & urlBase,  -							 std::string const & channel, -							 std::string const & version, -							 std::string const & platform, -							 std::string const & platform_version, -							 unsigned char       uniqueid[MD5HEX_STR_SIZE], -							 bool                willing_to_test); - -		LOG_CLASS(LLUpdateChecker::Implementation); -	}; +    // +    // The client interface implemented by a requestor checking for an update. +    // +    class Client +    { +    public: +        // An error occurred while checking for an update. +        virtual void error(std::string const & message) = 0; + +        // A successful response was received from the viewer version manager +        virtual void response(LLSD const & content) = 0; +    }; -	  	// An exception that may be raised on check errors.  	class CheckError; @@ -100,25 +66,54 @@ public:  					  bool                willing_to_test);  private: -	LLPointer<Implementation> mImplementation; -}; +    class Implementation +    { +    public: +        typedef boost::shared_ptr<Implementation> ptr_t; +        Implementation(Client & client); +        ~Implementation(); +        void checkVersion(std::string const & urlBase, +            std::string const & channel, +            std::string const & version, +            std::string const & platform, +            std::string const & platform_version, +            unsigned char       uniqueid[MD5HEX_STR_SIZE], +            bool                willing_to_test +            ); -class LLURI; // From lluri.h +    private: +        static const char * sLegacyProtocolVersion; +        static const char * sProtocolVersion; +        const char* mProtocol; -// -// The client interface implemented by a requestor checking for an update. -// -class LLUpdateChecker::Client -{ -public: -	// An error occurred while checking for an update. -	virtual void error(std::string const & message) = 0; -	 -	// A successful response was received from the viewer version manager -	virtual void response(LLSD const & content) = 0; -}; +        Client & mClient; +        bool         mInProgress; +        std::string   mVersion; +        std::string   mUrlBase; +        std::string   mChannel; +        std::string   mPlatform; +        std::string   mPlatformVersion; +        unsigned char mUniqueId[MD5HEX_STR_SIZE]; +        bool          mWillingToTest; + +        std::string buildUrl(std::string const & urlBase, +            std::string const & channel, +            std::string const & version, +            std::string const & platform, +            std::string const & platform_version, +            unsigned char       uniqueid[MD5HEX_STR_SIZE], +            bool                willing_to_test); + +        void checkVersionCoro(std::string url); +        LOG_CLASS(LLUpdateChecker::Implementation); +    }; + + +    Implementation::ptr_t       mImplementation; +	//LLPointer<Implementation> mImplementation; +};  #endif diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index f868e5cc2c..382689afa0 100755 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -26,7 +26,7 @@  #include "linden_common.h"  #include "llupdatedownloader.h" - +#include "httpcommon.h"  #include <stdexcept>  #include <boost/format.hpp>  #include <boost/lexical_cast.hpp> @@ -39,7 +39,6 @@  #include "llsdserialize.h"  #include "llthread.h"  #include "llupdaterservice.h" -#include "llcurl.h"  class LLUpdateDownloader::Implementation:  	public LLThread @@ -57,7 +56,7 @@ public:  	bool isDownloading(void);  	size_t onHeader(void * header, size_t size);  	size_t onBody(void * header, size_t size); -	int onProgress(double downloadSize, double bytesDownloaded); +	int onProgress(curl_off_t downloadSize, curl_off_t bytesDownloaded);  	void resume(void);  	void setBandwidthLimit(U64 bytesPerSecond); @@ -65,7 +64,7 @@ private:  	curl_off_t mBandwidthLimit;  	bool mCancelled;  	LLUpdateDownloader::Client & mClient; -	CURL * mCurl; +	LLCore::LLHttp::CURL_ptr mCurl;  	LLSD mDownloadData;  	llofstream mDownloadStream;  	unsigned char mDownloadPercent; @@ -175,11 +174,11 @@ namespace {  	} -	int progress_callback(void * downloader, -						  double dowloadTotal, -						  double downloadNow, -						  double uploadTotal, -						  double uploadNow) +	int xferinfo_callback(void * downloader, +						  curl_off_t dowloadTotal, +						  curl_off_t downloadNow, +						  curl_off_t uploadTotal, +						  curl_off_t uploadNow)  	{  		return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->  			onProgress(dowloadTotal, downloadNow); @@ -192,7 +191,7 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &  	mBandwidthLimit(0),  	mCancelled(false),  	mClient(client), -	mCurl(0), +	mCurl(),  	mDownloadPercent(0),  	mHeaderList(0)  { @@ -212,10 +211,7 @@ LLUpdateDownloader::Implementation::~Implementation()  	{  		; // No op.  	} -	if(mCurl) -	{ -		LLCurl::deleteEasyHandle(mCurl); -	} +    mCurl.reset();  } @@ -331,9 +327,9 @@ void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)  {  	if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean())  	{ -		llassert(mCurl != 0); +		llassert(static_cast<bool>(mCurl));  		mBandwidthLimit = bytesPerSecond; -		CURLcode code = curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit); +		CURLcode code = curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit);  		if(code != CURLE_OK)  		{  			LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL; @@ -390,9 +386,9 @@ size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)  } -int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double bytesDownloaded) +int LLUpdateDownloader::Implementation::onProgress(curl_off_t downloadSize, curl_off_t bytesDownloaded)  { -	int downloadPercent = static_cast<int>(100. * (bytesDownloaded / downloadSize)); +	int downloadPercent = static_cast<int>(100.0 * ((double) bytesDownloaded / (double) downloadSize));  	if(downloadPercent > mDownloadPercent) {  		mDownloadPercent = downloadPercent; @@ -400,8 +396,8 @@ int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double b  		event["pump"] = LLUpdaterService::pumpName();  		LLSD payload;  		payload["type"] = LLSD(LLUpdaterService::PROGRESS); -		payload["download_size"] = downloadSize; -		payload["bytes_downloaded"] = bytesDownloaded; +		payload["download_size"] = (LLSD::Integer) downloadSize; +		payload["bytes_downloaded"] = (LLSD::Integer) bytesDownloaded;  		event["payload"] = payload;  		LLEventPumps::instance().obtain("mainlooprepeater").post(event); @@ -416,7 +412,7 @@ int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double b  void LLUpdateDownloader::Implementation::run(void)  { -	CURLcode code = curl_easy_perform(mCurl); +    CURLcode code = curl_easy_perform(mCurl.get());  	mDownloadStream.close();  	if(code == CURLE_OK)  	{ @@ -460,36 +456,39 @@ void LLUpdateDownloader::Implementation::run(void)  void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)  { -	if(mCurl == 0) +	if(!mCurl)  	{ -		mCurl = LLCurl::newEasyHandle(); +		mCurl = LLCore::LLHttp::createEasyHandle();  	}  	else  	{ -		curl_easy_reset(mCurl); +        curl_easy_reset(mCurl.get());  	} -	if(mCurl == 0) +	if(!mCurl)  	{  		throw DownloadError("failed to initialize curl");  	} -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true)); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true)); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function)); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this)); +    throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOSIGNAL, true)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_FOLLOWLOCATION, true)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEFUNCTION, &write_function)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEDATA, this));  	if(processHeader)  	{ -	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function)); -	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this)); -	} -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true)); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str())); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &progress_callback)); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA, this)); -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, false)); +	   throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERFUNCTION, &header_function)); +	   throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERDATA, this)); +	} +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPGET, true)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_URL, url.c_str())); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_XFERINFOFUNCTION, &xferinfo_callback)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_XFERINFODATA, this)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOPROGRESS, 0));  	// if it's a required update set the bandwidth limit to 0 (unlimited)  	curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit; -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, limit)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, limit)); +    throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str())); +    throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_SSL_VERIFYHOST, 2)); +    throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_SSL_VERIFYPEER, 1));  	mDownloadPercent = 0;  } @@ -511,7 +510,7 @@ void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)  	{  		throw DownloadError("cannot add Range header");  	} -	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList)); +	throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPHEADER, mHeaderList));  	mDownloadStream.open(mDownloadData["path"].asString().c_str(),  						 std::ios_base::out | std::ios_base::binary | std::ios_base::app); | 
