diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 533469d93..1374a1b93 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -526,7 +526,7 @@ private: LLSD mResponse; protected: - /*virtual*/ LLSD const& getLLSD(void) const { llassert(mFinished && mCode == CURLE_OK && mStatus == HTTP_OK); return mResponse; } + /*virtual*/ LLSD const& getLLSD(void) const { llassert(mFinished && mCode == CURLE_OK); return mResponse; } /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { decode_llsd_body(status, reason, channels, buffer, mResponse); // This puts the body asString() in mResponse in case of http error. @@ -539,7 +539,7 @@ private: std::string mResponse; protected: - /*virtual*/ std::string const& getRaw(void) const { llassert(mFinished && mCode == CURLE_OK && mStatus == HTTP_OK); return mResponse; } + /*virtual*/ std::string const& getRaw(void) const { llassert(mFinished && mCode == CURLE_OK); return mResponse; } /*virtual*/ void completedRaw(U32 status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) { decode_raw_body(mCode, reason, channels, buffer, mResponse); diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index 9febd1777..f4bda53ac 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -16,6 +16,7 @@ #include "lltrans.h" #include "llviewercontrol.h" #include "llweb.h" +#include "aialert.h" // ******************************************************************** // Global Variables @@ -157,18 +158,32 @@ void HippoGridInfo::setGridNick(std::string gridNick) } } +void HippoGridInfo::useHttps() +{ + // If the Login URI starts with "http:", replace that with "https:". + if (mLoginUri.substr(0, 5) == "http:") + { + mLoginUri = "https:" + mLoginUri.substr(5); + } +} + void HippoGridInfo::setLoginUri(const std::string& loginUri) { - std::string uri = loginUri; - mLoginUri = sanitizeUri(uri); - if (utf8str_tolower(LLURI(uri).hostName()) == "login.agni.lindenlab.com") + mLoginUri = sanitizeUri(loginUri); + if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.agni.lindenlab.com") { mIsInProductionGrid = true; + useHttps(); } - if (utf8str_tolower(LLURI(uri).hostName()) == "login.avination.com" || - utf8str_tolower(LLURI(uri).hostName()) == "login.avination.net") + if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.aditi.lindenlab.com") + { + useHttps(); + } + if (utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.avination.com" || + utf8str_tolower(LLURI(mLoginUri).hostName()) == "login.avination.net") { mIsInAvination = true; + useHttps(); } } @@ -179,8 +194,7 @@ void HippoGridInfo::setLoginPage(const std::string& loginPage) void HippoGridInfo::setHelperUri(const std::string& helperUri) { - std::string uri = helperUri; - mHelperUri = sanitizeUri(uri); + mHelperUri = sanitizeUri(helperUri); } void HippoGridInfo::setWebSite(const std::string& website) @@ -398,15 +412,13 @@ void HippoGridInfo::onXmlCharacterData(void* userData, const XML_Char* s, int le case XML_LOGINURI: { - std::string loginuri(s, len); - self->mLoginUri = sanitizeUri( loginuri ); + self->setLoginUri(std::string(s, len)); break; } case XML_HELPERURI: { - std::string helperuri(s, len); - self->mHelperUri = sanitizeUri( helperuri ); + self->setHelperUri(std::string(s, len)); break; } @@ -437,24 +449,45 @@ void HippoGridInfo::onXmlCharacterData(void* userData, const XML_Char* s, int le } } - -bool HippoGridInfo::retrieveGridInfo() +// Throws AIAlert::ErrorCode with the http status as 'code' (HTTP_OK on XML parse error). +void HippoGridInfo::getGridInfo() { - if (mLoginUri == "") return false; - - // If last character in uri is not "/" - std::string uri = mLoginUri; - if (uri.compare(uri.length()-1, 1, "/") != 0) + if (mLoginUri.empty()) { - uri += '/'; + // By passing 0 we automatically get GridInfoErrorInstruction appended. + THROW_ALERTC(0, "GridInfoErrorNoLoginURI"); } + + // Make sure the uri ends on a '/'. + std::string uri = mLoginUri; + if (uri.compare(uri.length() - 1, 1, "/") != 0) + { + uri += '/'; + } + std::string reply; int result = LLHTTPClient::blockingGetRaw(uri + "get_grid_info", reply); - if (result != 200) return false; + if (result != HTTP_OK) + { + char const* xml_desc; + switch (result) + { + case HTTP_NOT_FOUND: + xml_desc = "GridInfoErrorNotFound"; + break; + case HTTP_METHOD_NOT_ALLOWED: + xml_desc = "GridInfoErrorNotAllowed"; + break; + default: + xml_desc = "AIError"; + break; + } + // LLHTTPClient::blockingGetRaw puts any error message in the reply. + THROW_ALERTC(result, xml_desc, AIArgs("[ERROR]", reply)); + } llinfos << "Received: " << reply << llendl; - bool success = true; XML_Parser parser = XML_ParserCreate(0); XML_SetUserData(parser, this); XML_SetElementHandler(parser, onXmlElementStart, onXmlElementEnd); @@ -462,15 +495,11 @@ bool HippoGridInfo::retrieveGridInfo() mXmlState = XML_VOID; if (!XML_Parse(parser, reply.data(), reply.size(), TRUE)) { - llwarns << "XML Parse Error: " << XML_ErrorString(XML_GetErrorCode(parser)) << llendl; - success = false; + THROW_ALERTC(HTTP_OK, "GridInfoParseError", AIArgs("[XML_ERROR]", XML_ErrorString(XML_GetErrorCode(parser)))); } XML_ParserFree(parser); - - return success; } - std::string HippoGridInfo::getUploadFee() const { std::string fee; @@ -558,22 +587,40 @@ const char* HippoGridInfo::getPlatformString(Platform platform) } // static -std::string HippoGridInfo::sanitizeUri(std::string &uri) +std::string HippoGridInfo::sanitizeUri(std::string const& uri_in) { - // if (uri.empty()) { - // return ""; - // } + std::string uri = uri_in; - // // If last character in uri is not "/" - // // NOTE: This wrongly assumes that all URIs should end with "/"! - // if (uri.compare(uri.length()-1, 1, "/") != 0) { - // return uri + '/'; - // } + // Strip any leading and trailing spaces. + LLStringUtil::trim(uri); + + // Only use https when it was entered. + bool use_https = uri.substr(0, 6) == "https:"; + + // Strip off attempts to use some prefix that is just wrong. + // We accept the following: + // "" (nothing) + // "http:" or "https:", optionally followed by one or more '/'. + std::string::size_type pos = uri.find_first_not_of("htps"); + if (pos != std::string::npos && pos < 6 && uri[pos] == ':') + { + do { ++pos; } while(uri[pos] == '/'); + uri = uri.substr(pos); + } + + // Add (back) the prefix. + if (use_https) + { + uri = "https://" + uri; + } + else + { + uri = "http://" + uri; + } return uri; } - void HippoGridInfo::initFallback() { FALLBACK_GRIDINFO.setPlatform(PLATFORM_OPENSIM); diff --git a/indra/newview/hippogridmanager.h b/indra/newview/hippogridmanager.h index 605a02e0d..089b381f9 100644 --- a/indra/newview/hippogridmanager.h +++ b/indra/newview/hippogridmanager.h @@ -98,7 +98,7 @@ public: bool getAutoUpdate(); void setAutoUpdate(bool b); - bool retrieveGridInfo(); + void getGridInfo(); static const char* getPlatformString(Platform platform); static std::string sanitizeGridNick(const std::string &gridnick); @@ -142,7 +142,8 @@ private: }; XmlState mXmlState; - static std::string sanitizeUri(std::string &uri); + static std::string sanitizeUri(std::string const& uri_in); + void useHttps(void); void formatFee(std::string &fee, int cost, bool showFree) const; static void onXmlElementStart(void* userData, const XML_Char* name, const XML_Char** atts); diff --git a/indra/newview/hippopanelgrids.cpp b/indra/newview/hippopanelgrids.cpp index b0239fead..d09d75fab 100644 --- a/indra/newview/hippopanelgrids.cpp +++ b/indra/newview/hippopanelgrids.cpp @@ -42,7 +42,7 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" #include "llnotificationsutil.h" - +#include "llhttpstatuscodes.h" // ******************************************************************** @@ -152,7 +152,7 @@ BOOL HippoPanelGridsImpl::postBuild() childSetCommitCallback("grid_selector", onSelectGrid, this); childSetCommitCallback("platform", onSelectPlatform, this); - + // !!!### server_choice_combo->setFocusLostCallback(onServerComboLostFocus); reset(); @@ -294,7 +294,7 @@ bool HippoPanelGridsImpl::saveCurGrid() HippoGridInfo *gridInfo = 0; gridInfo = gHippoGridManager->getGrid(mCurGrid); - //gridInfo->retrieveGridInfo(); + //gridInfo->getGridInfo(); refresh(); std::string gridname = childGetValue("gridname"); @@ -333,9 +333,30 @@ bool HippoPanelGridsImpl::saveCurGrid() mCurGrid = gridname; gridInfo = new HippoGridInfo(gridname); gHippoGridManager->addGrid(gridInfo); - gridInfo->retrieveGridInfo(); + try + { + gridInfo->getGridInfo(); + } + catch (AIAlert::ErrorCode const& error) + { + if (error.getCode() == HTTP_NOT_FOUND || error.getCode() == HTTP_METHOD_NOT_ALLOWED) + { + // Ignore this error; it might be a user entered entry for a grid that has no get_grid_info support. + llwarns << AIAlert::text(error) << llendl; + } + else if (error.getCode() == HTTP_OK) + { + // XML parse error. + AIAlert::add("GridInfoError", error); + } + else + { + // Append GridInfoErrorInstruction to error message. + AIAlert::add("GridInfoError", AIAlert::Error(AIAlert::Prefix(), AIAlert::not_modal, error, "GridInfoErrorInstruction")); + } + } } - + if (!gridInfo) { llwarns << "Grid not found, ignoring changes." << llendl; return true; @@ -394,7 +415,10 @@ void HippoPanelGridsImpl::retrieveGridInfo() } grid->setLoginUri(loginuri); - if (grid->retrieveGridInfo()) { + try + { + grid->getGridInfo(); + if (grid->getPlatform() != HippoGridInfo::PLATFORM_OTHER) getChild("platform")->setCurrentByIndex(grid->getPlatform()); if (grid->getGridName() != "") childSetText("gridname", grid->getGridName()); @@ -407,10 +431,20 @@ void HippoPanelGridsImpl::retrieveGridInfo() if (grid->getPasswordUrl() != "") childSetText("password", grid->getPasswordUrl()); if (grid->getSearchUrl() != "") childSetText("search", grid->getSearchUrl()); if (grid->getGridMessage() != "") childSetText("gridmessage", grid->getGridMessage()); - } else { - LLNotificationsUtil::add("GridInfoError"); } - + catch(AIAlert::ErrorCode const& error) + { + if (error.getCode() == HTTP_METHOD_NOT_ALLOWED || error.getCode() == HTTP_OK) + { + AIAlert::add("GridInfoError", error); + } + else + { + // Append GridInfoErrorInstruction to error message. + AIAlert::add("GridInfoError", AIAlert::Error(AIAlert::Prefix(), AIAlert::not_modal, error, "GridInfoErrorInstruction")); + } + } + if (cleanupGrid) delete grid; } @@ -472,8 +506,10 @@ void HippoPanelGridsImpl::onClickDefault(void *data) { HippoPanelGridsImpl *self = (HippoPanelGridsImpl*)data; if (self->mState == NORMAL) { - self->saveCurGrid(); - gHippoGridManager->setDefaultGrid(self->mCurGrid); + if (self->saveCurGrid()) + { + gHippoGridManager->setDefaultGrid(self->mCurGrid); + } self->refresh(); } } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index d8b8a1711..f0a950b40 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -1038,8 +1038,10 @@ void LLPanelLogin::onSelectGrid(LLUICtrl *ctrl) { HippoGridInfo* info(new HippoGridInfo("")); // Start off with empty grid name, otherwise we don't know what to name info->setLoginUri(grid); - if (info->retrieveGridInfo()) // There's info from this URI + try { + info->getGridInfo(); + grid = info->getGridName(); if (HippoGridInfo* nick_info = gHippoGridManager->getGrid(info->getGridNick())) // Grid of same nick exists { @@ -1051,8 +1053,23 @@ void LLPanelLogin::onSelectGrid(LLUICtrl *ctrl) gHippoGridManager->addGrid(info); // deletes info if not needed (existing or no name) } } - else + catch(AIAlert::ErrorCode const& error) { + // Inform the user of the problem, but only if something was entered that at least looks like a Login URI. + std::string::size_type pos1 = grid.find('.'); + std::string::size_type pos2 = grid.find_last_of(".:"); + if (grid.substr(0, 4) == "http" || (pos1 != std::string::npos && pos1 != pos2)) + { + if (error.getCode() == HTTP_METHOD_NOT_ALLOWED || error.getCode() == HTTP_OK) + { + AIAlert::add("GridInfoError", error); + } + else + { + // Append GridInfoErrorInstruction to error message. + AIAlert::add("GridInfoError", AIAlert::Error(AIAlert::Prefix(), AIAlert::not_modal, error, "GridInfoErrorInstruction")); + } + } delete info; grid = gHippoGridManager->getCurrentGridName(); } diff --git a/indra/newview/skins/default/xui/de/floater_directory2.xml b/indra/newview/skins/default/xui/de/floater_directory2.xml index 2e4dfe5ee..a99292f04 100644 --- a/indra/newview/skins/default/xui/de/floater_directory2.xml +++ b/indra/newview/skins/default/xui/de/floater_directory2.xml @@ -237,7 +237,7 @@ Um direkt zu kaufen, klicken Sie auf dem betreffenden Land in der Titelleiste au -