[Qt4.1] Dateiupload mit QHttp
Verfasst: 9. Juni 2006 08:10
Da öfter danach gefragt wurde, und es anscheinend nicht einfach ist , stelle ich hier mal ein Programm zum Dateiupload zur Verfügung. Kompiliert und getestet habe ich es nur mit Qt 4.1.3. Es handelt sich hierbei um ein Konsolenprogramm, mit dem man eine oder mehrere Dateien an ein PHP-Skript senden kann. Aufruf ist wie folgt:
programm -u=http://server/transfer.php -f=file1 -f=file2 [-p=serverantwort.html]
Zum testen packe ich mein PHP-Skript gleich bei.
Transfer.php
main.cpp
httppost.h
httppost.cpp
programm -u=http://server/transfer.php -f=file1 -f=file2 [-p=serverantwort.html]
Zum testen packe ich mein PHP-Skript gleich bei.
Transfer.php
Code: Alles auswählen
<?php
$path="./";
$log = fopen("request.log", "w");
fwrite($log, "Anfrage angekommen\r\n");
$uploadlog = array();
if ($_POST)
{
fwrite($log, "POST angekommen\r\n");
$count = 0;
if (isset($_FILES['datei']))
$count = count($_FILES['datei']['name']);
for ($i=0; $i<$count; $i++)
if (move_uploaded_file($_FILES['datei']['tmp_name'][$i], $path.$_FILES['datei']['name'][$i]))
array_push($uploadlog, "<br>Datei ".$_FILES['datei']['name'][$i]." einwandfrei empfangen und gesichert.");
else
array_push($uploadlog, "<br>Datei ".$_FILES['datei']['name'][$i]." machte Probleme.");
}
fclose($log);
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;CHARSET=iso-8859-1">
</head>
<body>
<?php
echo count($uploadlog)." Dateien empfangen";
foreach ($uploadlog as $text)
echo $text;
?>
</body>
</html>
Code: Alles auswählen
#include <QCoreApplication>
#include "httppost.h"
void displayHelp()
{
printf("Usage: HTTPpost.exe url='URI' file='file.1' file='file.n' [page='result.html']\n");
printf(" -u\t= gueltige Internetseite\n");
printf(" -f\t= ein oder mehrere Files vom lokalen Rechner\n");
printf("Optional\n");
printf(" -p\t= Name der Datei in der der empfangene Text gespeichert wird.\n");
printf(" \t Wird hinterher im Standardviewer angezeigt, default ist result.html\n\n");
exit(0);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HTTPpost w;
w.setApp(&a);
if (argc < 2)
displayHelp();
QString param, url;
QStringList sl, files;
for (int l=1; l<argc; l++)
{
param = argv[l];
sl = param.split("=", QString::SkipEmptyParts);
if (sl.count()!=2)
displayHelp();
else if (sl[0].toLower()=="-u")
w.setURI(sl[1]);
else if (sl[0].toLower()=="-p")
w.setPage(sl[1]);
else if (sl[0].toLower()=="-f")
w.appendFile(sl[1].replace("'","").replace("\"",""));
else
displayHelp();
}
w.send();
return a.exec();
}
Code: Alles auswählen
#ifndef HTTPPOST_H
#define HTTPPOST_H
#include <QHttp>
#include <QFile>
#include <QBuffer>
class HTTPpost : public QObject
{
Q_OBJECT
public:
HTTPpost();
~HTTPpost();
void send();
void appendFile(QString name) { files.append(name); };
void setURI(QString url) { urlName = url; };
void setPage(QString page) { resultFile = page; };
void setApp(QCoreApplication* a) { app = a; };
private:
QCoreApplication* app;
QByteArray* bytes;
QBuffer* buffer;
QHttp* http;
QFile* file;
QFile* logFile;
QString urlName;
QString resultFile;
int httpPostId;
QStringList files;
private slots:
void httpRequestFinished(int requestId, bool error);
void readResponseHeader(const QHttpResponseHeader &responseHeader);
};
#endif // HTTPPOST_H
Code: Alles auswählen
#include "httppost.h"
#include <QUrl>
#include <QFileInfo>
#include <QDir>
#include <QCoreApplication>
// Wird nur für ShellExecute benötigt
//#include <windows.h>
#define STRFILEVER "1.0.0"
HTTPpost::HTTPpost()
{
http = new QHttp();
connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool)));
connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
resultFile = "";
app = NULL;
}
HTTPpost::~HTTPpost()
{
}
void HTTPpost::send()
{
QString version(STRFILEVER);
version.replace(",",".").replace(" ","");
QUrl url(urlName);
http->setHost(url.host(), 80);
if (!url.userName().isEmpty())
http->setUser(url.userName(), url.password());
QHttpRequestHeader header("POST", url.path());
header.setValue("Host", url.host());
header.setValue("User-Agent", "HTTPpost.exe " + version);
header.setValue("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
header.setValue("Accept-Language", "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3");
header.setValue("Accept-Encoding", "gzip,deflate");
header.setValue("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
header.setValue("Keep-Alive", "300");
header.setValue("Connection", "keep-alive");
header.setValue("Referer", "HTTPpost.exe " + version);
// nur nötig falls Passwort geschützt, dann muss aber der Hash-Wert ersetzt werden
// header.setValue("Authorization", "Basic SG9sem1hOmN1dDJzaXpl");
header.setValue("Content-Type", "multipart/form-data boundary=---------------------------125282808721657");
bytes = new QByteArray();
bytes->append("-----------------------------125282808721657\n"); // Das hier ist ein Dummy-Feldname, damit
bytes->append("Content-Disposition: form-data; name=\"upload\"\n"); // das auch als POST wahr genommen wird
bytes->append("\nUploadFile\n");
// und jetzt kommen die einzelnen Files
QString name, dateiName;
file = new QFile();
for (int l=0; l<files.count(); l++)
{
QFileInfo fileInfo(files[l]);
file->setFileName(files[l]);
dateiName = fileInfo.fileName();
if (!file->exists())
{
printf("File %S doesn't exist.\n", files[l].utf16());
delete file;
file = 0;
exit(-1);
}
if (!file->open(QIODevice::ReadOnly))
{
printf("Unable to read the file %S: %S.",dateiName.utf16(), file->errorString().utf16());
delete file;
file = 0;
exit(-1);
}
bytes->append("-----------------------------125282808721657\n");
bytes->append("Content-Disposition: form-data; name=\"datei[" + QString::number(l));
bytes->append("]\"; filename=\"" + dateiName + "\"\n");
bytes->append("Content-length: " + QString::number(fileInfo.size()));
bytes->append("\nContent-Type: text/plain\n\n");
bytes->append(file->readAll());
file->close();
bytes->append("\n");
}
bytes->append("-----------------------------125282808721657--\n");
buffer = new QBuffer(bytes);
if (resultFile=="")
resultFile = "result.html";
QDir d;
if (d.exists(resultFile))
d.remove(resultFile);
logFile = new QFile(resultFile);
logFile->open(QIODevice::ReadWrite);
httpPostId = http->request(header, buffer, logFile);
}
void HTTPpost::httpRequestFinished(int requestId, bool error)
{
if (requestId != httpPostId)
return;
buffer->close();
logFile->close();
QFileInfo logFileInfo(resultFile);
// der ShellExecute zeigt nur das Logfile an, zu Testzwecken ganz praktisch
// ShellExecute(NULL, QString("open").toAscii(), logFileInfo.absoluteFilePath().toAscii(), NULL, NULL, SW_SHOW);
app->quit();
}
void HTTPpost::readResponseHeader(const QHttpResponseHeader &responseHeader)
{
printf("%d %S\n",responseHeader.statusCode(), responseHeader.reasonPhrase().utf16());
}