Make entering a Login URI in the grid manager more robust.
Before, when anything but the exact correct Login URI was entered, the user would either get no error, or a pop up saying "Cannot retrieve grid info from server." With this patch, that pop up includes what went wrong and stresses that they check if they entered the correct Login URI and where to find it. I was motivated to write this after looking at crash report 8405 where a user who had downloaded Singularity for the very first time crashed twice when entering things like "aviworlds" and " aviworlds.com:8002" (not the space), and "http:aviworlds.com:8002" (missing '//'). Especially in the light of FS accepting Login URI without the 'http://', a lot of grid websites (like that of aviworlds) might instruct users to enter the url without http://. Ie, this user was told to enter just "aviworlds.com:8002", and when that failed was instructed to add 'http' in front of it... Now the code accepts also really WEIRD things, but will never mess up a good entry. For example, if you enter "pssshht:aviworlds.com:8002" then that will work, as a side effect. The real objective however is of course to let things work like: "aviworlds.com:8002 ", "http:aviworlds.com:8002", " http:/aviworlds.com:8002", and to give a usable error message when there is a typo in the hostname (Cannot resolve hostname) or they forget to add a port number (404, or connection refused), plus the text "Make sure you entered the correct Login URI. An example of a Login URI is: \"http://cool.grid.com:8002/\", this url can usually be found on the website of the grid."
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<LLComboBox>("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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -1860,8 +1860,6 @@ Ein Grid mit dem gleichen Namen existiert bereits.</notification>
|
||||
|
||||
<notification name="GridInfoNoLoginUri">Eine Login URI wird benötigt um die Grid Informationen ab zu rufen.</notification>
|
||||
|
||||
<notification name="GridInfoError">Grid Info kann nicht vom Server abgerufen werden.</notification>
|
||||
|
||||
<notification name="HelpRenderCompat">Bauten mit erweiterten Hohlräumen oder erweiterten Lochgrößen werden auf anderen Viewern oft nicht korrekt gerendert. Bitte lassen Sie diese Option aktivuert, wenn Sie Ihren Bauten auch auf anderen Viewern korrekt anzeigen lassen wollen.</notification>
|
||||
|
||||
<notification name="ExportFailed">Fehlende Berechtigung zum Exportieren vom Objekt. Exportieren abgebrochen.</notification>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<string name="hippo_label_week">week</string>
|
||||
<string name="TeleportOfferMaturity">[NAME] is offering a TP to [DESTINATION]</string>
|
||||
<string name="TeleportLureMaturity">[NAME]'s teleport lure is to [DESTINATION]</string>
|
||||
<string name="GridInfoError">Grid Info kann nicht vom Server abgerufen werden:</string>
|
||||
|
||||
<!-- Default Args - these arguments will be replaced in all strings -->
|
||||
<string name="SECOND_LIFE">Second Life</string>
|
||||
|
||||
@@ -5801,13 +5801,6 @@ A grid with the same nickname already exists.
|
||||
A login URI is required to retrieve the grid info.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="GridInfoError"
|
||||
type="alertmodal">
|
||||
Cannot retrieve grid info from server.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="HelpRenderCompat"
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
<string name="TeleportLureMaturity">
|
||||
[NAME]'s teleport lure is to [DESTINATION]
|
||||
</string>
|
||||
<string name="GridInfoError">Cannot retrieve grid info from server:</string>
|
||||
<!-- The following entry starts and ends with a ", this is to allow the newline at the beginning. It also requires to use \" for quotes within. -->
|
||||
<string name="GridInfoErrorInstruction">"
|
||||
Make sure you entered the correct Login URI. An example of a Login URI is: \"http://cool.grid.com:8002/\", this url can usually be found on the website of the grid."
|
||||
</string>
|
||||
<string name="GridInfoErrorNoLoginURI">A login URI is required to retrieve the Grid Info.</string>
|
||||
<string name="GridInfoErrorNotFound">404 Page not found</string>
|
||||
<string name="GridInfoErrorNotAllowed">This grid does not support retrieving 'Grid Info'</string>
|
||||
<string name="GridInfoParseError">XML Parse Error: [XML_ERROR]</string>
|
||||
|
||||
<!-- Default Args - these arguments will be replaced in all strings -->
|
||||
<string name="SECOND_LIFE">Second Life</string>
|
||||
@@ -4368,9 +4377,11 @@ Try enclosing path to the editor with double quotes.
|
||||
<string name="completed_from">Teleport completed from</string>
|
||||
|
||||
<!-- AIAlert messages -->
|
||||
<!-- These two do not need translation ;) -->
|
||||
<string name="AIError">"\"[ERROR]\""</string>
|
||||
<string name="AIPrefix">"[PREFIX]: "</string>
|
||||
|
||||
<!-- AIFile exception alerts -->
|
||||
<!-- AIFile exception alerts -->
|
||||
<string name="AIFile_mkdir_Failed_to_create_DIRNAME">Failed to create folder [DIRNAME]: [ERROR]</string>
|
||||
<string name="AIFile_rmdir_Failed_to_remove_DIRNAME">Failed to remove folder [DIRNAME]: [ERROR]</string>
|
||||
<string name="AIFile_fopen_Failed_to_open_FILENAME">Failed to open file "[FILENAME]": [ERROR]</string>
|
||||
|
||||
@@ -3262,11 +3262,7 @@ Ya existe un grid con el mismo nombre.
|
||||
<notification name="GridInfoNoLoginUri">
|
||||
Se requiere un URI de inicio de sesión para recuperar la información del grid.
|
||||
</notification>
|
||||
|
||||
<notification name="GridInfoError">
|
||||
No se puede recuperar la información del grid desde el servidor.
|
||||
</notification>
|
||||
|
||||
|
||||
<notification name="HelpRenderCompat">
|
||||
Las construcciones con huecos extendidos o tamaños de agujeros extendidos no se renderizarán adecuadamente en otros visores. Por favor, mantén esta opción marcada si quieres que tus construcciones se vean adecuadamente in otros visores.
|
||||
</notification>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<string name="hippo_label_week">semana</string>
|
||||
<string name="TeleportOfferMaturity">[NAME] te ofrece un TP a [DESTINATION]</string>
|
||||
<string name="TeleportLureMaturity">[NAME] te ofrece una invitación de teleporte a [DESTINATION]</string>
|
||||
<string name="GridInfoError">No se puede recuperar la información del grid desde el servidor:</string>
|
||||
|
||||
<!-- Default Args - these arguments will be replaced in all strings -->
|
||||
<string name="SECOND_LIFE">Second Life</string>
|
||||
|
||||
Reference in New Issue
Block a user