Skip to content

Instantly share code, notes, and snippets.

@bradley219
Created April 9, 2013 05:53
Show Gist options
  • Save bradley219/5343285 to your computer and use it in GitHub Desktop.
Save bradley219/5343285 to your computer and use it in GitHub Desktop.
Patch for wkhtmltopdf as posted at http://code.google.com/p/wkhtmltopdf/issues/detail?id=353 on 9/28/2012
diff -rupN wkhtmltopdf-0.11.0_rc1/common.pri wkhtmltopdf-0.11.0_rc1-working/common.pri
--- wkhtmltopdf-0.11.0_rc1/common.pri 2011-10-02 10:21:02.000000000 -0700
+++ wkhtmltopdf-0.11.0_rc1-working/common.pri 2012-09-26 10:22:30.764000002 -0700
@@ -17,7 +17,7 @@
unix {
TEMP = $$[QT_INSTALL_LIBS] libQtGui.prl
- PRL = $$[QT_INSTALL_LIBS] QtGui.framework/QtGui.prl
+ PRL = $$[QT_INSTALL_LIBS] libQtGui.prl
include($$join(TEMP, "/"))
include($$join(PRL, "/"))
}
diff -rupN wkhtmltopdf-0.11.0_rc1/common.pri.rej wkhtmltopdf-0.11.0_rc1-working/common.pri.rej
--- wkhtmltopdf-0.11.0_rc1/common.pri.rej 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/common.pri.rej 2012-09-27 17:21:57.868000005 -0700
@@ -0,0 +1,11 @@
+--- common.pri 2011-10-02 10:21:02.000000000 -0700
++++ common.pri 2012-09-26 10:22:30.764000002 -0700
+@@ -17,7 +17,7 @@
+
+ unix {
+ TEMP = $$[QT_INSTALL_LIBS] libQtGui.prl
+- PRL = $$[QT_INSTALL_LIBS] QtGui.framework/QtGui.prl
++ PRL = $$[QT_INSTALL_LIBS] libQtGui.prl
+ include($$join(TEMP, "/"))
+ include($$join(PRL, "/"))
+ }
diff -rupN wkhtmltopdf-0.11.0_rc1/include/wkhtmltox/loadsettings.hh wkhtmltopdf-0.11.0_rc1-working/include/wkhtmltox/loadsettings.hh
--- wkhtmltopdf-0.11.0_rc1/include/wkhtmltox/loadsettings.hh 2011-10-02 10:21:02.000000000 -0700
+++ wkhtmltopdf-0.11.0_rc1-working/include/wkhtmltox/loadsettings.hh 2012-09-19 13:25:21.000000000 -0700
@@ -118,6 +118,8 @@ struct DLL_PUBLIC LoadPage {
QString checkboxCheckedSvg;
QString radiobuttonSvg;
QString radiobuttonCheckedSvg;
+
+ QList< QString > basePaths;
};
DLL_PUBLIC LoadPage::LoadErrorHandling strToLoadErrorHandling(const char * s, bool * ok=0);
diff -rupN wkhtmltopdf-0.11.0_rc1/include/wkhtmltox/loadsettings.hh.rej wkhtmltopdf-0.11.0_rc1-working/include/wkhtmltox/loadsettings.hh.rej
--- wkhtmltopdf-0.11.0_rc1/include/wkhtmltox/loadsettings.hh.rej 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/include/wkhtmltox/loadsettings.hh.rej 2012-09-27 17:21:59.692000007 -0700
@@ -0,0 +1,11 @@
+--- include/wkhtmltox/loadsettings.hh 2011-10-02 10:21:02.000000000 -0700
++++ include/wkhtmltox/loadsettings.hh 2012-09-19 13:25:21.000000000 -0700
+@@ -118,6 +118,8 @@
+ QString checkboxCheckedSvg;
+ QString radiobuttonSvg;
+ QString radiobuttonCheckedSvg;
++
++ QList< QString > basePaths;
+ };
+
+ DLL_PUBLIC LoadPage::LoadErrorHandling strToLoadErrorHandling(const char * s, bool * ok=0);
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/lib.pri wkhtmltopdf-0.11.0_rc1-working/src/lib/lib.pri
--- wkhtmltopdf-0.11.0_rc1/src/lib/lib.pri 2011-10-02 10:21:02.000000000 -0700
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/lib.pri 2012-09-19 13:25:21.000000000 -0700
@@ -18,13 +18,13 @@
DEFINES += BUILDING_DLL
#Shared
-PUBLIC_HEADERS += ../lib/converter.hh ../lib/multipageloader.hh ../lib/dllbegin.inc
+PUBLIC_HEADERS += ../lib/converter.hh ../lib/multipageloader.hh ../lib/dllbegin.inc ../lib/synchttp.h
PUBLIC_HEADERS += ../lib/dllend.inc ../lib/loadsettings.hh ../lib/websettings.hh
PUBLIC_HEADERS += ../lib/utilities.hh
HEADERS += ../lib/multipageloader_p.hh ../lib/converter_p.hh
SOURCES += ../lib/loadsettings.cc ../lib/multipageloader.cc ../lib/tempfile.cc \
../lib/converter.cc ../lib/websettings.cc \
- ../lib/reflect.cc ../lib/utilities.cc
+ ../lib/reflect.cc ../lib/utilities.cc ../lib/synchttp.cc
#Pdf
PUBLIC_HEADERS += ../lib/pdfconverter.hh ../lib/pdfsettings.hh
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/lib.pri.rej wkhtmltopdf-0.11.0_rc1-working/src/lib/lib.pri.rej
--- wkhtmltopdf-0.11.0_rc1/src/lib/lib.pri.rej 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/lib.pri.rej 2012-09-27 17:22:00.584000007 -0700
@@ -0,0 +1,18 @@
+--- src/lib/lib.pri 2011-10-02 10:21:02.000000000 -0700
++++ src/lib/lib.pri 2012-09-19 13:25:21.000000000 -0700
+@@ -18,13 +18,13 @@
+ DEFINES += BUILDING_DLL
+
+ #Shared
+-PUBLIC_HEADERS += ../lib/converter.hh ../lib/multipageloader.hh ../lib/dllbegin.inc
++PUBLIC_HEADERS += ../lib/converter.hh ../lib/multipageloader.hh ../lib/dllbegin.inc ../lib/synchttp.h
+ PUBLIC_HEADERS += ../lib/dllend.inc ../lib/loadsettings.hh ../lib/websettings.hh
+ PUBLIC_HEADERS += ../lib/utilities.hh
+ HEADERS += ../lib/multipageloader_p.hh ../lib/converter_p.hh
+ SOURCES += ../lib/loadsettings.cc ../lib/multipageloader.cc ../lib/tempfile.cc \
+ ../lib/converter.cc ../lib/websettings.cc \
+- ../lib/reflect.cc ../lib/utilities.cc
++ ../lib/reflect.cc ../lib/utilities.cc ../lib/synchttp.cc
+
+ #Pdf
+ PUBLIC_HEADERS += ../lib/pdfconverter.hh ../lib/pdfsettings.hh
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/loadsettings.hh wkhtmltopdf-0.11.0_rc1-working/src/lib/loadsettings.hh
--- wkhtmltopdf-0.11.0_rc1/src/lib/loadsettings.hh 2011-10-02 10:21:02.000000000 -0700
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/loadsettings.hh 2012-09-19 13:25:21.000000000 -0700
@@ -121,6 +121,9 @@ struct DLL_PUBLIC LoadPage {
QString checkboxCheckedSvg;
QString radiobuttonSvg;
QString radiobuttonCheckedSvg;
+
+ //! Base path list for resolving relative URLs
+ QList< QString > basePaths;
};
DLL_PUBLIC LoadPage::LoadErrorHandling strToLoadErrorHandling(const char * s, bool * ok=0);
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/loadsettings.hh.rej wkhtmltopdf-0.11.0_rc1-working/src/lib/loadsettings.hh.rej
--- wkhtmltopdf-0.11.0_rc1/src/lib/loadsettings.hh.rej 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/loadsettings.hh.rej 2012-09-27 17:22:01.316000008 -0700
@@ -0,0 +1,12 @@
+--- src/lib/loadsettings.hh 2011-10-02 10:21:02.000000000 -0700
++++ src/lib/loadsettings.hh 2012-09-19 13:25:21.000000000 -0700
+@@ -121,6 +121,9 @@
+ QString checkboxCheckedSvg;
+ QString radiobuttonSvg;
+ QString radiobuttonCheckedSvg;
++
++ //! Base path list for resolving relative URLs
++ QList< QString > basePaths;
+ };
+
+ DLL_PUBLIC LoadPage::LoadErrorHandling strToLoadErrorHandling(const char * s, bool * ok=0);
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/multipageloader.cc wkhtmltopdf-0.11.0_rc1-working/src/lib/multipageloader.cc
--- wkhtmltopdf-0.11.0_rc1/src/lib/multipageloader.cc 2011-10-02 10:21:02.000000000 -0700
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/multipageloader.cc 2012-09-28 09:40:05.632000001 -0700
@@ -30,6 +30,14 @@
#include <QNetworkCookie>
#include <QTimer>
#include <QUuid>
+#include <QWebPage>
+#include <QWebFrame>
+#include <QWebElementCollection>
+
+#include "synchttp.h"
+
+// Uncomment to allow debug info to be printed to stderr
+//#define DEBUG_PRINTING
namespace wkhtmltopdf {
/*!
@@ -54,7 +62,14 @@ void MyNetworkAccessManager::allow(QStri
}
QNetworkReply * MyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) {
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "createRequest for %s ", req.url().scheme().toAscii().data() );
+#endif
+
if (req.url().scheme() == "file" && settings.blockLocalFileAccess) {
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "%s...", req.url().toLocalFile().toAscii().data() );
+#endif
bool ok=false;
QString path = QFileInfo(req.url().toLocalFile()).canonicalFilePath();
QString old = "";
@@ -73,12 +88,89 @@ QNetworkReply * MyNetworkAccessManager::
return QNetworkAccessManager::createRequest(op, r2, outgoingData);
}
}
+ else if( req.url().scheme() == "file" ) {
+
+ // Remove query string from the end of a path, including the question mark
+ QString fname(req.url().toLocalFile().toAscii());
+ int idx = -1;
+ if( ( idx = fname.indexOf("?") ) >= 0 )
+ {
+ fname = fname.left(idx);
+ }
+
+ // search for file
+ bool ok = false;
+ QFile fn(fname.toAscii());
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "\nTrying w/o basepath file: %s...", fn.fileName().toAscii().data() );
+#endif
+ if( fn.exists() )
+ {
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "exists!" );
+#endif
+ ok = true;
+ fname = QString(fn.fileName());
+ }
+ else
+ {
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "does not exist..." );
+#endif
+ if(!settings.basePaths.isEmpty()) {
+ foreach(const QString &bp, settings.basePaths) {
+ QString c(bp);
+ c = c.append("/").append(req.url().toLocalFile().toAscii());
+ QFile fn(c);
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "\nTrying file: %s...", fn.fileName().toAscii().data() );
+#endif
+ if (fn.exists()) {
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "exists!" );
+#endif
+ ok = true;
+ fname = QString(c);
+ break;
+ }
+#ifdef DEBUG_PRINTING
+ else
+ {
+ fprintf(stderr, "does not exist..." );
+ }
+#endif
+ }
+ }
+ if( ok )
+ {
+ QNetworkRequest r4 = req;
+ if (settings.repeatCustomHeaders) {
+ typedef QPair<QString, QString> HT;
+ foreach (const HT & j, settings.customHeaders)
+ r4.setRawHeader(j.first.toAscii(), j.second.toAscii());
+ }
+ QUrl u(fname);
+ u.setScheme("file");
+ r4.setUrl(u);
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "\n" );
+#endif
+ return QNetworkAccessManager::createRequest(op, r4, outgoingData);
+ }
+ }
+ }
QNetworkRequest r3 = req;
if (settings.repeatCustomHeaders) {
typedef QPair<QString, QString> HT;
foreach (const HT & j, settings.customHeaders)
r3.setRawHeader(j.first.toAscii(), j.second.toAscii());
}
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "%s...", req.url().toString().toAscii().data() );
+#endif
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "\n" );
+#endif
return QNetworkAccessManager::createRequest(op, r3, outgoingData);
}
@@ -201,6 +293,9 @@ void ResourceObject::loadProgress(int p)
void ResourceObject::loadFinished(bool ok) {
+#ifdef DEBUG_PRINTING
+ fprintf(stderr,"void ResourceObject::loadFinished(bool ok)\n");
+#endif
multiPageLoader.hasError = multiPageLoader.hasError || (!ok && settings.loadErrorHandling == settings::LoadPage::abort);
if (!ok) {
if (settings.loadErrorHandling == settings::LoadPage::abort)
@@ -212,6 +307,136 @@ void ResourceObject::loadFinished(bool o
warning(QString("Failed loading page ") + url.toString() + " (ignored)");
}
+ SyncHTTP *http = new SyncHTTP(this);
+
+ QWebElementCollection coll = webPage.mainFrame()->findAllElements("img");
+ for (int i = 0; i < coll.count(); i++) { // loop collection
+ QWebElement elem = coll.at(i);
+ if (elem.hasAttribute("src")) {
+ bool ok = false;
+ if (!elem.attribute("src").startsWith("http")) { // doesn't start with http
+
+ // Remove query string from the end of a path, including the question mark
+ QString srcString(elem.attribute("src"));
+ int idx = -1;
+ if( ( idx = srcString.indexOf("?") ) >= 0 )
+ {
+ srcString = srcString.left(idx);
+ elem.setAttribute("src", srcString.toAscii().data());
+ }
+
+ QString *fname = NULL;
+ QFile fn(elem.attribute("src"));
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "Trying file: %s...", fn.fileName().toAscii().data() );
+#endif
+ if (fn.exists()) {
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "exists!\n" );
+#endif
+ ok = true;
+ fname = new QString(elem.attribute("src"));
+ }
+ else
+ {
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "does not exist\n" );
+#endif
+ }
+
+ if (!ok && !settings.basePaths.isEmpty()) {
+ foreach(const QString &bp, settings.basePaths) {
+ QString c(bp);
+ c = c.append("/").append(elem.attribute("src"));
+
+ QFile fn(c);
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "Trying file: %s...", fn.fileName().toAscii().data() );
+#endif
+ if (fn.exists()) {
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "exists!\n" );
+#endif
+ ok = true;
+ fname = new QString(c);
+ break;
+ }
+ else
+ {
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "does not exist\n" );
+#endif
+ }
+ }
+ }
+ if( ok )
+ {
+ elem.setAttribute("src", fname->toAscii().data() );
+ continue;
+ }
+
+
+ if (!settings.basePaths.isEmpty()) {
+ foreach(const QString &bp, settings.basePaths) {
+ QString c(bp);
+ c = c.append("/");
+
+ QUrl url(c.append(elem.attribute("src"))); // create appended url
+ int port = url.port(80);
+ QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
+ if (url.toString().toLower().startsWith("https")) {
+ port = url.port(443);
+ mode = QHttp::ConnectionModeHttps;
+ }
+
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "trying %s\n", url.toString().toAscii().data());
+#endif
+ http->setHost(url.host(), mode, port);
+ http->setUser(url.userName(), url.password());
+ http->syncGet(url.encodedPath());
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "error %d\n", http->lastResponse().statusCode());
+#endif
+ if (http->lastResponse().statusCode() == 200) {
+ elem.setAttribute("src", url.toString());
+ ok = true;
+ break;
+ }
+ }
+ }
+ } else { // does start with http
+ QUrl url(elem.attribute("src"));
+ int port = url.port(80);
+ QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
+ if (url.toString().toLower().startsWith("https")) {
+ port = url.port(443);
+ mode = QHttp::ConnectionModeHttps;
+ }
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "trying %s\n", url.toString().toAscii().data());
+#endif
+ http->setHost(url.host(), mode, port);
+ http->setUser(url.userName(), url.password());
+ http->syncGet(url.encodedPath());
+#ifdef DEBUG_PRINTING
+ fprintf(stderr, "error %d\n", http->lastResponse().statusCode());
+#endif
+ if (http->lastResponse().statusCode() == 200) {
+ ok = true;
+ }
+ }
+ if (!ok) {
+ elem.removeAttribute("src");
+ elem.setAttribute("style", "display:none;");
+ }
+ }
+ }
+
+ delete http;
+
+ //printf("HTML %s\n", webPage.mainFrame()->toHtml().toAscii().data());
+
// Evaluate extra user supplied javascript
foreach (const QString & str, settings.runScript)
webPage.mainFrame()->evaluateJavaScript(str);
@@ -446,7 +671,12 @@ void MultiPageLoaderPrivate::load() {
loading=0;
for (int i=0; i < resources.size(); ++i)
+ {
+#ifdef DEBUG_PRINTING
+ fprintf( stderr, "resources[%d]->load();\n", i );
+#endif
resources[i]->load();
+ }
if (resources.size() == 0) loadDone();
}
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/multipageloader.cc.rej wkhtmltopdf-0.11.0_rc1-working/src/lib/multipageloader.cc.rej
--- wkhtmltopdf-0.11.0_rc1/src/lib/multipageloader.cc.rej 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/multipageloader.cc.rej 2012-09-27 17:22:02.128000007 -0700
@@ -0,0 +1,275 @@
+--- src/lib/multipageloader.cc 2011-10-02 10:21:02.000000000 -0700
++++ src/lib/multipageloader.cc 2012-09-26 10:26:12.244000006 -0700
+@@ -30,6 +30,14 @@
+ #include <QNetworkCookie>
+ #include <QTimer>
+ #include <QUuid>
++#include <QWebPage>
++#include <QWebFrame>
++#include <QWebElementCollection>
++
++#include "synchttp.h"
++
++// Uncomment to allow debug info to be printed to stderr
++//#define DEBUG_PRINTING
+
+ namespace wkhtmltopdf {
+ /*!
+@@ -54,7 +62,14 @@
+ }
+
+ QNetworkReply * MyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) {
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "createRequest for %s ", req.url().scheme().toAscii().data() );
++#endif
++
+ if (req.url().scheme() == "file" && settings.blockLocalFileAccess) {
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "%s...", req.url().toLocalFile().toAscii().data() );
++#endif
+ bool ok=false;
+ QString path = QFileInfo(req.url().toLocalFile()).canonicalFilePath();
+ QString old = "";
+@@ -73,12 +88,82 @@
+ return QNetworkAccessManager::createRequest(op, r2, outgoingData);
+ }
+ }
++ else if( req.url().scheme() == "file" ) {
++
++ // search for file
++ bool ok = false;
++ QString *fname = NULL;
++ QFile fn(req.url().toLocalFile().toAscii());
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "\nTrying w/o basepath file: %s...", fn.fileName().toAscii().data() );
++#endif
++ if( fn.exists() )
++ {
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "exists!" );
++#endif
++ ok = true;
++ fname = new QString(fn.fileName());
++ }
++ else
++ {
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "does not exist..." );
++#endif
++ if(!settings.basePaths.isEmpty()) {
++ foreach(const QString &bp, settings.basePaths) {
++ QString c(bp);
++ c = c.append("/").append(req.url().toLocalFile().toAscii());
++ QFile fn(c);
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "\nTrying file: %s...", fn.fileName().toAscii().data() );
++#endif
++ if (fn.exists()) {
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "exists!" );
++#endif
++ ok = true;
++ fname = new QString(c);
++ break;
++ }
++#ifdef DEBUG_PRINTING
++ else
++ {
++ fprintf(stderr, "does not exist..." );
++ }
++#endif
++ }
++ }
++ if( ok && fname )
++ {
++ QNetworkRequest r4 = req;
++ if (settings.repeatCustomHeaders) {
++ typedef QPair<QString, QString> HT;
++ foreach (const HT & j, settings.customHeaders)
++ r4.setRawHeader(j.first.toAscii(), j.second.toAscii());
++ }
++ QUrl u(*fname);
++ u.setScheme("file");
++ r4.setUrl(u);
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "\n" );
++#endif
++ return QNetworkAccessManager::createRequest(op, r4, outgoingData);
++ }
++ }
++ }
+ QNetworkRequest r3 = req;
+ if (settings.repeatCustomHeaders) {
+ typedef QPair<QString, QString> HT;
+ foreach (const HT & j, settings.customHeaders)
+ r3.setRawHeader(j.first.toAscii(), j.second.toAscii());
+ }
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "%s...", req.url().toString().toAscii().data() );
++#endif
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "\n" );
++#endif
+ return QNetworkAccessManager::createRequest(op, r3, outgoingData);
+ }
+
+@@ -201,6 +286,9 @@
+
+
+ void ResourceObject::loadFinished(bool ok) {
++#ifdef DEBUG_PRINTING
++ fprintf(stderr,"void ResourceObject::loadFinished(bool ok)\n");
++#endif
+ multiPageLoader.hasError = multiPageLoader.hasError || (!ok && settings.loadErrorHandling == settings::LoadPage::abort);
+ if (!ok) {
+ if (settings.loadErrorHandling == settings::LoadPage::abort)
+@@ -212,6 +300,136 @@
+ warning(QString("Failed loading page ") + url.toString() + " (ignored)");
+ }
+
++ SyncHTTP *http = new SyncHTTP(this);
++
++ QWebElementCollection coll = webPage.mainFrame()->findAllElements("img");
++ for (int i = 0; i < coll.count(); i++) { // loop collection
++ QWebElement elem = coll.at(i);
++ if (elem.hasAttribute("src")) {
++ bool ok = false;
++ if (!elem.attribute("src").startsWith("http")) { // doesn't start with http
++
++ // Remove query string from the end of a path, including the question mark
++ QString srcString(elem.attribute("src"));
++ int idx = -1;
++ if( ( idx = srcString.indexOf("?") ) >= 0 )
++ {
++ srcString = srcString.left(idx);
++ elem.setAttribute("src", srcString.toAscii().data());
++ }
++
++ QString *fname = NULL;
++ QFile fn(elem.attribute("src"));
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "Trying file: %s...", fn.fileName().toAscii().data() );
++#endif
++ if (fn.exists()) {
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "exists!\n" );
++#endif
++ ok = true;
++ fname = new QString(elem.attribute("src"));
++ }
++ else
++ {
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "does not exist\n" );
++#endif
++ }
++
++ if (!ok && !settings.basePaths.isEmpty()) {
++ foreach(const QString &bp, settings.basePaths) {
++ QString c(bp);
++ c = c.append("/").append(elem.attribute("src"));
++
++ QFile fn(c);
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "Trying file: %s...", fn.fileName().toAscii().data() );
++#endif
++ if (fn.exists()) {
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "exists!\n" );
++#endif
++ ok = true;
++ fname = new QString(c);
++ break;
++ }
++ else
++ {
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "does not exist\n" );
++#endif
++ }
++ }
++ }
++ if( ok )
++ {
++ elem.setAttribute("src", fname->toAscii().data() );
++ continue;
++ }
++
++
++ if (!settings.basePaths.isEmpty()) {
++ foreach(const QString &bp, settings.basePaths) {
++ QString c(bp);
++ c = c.append("/");
++
++ QUrl url(c.append(elem.attribute("src"))); // create appended url
++ int port = url.port(80);
++ QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
++ if (url.toString().toLower().startsWith("https")) {
++ port = url.port(443);
++ mode = QHttp::ConnectionModeHttps;
++ }
++
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "trying %s\n", url.toString().toAscii().data());
++#endif
++ http->setHost(url.host(), mode, port);
++ http->setUser(url.userName(), url.password());
++ http->syncGet(url.encodedPath());
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "error %d\n", http->lastResponse().statusCode());
++#endif
++ if (http->lastResponse().statusCode() == 200) {
++ elem.setAttribute("src", url.toString());
++ ok = true;
++ break;
++ }
++ }
++ }
++ } else { // does start with http
++ QUrl url(elem.attribute("src"));
++ int port = url.port(80);
++ QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
++ if (url.toString().toLower().startsWith("https")) {
++ port = url.port(443);
++ mode = QHttp::ConnectionModeHttps;
++ }
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "trying %s\n", url.toString().toAscii().data());
++#endif
++ http->setHost(url.host(), mode, port);
++ http->setUser(url.userName(), url.password());
++ http->syncGet(url.encodedPath());
++#ifdef DEBUG_PRINTING
++ fprintf(stderr, "error %d\n", http->lastResponse().statusCode());
++#endif
++ if (http->lastResponse().statusCode() == 200) {
++ ok = true;
++ }
++ }
++ if (!ok) {
++ elem.removeAttribute("src");
++ elem.setAttribute("style", "display:none;");
++ }
++ }
++ }
++
++ delete http;
++
++ //printf("HTML %s\n", webPage.mainFrame()->toHtml().toAscii().data());
++
+ // Evaluate extra user supplied javascript
+ foreach (const QString & str, settings.runScript)
+ webPage.mainFrame()->evaluateJavaScript(str);
+@@ -446,7 +664,12 @@
+ loading=0;
+
+ for (int i=0; i < resources.size(); ++i)
++ {
++#ifdef DEBUG_PRINTING
++ fprintf( stderr, "resources[%d]->load();\n", i );
++#endif
+ resources[i]->load();
++ }
+
+ if (resources.size() == 0) loadDone();
+ }
Binary files wkhtmltopdf-0.11.0_rc1/src/lib/.multipageloader.cc.swp and wkhtmltopdf-0.11.0_rc1-working/src/lib/.multipageloader.cc.swp differ
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/synchttp.cc wkhtmltopdf-0.11.0_rc1-working/src/lib/synchttp.cc
--- wkhtmltopdf-0.11.0_rc1/src/lib/synchttp.cc 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/synchttp.cc 2012-09-19 13:25:21.000000000 -0700
@@ -0,0 +1,44 @@
+#ifdef __WKHTMLTOX_UNDEF_QT_DLL__
+#ifdef QT_DLL
+#undef QT_DLL
+#endif
+#endif
+
+#include "synchttp.h"
+
+namespace wkhtmltopdf {
+
+bool SyncHTTP::syncGet ( const QString & path, QIODevice * to)
+{
+ ///connect the requestFinished signal to our finished slot
+ connect(this,SIGNAL(requestFinished(int,bool)),SLOT(finished(int,bool)));
+ /// start the request and store the requestID
+ requestID = get(path, to );
+ /// block until the request is finished
+ loop.exec();
+ /// return the request status
+ return status;
+}
+
+/// send POST request and wait until finished
+bool SyncHTTP::syncPost ( const QString & path, QIODevice * data, QIODevice * to)
+{
+ ///connect the requestFinished signal to our finished slot
+ connect(this,SIGNAL(requestFinished(int,bool)),SLOT(finished(int,bool)));
+ /// start the request and store the requestID
+ requestID = post(path, data , to );
+ /// block until the request is finished
+ loop.exec();
+ /// return the request status
+ return status;
+}
+
+bool SyncHTTP::syncPost ( const QString & path, const QByteArray& data, QIODevice * to)
+{
+ /// create io device from QByteArray
+ QBuffer buffer;
+ buffer.setData(data);
+ return syncPost(path,&buffer,to);
+}
+
+};
diff -rupN wkhtmltopdf-0.11.0_rc1/src/lib/synchttp.h wkhtmltopdf-0.11.0_rc1-working/src/lib/synchttp.h
--- wkhtmltopdf-0.11.0_rc1/src/lib/synchttp.h 1969-12-31 16:00:00.000000000 -0800
+++ wkhtmltopdf-0.11.0_rc1-working/src/lib/synchttp.h 2012-09-19 13:25:21.000000000 -0700
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Iulian M *
+ * [email protected] *
+ ***************************************************************************/
+#ifndef ETKSYNCHTTP_H
+#define ETKSYNCHTTP_H
+
+#include <QHttp>
+#include <QEventLoop>
+#include <QBuffer>
+
+/**
+ * Provide a synchronous api over QHttp
+ * Uses a QEventLoop to block until the request is completed
+ * @author Iulian M <[email protected]>
+*/
+namespace wkhtmltopdf {
+class SyncHTTP: public QHttp
+{
+ Q_OBJECT
+ public:
+ /// structors
+ SyncHTTP( QObject * parent = 0 )
+ :QHttp(parent),requestID(-1),status(false){}
+
+ SyncHTTP( const QString & hostName, quint16 port = 80, QObject * parent = 0 )
+ :QHttp(hostName,port,parent),requestID(-1),status(false){}
+
+ virtual ~SyncHTTP(){}
+
+ /// send GET request and wait until finished
+ bool syncGet ( const QString & path, QIODevice * to = 0 );
+ /*
+ bool syncGet ( const QString & path, QIODevice * to = 0 )
+ {
+ ///connect the requestFinished signal to our finished slot
+ connect(this,SIGNAL(requestFinished(int,bool)),SLOT(finished(int,bool)));
+ /// start the request and store the requestID
+ requestID = get(path, to );
+ /// block until the request is finished
+ loop.exec();
+ /// return the request status
+ return status;
+ }
+ */
+
+ /// send POST request and wait until finished
+ bool syncPost ( const QString & path, QIODevice * data, QIODevice * to = 0 );
+ /*
+ bool syncPost ( const QString & path, QIODevice * data, QIODevice * to = 0 )
+ {
+ ///connect the requestFinished signal to our finished slot
+ connect(this,SIGNAL(requestFinished(int,bool)),SLOT(finished(int,bool)));
+ /// start the request and store the requestID
+ requestID = post(path, data , to );
+ /// block until the request is finished
+ loop.exec();
+ /// return the request status
+ return status;
+ }
+ */
+
+ bool syncPost ( const QString & path, const QByteArray& data, QIODevice * to = 0 );
+ /*
+ bool syncPost ( const QString & path, const QByteArray& data, QIODevice * to = 0 )
+ {
+ /// create io device from QByteArray
+ QBuffer buffer;
+ buffer.setData(data);
+ return syncPost(path,&buffer,to);
+ }
+ */
+
+ protected slots:
+ virtual void finished(int idx, bool err)
+ {
+ /// check to see if it's the request we made
+ if(idx!=requestID)
+ return;
+ /// set status of the request
+ status = !err;
+ /// end the loop
+ loop.exit();
+ }
+
+ private:
+ /// id of current request
+ int requestID;
+ /// error status of current request
+ bool status;
+ /// event loop used to block until request finished
+ QEventLoop loop;
+};
+};
+
+#endif
diff -rupN wkhtmltopdf-0.11.0_rc1/src/shared/commonarguments.cc wkhtmltopdf-0.11.0_rc1-working/src/shared/commonarguments.cc
--- wkhtmltopdf-0.11.0_rc1/src/shared/commonarguments.cc 2011-10-02 10:21:02.000000000 -0700
+++ wkhtmltopdf-0.11.0_rc1-working/src/shared/commonarguments.cc 2012-09-19 13:25:21.000000000 -0700
@@ -219,6 +219,8 @@ void CommandLineParserBase::addPageLoadA
addarg("enable-local-file-access", 0, "Allowed conversion of a local file to read in other local files.", new ConstSetter<bool>(s.blockLocalFileAccess, false));
addarg("allow", 0, "Allow the file or files from the specified folder to be loaded (repeatable)", new StringListSetter(s.allowed,"path"));
+ addarg("basepath", 0, "Add HTML Path to search for relative links", new StringListSetter(s.basePaths,"value"));
+
addarg("debug-javascript", 0,"Show javascript debugging output", new ConstSetter<bool>(s.debugJavascript, true));
addarg("no-debug-javascript", 0,"Do not show javascript debugging output", new ConstSetter<bool>(s.debugJavascript, false));
#if QT_VERSION >= 0x040600
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment