Преглед изворни кода

Add support for post, and file post

Antialize пре 16 година
родитељ
комит
0d8e5f1aca
3 измењених фајлова са 86 додато и 13 уклоњено
  1. 28 5
      src/arguments.cc
  2. 49 6
      src/multipageloader.cc
  3. 9 2
      src/settings.hh

+ 28 - 5
src/arguments.cc

@@ -112,18 +112,37 @@ public:
 	}
 };
 
+struct StringPairCreator {
+	typedef QPair<QString, QString> T;
+	inline T operator()(const QString & key, const QString & value) const {
+		return T(key, value);
+	}
+};
+
+template <bool file> 
+struct PostItemCreator {
+	typedef typename Settings::PostItem T;
+	inline T operator()(const QString & key, const QString & value) const {
+		T p;
+		p.name = key;
+		p.value = value;
+		p.file = file;
+		return p;
+	}
+};
 
 /*!
   Putting values into a map
 */
+template <typename T=StringPairCreator>
 struct MapSetter: public ArgHandler {
-	QHash<QString, QString> & dst;
-	MapSetter(QHash<QString, QString> & a, QString keyName, QString valueName) : dst(a) {
+	QList< typename T::T > & dst;
+	MapSetter(QList<typename T::T > & a, QString keyName, QString valueName) : dst(a) {
 		argn.push_back(keyName);
 		argn.push_back(valueName);
 	}
 	virtual bool operator() (const char ** args, CommandLineParserPrivate &) {
-		dst[QString(args[0])] = QString(args[1]);
+		dst.append( T()(args[0], args[1]) );
 		return true;
 	}
 	virtual void useDefault() {
@@ -131,6 +150,7 @@ struct MapSetter: public ArgHandler {
 	}
 };
 
+
 /*!
   SomeSetter template method base
 */
@@ -432,7 +452,7 @@ CommandLineParserPrivate::CommandLineParserPrivate(Settings & s):
 	addarg("proxy",'p',"Use a proxy", new ProxySetter(s.proxy, "proxy"));
 	addarg("username",0,"HTTP Authentication username", new QStrSetter(s.username, "username",""));
 	addarg("password",0,"HTTP Authentication password", new QStrSetter(s.password, "password",""));
-	addarg("custom-header",0,"Set an additional HTTP header (repeatable)", new MapSetter(s.customHeaders, "name", "value"));
+	addarg("custom-header",0,"Set an additional HTTP header (repeatable)", new MapSetter<>(s.customHeaders, "name", "value"));
 	qthack(true);
 	addarg("book",'b',"Set the options one would usually set when printing a book", new Caller<BookFunc>());
 	addarg("cover",0,"Use html document as cover. It will be inserted before the toc with no headers and footers",new QStrSetter(s.cover,"url",""));
@@ -459,7 +479,10 @@ CommandLineParserPrivate::CommandLineParserPrivate(Settings & s):
 	addarg("zoom",0,"Use this zoom factor", new FloatSetter(s.zoomFactor,"float",1.0));
 	addarg("read-args-from-stdin",0,"Read command line arguments from stdin", new ConstSetter<bool>(s.readArgsFromStdin,true,false));
 	addarg("cookie-jar", 0, "Read and write cookies from and to the supplied cookie jar file", new QStrSetter(s.cookieJar, "path", "") );
-	addarg("cookie",0,"Set an additional cookie (repeatable)", new MapSetter(s.cookies, "name", "value"));
+	addarg("cookie",0,"Set an additional cookie (repeatable)", new MapSetter<>(s.cookies, "name", "value"));
+
+	addarg("post", 0, "Add an additional post field (repeatable)", new MapSetter<PostItemCreator<false> >(s.post, "name", "value"));
+	addarg("post-file", 0, "Post an aditional file (repeatable)", new MapSetter<PostItemCreator<true> >(s.post, "name", "path"));
 
 	qthack(true);
 	addarg("disable-internal-links",0,"Do no make local links", new ConstSetter<bool>(s.useLocalLinks,false,true));

+ 49 - 6
src/multipageloader.cc

@@ -18,6 +18,7 @@
 #include <QFileInfo>
 #include <QTimer>
 #include <QNetworkCookie>
+#include <QUuid>
 
 /*!
   \file multipageloader.hh
@@ -138,8 +139,9 @@ MultiPageLoaderPrivate::MultiPageLoaderPrivate(Settings & s, MultiPageLoader & o
 	if (!settings.cookieJar.isEmpty()) 
 		cookieJar.loadFromFile(settings.cookieJar);
 	
-	foreach (const QString & name, settings.cookies )
-		cookieJar.addGlobalCookie(name, settings.cookies[name]);
+	typedef QPair<QString, QString> SSP;
+	foreach (const SSP & pair, settings.cookies)
+		cookieJar.addGlobalCookie(pair.first, pair.second);
 		
 	//If we must use a proxy, create a host of objects
 	if (!settings.proxy.host.isEmpty()) {
@@ -193,11 +195,52 @@ void MultiPageLoaderPrivate::load() {
 	loadStartedEmitted=false;
 	error=false;
 	loadingPages=0;
-	for(int i=0; i < pages.size(); ++i) {
+
+	QString boundary = QUuid::createUuid().toString().remove('-').remove('{').remove('}');
+	QByteArray postData;
+	
+	foreach (const Settings::PostItem & pi, settings.post) {
+		//TODO escape values here
+		postData.append("--");
+		postData.append(boundary);
+		postData.append("\ncontent-disposition: form-data; name=\"");
+		postData.append(pi.name);
+		postData.append('\"');
+		if (pi.file) {
+			QFile f(pi.value);
+			if (!f.open(QIODevice::ReadOnly) ) {
+				emit outer.error(QString("Unable to open file ")+pi.value);
+				fail();
+			}
+			postData.append("; filename=\"");
+			postData.append( QFileInfo(pi.value).fileName());
+			postData.append("\"\n\n");
+			postData.append( f.readAll() );
+			//TODO ADD MIME TYPE
+		} else {
+			postData.append("\n\n");
+			postData.append(pi.value);
+		}
+		postData.append('\n');
+	}
+	if (!postData.isEmpty()) {
+		postData.append("--");
+		postData.append(boundary);
+		postData.append("--\n");
+	}
+
+	for (int i=0; i < pages.size(); ++i) {
 		QNetworkRequest r = QNetworkRequest(urls[i]);
-		for(QHash<QString, QString>::const_iterator j = settings.customHeaders.constBegin(); j != settings.customHeaders.constEnd(); ++j)
-			r.setRawHeader(j.key().toAscii(), j.value().toAscii());
-		pages[i]->mainFrame()->load(r);
+		typedef QPair<QString, QString> HT;
+		foreach (const HT & j, settings.customHeaders)
+			r.setRawHeader(j.first.toAscii(), j.second.toAscii());
+	
+		if (postData.isEmpty())
+			pages[i]->mainFrame()->load(r);
+		else {
+			r.setHeader(QNetworkRequest::ContentTypeHeader, QString("multipart/form-data, boundary=")+boundary);
+			pages[i]->mainFrame()->load(r, QNetworkAccessManager::PostOperation, postData);
+		}
 	}	
 }
 

+ 9 - 2
src/settings.hh

@@ -81,6 +81,12 @@ struct Settings {
 		//! Password for the said proxy or NULL
 		QString password; 
 	};
+
+	struct PostItem {
+		QString name;
+		QString value;
+		bool file;
+	};
 	
 	/*! \brief Settings consdering margins */
 	struct MarginSettings {
@@ -174,14 +180,15 @@ struct Settings {
 	//! The file where in to store the output
 	QString out;
 	//! Map of custum header valiabels
-	QHash<QString, QString> customHeaders;
+	QList< QPair<QString, QString> > customHeaders;
 	//! Should we read arguments from stdin
 	bool readArgsFromStdin;
 	//! Map of cookies
-	QHash<QString, QString> cookies;
+	QList< QPair<QString, QString> > cookies;
 	//! Path of the cookie jar file
 	QString cookieJar;
 	
+	QList< PostItem > post;
 
 	static QPrinter::PageSize strToPageSize(const char * s, bool * ok=0);
 	static QPair<qreal, QPrinter::Unit> strToUnitReal(const char * s, bool * ok=0);