forked from soutade/libgourou
Add support for PDF (needs uPDFParser library)
This commit is contained in:
parent
8bc346d139
commit
3d9e343734
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,5 +4,5 @@ lib
|
||||||
*.so
|
*.so
|
||||||
*~
|
*~
|
||||||
utils/acsmdownloader
|
utils/acsmdownloader
|
||||||
utils/activate
|
utils/adept_activate
|
||||||
.adept
|
.adept
|
||||||
|
|
25
Makefile
25
Makefile
|
@ -2,8 +2,21 @@
|
||||||
AR ?= $(CROSS)ar
|
AR ?= $(CROSS)ar
|
||||||
CXX ?= $(CROSS)g++
|
CXX ?= $(CROSS)g++
|
||||||
|
|
||||||
CXXFLAGS=-Wall -fPIC -I./include -I./lib -I./lib/pugixml/src/
|
UPDFPARSERLIB = ./lib/updfparser/libupdfparser.a
|
||||||
LDFLAGS=
|
|
||||||
|
CXXFLAGS=-Wall -fPIC -I./include -I./lib -I./lib/pugixml/src/ -I./lib/updfparser/include
|
||||||
|
LDFLAGS = $(UPDFPARSERLIB)
|
||||||
|
|
||||||
|
BUILD_STATIC ?= 0
|
||||||
|
BUILD_SHARED ?= 1
|
||||||
|
|
||||||
|
TARGETS =
|
||||||
|
ifneq (BUILD_STATIC, 0)
|
||||||
|
TARGETS += libgourou.a
|
||||||
|
endif
|
||||||
|
ifneq (BUILD_SHARED, 0)
|
||||||
|
TARGETS += libgourou.so
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(DEBUG),)
|
ifneq ($(DEBUG),)
|
||||||
CXXFLAGS += -ggdb -O0
|
CXXFLAGS += -ggdb -O0
|
||||||
|
@ -18,12 +31,12 @@ TARGETDIR := bin
|
||||||
SRCEXT := cpp
|
SRCEXT := cpp
|
||||||
OBJEXT := o
|
OBJEXT := o
|
||||||
|
|
||||||
SOURCES=src/libgourou.cpp src/user.cpp src/device.cpp src/fulfillment_item.cpp src/bytearray.cpp src/pugixml.cpp
|
SOURCES = src/libgourou.cpp src/user.cpp src/device.cpp src/fulfillment_item.cpp src/bytearray.cpp src/pugixml.cpp
|
||||||
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))
|
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))
|
||||||
|
|
||||||
.PHONY: utils
|
.PHONY: utils
|
||||||
|
|
||||||
all: lib obj libgourou utils
|
all: lib obj $(TARGETS) utils
|
||||||
|
|
||||||
lib:
|
lib:
|
||||||
mkdir lib
|
mkdir lib
|
||||||
|
@ -38,9 +51,9 @@ $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)
|
||||||
libgourou: libgourou.a libgourou.so
|
libgourou: libgourou.a libgourou.so
|
||||||
|
|
||||||
libgourou.a: $(OBJECTS)
|
libgourou.a: $(OBJECTS)
|
||||||
$(AR) crs $@ obj/*.o
|
$(AR) crs $@ obj/*.o $(LDFLAGS)
|
||||||
|
|
||||||
libgourou.so: libgourou.a
|
libgourou.so: $(OBJECTS) $(UPDFPARSERLIB)
|
||||||
$(CXX) obj/*.o $(LDFLAGS) -o $@ -shared
|
$(CXX) obj/*.o $(LDFLAGS) -o $@ -shared
|
||||||
|
|
||||||
utils:
|
utils:
|
||||||
|
|
|
@ -47,7 +47,7 @@ Compilation
|
||||||
|
|
||||||
Use _make_ command
|
Use _make_ command
|
||||||
|
|
||||||
make [CROSS=XXX] [DEBUG=1] [STATIC_UTILS=1]
|
make [CROSS=XXX] [DEBUG=1] [STATIC_UTILS=1] [BUILD_STATIC=(0|1)] [BUILD_SHARED=(0|1)]
|
||||||
|
|
||||||
CROSS can define a cross compiler prefix (ie arm-linux-gnueabihf-)
|
CROSS can define a cross compiler prefix (ie arm-linux-gnueabihf-)
|
||||||
|
|
||||||
|
@ -55,6 +55,9 @@ DEBUG can be set to compile in DEBUG mode
|
||||||
|
|
||||||
STATIC_UTILS to build utils with static library (libgourou.a) instead of default dynamic one (libgourou.so)
|
STATIC_UTILS to build utils with static library (libgourou.a) instead of default dynamic one (libgourou.so)
|
||||||
|
|
||||||
|
BUILD_STATIC build libgourou.a if 1, nothing if 0 (default value), can be combined with BUILD_SHARED
|
||||||
|
|
||||||
|
BUILD_SHARED build libgourou.so if 1 (default value), nothing if 0, can be combined with BUILD_STATIC
|
||||||
|
|
||||||
Utils
|
Utils
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define _DRMPROCESSORCLIENT_H_
|
#define _DRMPROCESSORCLIENT_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <bytearray.h>
|
||||||
|
|
||||||
namespace gourou
|
namespace gourou
|
||||||
{
|
{
|
||||||
|
@ -96,8 +97,11 @@ namespace gourou
|
||||||
* @param URL HTTP URL
|
* @param URL HTTP URL
|
||||||
* @param POSTData POST data if needed, if not set, a GET request is done
|
* @param POSTData POST data if needed, if not set, a GET request is done
|
||||||
* @param contentType Optional content type of POST Data
|
* @param contentType Optional content type of POST Data
|
||||||
|
* @param responseHeaders Optional Response headers of HTTP request
|
||||||
|
*
|
||||||
|
* @return data of HTTP response
|
||||||
*/
|
*/
|
||||||
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string("")) = 0;
|
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""), std::map<std::string, std::string>* responseHeaders=0) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RSAInterface
|
class RSAInterface
|
||||||
|
@ -355,6 +359,27 @@ namespace gourou
|
||||||
* @param handler ZIP file handler
|
* @param handler ZIP file handler
|
||||||
*/
|
*/
|
||||||
virtual void zipClose(void* handler) = 0;
|
virtual void zipClose(void* handler) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inflate algorithm
|
||||||
|
*
|
||||||
|
* @param data Data to inflate
|
||||||
|
* @param result Zipped data
|
||||||
|
* @param wbits Window bits value for libz
|
||||||
|
*/
|
||||||
|
virtual void inflate(std::string data, gourou::ByteArray& result,
|
||||||
|
int wbits=-15) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deflate algorithm
|
||||||
|
*
|
||||||
|
* @param data Data to deflate
|
||||||
|
* @param result Unzipped data
|
||||||
|
* @param wbits Window bits value for libz
|
||||||
|
* @param compressionLevel Compression level for libz
|
||||||
|
*/
|
||||||
|
virtual void deflate(std::string data, gourou::ByteArray& result,
|
||||||
|
int wbits=-15, int compressionLevel=8) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DRMProcessorClient: public DigestInterface, public RandomInterface, public HTTPInterface, \
|
class DRMProcessorClient: public DigestInterface, public RandomInterface, public HTTPInterface, \
|
||||||
|
|
|
@ -53,10 +53,16 @@ namespace gourou
|
||||||
*/
|
*/
|
||||||
std::string getDownloadURL();
|
std::string getDownloadURL();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return resource value
|
||||||
|
*/
|
||||||
|
std::string getResource();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pugi::xml_node metadatas;
|
pugi::xml_node metadatas;
|
||||||
pugi::xml_document rights;
|
pugi::xml_document rights;
|
||||||
std::string downloadURL;
|
std::string downloadURL;
|
||||||
|
std::string resource;
|
||||||
|
|
||||||
void buildRights(const pugi::xml_node& licenseToken, User* user);
|
void buildRights(const pugi::xml_node& licenseToken, User* user);
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#define ACS_SERVER "http://adeactivate.adobe.com/adept"
|
#define ACS_SERVER "http://adeactivate.adobe.com/adept"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LIBGOUROU_VERSION "0.3.2"
|
#define LIBGOUROU_VERSION "0.4"
|
||||||
|
|
||||||
namespace gourou
|
namespace gourou
|
||||||
{
|
{
|
||||||
|
@ -53,6 +53,7 @@ namespace gourou
|
||||||
|
|
||||||
static const std::string VERSION;
|
static const std::string VERSION;
|
||||||
|
|
||||||
|
enum ITEM_TYPE { EPUB=0, PDF };
|
||||||
/**
|
/**
|
||||||
* @brief Main constructor. To be used once all is configured (user has signedIn, device is activated)
|
* @brief Main constructor. To be used once all is configured (user has signedIn, device is activated)
|
||||||
*
|
*
|
||||||
|
@ -80,8 +81,10 @@ namespace gourou
|
||||||
*
|
*
|
||||||
* @param item Item from fulfill() method
|
* @param item Item from fulfill() method
|
||||||
* @param path Output file path
|
* @param path Output file path
|
||||||
|
*
|
||||||
|
* @return Type of downloaded item
|
||||||
*/
|
*/
|
||||||
void download(FulfillmentItem* item, std::string path);
|
ITEM_TYPE download(FulfillmentItem* item, std::string path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SignIn into ACS Server (required to activate device)
|
* @brief SignIn into ACS Server (required to activate device)
|
||||||
|
@ -130,8 +133,11 @@ namespace gourou
|
||||||
* @param URL HTTP URL
|
* @param URL HTTP URL
|
||||||
* @param POSTData POST data if needed, if not set, a GET request is done
|
* @param POSTData POST data if needed, if not set, a GET request is done
|
||||||
* @param contentType Optional content type of POST Data
|
* @param contentType Optional content type of POST Data
|
||||||
|
* @param responseHeaders Optional Response headers of HTTP request
|
||||||
|
*
|
||||||
|
* @return data of HTTP response
|
||||||
*/
|
*/
|
||||||
ByteArray sendRequest(const std::string& URL, const std::string& POSTData=std::string(), const char* contentType=0);
|
ByteArray sendRequest(const std::string& URL, const std::string& POSTData=std::string(), const char* contentType=0, std::map<std::string, std::string>* responseHeaders=0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send HTTP POST request to URL with document as POSTData
|
* @brief Send HTTP POST request to URL with document as POSTData
|
||||||
|
|
|
@ -233,6 +233,32 @@ namespace gourou
|
||||||
return trim(res);
|
return trim(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline std::string extractTextElem(const pugi::xml_node& doc, const char* tagName, bool throwOnNull=true)
|
||||||
|
{
|
||||||
|
pugi::xpath_node xpath_node = doc.select_node(tagName);
|
||||||
|
|
||||||
|
if (!xpath_node)
|
||||||
|
{
|
||||||
|
if (throwOnNull)
|
||||||
|
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Tag " << tagName << " not found");
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
pugi::xml_node node = xpath_node.node().first_child();
|
||||||
|
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
if (throwOnNull)
|
||||||
|
EXCEPTION(GOUROU_TAG_NOT_FOUND, "Text element for tag " << tagName << " not found");
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string res = node.value();
|
||||||
|
return trim(res);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Append an element to root with a sub text element
|
* @brief Append an element to root with a sub text element
|
||||||
*
|
*
|
||||||
|
@ -267,7 +293,7 @@ namespace gourou
|
||||||
*/
|
*/
|
||||||
static inline void writeFile(std::string path, ByteArray& data)
|
static inline void writeFile(std::string path, ByteArray& data)
|
||||||
{
|
{
|
||||||
writeFile(path, data.data(), data.length());
|
writeFile(path, data.data(), data.length()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,3 +12,11 @@ fi
|
||||||
if [ ! -d lib/base64 ] ; then
|
if [ ! -d lib/base64 ] ; then
|
||||||
git clone https://gist.github.com/f0fd86b6c73063283afe550bc5d77594.git lib/base64
|
git clone https://gist.github.com/f0fd86b6c73063283afe550bc5d77594.git lib/base64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# uPDFParser
|
||||||
|
if [ ! -d lib/updfparser ] ; then
|
||||||
|
git clone http://indefero.soutade.fr/p/updfparser lib/updfparser
|
||||||
|
pushd lib/updfparser
|
||||||
|
make STATIC=1 SHARED=0
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <uPDFParser.h>
|
||||||
|
|
||||||
#include <libgourou.h>
|
#include <libgourou.h>
|
||||||
#include <libgourou_common.h>
|
#include <libgourou_common.h>
|
||||||
#include <libgourou_log.h>
|
#include <libgourou_log.h>
|
||||||
|
@ -299,11 +301,11 @@ namespace gourou
|
||||||
appendTextElem(root, "adept:expiration", buffer);
|
appendTextElem(root, "adept:expiration", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteArray DRMProcessor::sendRequest(const std::string& URL, const std::string& POSTdata, const char* contentType)
|
ByteArray DRMProcessor::sendRequest(const std::string& URL, const std::string& POSTdata, const char* contentType, std::map<std::string, std::string>* responseHeaders)
|
||||||
{
|
{
|
||||||
if (contentType == 0)
|
if (contentType == 0)
|
||||||
contentType = "";
|
contentType = "";
|
||||||
std::string reply = client->sendHTTPRequest(URL, POSTdata, contentType);
|
std::string reply = client->sendHTTPRequest(URL, POSTdata, contentType, responseHeaders);
|
||||||
|
|
||||||
pugi::xml_document replyDoc;
|
pugi::xml_document replyDoc;
|
||||||
replyDoc.load_buffer(reply.c_str(), reply.length());
|
replyDoc.load_buffer(reply.c_str(), reply.length());
|
||||||
|
@ -580,12 +582,16 @@ namespace gourou
|
||||||
return new FulfillmentItem(fulfillReply, user);
|
return new FulfillmentItem(fulfillReply, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRMProcessor::download(FulfillmentItem* item, std::string path)
|
DRMProcessor::ITEM_TYPE DRMProcessor::download(FulfillmentItem* item, std::string path)
|
||||||
{
|
{
|
||||||
|
ITEM_TYPE res = EPUB;
|
||||||
|
|
||||||
if (!item)
|
if (!item)
|
||||||
EXCEPTION(DW_NO_ITEM, "No item");
|
EXCEPTION(DW_NO_ITEM, "No item");
|
||||||
|
|
||||||
ByteArray replyData = sendRequest(item->getDownloadURL());
|
std::map<std::string, std::string> headers;
|
||||||
|
|
||||||
|
ByteArray replyData = sendRequest(item->getDownloadURL(), "", 0, &headers);
|
||||||
|
|
||||||
writeFile(path, replyData);
|
writeFile(path, replyData);
|
||||||
|
|
||||||
|
@ -593,10 +599,54 @@ namespace gourou
|
||||||
|
|
||||||
std::string rightsStr = item->getRights();
|
std::string rightsStr = item->getRights();
|
||||||
|
|
||||||
|
if (headers.count("Content-Type") && headers["Content-Type"] == "application/pdf")
|
||||||
|
res = PDF;
|
||||||
|
|
||||||
|
if (res == EPUB)
|
||||||
|
{
|
||||||
void* handler = client->zipOpen(path);
|
void* handler = client->zipOpen(path);
|
||||||
client->zipWriteFile(handler, "META-INF/rights.xml", rightsStr);
|
client->zipWriteFile(handler, "META-INF/rights.xml", rightsStr);
|
||||||
client->zipClose(handler);
|
client->zipClose(handler);
|
||||||
}
|
}
|
||||||
|
else if (res == PDF)
|
||||||
|
{
|
||||||
|
uPDFParser::Parser parser;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GOUROU_LOG(DEBUG, "Parse PDF");
|
||||||
|
parser.parse(path);
|
||||||
|
}
|
||||||
|
catch(std::invalid_argument& e)
|
||||||
|
{
|
||||||
|
GOUROU_LOG(ERROR, "Invalid PDF");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uPDFParser::Object*> objects = parser.objects();
|
||||||
|
std::vector<uPDFParser::Object*>::reverse_iterator it;
|
||||||
|
|
||||||
|
for(it = objects.rbegin(); it != objects.rend(); it++)
|
||||||
|
{
|
||||||
|
// Update EBX_HANDLER with rights
|
||||||
|
if ((*it)->hasKey("Filter") && (**it)["Filter"]->str() == "/EBX_HANDLER")
|
||||||
|
{
|
||||||
|
uPDFParser::Object* ebx = (*it)->clone();
|
||||||
|
(*ebx)["ADEPT_ID"] = new uPDFParser::String(item->getResource());
|
||||||
|
(*ebx)["EBX_BOOKID"] = new uPDFParser::String(item->getResource());
|
||||||
|
ByteArray zipped;
|
||||||
|
client->deflate(rightsStr, zipped);
|
||||||
|
(*ebx)["ADEPT_LICENSE"] = new uPDFParser::String(zipped.toBase64());
|
||||||
|
parser.addObject(ebx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.write(path, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void DRMProcessor::buildSignInRequest(pugi::xml_document& signInRequest,
|
void DRMProcessor::buildSignInRequest(pugi::xml_document& signInRequest,
|
||||||
const std::string& adobeID, const std::string& adobePassword,
|
const std::string& adobeID, const std::string& adobePassword,
|
||||||
|
|
|
@ -5,7 +5,7 @@ CXXFLAGS=-Wall `pkg-config --cflags Qt5Core Qt5Network` -fPIC -I$(ROOT)/include
|
||||||
ifneq ($(STATIC_UTILS),)
|
ifneq ($(STATIC_UTILS),)
|
||||||
LDFLAGS=`pkg-config --libs Qt5Core Qt5Network` -L$(ROOT) $(ROOT)/libgourou.a -lcrypto -lzip
|
LDFLAGS=`pkg-config --libs Qt5Core Qt5Network` -L$(ROOT) $(ROOT)/libgourou.a -lcrypto -lzip
|
||||||
else
|
else
|
||||||
LDFLAGS=`pkg-config --libs Qt5Core Qt5Network` -L$(ROOT) -lgourou -lcrypto -lzip
|
LDFLAGS=`pkg-config --libs Qt5Core Qt5Network` -L$(ROOT) -lgourou -lcrypto -lzip -lz
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(DEBUG),)
|
ifneq ($(DEBUG),)
|
||||||
|
|
|
@ -79,9 +79,7 @@ public:
|
||||||
{
|
{
|
||||||
filename = item->getMetadata("title");
|
filename = item->getMetadata("title");
|
||||||
if (filename == "")
|
if (filename == "")
|
||||||
filename = "output.epub";
|
filename = "output";
|
||||||
else
|
|
||||||
filename += ".epub";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
filename = outputFile;
|
filename = outputFile;
|
||||||
|
@ -95,7 +93,19 @@ public:
|
||||||
filename = std::string(outputDir) + "/" + filename;
|
filename = std::string(outputDir) + "/" + filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
processor.download(item, filename);
|
gourou::DRMProcessor::ITEM_TYPE type = processor.download(item, filename);
|
||||||
|
|
||||||
|
if (!outputFile)
|
||||||
|
{
|
||||||
|
std::string finalName = filename;
|
||||||
|
if (type == gourou::DRMProcessor::ITEM_TYPE::PDF)
|
||||||
|
finalName += ".pdf";
|
||||||
|
else
|
||||||
|
finalName += ".epub";
|
||||||
|
QDir dir;
|
||||||
|
dir.rename(filename.c_str(), finalName.c_str());
|
||||||
|
filename = finalName;
|
||||||
|
}
|
||||||
std::cout << "Created " << filename << std::endl;
|
std::cout << "Created " << filename << std::endl;
|
||||||
} catch(std::exception& e)
|
} catch(std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#include <zip.h>
|
#include <zip.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include <libgourou_common.h>
|
#include <libgourou_common.h>
|
||||||
#include <libgourou_log.h>
|
#include <libgourou_log.h>
|
||||||
|
@ -82,7 +83,7 @@ void DRMProcessorClientImpl::randBytes(unsigned char* bytesOut, unsigned int len
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HTTP interface */
|
/* HTTP interface */
|
||||||
std::string DRMProcessorClientImpl::sendHTTPRequest(const std::string& URL, const std::string& POSTData, const std::string& contentType)
|
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()));
|
QNetworkRequest request(QUrl(URL.c_str()));
|
||||||
QNetworkAccessManager networkManager;
|
QNetworkAccessManager networkManager;
|
||||||
|
@ -121,12 +122,12 @@ std::string DRMProcessorClientImpl::sendHTTPRequest(const std::string& URL, cons
|
||||||
if (reply->error() != QNetworkReply::NoError)
|
if (reply->error() != QNetworkReply::NoError)
|
||||||
EXCEPTION(gourou::CLIENT_NETWORK_ERROR, "Error " << reply->errorString().toStdString());
|
EXCEPTION(gourou::CLIENT_NETWORK_ERROR, "Error " << reply->errorString().toStdString());
|
||||||
|
|
||||||
if (gourou::logLevel >= gourou::DEBUG)
|
|
||||||
{
|
|
||||||
QList<QByteArray> headers = reply->rawHeaderList();
|
QList<QByteArray> headers = reply->rawHeaderList();
|
||||||
for (int i = 0; i < headers.size(); ++i) {
|
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;
|
std::cout << headers[i].constData() << " : " << reply->rawHeader(headers[i]).constData() << std::endl;
|
||||||
}
|
if (responseHeaders)
|
||||||
|
(*responseHeaders)[headers[i].constData()] = reply->rawHeader(headers[i]).constData();
|
||||||
}
|
}
|
||||||
|
|
||||||
replyData = reply->readAll();
|
replyData = reply->readAll();
|
||||||
|
@ -420,3 +421,78 @@ void DRMProcessorClientImpl::zipClose(void* handler)
|
||||||
{
|
{
|
||||||
zip_close((zip_t*)handler);
|
zip_close((zip_t*)handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DRMProcessorClientImpl::inflate(std::string data, gourou::ByteArray& result,
|
||||||
|
int wbits)
|
||||||
|
{
|
||||||
|
unsigned int dataSize = data.size()*2;
|
||||||
|
unsigned char* buffer = new unsigned char[dataSize];
|
||||||
|
|
||||||
|
z_stream infstream;
|
||||||
|
|
||||||
|
infstream.zalloc = Z_NULL;
|
||||||
|
infstream.zfree = Z_NULL;
|
||||||
|
infstream.opaque = Z_NULL;
|
||||||
|
|
||||||
|
infstream.avail_in = (uInt)data.size();
|
||||||
|
infstream.next_in = (Bytef *)data.c_str(); // input char array
|
||||||
|
infstream.avail_out = (uInt)dataSize; // size of output
|
||||||
|
infstream.next_out = (Bytef *)buffer; // output char array
|
||||||
|
|
||||||
|
int ret = inflateInit2(&infstream, wbits);
|
||||||
|
|
||||||
|
ret = ::inflate(&infstream, Z_SYNC_FLUSH);
|
||||||
|
while (ret == Z_OK || ret == Z_STREAM_END)
|
||||||
|
{
|
||||||
|
result.append(buffer, dataSize-infstream.avail_out);
|
||||||
|
if (ret == Z_STREAM_END) break;
|
||||||
|
infstream.avail_out = (uInt)dataSize; // size of output
|
||||||
|
infstream.next_out = (Bytef *)buffer; // output char array
|
||||||
|
ret = ::inflate(&infstream, Z_SYNC_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
inflateEnd(&infstream);
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR)
|
||||||
|
EXCEPTION(gourou::CLIENT_ZIP_ERROR, zError(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DRMProcessorClientImpl::deflate(std::string data, gourou::ByteArray& result,
|
||||||
|
int wbits, int compressionLevel)
|
||||||
|
{
|
||||||
|
unsigned int dataSize = data.size();
|
||||||
|
unsigned char* buffer = new unsigned char[dataSize];
|
||||||
|
|
||||||
|
z_stream defstream;
|
||||||
|
|
||||||
|
defstream.zalloc = Z_NULL;
|
||||||
|
defstream.zfree = Z_NULL;
|
||||||
|
defstream.opaque = Z_NULL;
|
||||||
|
|
||||||
|
defstream.avail_in = (uInt)data.size();
|
||||||
|
defstream.next_in = (Bytef *)data.c_str(); // input char array
|
||||||
|
defstream.avail_out = (uInt)dataSize; // size of output
|
||||||
|
defstream.next_out = (Bytef *)buffer; // output char array
|
||||||
|
|
||||||
|
int ret = deflateInit2(&defstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, wbits,
|
||||||
|
compressionLevel, Z_DEFAULT_STRATEGY);
|
||||||
|
|
||||||
|
ret = ::deflate(&defstream, Z_SYNC_FLUSH);
|
||||||
|
while (ret == Z_OK || ret == Z_STREAM_END)
|
||||||
|
{
|
||||||
|
result.append(buffer, dataSize-defstream.avail_out);
|
||||||
|
if (ret == Z_STREAM_END) break;
|
||||||
|
defstream.avail_out = (uInt)dataSize; // size of output
|
||||||
|
defstream.next_out = (Bytef *)buffer; // output char array
|
||||||
|
ret = ::deflate(&defstream, Z_SYNC_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
deflateEnd(&defstream);
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR)
|
||||||
|
EXCEPTION(gourou::CLIENT_ZIP_ERROR, zError(ret));
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ class DRMProcessorClientImpl : public gourou::DRMProcessorClient
|
||||||
virtual void randBytes(unsigned char* bytesOut, unsigned int length);
|
virtual void randBytes(unsigned char* bytesOut, unsigned int length);
|
||||||
|
|
||||||
/* HTTP interface */
|
/* HTTP interface */
|
||||||
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""));
|
virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""), std::map<std::string, std::string>* responseHeaders=0);
|
||||||
|
|
||||||
virtual void RSAPrivateEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
virtual void RSAPrivateEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,
|
||||||
const RSA_KEY_TYPE keyType, const std::string& password,
|
const RSA_KEY_TYPE keyType, const std::string& password,
|
||||||
|
@ -108,6 +108,10 @@ class DRMProcessorClientImpl : public gourou::DRMProcessorClient
|
||||||
|
|
||||||
virtual void zipClose(void* handler);
|
virtual void zipClose(void* handler);
|
||||||
|
|
||||||
|
virtual void inflate(std::string data, gourou::ByteArray& result, int wbits=-15);
|
||||||
|
|
||||||
|
virtual void deflate(std::string data, gourou::ByteArray& result,
|
||||||
|
int wbits=-15, int compressionLevel=8);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user