[X2Go-Commits] [x2goclient] 01/01: Support for HTTP(S) urls in the session icons when using http broker.

git-admin at x2go.org git-admin at x2go.org
Tue Jul 13 10:50:43 CEST 2021


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2goclient.

commit df4a8ec7f4c2d19dac358579fdb246b9900f1cee
Author: Oleksandr Shneyder <o.shneyder at phoca-gmbh.de>
Date:   Tue Jul 13 10:50:31 2021 +0200

    Support for HTTP(S) urls in the session icons when using http broker.
---
 debian/changelog         |   1 +
 src/folderbutton.cpp     |  21 ++++-----
 src/httpbrokerclient.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/httpbrokerclient.h   |   6 +++
 src/sessionbutton.cpp    |  13 +++++-
 5 files changed, 140 insertions(+), 13 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index e7c8a85..388983b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -20,6 +20,7 @@ x2goclient (4.1.2.3-0x2go1) UNRELEASED; urgency=medium
     - X2Go Client will send it's OS name to the broker when sending client
       event.
     - Don't exit if connection to HTTP broker is failed when sync sessions.
+    - Support for HTTP(S) urls in the session icons when using http broker.
 
   [ Ryan Schmidt ]
   * New upstream version (4.1.2.3):
diff --git a/src/folderbutton.cpp b/src/folderbutton.cpp
index c0d4016..9f2211f 100644
--- a/src/folderbutton.cpp
+++ b/src/folderbutton.cpp
@@ -106,24 +106,25 @@ void FolderButton::loadIcon()
     else
         st= new X2goSettings( "sessions" );
 
-    QString sessIcon=par->iconsPath("/128x128/folder.png");
-    QPixmap* pix;
+    QPixmap* pix=new QPixmap();
 
     QString normPath=(path+"/"+name).split("/",QString::SkipEmptyParts).join("::");
-
-    QByteArray picture = QByteArray::fromBase64( st->setting()->value ( "icon_"+normPath,
-                       ( QVariant )QString()).toString().toLocal8Bit());
-    if(!picture.size())
+    QString picURL=st->setting()->value ( "icon_"+normPath, ( QVariant )QString()).toString();
+    if(picURL.indexOf("file://")!=-1)
     {
-        pix=new QPixmap( sessIcon );
+        //load icon from file URL
+        pix->load(picURL.replace("file://",""));
     }
     else
     {
-        pix=new QPixmap();
-        pix->loadFromData(picture);
+        pix->loadFromData(QByteArray::fromBase64( picURL.toLocal8Bit()));
+    }
+    if(pix->isNull())
+    {
+        //loading icon has failed, load default icon
+        pix->load(par->iconsPath("/128x128/folder.png"));
     }
     bool miniMode=par->retMiniMode();
-
     if ( !miniMode )
     {
         icon->setPixmap ( pix->scaled ( 64,64,Qt::IgnoreAspectRatio,
diff --git a/src/httpbrokerclient.cpp b/src/httpbrokerclient.cpp
index fa66613..88fbdc3 100644
--- a/src/httpbrokerclient.cpp
+++ b/src/httpbrokerclient.cpp
@@ -19,6 +19,7 @@
 #include <QNetworkAccessManager>
 #include <QUrl>
 #include <QNetworkRequest>
+#include <QNetworkDiskCache>
 #include <QNetworkReply>
 #include <QUuid>
 #include <QTextStream>
@@ -74,7 +75,12 @@ HttpBrokerClient::HttpBrokerClient ( ONMainWindow* wnd, ConfigFile* cfg )
             x2goDebug<<"Custom CA certificate file loaded into HTTPS broker client: "<<config->brokerCaCertFile;
         }
 
+        QDir dr;
+        dr.mkpath(mainWindow->getHomeDirectory()+"/.x2go");
         http=new QNetworkAccessManager ( this );
+        QNetworkDiskCache *cache = new QNetworkDiskCache(this);
+        cache->setCacheDirectory(mainWindow->getHomeDirectory()+"/.x2go/cache");
+        http->setCache(cache);
         x2goDebug<<"Setting up connection to broker: "<<config->brokerurl;
 
         connect ( http, SIGNAL ( sslErrors ( QNetworkReply*, const QList<QSslError>& ) ),this,
@@ -541,7 +547,39 @@ void HttpBrokerClient::createIniFile(const QString& raw_content)
         cont=lines[1];
         cont=cont.split("END_USER_SESSIONS\n")[0];
     }
-    mainWindow->config.iniFile=cont;
+
+    if(!sshBroker)
+    {
+        QStringList iniLines=cont.split("\n");
+        cont.clear();
+        clearResRequests();
+        //check if some of the icon or icon_foldername values are URLs and need to be downloaded
+        foreach(QString ln, iniLines)
+        {
+            ln=ln.trimmed();
+            if(ln.indexOf("icon")==0)
+            {
+                QStringList lnParts=ln.split("=");
+                QString iconUrl=lnParts.last().trimmed();
+                if((iconUrl.indexOf("http://")!=-1)||(iconUrl.indexOf("https://")!=-1))
+                {
+                    ln=lnParts[0]+"=file://"+getResource(iconUrl);
+                }
+            }
+            cont+=ln+"\n";
+        }
+        mainWindow->config.iniFile=cont;
+        if(resReplies.count()==0)
+        {
+            //we didn't request any resources, all session info is loaded
+            emit sessionsLoaded();
+        }
+    }
+    else
+    {
+        mainWindow->config.iniFile=cont;
+        emit sessionsLoaded();
+    }
     lines=content.split("START_CLIENT_CONFIG\n");
     if (lines.count()>1)
     {
@@ -556,6 +594,52 @@ void HttpBrokerClient::createIniFile(const QString& raw_content)
 }
 
 
+//get the fname on disk from resource URL
+QString HttpBrokerClient::resourceFname(const QUrl& url)
+{
+    QString fname=url.toString();
+    fname.replace("http://","");
+    fname.replace("https://","");
+    fname.replace("/","_");
+    QDir dr;
+    dr.mkdir(mainWindow->getHomeDirectory()+"/.x2go/res");
+    return mainWindow->getHomeDirectory()+"/.x2go/res/"+fname;
+}
+
+//return true if the URL is already requested
+bool HttpBrokerClient::isResRequested(const QUrl& url)
+{
+    foreach(QNetworkReply* reply, resReplies)
+    {
+        if(reply->url().toString()==url.toString())
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+//download resource if needed and return the name on the disk
+QString HttpBrokerClient::getResource(QString resURL)
+{
+    QUrl url(resURL);
+    if(!isResRequested(url))
+    {
+        resReplies << http->get(QNetworkRequest(url));
+    }
+    return resourceFname(url);
+}
+
+//clear list of res requests
+void HttpBrokerClient::clearResRequests()
+{
+    foreach(QNetworkReply* reply, resReplies)
+    {
+        reply->deleteLater();
+    }
+    resReplies.clear();
+}
+
 bool HttpBrokerClient::checkAccess(QString answer )
 {
 //     x2goDebug<<"Called checkAccess - answer was: "<<answer;
@@ -616,7 +700,6 @@ void HttpBrokerClient::slotListSessions(bool success, QString answer, int)
     mainWindow->setBrokerStatus(tr("Connected to broker"));
 
     createIniFile(answer);
-    emit sessionsLoaded();
 }
 
 void HttpBrokerClient::slotPassChanged(bool success, QString answer, int)
@@ -651,6 +734,30 @@ void HttpBrokerClient::slotSelectSession(bool success, QString answer, int)
 
 void HttpBrokerClient::slotRequestFinished ( QNetworkReply*  reply )
 {
+    if(resReplies.indexOf(reply) != -1)
+    {
+        if(reply->error() != QNetworkReply::NoError)
+        {
+            x2goDebug<<"Download request for "<<reply->url().toString()<< " failed with error: "<<reply->errorString();
+        }
+        else
+        {
+//             x2goDebug<<"saving to "<<resourceFname(reply->url().toString())<<" from cache: "<<reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
+            QFile file(resourceFname(reply->url().toString()));
+            file.open(QIODevice::WriteOnly);
+            file.write(reply->readAll());
+            file.close();
+        }
+        foreach(QNetworkReply* r, resReplies)
+        {
+            if(!r->isFinished())
+            {
+                return;
+            }
+        }
+        emit sessionsLoaded();
+        return;
+    }
     if(reply->error() != QNetworkReply::NoError)
     {
         x2goDebug<<"Broker HTTP request failed with error: "<<reply->errorString();
@@ -698,6 +805,7 @@ void HttpBrokerClient::slotRequestFinished ( QNetworkReply*  reply )
         slotEventSent(true,answer,0);
     }
 
+
     // We receive ownership of the reply object
     // and therefore need to handle deletion.
     reply->deleteLater();
diff --git a/src/httpbrokerclient.h b/src/httpbrokerclient.h
index f1ad345..bb15720 100644
--- a/src/httpbrokerclient.h
+++ b/src/httpbrokerclient.h
@@ -57,6 +57,8 @@ private:
     QNetworkReply* chPassRequest;
     QNetworkReply* testConRequest;
     QNetworkReply* eventRequest;
+    //List of replies with http resources (icons)
+    QList<QNetworkReply*> resReplies;
     QString nextAuthId;
     QString newBrokerPass;
     ConfigFile* config;
@@ -72,6 +74,10 @@ private:
     void createSshConnection();
     bool checkAccess(QString answer);
     QString scramblePwd(const QString& req);
+    QString getResource(QString resURL);
+    QString resourceFname(const QUrl& url);
+    bool isResRequested(const QUrl& url);
+    void clearResRequests();
 
 private slots:
     void slotRequestFinished ( QNetworkReply*  reply );
diff --git a/src/sessionbutton.cpp b/src/sessionbutton.cpp
index 0a46ee6..bfccf2a 100644
--- a/src/sessionbutton.cpp
+++ b/src/sessionbutton.cpp
@@ -373,7 +373,18 @@ void SessionButton::redraw()
     else
     {
         pix=new QPixmap;
-        pix->loadFromData(QByteArray::fromBase64(sessIcon.toLatin1()));
+        if(sessIcon.indexOf("file://")!=-1)
+        {
+            //load icon from file URL
+            pix->load(sessIcon.replace("file://",""));
+        }
+        else
+            pix->loadFromData(QByteArray::fromBase64(sessIcon.toLatin1()));
+        if(pix->isNull())
+        {
+            //loading icon has failed, load default icon
+            pix->load(par->iconsPath("/128x128/x2gosession.png"));
+        }
     }
     if ( !par->retMiniMode() )
         icon->setPixmap ( pix->scaled ( 64,64,Qt::IgnoreAspectRatio,

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goclient.git


More information about the x2go-commits mailing list