tags:

views:

1020

answers:

3

Hello!

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\r\n");
    totalBytes.append("Content-Disposition: form-data; name=\"email\"\r\n");
    totalBytes.append("\r\n");
    totalBytes.append("[email protected]\r\n");
    totalBytes.append("--AaB03x\r\n");
    totalBytes.append("Content-Disposition: form-data; name=\"photo\"; filename=\"" + bytes+ "\"\r\n");
    totalBytes.append("Content-Transfer-Encoding: binary\r\n\r\n");
    totalBytes.append(file->readAll());
    totalBytes.append("\r\n");
    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;
}
A: 

Use QNetworkAccessManager.

manager.post(your_qhttpnetworkrequest, your_image_qfile);
guruz
@guruz: Thanks, but this is not the goal answer...
mosg
+3  A: 

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 + "\r\n").toAscii());
    data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
    data += "file_upload\r\n";

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

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

    data += file.readAll();
    data += "\r\n";

    // password
    data += QString("--" + boundary + "\r\n").toAscii();
    data += "Content-Disposition: form-data; name=\"password\"\r\n\r\n";
    //data += "password\r\n"; // put password if needed
    data += "\r\n";

    // description
    data += QString("--" + boundary + "\r\n").toAscii();
    data += "Content-Disposition: form-data; name=\"description\"\r\n\r\n";
    //data += "description\r\n"; // put description if needed
    data += "\r\n";

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

    data += QString("--" + boundary + "--\r\n").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 ;)

serge_gubenko
@serge_gubenko: Thank you very much and good luck. This code worked for me! :) Спасибо!
mosg
+1  A: 

Also, I found today nice code: link text

It's uploader/downloader app based on Qt4, with full set of POST headers managed by QNetworkAccessManager inside, so for beginners it will be very helpful.

Owner: stiff.ru

Committer: hoxnox

mosg