restructure curlrequester
This commit is contained in:
parent
47cde78edc
commit
6c4e48d69c
5 changed files with 105 additions and 125 deletions
|
@ -36,7 +36,6 @@ DEFINES += SEAPRINT_VERSION='\\"$$VERSION\\"'
|
||||||
SOURCES += src/harbour-seaprint.cpp \
|
SOURCES += src/harbour-seaprint.cpp \
|
||||||
src/convertchecker.cpp \
|
src/convertchecker.cpp \
|
||||||
src/curlrequester.cpp \
|
src/curlrequester.cpp \
|
||||||
src/curlworker.cpp \
|
|
||||||
src/ippdiscovery.cpp \
|
src/ippdiscovery.cpp \
|
||||||
src/ippmsg.cpp \
|
src/ippmsg.cpp \
|
||||||
src/ippprinter.cpp \
|
src/ippprinter.cpp \
|
||||||
|
@ -83,7 +82,6 @@ TRANSLATIONS += translations/harbour-seaprint-de.ts \
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/convertchecker.h \
|
src/convertchecker.h \
|
||||||
src/curlrequester.h \
|
src/curlrequester.h \
|
||||||
src/curlworker.h \
|
|
||||||
src/ippdiscovery.h \
|
src/ippdiscovery.h \
|
||||||
src/ippmsg.h \
|
src/ippmsg.h \
|
||||||
src/ippprinter.h \
|
src/ippprinter.h \
|
||||||
|
|
|
@ -1,28 +1,86 @@
|
||||||
#include "curlrequester.h"
|
#include "curlrequester.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
CurlRequester::CurlRequester(QUrl addr) : _addr(addr), _canWrite(1), _canRead(), _reading(false), _done(false), _dest(nullptr), _size(0), _offset(0), _performer(addr, this)
|
static size_t trampoline(char* dest, size_t size, size_t nmemb, void* userp)
|
||||||
{
|
{
|
||||||
_performer.start();
|
CurlRequester* cid = (CurlRequester*)userp;
|
||||||
|
return cid->requestWrite(dest, size*nmemb);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurlRequester::CurlRequester(QUrl addr, Role role)
|
||||||
|
: _addr(addr), _canWrite(1), _canRead(), _reading(false), _done(false), _dest(nullptr), _size(0), _offset(0), _curl(curl_easy_init())
|
||||||
|
{
|
||||||
|
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_URL, addr.toString().toStdString().c_str());
|
||||||
|
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
if(Settings::instance()->ignoreSslErrors())
|
||||||
|
{
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYSTATUS, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
_opts = NULL;
|
||||||
|
_opts = curl_slist_append(_opts, "User-Agent: SeaPrint " SEAPRINT_VERSION);
|
||||||
|
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case IppRequest:
|
||||||
|
{
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_POST, 1L);
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_READFUNCTION, trampoline);
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_READDATA, this);
|
||||||
|
|
||||||
|
_opts = curl_slist_append(_opts, "Expect:");
|
||||||
|
_opts = curl_slist_append(_opts, "Transfer-Encoding: chunked");
|
||||||
|
_opts = curl_slist_append(_opts, "Content-Type: application/ipp");
|
||||||
|
_opts = curl_slist_append(_opts, "Accept-Encoding: identity");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HttpGetRequest:
|
||||||
|
{
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_HTTPGET, 1L);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _opts);
|
||||||
|
|
||||||
|
_worker = QtConcurrent::run([this](){
|
||||||
|
Bytestream buf;
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &buf);
|
||||||
|
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||||
|
|
||||||
|
CURLcode res = curl_easy_perform(_curl);
|
||||||
|
if(res != CURLE_OK)
|
||||||
|
qDebug() << "curl_easy_perform() failed: " << curl_easy_strerror(res);
|
||||||
|
|
||||||
|
emit done(res, buf);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CurlRequester::~CurlRequester()
|
CurlRequester::~CurlRequester()
|
||||||
{
|
{
|
||||||
while(!_canWrite.tryAcquire(1, 500))
|
while(!_canWrite.tryAcquire(1, 500))
|
||||||
{
|
{
|
||||||
if(!_performer.isRunning())
|
if(!_worker.isRunning())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_done = true;
|
_done = true;
|
||||||
_canRead.release();
|
_canRead.release();
|
||||||
_performer.wait();
|
_worker.waitForFinished();
|
||||||
|
|
||||||
if(_dest != nullptr)
|
if(_dest != nullptr)
|
||||||
{
|
{
|
||||||
delete _dest;
|
delete _dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curl_slist_free_all(_opts);
|
||||||
|
curl_easy_cleanup(_curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CurlRequester::write(const char *data, size_t size)
|
bool CurlRequester::write(const char *data, size_t size)
|
||||||
|
@ -30,7 +88,7 @@ bool CurlRequester::write(const char *data, size_t size)
|
||||||
qDebug() << "write " << size;
|
qDebug() << "write " << size;
|
||||||
while(!_canWrite.tryAcquire(1, 500))
|
while(!_canWrite.tryAcquire(1, 500))
|
||||||
{
|
{
|
||||||
if(!_performer.isRunning())
|
if(!_worker.isRunning())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,29 +5,56 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
#include <QMetaMethod>
|
#include <QMetaMethod>
|
||||||
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
#include <bytestream.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "curlworker.h"
|
#include <functional>
|
||||||
|
|
||||||
class CurlRequester : public QObject
|
class CurlRequester : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CurlRequester(QUrl addr);
|
enum Role {
|
||||||
~CurlRequester();
|
IppRequest,
|
||||||
|
HttpGetRequest
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Class, typename Callback>
|
CurlRequester(QUrl addr, Role role = IppRequest);
|
||||||
bool setFinishedCallback(const Class* receiverObject, Callback cb)
|
~CurlRequester();
|
||||||
{
|
|
||||||
connect(&_performer, &CurlWorker::done, receiverObject, cb);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool write(const char *data, size_t size);
|
bool write(const char *data, size_t size);
|
||||||
size_t requestWrite(char* dest, size_t size);
|
size_t requestWrite(char* dest, size_t size);
|
||||||
|
|
||||||
|
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void* userdata)
|
||||||
|
{
|
||||||
|
size_t bytes_to_write = size*nmemb;
|
||||||
|
((Bytestream*)userdata)->putBytes(ptr, bytes_to_write);
|
||||||
|
return bytes_to_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void done(CURLcode, Bytestream);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CurlRequester();
|
||||||
|
|
||||||
|
// Container for the cURL global init and cleanup
|
||||||
|
class GlobalEnv
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GlobalEnv()
|
||||||
|
{
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
}
|
||||||
|
~GlobalEnv()
|
||||||
|
{
|
||||||
|
curl_global_cleanup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Must be run exactly once, thus static
|
||||||
|
static GlobalEnv _gEnv;
|
||||||
|
|
||||||
QUrl _addr;
|
QUrl _addr;
|
||||||
|
|
||||||
QSemaphore _canWrite;
|
QSemaphore _canWrite;
|
||||||
|
@ -39,7 +66,12 @@ private:
|
||||||
size_t _size;
|
size_t _size;
|
||||||
size_t _offset;
|
size_t _offset;
|
||||||
|
|
||||||
CurlWorker _performer;
|
friend class CurlWorker;
|
||||||
|
|
||||||
|
CURL* _curl;
|
||||||
|
struct curl_slist* _opts = NULL;
|
||||||
|
|
||||||
|
QFuture<void> _worker;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CURLREQUESTER_H
|
#endif // CURLREQUESTER_H
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
#include "curlworker.h"
|
|
||||||
#include "curlrequester.h"
|
|
||||||
#include "settings.h"
|
|
||||||
|
|
||||||
static size_t trampoline(char* dest, size_t size, size_t nmemb, void* userp)
|
|
||||||
{
|
|
||||||
CurlRequester* cid = (CurlRequester*)userp;
|
|
||||||
return cid->requestWrite(dest, size*nmemb);
|
|
||||||
}
|
|
||||||
|
|
||||||
CurlWorker::CurlWorker(QUrl addr, void* parent)
|
|
||||||
{
|
|
||||||
_curl = curl_easy_init();
|
|
||||||
// if(!curl)
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_URL, addr.toString().toStdString().c_str());
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_POST, 1L);
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_READFUNCTION, trampoline);
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_READDATA, parent);
|
|
||||||
// curl_easy_setopt(_curl, CURLOPT_VERBOSE, 1L);
|
|
||||||
if(Settings::instance()->ignoreSslErrors())
|
|
||||||
{
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYSTATUS, 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
_opts = NULL;
|
|
||||||
|
|
||||||
_opts = curl_slist_append(_opts, "Expect:");
|
|
||||||
_opts = curl_slist_append(_opts, "Transfer-Encoding: chunked");
|
|
||||||
_opts = curl_slist_append(_opts, "Content-Type: application/ipp");
|
|
||||||
_opts = curl_slist_append(_opts, "User-Agent: SeaPrint " SEAPRINT_VERSION);
|
|
||||||
_opts = curl_slist_append(_opts, "Accept-Encoding: identity");
|
|
||||||
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _opts);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CurlWorker::~CurlWorker()
|
|
||||||
{
|
|
||||||
curl_slist_free_all(_opts);
|
|
||||||
curl_easy_cleanup(_curl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CurlWorker::run(){
|
|
||||||
Bytestream buf;
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &buf);
|
|
||||||
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, write_callback);
|
|
||||||
|
|
||||||
CURLcode res = curl_easy_perform(_curl);
|
|
||||||
if(res != CURLE_OK)
|
|
||||||
qDebug() << "curl_easy_perform() failed: " << curl_easy_strerror(res);
|
|
||||||
|
|
||||||
emit done(res, buf);
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
#ifndef CURLWORKER_H
|
|
||||||
#define CURLWORKER_H
|
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <QtDebug>
|
|
||||||
#include <bytestream.h>
|
|
||||||
|
|
||||||
class CurlWorker : public QThread
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
CurlWorker(QUrl addr, void* parent);
|
|
||||||
~CurlWorker();
|
|
||||||
|
|
||||||
void run() override;
|
|
||||||
|
|
||||||
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void* userdata)
|
|
||||||
{
|
|
||||||
size_t bytes_to_write = size*nmemb;
|
|
||||||
((Bytestream*)userdata)->putBytes(ptr, bytes_to_write);
|
|
||||||
return bytes_to_write;
|
|
||||||
}
|
|
||||||
signals:
|
|
||||||
void done(CURLcode, Bytestream);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Container for the cURL global init and cleanup
|
|
||||||
class GlobalEnv
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GlobalEnv()
|
|
||||||
{
|
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
||||||
}
|
|
||||||
~GlobalEnv()
|
|
||||||
{
|
|
||||||
curl_global_cleanup();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Must be run exactly once, thus static
|
|
||||||
static GlobalEnv _gEnv;
|
|
||||||
|
|
||||||
CurlWorker();
|
|
||||||
CURL* _curl = nullptr;
|
|
||||||
struct curl_slist* _opts;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CURLWORKER_H
|
|
Loading…
Reference in a new issue