Remove QtCore and QtNetwork, replace them by libcurl + libc
This commit is contained in:
parent
0f475423c0
commit
2ce6142596
|
@ -39,8 +39,7 @@ For libgourou :
|
|||
|
||||
For utils :
|
||||
|
||||
* QT5Core
|
||||
* QT5Network
|
||||
* libcurl
|
||||
* OpenSSL
|
||||
* libzip
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define ACS_SERVER "http://adeactivate.adobe.com/adept"
|
||||
#endif
|
||||
|
||||
#define LIBGOUROU_VERSION "0.5.3"
|
||||
#define LIBGOUROU_VERSION "0.6"
|
||||
|
||||
namespace gourou
|
||||
{
|
||||
|
|
|
@ -111,7 +111,8 @@ namespace gourou
|
|||
CLIENT_ZIP_ERROR,
|
||||
CLIENT_GENERIC_EXCEPTION,
|
||||
CLIENT_NETWORK_ERROR,
|
||||
CLIENT_INVALID_PKCS8
|
||||
CLIENT_INVALID_PKCS8,
|
||||
CLIENT_FILE_ERROR
|
||||
};
|
||||
|
||||
enum DRM_REMOVAL_ERROR {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
TARGETS=acsmdownloader adept_activate adept_remove
|
||||
|
||||
CXXFLAGS=-Wall `pkg-config --cflags Qt5Core Qt5Network` -fPIC -I$(ROOT)/include -I$(ROOT)/lib/pugixml/src/
|
||||
CXXFLAGS=-Wall -fPIC -I$(ROOT)/include -I$(ROOT)/lib/pugixml/src/
|
||||
|
||||
STATIC_DEP=
|
||||
LDFLAGS=`pkg-config --libs Qt5Core Qt5Network` -L$(ROOT) -lcrypto -lzip -lz
|
||||
LDFLAGS=-L$(ROOT) -lcrypto -lzip -lz -lcurl
|
||||
|
||||
ifneq ($(STATIC_UTILS),)
|
||||
STATIC_DEP = $(ROOT)/libgourou.a
|
||||
|
@ -18,7 +18,7 @@ else
|
|||
CXXFLAGS += -O2
|
||||
endif
|
||||
|
||||
COMMON_DEPS = drmprocessorclientimpl.cpp $(STATIC_DEP)
|
||||
COMMON_DEPS = drmprocessorclientimpl.cpp utils_common.cpp $(STATIC_DEP)
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
|
|
|
@ -26,21 +26,14 @@
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <algorithm>
|
||||
|
||||
#include <libgourou.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
#include "utils_common.h"
|
||||
|
||||
static const char* deviceFile = "device.xml";
|
||||
static const char* activationFile = "activation.xml";
|
||||
|
@ -49,23 +42,13 @@ static const char* acsmFile = 0;
|
|||
static bool exportPrivateKey = false;
|
||||
static const char* outputFile = 0;
|
||||
static const char* outputDir = 0;
|
||||
static const char* defaultDirs[] = {
|
||||
".adept/",
|
||||
"./adobe-digital-editions/",
|
||||
"./.adobe-digital-editions/"
|
||||
};
|
||||
|
||||
|
||||
class ACSMDownloader: public QRunnable
|
||||
class ACSMDownloader
|
||||
{
|
||||
public:
|
||||
ACSMDownloader(QCoreApplication* app):
|
||||
app(app)
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
void run()
|
||||
|
||||
int run()
|
||||
{
|
||||
int ret = 0;
|
||||
try
|
||||
|
@ -84,9 +67,8 @@ public:
|
|||
|
||||
if (outputDir)
|
||||
{
|
||||
QDir dir(outputDir);
|
||||
if (!dir.exists(outputDir))
|
||||
dir.mkpath(outputDir);
|
||||
if (!fileExists(outputDir))
|
||||
mkpath(outputDir);
|
||||
|
||||
filename = std::string(outputDir) + "/" + filename;
|
||||
}
|
||||
|
@ -116,9 +98,8 @@ public:
|
|||
|
||||
if (outputDir)
|
||||
{
|
||||
QDir dir(outputDir);
|
||||
if (!dir.exists(outputDir))
|
||||
dir.mkpath(outputDir);
|
||||
if (!fileExists(outputDir))
|
||||
mkpath(outputDir);
|
||||
|
||||
filename = std::string(outputDir) + "/" + filename;
|
||||
}
|
||||
|
@ -132,8 +113,7 @@ public:
|
|||
finalName += ".pdf";
|
||||
else
|
||||
finalName += ".epub";
|
||||
QDir dir;
|
||||
dir.rename(filename.c_str(), finalName.c_str());
|
||||
rename(filename.c_str(), finalName.c_str());
|
||||
filename = finalName;
|
||||
}
|
||||
std::cout << "Created " << filename << std::endl;
|
||||
|
@ -144,37 +124,10 @@ public:
|
|||
ret = 1;
|
||||
}
|
||||
|
||||
this->app->exit(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
QCoreApplication* app;
|
||||
};
|
||||
|
||||
static const char* findFile(const char* filename, bool inDefaultDirs=true)
|
||||
{
|
||||
QFile file(filename);
|
||||
|
||||
if (file.exists())
|
||||
return strdup(filename);
|
||||
|
||||
if (!inDefaultDirs) return 0;
|
||||
|
||||
for (int i=0; i<(int)ARRAY_SIZE(defaultDirs); i++)
|
||||
{
|
||||
QString path = QString(defaultDirs[i]) + QString(filename);
|
||||
file.setFileName(path);
|
||||
if (file.exists())
|
||||
return strdup(path.toStdString().c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
{
|
||||
std::cout << "Current libgourou version : " << gourou::DRMProcessor::VERSION << std::endl ;
|
||||
}
|
||||
|
||||
static void usage(const char* cmd)
|
||||
{
|
||||
|
@ -275,8 +228,7 @@ int main(int argc, char** argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
ACSMDownloader downloader(&app);
|
||||
ACSMDownloader downloader;
|
||||
|
||||
int i;
|
||||
bool hasErrors = false;
|
||||
|
@ -306,8 +258,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
QFile file(acsmFile);
|
||||
if (!file.exists())
|
||||
if (!fileExists(acsmFile))
|
||||
{
|
||||
std::cout << "Error : " << acsmFile << " doesn't exists" << std::endl;
|
||||
ret = -1;
|
||||
|
@ -315,9 +266,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
QThreadPool::globalInstance()->start(&downloader);
|
||||
|
||||
ret = app.exec();
|
||||
ret = downloader.run();
|
||||
|
||||
end:
|
||||
for (i=0; i<(int)ARRAY_SIZE(files); i++)
|
||||
|
|
|
@ -28,22 +28,16 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <libgourou.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
#include "utils_common.h"
|
||||
|
||||
static const char* username = 0;
|
||||
static const char* password = 0;
|
||||
|
@ -100,16 +94,11 @@ static std::string getpass(const char *prompt, bool show_asterisk=false)
|
|||
}
|
||||
|
||||
|
||||
class ADEPTActivate: public QRunnable
|
||||
class ADEPTActivate
|
||||
{
|
||||
public:
|
||||
ADEPTActivate(QCoreApplication* app):
|
||||
app(app)
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
void run()
|
||||
public:
|
||||
|
||||
int run()
|
||||
{
|
||||
int ret = 0;
|
||||
try
|
||||
|
@ -128,17 +117,10 @@ public:
|
|||
ret = 1;
|
||||
}
|
||||
|
||||
this->app->exit(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
QCoreApplication* app;
|
||||
};
|
||||
|
||||
static void version(void)
|
||||
{
|
||||
std::cout << "Current libgourou version : " << gourou::DRMProcessor::VERSION << std::endl ;
|
||||
}
|
||||
|
||||
static void usage(const char* cmd)
|
||||
{
|
||||
|
@ -162,8 +144,8 @@ static void usage(const char* cmd)
|
|||
static const char* abspath(const char* filename)
|
||||
{
|
||||
const char* root = getcwd(0, PATH_MAX);
|
||||
QString fullPath = QString(root) + QString("/") + QString(filename);
|
||||
const char* res = strdup(fullPath.toStdString().c_str());
|
||||
std::string fullPath = std::string(root) + std::string("/") + filename;
|
||||
const char* res = strdup(fullPath.c_str());
|
||||
|
||||
free((void*)root);
|
||||
|
||||
|
@ -255,9 +237,8 @@ int main(int argc, char** argv)
|
|||
// Relative path
|
||||
if (_outputDir[0] == '.' || _outputDir[0] != '/')
|
||||
{
|
||||
QFile file(_outputDir);
|
||||
// realpath doesn't works if file/dir doesn't exists
|
||||
if (file.exists())
|
||||
if (fileExists(_outputDir))
|
||||
outputDir = strdup(realpath(_outputDir, 0));
|
||||
else
|
||||
outputDir = strdup(abspath(_outputDir));
|
||||
|
@ -266,10 +247,8 @@ int main(int argc, char** argv)
|
|||
outputDir = strdup(_outputDir);
|
||||
}
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
QFile file(outputDir);
|
||||
if (file.exists())
|
||||
std::string pass;
|
||||
if (fileExists(outputDir))
|
||||
{
|
||||
int key;
|
||||
|
||||
|
@ -289,7 +268,6 @@ int main(int argc, char** argv)
|
|||
;
|
||||
}
|
||||
|
||||
std::string pass;
|
||||
if (!password)
|
||||
{
|
||||
char prompt[128];
|
||||
|
@ -298,13 +276,11 @@ int main(int argc, char** argv)
|
|||
password = pass.c_str();
|
||||
}
|
||||
|
||||
ADEPTActivate activate(&app);
|
||||
QThreadPool::globalInstance()->start(&activate);
|
||||
ADEPTActivate activate;
|
||||
|
||||
ret = app.exec();
|
||||
ret = activate.run();
|
||||
|
||||
end:
|
||||
|
||||
end:
|
||||
free((void*)outputDir);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -26,23 +26,15 @@
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include <libgourou.h>
|
||||
#include <libgourou_common.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
#include "drmprocessorclientimpl.h"
|
||||
#include "utils_common.h"
|
||||
|
||||
static const char* deviceFile = "device.xml";
|
||||
static const char* activationFile = "activation.xml";
|
||||
|
@ -50,13 +42,9 @@ static const char* devicekeyFile = "devicesalt";
|
|||
static const char* inputFile = 0;
|
||||
static const char* outputFile = 0;
|
||||
static const char* outputDir = 0;
|
||||
static const char* defaultDirs[] = {
|
||||
".adept/",
|
||||
"./adobe-digital-editions/",
|
||||
"./.adobe-digital-editions/"
|
||||
};
|
||||
static char* encryptionKeyUser = 0;
|
||||
static unsigned char* encryptionKey = 0;
|
||||
|
||||
static char* encryptionKeyUser = 0;
|
||||
static unsigned char* encryptionKey = 0;
|
||||
static unsigned encryptionKeySize = 0;
|
||||
|
||||
static inline unsigned char htoi(unsigned char c)
|
||||
|
@ -78,16 +66,11 @@ static inline bool endsWith(const std::string& s, const std::string& suffix)
|
|||
return s.rfind(suffix) == std::abs((int)(s.size()-suffix.size()));
|
||||
}
|
||||
|
||||
class ADEPTRemove: public QRunnable
|
||||
class ADEPTRemove
|
||||
{
|
||||
public:
|
||||
ADEPTRemove(QCoreApplication* app):
|
||||
app(app)
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
void run()
|
||||
int run()
|
||||
{
|
||||
int ret = 0;
|
||||
try
|
||||
|
@ -104,9 +87,8 @@ public:
|
|||
|
||||
if (outputDir)
|
||||
{
|
||||
QDir dir(outputDir);
|
||||
if (!dir.exists(outputDir))
|
||||
dir.mkpath(outputDir);
|
||||
if (!fileExists(outputDir))
|
||||
mkpath(outputDir);
|
||||
|
||||
filename = std::string(outputDir) + "/" + filename;
|
||||
}
|
||||
|
@ -122,11 +104,8 @@ public:
|
|||
|
||||
if (inputFile != filename)
|
||||
{
|
||||
QFile::remove(filename.c_str());
|
||||
if (!QFile::copy(inputFile, filename.c_str()))
|
||||
{
|
||||
EXCEPTION(gourou::DRM_FILE_ERROR, "Unable to copy " << inputFile << " into " << filename);
|
||||
}
|
||||
unlink(filename.c_str());
|
||||
fileCopy(inputFile, filename.c_str());
|
||||
processor.removeDRM(inputFile, filename, type, encryptionKey, encryptionKeySize);
|
||||
std::cout << "DRM removed into new file " << filename << std::endl;
|
||||
}
|
||||
|
@ -135,18 +114,16 @@ public:
|
|||
// Use temp file for PDF
|
||||
if (type == gourou::DRMProcessor::ITEM_TYPE::PDF)
|
||||
{
|
||||
QTemporaryFile tempFile;
|
||||
tempFile.open();
|
||||
tempFile.setAutoRemove(false); // In case of failure
|
||||
processor.removeDRM(inputFile, tempFile.fileName().toStdString(), type, encryptionKey, encryptionKeySize);
|
||||
char* tempFile = tempnam("/tmp", NULL);
|
||||
processor.removeDRM(inputFile, tempFile, type, encryptionKey, encryptionKeySize);
|
||||
/* Original file must be removed before doing a copy... */
|
||||
QFile origFile(inputFile);
|
||||
origFile.remove();
|
||||
if (!QFile::copy(tempFile.fileName(), filename.c_str()))
|
||||
unlink(inputFile);
|
||||
if (!rename(tempFile, filename.c_str()))
|
||||
{
|
||||
EXCEPTION(gourou::DRM_FILE_ERROR, "Unable to copy " << tempFile.fileName().toStdString() << " into " << filename);
|
||||
free(tempFile);
|
||||
EXCEPTION(gourou::DRM_FILE_ERROR, "Unable to copy " << tempFile << " into " << filename);
|
||||
}
|
||||
tempFile.setAutoRemove(true);
|
||||
free(tempFile);
|
||||
}
|
||||
else
|
||||
processor.removeDRM(inputFile, filename, type, encryptionKey, encryptionKeySize);
|
||||
|
@ -158,38 +135,10 @@ public:
|
|||
ret = 1;
|
||||
}
|
||||
|
||||
this->app->exit(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
QCoreApplication* app;
|
||||
};
|
||||
|
||||
static const char* findFile(const char* filename, bool inDefaultDirs=true)
|
||||
{
|
||||
QFile file(filename);
|
||||
|
||||
if (file.exists())
|
||||
return strdup(filename);
|
||||
|
||||
if (!inDefaultDirs) return 0;
|
||||
|
||||
for (int i=0; i<(int)ARRAY_SIZE(defaultDirs); i++)
|
||||
{
|
||||
QString path = QString(defaultDirs[i]) + QString(filename);
|
||||
file.setFileName(path);
|
||||
if (file.exists())
|
||||
return strdup(path.toStdString().c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void version(void)
|
||||
{
|
||||
std::cout << "Current libgourou version : " << gourou::DRMProcessor::VERSION << std::endl ;
|
||||
}
|
||||
|
||||
static void usage(const char* cmd)
|
||||
{
|
||||
std::cout << "Remove ADEPT DRM (from Adobe) of EPUB/PDF file" << std::endl;
|
||||
|
@ -288,8 +237,7 @@ int main(int argc, char** argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
ADEPTRemove remover(&app);
|
||||
ADEPTRemove remover;
|
||||
|
||||
int i;
|
||||
bool hasErrors = false;
|
||||
|
@ -335,10 +283,8 @@ int main(int argc, char** argv)
|
|||
if (hasErrors)
|
||||
goto end;
|
||||
|
||||
QThreadPool::globalInstance()->start(&remover);
|
||||
|
||||
ret = app.exec();
|
||||
|
||||
ret = remover.run();
|
||||
|
||||
end:
|
||||
for (i=0; i<(int)ARRAY_SIZE(files); i++)
|
||||
{
|
||||
|
|
|
@ -25,17 +25,18 @@
|
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <bytearray.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QFile>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <zlib.h>
|
||||
#include <zip.h>
|
||||
|
@ -44,6 +45,27 @@
|
|||
#include <libgourou_log.h>
|
||||
#include "drmprocessorclientimpl.h"
|
||||
|
||||
// https://stackoverflow.com/questions/216823/how-to-trim-a-stdstring
|
||||
// trim from start (in place)
|
||||
static inline void ltrim(std::string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
}
|
||||
|
||||
// trim from end (in place)
|
||||
static inline void rtrim(std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
}
|
||||
|
||||
// trim from both ends (in place)
|
||||
static inline void trim(std::string &s) {
|
||||
ltrim(s);
|
||||
rtrim(s);
|
||||
}
|
||||
|
||||
/* Digest interface */
|
||||
void* DRMProcessorClientImpl::createDigest(const std::string& digestName)
|
||||
{
|
||||
|
@ -90,78 +112,120 @@ void DRMProcessorClientImpl::randBytes(unsigned char* bytesOut, unsigned int len
|
|||
/* HTTP interface */
|
||||
#define DISPLAY_THRESHOLD 10*1024 // Threshold to display download progression
|
||||
|
||||
static void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
|
||||
// For "big" files only
|
||||
if (bytesTotal >= DISPLAY_THRESHOLD && gourou::logLevel >= gourou::WARN)
|
||||
static int downloadProgress(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
||||
curl_off_t ultotal, curl_off_t ulnow)
|
||||
{
|
||||
// For "big" files only
|
||||
if (dltotal >= DISPLAY_THRESHOLD && gourou::logLevel >= gourou::WARN)
|
||||
{
|
||||
int percent = 0;
|
||||
if (bytesTotal)
|
||||
percent = (bytesReceived * 100) / bytesTotal;
|
||||
if (dltotal)
|
||||
percent = (dlnow * 100) / dltotal;
|
||||
|
||||
std::cout << "\rDownload " << percent << "%" << std::flush;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t curlRead(void *data, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
gourou::ByteArray* replyData = (gourou::ByteArray*) userp;
|
||||
|
||||
replyData->append((unsigned char*)data, size*nmemb);
|
||||
|
||||
return size*nmemb;
|
||||
}
|
||||
|
||||
static size_t curlHeaders(char *buffer, size_t size, size_t nitems, void *userdata)
|
||||
{
|
||||
std::map<std::string, std::string>* responseHeaders = (std::map<std::string, std::string>*)userdata;
|
||||
std::string::size_type pos = 0;
|
||||
std::string buf(buffer, size*nitems);
|
||||
|
||||
pos = buf.find(":", pos);
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string key = std::string(buffer, pos);
|
||||
std::string value = std::string(&buffer[pos+1], (size*nitems)-(pos+1));
|
||||
|
||||
trim(key);
|
||||
trim(value);
|
||||
|
||||
(*responseHeaders)[key] = value;
|
||||
|
||||
if (gourou::logLevel >= gourou::DEBUG)
|
||||
std::cout << key << " : " << value << std::endl;
|
||||
}
|
||||
|
||||
return size*nitems;
|
||||
}
|
||||
|
||||
std::string DRMProcessorClientImpl::sendHTTPRequest(const std::string& URL, const std::string& POSTData, const std::string& contentType, std::map<std::string, std::string>* responseHeaders)
|
||||
{
|
||||
QNetworkRequest request(QUrl(URL.c_str()));
|
||||
QNetworkAccessManager networkManager;
|
||||
QByteArray replyData;
|
||||
gourou::ByteArray replyData;
|
||||
std::map<std::string, std::string> localHeaders;
|
||||
|
||||
if (!responseHeaders)
|
||||
responseHeaders = &localHeaders;
|
||||
|
||||
GOUROU_LOG(gourou::INFO, "Send request to " << URL);
|
||||
if (POSTData.size())
|
||||
{
|
||||
GOUROU_LOG(gourou::DEBUG, "<<< " << std::endl << POSTData);
|
||||
}
|
||||
|
||||
request.setRawHeader("Accept", "*/*");
|
||||
request.setRawHeader("User-Agent", "book2png");
|
||||
if (contentType.size())
|
||||
request.setRawHeader("Content-Type", contentType.c_str());
|
||||
|
||||
QNetworkReply* reply;
|
||||
CURL *curl = curl_easy_init();
|
||||
CURLcode res;
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "book2png");
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
|
||||
struct curl_slist *list = NULL;
|
||||
list = curl_slist_append(list, "Accept: */*");
|
||||
std::string _contentType;
|
||||
if (contentType.size())
|
||||
{
|
||||
_contentType = "Content-Type: " + contentType;
|
||||
list = curl_slist_append(list, _contentType.c_str());
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
|
||||
|
||||
if (POSTData.size())
|
||||
reply = networkManager.post(request, POSTData.c_str());
|
||||
else
|
||||
reply = networkManager.get(request);
|
||||
|
||||
QEventLoop loop;
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
// Handled just below
|
||||
QObject::connect(reply, &QNetworkReply::errorOccurred, &loop, &QEventLoop::quit);
|
||||
QObject::connect(reply, &QNetworkReply::downloadProgress, &loop, downloadProgress);
|
||||
|
||||
loop.exec();
|
||||
|
||||
QByteArray location = reply->rawHeader("Location");
|
||||
if (location.size() != 0)
|
||||
{
|
||||
GOUROU_LOG(gourou::DEBUG, "New location");
|
||||
return sendHTTPRequest(location.constData(), POSTData, contentType, responseHeaders);
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, POSTData.size());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, POSTData.data());
|
||||
}
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
EXCEPTION(gourou::CLIENT_NETWORK_ERROR, "Error " << reply->errorString().toStdString());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlRead);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&replyData);
|
||||
|
||||
QList<QByteArray> headers = reply->rawHeaderList();
|
||||
for (int i = 0; i < headers.size(); ++i) {
|
||||
if (gourou::logLevel >= gourou::DEBUG)
|
||||
std::cout << headers[i].constData() << " : " << reply->rawHeader(headers[i]).constData() << std::endl;
|
||||
if (responseHeaders)
|
||||
(*responseHeaders)[headers[i].constData()] = reply->rawHeader(headers[i]).constData();
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curlHeaders);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void*)responseHeaders);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, downloadProgress);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_slist_free_all(list);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res != CURLE_OK)
|
||||
EXCEPTION(gourou::CLIENT_NETWORK_ERROR, "Error " << curl_easy_strerror(res));
|
||||
|
||||
replyData = reply->readAll();
|
||||
if (replyData.size() >= DISPLAY_THRESHOLD && gourou::logLevel >= gourou::WARN)
|
||||
std::cout << std::endl;
|
||||
if (reply->rawHeader("Content-Type") == "application/vnd.adobe.adept+xml")
|
||||
|
||||
if ((*responseHeaders)["Content-Type"] == "application/vnd.adobe.adept+xml")
|
||||
{
|
||||
GOUROU_LOG(gourou::DEBUG, ">>> " << std::endl << replyData.data());
|
||||
}
|
||||
|
||||
return std::string(replyData.data(), replyData.length());
|
||||
return std::string((char*)replyData.data(), replyData.length());
|
||||
}
|
||||
|
||||
void DRMProcessorClientImpl::RSAPrivateEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
||||
|
|
127
utils/utils_common.cpp
Normal file
127
utils/utils_common.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
Copyright (c) 2022, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <libgourou.h>
|
||||
#include <libgourou_common.h>
|
||||
#include "utils_common.h"
|
||||
|
||||
static const char* defaultDirs[] = {
|
||||
".adept/",
|
||||
"./adobe-digital-editions/",
|
||||
"./.adobe-digital-editions/"
|
||||
};
|
||||
|
||||
void version(void)
|
||||
{
|
||||
std::cout << "Current libgourou version : " << gourou::DRMProcessor::VERSION << std::endl ;
|
||||
}
|
||||
|
||||
bool fileExists(const char* filename)
|
||||
{
|
||||
struct stat _stat;
|
||||
int ret = stat(filename, &_stat);
|
||||
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
const char* findFile(const char* filename, bool inDefaultDirs)
|
||||
{
|
||||
if (fileExists(filename))
|
||||
return strdup(filename);
|
||||
|
||||
if (!inDefaultDirs) return 0;
|
||||
|
||||
for (int i=0; i<(int)ARRAY_SIZE(defaultDirs); i++)
|
||||
{
|
||||
std::string path = std::string(defaultDirs[i]) + filename;
|
||||
if (fileExists(path.c_str()))
|
||||
return strdup(path.c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/2336242/recursive-mkdir-system-call-on-unix
|
||||
void mkpath(const char *dir)
|
||||
{
|
||||
char tmp[PATH_MAX];
|
||||
char *p = NULL;
|
||||
size_t len;
|
||||
|
||||
snprintf(tmp, sizeof(tmp),"%s",dir);
|
||||
len = strlen(tmp);
|
||||
if (tmp[len - 1] == '/')
|
||||
tmp[len - 1] = 0;
|
||||
for (p = tmp + 1; *p; p++)
|
||||
if (*p == '/') {
|
||||
*p = 0;
|
||||
mkdir(tmp, S_IRWXU);
|
||||
*p = '/';
|
||||
}
|
||||
mkdir(tmp, S_IRWXU);
|
||||
}
|
||||
|
||||
void fileCopy(const char* in, const char* out)
|
||||
{
|
||||
char buffer[4096];
|
||||
int ret, fdIn, fdOut;
|
||||
|
||||
fdIn = open(in, O_RDONLY);
|
||||
|
||||
if (!fdIn)
|
||||
EXCEPTION(gourou::CLIENT_FILE_ERROR, "Unable to open " << in);
|
||||
|
||||
fdOut = open(out, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
|
||||
|
||||
if (!fdOut)
|
||||
{
|
||||
close (fdIn);
|
||||
EXCEPTION(gourou::CLIENT_FILE_ERROR, "Unable to open " << out);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
ret = ::read(fdIn, buffer, sizeof(buffer));
|
||||
if (ret <= 0)
|
||||
break;
|
||||
::write(fdOut, buffer, ret);
|
||||
}
|
||||
|
||||
close (fdIn);
|
||||
close (fdOut);
|
||||
}
|
64
utils/utils_common.h
Normal file
64
utils/utils_common.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright (c) 2022, Grégory Soutadé
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_COMMON_H_
|
||||
#define _UTILS_COMMON_H_
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
/**
|
||||
* @brief Display libgourou version
|
||||
*/
|
||||
void version(void);
|
||||
|
||||
/**
|
||||
* @brief Find a given filename in current directory and/or in default directories
|
||||
*
|
||||
* @param filename Filename to search
|
||||
* @param inDefaultDirs Search is default directories or not
|
||||
*
|
||||
* @return A copy of full path
|
||||
*/
|
||||
const char* findFile(const char* filename, bool inDefaultDirs=true);
|
||||
|
||||
/**
|
||||
* @brief Does the file (or directory exists)
|
||||
*/
|
||||
bool fileExists(const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Recursively created dir
|
||||
*/
|
||||
void mkpath(const char *dir);
|
||||
|
||||
/**
|
||||
* @brief Copy file in into file out
|
||||
*/
|
||||
void fileCopy(const char* in, const char* out);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user