Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
678 views
in Technique[技术] by (71.8m points)

qt - Upload file with POST method on Qt4

I'm looking for a basic code samples of how to upload files to server with HTTP POST method on Qt.

My task: I have simple Qt program and I need to select any image file from the local host and upload it to the server. The selection part and GUI is simple and I have already done it, but with POST uploading I'm confused. In addition I have to say, that there is no authorization to upload file.

If someone already looking this topic?

PS: the reason why I'm asking and not coding my self is time, I need to get this method quick.

Thank you, all success solutions from my side will be posted here for others.

ADDED: Here is my code, that doesn't work yet. Upload site located here.

void    CDialog::on_uploadButton_clicked() {

    QFileInfo fileInfo(absPathLineEdit->text());

    if (!fileInfo.exists()) {
        QMessageBox::information(this, 
            tr("Information"), 
            tr("File doesn't exists! Please, select another image."));
        return;
    }

    file = new QFile(fileInfo.filePath());
    if (!file->open(QIODevice::ReadOnly)) {
        QMessageBox::information(this,
            tr("Information"),
            tr("Unable to open file for reading!"));
        return;
    }

    QString host = "http://data.cod.ru";

    QUrl url(host);

    QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
    http->setHost(url.host(), mode, (url.port() == -1) ? 80 : url.port());

    QHttpRequestHeader header("POST", "/", 1, 1);
    header.setValue("Host", "data.cod.ru");
    header.setValue("Content-type", "multipart/form-data, boundary=AaB03x");
    header.setValue("Cache-Control", "no-cache");
    header.setValue("Accept", "*/*");

    QByteArray bytes(fileInfo.filePath().toUtf8());
    QByteArray totalBytes;
    totalBytes.append("--AaB03x
");
    totalBytes.append("Content-Disposition: form-data; name="email"
");
    totalBytes.append("
");
    totalBytes.append("billgates@microsoft.com
");
    totalBytes.append("--AaB03x
");
    totalBytes.append("Content-Disposition: form-data; name="photo"; filename="" + bytes+ ""
");
    totalBytes.append("Content-Transfer-Encoding: binary

");
    totalBytes.append(file->readAll());
    totalBytes.append("
");
    totalBytes.append("--AaB03x--");

    header.setContentLength(totalBytes.length());

    httpRequestAborted = false;
    httpGetId = http->request(header, totalBytes);

    file->close();
}

and read answer function below:

void    CDialog::httpRequestFinished(int requestId, bool error) {

    if (requestId != httpGetId)
        return;

    if (httpRequestAborted) {
        if (file) {
            file->close();
//          file->remove();
//          delete file;
            file = 0;
        }
        return;
    }

    if (requestId != httpGetId)
        return;

    file->close();

    if (error) {
//      file->remove();
        QMessageBox::information(this, tr("HTTP"),
            tr("Download failed: %1.")
            .arg(http->errorString()));
    } else {
        QByteArray data = http->readAll();
        QFile *dataFile = new QFile("answer.txt");
        dataFile->open(QIODevice::WriteOnly | QIODevice::Text);
        dataFile->write(data);
        dataFile->flush();
        dataFile->close();
    }

//  delete file;
    file = 0;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I see you're trying to use QHTTP and QHttpRequestHeader classes. QT documentation says those are deprecated:

This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.

so, as it was suggested before; I would recommend using QNetworkAccessManager for what you're trying to do

as for your original question; you still can use QHTTP to upload files; I believe actual request headers structure depends on the particular site you're trying to access. In this case tools like wireshark would be in great help. Pls, check if code below would work for you, it should upload test1.jpg file from the home folder and dump its link on the server if 302 response returned.

void MainWindow::on_pushButton_clicked()
{   
    http = new QHttp(this); // http declared as a member of MainWindow class 
    connect(http, SIGNAL(requestFinished(int,bool)), SLOT(httpRequestFinished(int, bool)));

    QString boundary = "---------------------------723690991551375881941828858";

    // action
    QByteArray data(QString("--" + boundary + "
").toAscii());
    data += "Content-Disposition: form-data; name="action"

";
    data += "file_upload
";

    // file
    data += QString("--" + boundary + "
").toAscii();
    data += "Content-Disposition: form-data; name="sfile"; filename="test1.jpg"
";
    data += "Content-Type: image/jpeg

";

    QFile file("/home/test1.jpg");
    if (!file.open(QIODevice::ReadOnly))
        return;

    data += file.readAll();
    data += "
";

    // password
    data += QString("--" + boundary + "
").toAscii();
    data += "Content-Disposition: form-data; name="password"

";
    //data += "password
"; // put password if needed
    data += "
";

    // description
    data += QString("--" + boundary + "
").toAscii();
    data += "Content-Disposition: form-data; name="description"

";
    //data += "description
"; // put description if needed
    data += "
";

    // agree
    data += QString("--" + boundary + "
").toAscii();
    data += "Content-Disposition: form-data; name="agree"

";
    data += "1
";

    data += QString("--" + boundary + "--
").toAscii();

    QHttpRequestHeader header("POST", "/cabinet/upload/");
    header.setValue("Host", "data.cod.ru");
    header.setValue("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9");
    header.setValue("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    header.setValue("Accept-Language", "en-us,en;q=0.5");
    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", "http://data.cod.ru/");

    //multipart/form-data; boundary=---------------------------723690991551375881941828858

    header.setValue("Content-Type", "multipart/form-data; boundary=" + boundary);
    header.setValue("Content-Length", QString::number(data.length()));

    http->setHost("data.cod.ru");
    http->request(header, data);

    file.close();
}

void MainWindow::httpRequestFinished(int, bool)
{
    QHttpResponseHeader responce = http->lastResponse();
    if (responce.statusCode()==302)
    {
        qDebug() << "file accepted; get it from:";
        qDebug() << "data.cod.ru" << responce.value("Location");
    }
}

httpRequestFinished declared in the signals section of the MainWindow class

hope this helps, privet ;)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...