Cloud storage: check connection before connecting

libgit2 takes forever (a minute or so) to figure out that it can't connect
to a remote server.
So if we are using https as connection protocol, quickly check utilizing
RFCs 2324/7168 to make sure we can reach the cloud server (and not some
captive portal or something).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2015-06-12 06:31:16 -07:00
parent 5e0c546beb
commit 4d06e8f7b5
4 changed files with 61 additions and 1 deletions

View file

@ -217,6 +217,7 @@ static int check_remote_status(git_repository *repo, git_remote *origin, const c
/* from qthelper.cpp */
extern bool getProxyString(char **proxy_string);
extern bool canReachCloudServer();
static git_repository *update_local_repo(const char *localdir, const char *remote, const char *branch)
{
@ -259,6 +260,8 @@ static git_repository *update_local_repo(const char *localdir, const char *remot
return repo;
}
if (rt == HTTPS && !canReachCloudServer())
return repo;
#if USE_LIBGIT23_API
git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
if (rt == SSH)

View file

@ -944,7 +944,6 @@ QNetworkReply* UserSurveyServices::sendSurvey(QString values)
CloudStorageAuthenticate::CloudStorageAuthenticate(QObject *parent) : QObject(parent)
{
userAgent = getUserAgent();
}
#define CLOUDURL "https://cloud.subsurface-divelog.org/"
@ -998,3 +997,48 @@ void CloudStorageAuthenticate::sslErrors(QList<QSslError> errorList)
qDebug() << err.errorString();
}
}
CheckCloudConnection::CheckCloudConnection(QObject *parent)
{
}
#define TEAPOT "https://cloud.subsurface-divelog.org/make-latte?number-of-shots=3"
#define HTTP_I_AM_A_TEAPOT 418
#define MILK "Linus does not like non-fat milk"
bool CheckCloudConnection::checkServer()
{
QTimer timer;
timer.setSingleShot(true);
QEventLoop loop;
QNetworkRequest request;
request.setRawHeader("Accept", "text/plain");
request.setRawHeader("User-Agent", getUserAgent().toUtf8());
request.setUrl(QString(TEAPOT));
QNetworkAccessManager *mgr = new QNetworkAccessManager();
QNetworkReply *reply = mgr->get(request);
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
timer.start(2000); // wait two seconds
loop.exec();
if (timer.isActive()) {
// didn't time out, did we get the right response?
timer.stop();
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == HTTP_I_AM_A_TEAPOT &&
reply->readAll() == QByteArray(MILK)) {
reply->deleteLater();
mgr->deleteLater();
return true;
}
// qDebug() << "did not get expected response - server unreachable" <<
// reply->error() << reply->errorString() <<
// reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() <<
// reply->readAll();
} else {
disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
reply->abort();
}
reply->deleteLater();
mgr->deleteLater();
return false;
}

View file

@ -129,6 +129,13 @@ private:
};
class CheckCloudConnection : public QObject {
Q_OBJECT
public:
explicit CheckCloudConnection(QObject *parent = 0);
static bool checkServer();
};
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -33,6 +33,7 @@
#include <QImageReader>
#include <QtConcurrent>
#include "divepicturewidget.h"
#include "subsurfacewebservices.h"
#include <libxslt/documents.h>
@ -1051,3 +1052,8 @@ extern "C" bool getProxyString(char **buffer)
}
return false;
}
extern "C" bool canReachCloudServer()
{
return CheckCloudConnection::checkServer();
}