summaryrefslogtreecommitdiff
path: root/indra/viewer_components
diff options
context:
space:
mode:
Diffstat (limited to 'indra/viewer_components')
-rwxr-xr-xindra/viewer_components/login/lllogin.cpp246
-rwxr-xr-xindra/viewer_components/login/tests/lllogin_test.cpp191
-rwxr-xr-xindra/viewer_components/updater/llupdatechecker.cpp2
-rwxr-xr-xindra/viewer_components/updater/llupdatedownloader.cpp54
-rwxr-xr-xindra/viewer_components/updater/llupdaterservice.cpp56
-rwxr-xr-xindra/viewer_components/updater/llupdaterservice.h1
6 files changed, 176 insertions, 374 deletions
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 88415ff11a..53d4acc9e0 100755
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -108,7 +108,7 @@ private:
// In a coroutine's top-level function args, do NOT NOT NOT accept
// references (const or otherwise) to anything! Pass by value only!
- void login_(std::string uri, LLSD credentials);
+ void loginCoro(std::string uri, LLSD credentials);
LLEventStream mPump;
LLSD mAuthResponse, mValidAuthResponse;
@@ -122,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, 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_(std::string uri, LLSD login_params)
+void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
{
try
{
@@ -143,43 +143,6 @@ void LLLogin::Impl::login_(std::string uri, LLSD login_params)
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 = llcoro::postAndWait(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
@@ -190,107 +153,103 @@ void LLLogin::Impl::login_(std::string uri, LLSD login_params)
// 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(),
- llcoro::postAndWait(request, xmlrpcPump, loginReplyPump, "reply"));
- mAuthResponse["status"].asString() == "Downloading";
- mAuthResponse = validateResponse(loginReplyPump.getName(),
- llcoro::waitForEventOn(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
@@ -351,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/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index e889f83aa9..1bb5e95740 100755
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -135,7 +135,7 @@ void LLUpdateChecker::Implementation::checkVersionCoro(std::string url)
LL_INFOS("checkVersionCoro") << "Getting update information from " << url << LL_ENDL;
- LLSD result = httpAdapter->getAndYield(httpRequest, url);
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index f868e5cc2c..53c729469b 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
@@ -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;
@@ -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;
@@ -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,36 @@ 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_PROGRESSFUNCTION, &progress_callback));
+ throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_PROGRESSDATA, this));
+ throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOPROGRESS, false));
// 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));
mDownloadPercent = 0;
}
@@ -511,7 +507,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);
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index c152493a51..788955a1b2 100755
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -132,6 +132,7 @@ public:
void startChecking(bool install_if_ready);
void stopChecking();
+ bool forceCheck();
bool isChecking();
LLUpdaterService::eUpdaterState getState();
@@ -266,6 +267,46 @@ void LLUpdaterServiceImpl::stopChecking()
setState(LLUpdaterService::TERMINAL);
}
+bool LLUpdaterServiceImpl::forceCheck()
+{
+ if (!mIsDownloading && getState() != LLUpdaterService::CHECKING_FOR_UPDATE)
+ {
+ if (mIsChecking)
+ {
+ // Service is running, just reset the timer
+ if (mTimer.getStarted())
+ {
+ mTimer.setTimerExpirySec(0);
+ setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+ return true;
+ }
+ }
+ else if (!mChannel.empty() && !mVersion.empty())
+ {
+ // one time check
+ bool has_install = checkForInstall(false);
+ if (!has_install)
+ {
+ std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL();
+ if (!query_url.empty())
+ {
+ setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+ mUpdateChecker.checkVersion(query_url, mChannel, mVersion,
+ mPlatform, mPlatformVersion, mUniqueId,
+ mWillingToTest);
+ return true;
+ }
+ else
+ {
+ LL_WARNS("UpdaterService")
+ << "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid() << LL_ENDL;
+ }
+ }
+ }
+ }
+ return false;
+}
+
bool LLUpdaterServiceImpl::isChecking()
{
return mIsChecking;
@@ -402,9 +443,9 @@ bool LLUpdaterServiceImpl::checkForResume()
void LLUpdaterServiceImpl::error(std::string const & message)
{
+ setState(LLUpdaterService::TEMPORARY_ERROR);
if(mIsChecking)
{
- setState(LLUpdaterService::TEMPORARY_ERROR);
restartTimer(mCheckPeriod);
}
}
@@ -449,8 +490,12 @@ void LLUpdaterServiceImpl::response(LLSD const & content)
else
{
LL_WARNS("UpdaterService") << "Invalid update query response ignored; retry in "
- << mCheckPeriod << " seconds" << LL_ENDL;
- restartTimer(mCheckPeriod);
+ << mCheckPeriod << " seconds" << LL_ENDL;
+ setState(LLUpdaterService::TEMPORARY_ERROR);
+ if (mIsChecking)
+ {
+ restartTimer(mCheckPeriod);
+ }
}
}
@@ -672,6 +717,11 @@ void LLUpdaterService::stopChecking()
mImpl->stopChecking();
}
+bool LLUpdaterService::forceCheck()
+{
+ return mImpl->forceCheck();
+}
+
bool LLUpdaterService::isChecking()
{
return mImpl->isChecking();
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 0ddf24935b..95bbe1695c 100755
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -84,6 +84,7 @@ public:
void startChecking(bool install_if_ready = false);
void stopChecking();
+ bool forceCheck();
bool isChecking();
eUpdaterState getState();