From b4a5582309a2ceb03184ff07d26643f1e064e349 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Tue, 24 May 2016 12:38:18 -0300 Subject: [PATCH] Web: support for saving cookies across sessions - fixes #2447 --- src/Mod/Web/Gui/BrowserView.cpp | 5 ++ src/Mod/Web/Gui/CMakeLists.txt | 3 + src/Mod/Web/Gui/CookieJar.cpp | 131 ++++++++++++++++++++++++++++++++ src/Mod/Web/Gui/CookieJar.h | 59 ++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 src/Mod/Web/Gui/CookieJar.cpp create mode 100644 src/Mod/Web/Gui/CookieJar.h diff --git a/src/Mod/Web/Gui/BrowserView.cpp b/src/Mod/Web/Gui/BrowserView.cpp index 3bd5ea11b..c66262fb6 100644 --- a/src/Mod/Web/Gui/BrowserView.cpp +++ b/src/Mod/Web/Gui/BrowserView.cpp @@ -53,6 +53,7 @@ #endif #include "BrowserView.h" +#include "CookieJar.h" #include #include #include @@ -168,6 +169,10 @@ BrowserView::BrowserView(QWidget* parent) view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); view->page()->setForwardUnsupportedContent(true); + + // set our custom cookie manager + FcCookieJar* cookiejar = new FcCookieJar(this); + view->page()->networkAccessManager()->setCookieJar(cookiejar); // setting background to white QPalette palette = view->palette(); diff --git a/src/Mod/Web/Gui/CMakeLists.txt b/src/Mod/Web/Gui/CMakeLists.txt index 9df138834..8a4b7d7cd 100644 --- a/src/Mod/Web/Gui/CMakeLists.txt +++ b/src/Mod/Web/Gui/CMakeLists.txt @@ -24,10 +24,13 @@ SET(WebGui_SRCS Workbench.h BrowserView.h BrowserView.cpp + CookieJar.cpp + CookieJar.h ) set(WebGui_MOC_HDRS BrowserView.h + CookieJar.h ) fc_wrap_cpp(WebGui_MOC_SRCS ${WebGui_MOC_HDRS}) SOURCE_GROUP("Moc" FILES ${SketcherGui_MOC_SRCS}) diff --git a/src/Mod/Web/Gui/CookieJar.cpp b/src/Mod/Web/Gui/CookieJar.cpp new file mode 100644 index 000000000..c4ca5524f --- /dev/null +++ b/src/Mod/Web/Gui/CookieJar.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (c) 2016 Yorik van Havre * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#include +#include +#include +#endif + +#include "CookieJar.h" + +#include +#include + +using namespace WebGui; + +/** + * The default cookiejar of qt does not implement saving and restoring of + * cookies to disk. So we extend it here, and make it save and restore cookies + * to a simple text file saved in the FreeCAD user folder. + * adapted from https://github.com/adobe/webkit/blob/master/Tools/QtTestBrowser + */ + +FcCookieJar::FcCookieJar(QObject* parent) + : QNetworkCookieJar(parent) +{ + // We use a timer for the real disk write to avoid multiple IO + // syscalls in sequence (when loading pages which set multiple cookies). + m_timer.setInterval(10000); + m_timer.setSingleShot(true); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(saveToDisk())); + Base::FileInfo cookiefile(App::Application::getUserAppDataDir() + "cookies"); + m_file.setFileName(QString::fromUtf8(cookiefile.filePath().c_str())); + if (allCookies().isEmpty()) + loadFromDisk(); +} + +FcCookieJar::~FcCookieJar() +{ + extractRawCookies(); + saveToDisk(); +} + +bool FcCookieJar::setCookiesFromUrl(const QList& cookieList, const QUrl& url) +{ + bool status = QNetworkCookieJar::setCookiesFromUrl(cookieList, url); + if (status) + scheduleSaveToDisk(); + return status; +} + +void FcCookieJar::scheduleSaveToDisk() +{ + // We extract the raw cookies here because the user may + // enable/disable/clear cookies while the timer is running. + extractRawCookies(); + m_timer.start(); +} + +void FcCookieJar::extractRawCookies() +{ + QList cookies = allCookies(); + m_rawCookies.clear(); + + for (QList::iterator i = cookies.begin(); i != cookies.end(); i++) { + if (!(*i).isSessionCookie()) + m_rawCookies.append((*i).toRawForm()); + } +} + +void FcCookieJar::saveToDisk() +{ + m_timer.stop(); + + if (m_file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&m_file); + for (QList::iterator i = m_rawCookies.begin(); i != m_rawCookies.end(); i++) { + out << (*i) + "\n"; + } + m_file.close(); + } else + qWarning("IO error handling cookiejar file"); +} + +void FcCookieJar::loadFromDisk() +{ + if (!m_file.exists()) + return; + + QList cookies; + + if (m_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&m_file); + while (!in.atEnd()) + cookies.append(QNetworkCookie::parseCookies(in.readLine().toUtf8())); + m_file.close(); + } else + qWarning("IO error handling cookiejar file"); + + setAllCookies(cookies); +} + +void FcCookieJar::reset() +{ + setAllCookies(QList()); + scheduleSaveToDisk(); +} + +#include "moc_CookieJar.cpp" diff --git a/src/Mod/Web/Gui/CookieJar.h b/src/Mod/Web/Gui/CookieJar.h new file mode 100644 index 000000000..daba28309 --- /dev/null +++ b/src/Mod/Web/Gui/CookieJar.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (c) 2016 Yorik van Havre * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef WEBGUI_COOKIEJAR_H +#define WEBGUI_COOKIEJAR_H + +#include + +class QNetworkCookieJar; + +namespace WebGui { + + class WebGuiExport FcCookieJar : public QNetworkCookieJar { + + Q_OBJECT + + public: + FcCookieJar(QObject* parent = 0); + virtual ~FcCookieJar(); + virtual bool setCookiesFromUrl(const QList&, const QUrl&); + + public Q_SLOTS: + void scheduleSaveToDisk(); + void loadFromDisk(); + void reset(); + + private Q_SLOTS: + void saveToDisk(); + + private: + void extractRawCookies(); + QList m_rawCookies; + QFile m_file; + QTimer m_timer; + }; + +} + +#endif // WEBGUI_COOKIEJAR_H