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 \
|
||||
src/convertchecker.cpp \
|
||||
src/curlrequester.cpp \
|
||||
src/curlworker.cpp \
|
||||
src/ippdiscovery.cpp \
|
||||
src/ippmsg.cpp \
|
||||
src/ippprinter.cpp \
|
||||
|
@ -83,7 +82,6 @@ TRANSLATIONS += translations/harbour-seaprint-de.ts \
|
|||
HEADERS += \
|
||||
src/convertchecker.h \
|
||||
src/curlrequester.h \
|
||||
src/curlworker.h \
|
||||
src/ippdiscovery.h \
|
||||
src/ippmsg.h \
|
||||
src/ippprinter.h \
|
||||
|
|
|
@ -1,28 +1,86 @@
|
|||
#include "curlrequester.h"
|
||||
#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()
|
||||
{
|
||||
while(!_canWrite.tryAcquire(1, 500))
|
||||
{
|
||||
if(!_performer.isRunning())
|
||||
if(!_worker.isRunning())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
_done = true;
|
||||
_canRead.release();
|
||||
_performer.wait();
|
||||
_worker.waitForFinished();
|
||||
|
||||
if(_dest != nullptr)
|
||||
{
|
||||
delete _dest;
|
||||
}
|
||||
|
||||
curl_slist_free_all(_opts);
|
||||
curl_easy_cleanup(_curl);
|
||||
}
|
||||
|
||||
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;
|
||||
while(!_canWrite.tryAcquire(1, 500))
|
||||
{
|
||||
if(!_performer.isRunning())
|
||||
if(!_worker.isRunning())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5,29 +5,56 @@
|
|||
#include <QThread>
|
||||
#include <QSemaphore>
|
||||
#include <QMetaMethod>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <curl/curl.h>
|
||||
#include <bytestream.h>
|
||||
#include <QDebug>
|
||||
#include "curlworker.h"
|
||||
#include <functional>
|
||||
|
||||
class CurlRequester : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CurlRequester(QUrl addr);
|
||||
~CurlRequester();
|
||||
enum Role {
|
||||
IppRequest,
|
||||
HttpGetRequest
|
||||
};
|
||||
|
||||
template<typename Class, typename Callback>
|
||||
bool setFinishedCallback(const Class* receiverObject, Callback cb)
|
||||
{
|
||||
connect(&_performer, &CurlWorker::done, receiverObject, cb);
|
||||
return true;
|
||||
}
|
||||
CurlRequester(QUrl addr, Role role = IppRequest);
|
||||
~CurlRequester();
|
||||
|
||||
bool write(const char *data, 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:
|
||||
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;
|
||||
|
||||
QSemaphore _canWrite;
|
||||
|
@ -39,7 +66,12 @@ private:
|
|||
size_t _size;
|
||||
size_t _offset;
|
||||
|
||||
CurlWorker _performer;
|
||||
friend class CurlWorker;
|
||||
|
||||
CURL* _curl;
|
||||
struct curl_slist* _opts = NULL;
|
||||
|
||||
QFuture<void> _worker;
|
||||
};
|
||||
|
||||
#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