mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-19 10:20:17 -06:00
dbhub: Push databases using the POST method instead of PUT
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QHttpMultiPart>
|
||||
|
||||
#include "RemoteDatabase.h"
|
||||
#include "version.h"
|
||||
@@ -98,10 +99,6 @@ void RemoteDatabase::gotEncrypted(QNetworkReply* reply)
|
||||
|
||||
void RemoteDatabase::gotReply(QNetworkReply* reply)
|
||||
{
|
||||
// If this was a push database request, close the opened file
|
||||
if(reply->property("type").toInt() == RequestTypePush)
|
||||
delete reinterpret_cast<const QFile*>(reply->property("file").value<void*>());
|
||||
|
||||
// Check if request was successful
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
@@ -197,10 +194,6 @@ void RemoteDatabase::gotReply(QNetworkReply* reply)
|
||||
|
||||
void RemoteDatabase::gotError(QNetworkReply* reply, const QList<QSslError>& errors)
|
||||
{
|
||||
// If this was a push database request, close the opened file
|
||||
if(reply->property("type").toInt() == RequestTypePush)
|
||||
delete reinterpret_cast<const QFile*>(reply->property("file").value<void*>());
|
||||
|
||||
// Are there any errors in here that aren't about self-signed certificates and non-matching hostnames?
|
||||
bool serious_errors = false;
|
||||
foreach(const QSslError& error, errors)
|
||||
@@ -395,7 +388,7 @@ void RemoteDatabase::fetch(const QString& url, RequestType type, const QString&
|
||||
prepareProgressDialog(reply, false, url);
|
||||
}
|
||||
|
||||
void RemoteDatabase::push(const QString& filename, const QString& url, const QString& clientCert,
|
||||
void RemoteDatabase::push(const QString& filename, const QString& url, const QString& clientCert, const QString& remotename,
|
||||
const QString& commitMessage, const QString& licence, bool isPublic)
|
||||
{
|
||||
// Check if network is accessible. If not, abort right here
|
||||
@@ -419,10 +412,12 @@ void RemoteDatabase::push(const QString& filename, const QString& url, const QSt
|
||||
request.setUrl(url);
|
||||
request.setRawHeader("User-Agent", QString("%1 %2").arg(qApp->organizationName()).arg(APP_VERSION).toUtf8());
|
||||
|
||||
// Set custom headers for extra information about the commit
|
||||
request.setRawHeader("commitmsg", commitMessage.toUtf8());
|
||||
request.setRawHeader("licence", licence.toUtf8());
|
||||
request.setRawHeader("public", isPublic ? "true" : "false");
|
||||
// Prepare HTTP multi part data containing all the information about the commit we're about to push
|
||||
QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||
addPart(multipart, "file", file, remotename);
|
||||
addPart(multipart, "commitmsg", commitMessage);
|
||||
addPart(multipart, "licence", licence);
|
||||
addPart(multipart, "public", isPublic ? "true" : "false");
|
||||
|
||||
// Set SSL configuration when trying to access a file via the HTTPS protocol
|
||||
bool https = QUrl(url).scheme().compare("https", Qt::CaseInsensitive) == 0;
|
||||
@@ -440,14 +435,33 @@ void RemoteDatabase::push(const QString& filename, const QString& url, const QSt
|
||||
clearAccessCache(clientCert);
|
||||
|
||||
// Put database to remote server and save pending reply for future processing
|
||||
QNetworkReply* reply = m_manager->put(request, file);
|
||||
QNetworkReply* reply = m_manager->post(request, multipart);
|
||||
reply->setProperty("type", RequestTypePush);
|
||||
reply->setProperty("file", qVariantFromValue(dynamic_cast<void*>(file)));
|
||||
multipart->setParent(reply); // Delete the multi-part object along with the reply
|
||||
|
||||
// Initialise the progress dialog for this request
|
||||
prepareProgressDialog(reply, true, url);
|
||||
}
|
||||
|
||||
void RemoteDatabase::addPart(QHttpMultiPart* multipart, const QString& name, const QString& value)
|
||||
{
|
||||
QHttpPart part;
|
||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(name));
|
||||
part.setBody(value.toUtf8());
|
||||
|
||||
multipart->append(part);
|
||||
}
|
||||
|
||||
void RemoteDatabase::addPart(QHttpMultiPart* multipart, const QString& name, QFile* file, const QString& filename)
|
||||
{
|
||||
QHttpPart part;
|
||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"; filename=\"%2\"").arg(name).arg(filename));
|
||||
part.setBodyDevice(file);
|
||||
file->setParent(multipart); // Close the file and delete the file object as soon as the multi-part object is destroyed
|
||||
|
||||
multipart->append(part);
|
||||
}
|
||||
|
||||
void RemoteDatabase::localAssureOpened()
|
||||
{
|
||||
// This function should be called first in each RemoteDatabase::local* function. It assures the database for storing
|
||||
|
||||
@@ -10,6 +10,8 @@ class QNetworkReply;
|
||||
class QSslError;
|
||||
class QProgressDialog;
|
||||
class QNetworkRequest;
|
||||
class QHttpMultiPart;
|
||||
class QFile;
|
||||
struct sqlite3;
|
||||
|
||||
class RemoteDatabase : public QObject
|
||||
@@ -42,7 +44,7 @@ public:
|
||||
};
|
||||
|
||||
void fetch(const QString& url, RequestType type, const QString& clientCert = QString(), QVariant userdata = QVariant());
|
||||
void push(const QString& filename, const QString& url, const QString& clientCert,
|
||||
void push(const QString& filename, const QString& url, const QString& clientCert, const QString& remotename,
|
||||
const QString& commitMessage = QString(), const QString& licence = QString(), bool isPublic = false);
|
||||
|
||||
signals:
|
||||
@@ -72,6 +74,10 @@ private:
|
||||
void localAdd(QString filename, QString identity, const QUrl& url);
|
||||
QString localExists(const QUrl& url, QString identity);
|
||||
|
||||
// Helper functions for building multi-part HTTP requests
|
||||
void addPart(QHttpMultiPart* multipart, const QString& name, const QString& value);
|
||||
void addPart(QHttpMultiPart* multipart, const QString& name, QFile* file, const QString& filename);
|
||||
|
||||
// Before using a new client certificate we need to clear the access and authentication cache of the network manager
|
||||
// object. Otherwise Qt might reuse the old certificate if the requested URL has been used before.
|
||||
void clearAccessCache(const QString& clientCert);
|
||||
|
||||
@@ -110,7 +110,7 @@ void RemoteDock::pushDatabase()
|
||||
url.append(pushDialog.name());
|
||||
|
||||
// Push database
|
||||
remoteDatabase.push(mainWindow->getDb().currentFile(), url, remoteModel->currentClientCertificate(),
|
||||
remoteDatabase.push(mainWindow->getDb().currentFile(), url, remoteModel->currentClientCertificate(), pushDialog.name(),
|
||||
pushDialog.commitMessage(), pushDialog.licence(), pushDialog.isPublic());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user