Skip to content

Instantly share code, notes, and snippets.

@micjabbour
Created April 6, 2018 19:22
Show Gist options
  • Save micjabbour/3041e82f29aabf82d3a0d259b4b11f26 to your computer and use it in GitHub Desktop.
Save micjabbour/3041e82f29aabf82d3a0d259b4b11f26 to your computer and use it in GitHub Desktop.
A minimal test case for a possible bug in QHttpMultiPart that I am trying to track down
//the following file demonstrates a minimal test case for a possible bug in
//QHttpMultiPart. The request hangs completely when calling
//QApplication::processEvents() from a slot connected to
//QNetworkReply::uploadProgress. Note that this happens naturally when using
//QProgressDialog::setValue from a slot connected to uploadProgress signal (as
//setValue is documented to call QApplication::processEvents internally)
#include <QtWidgets>
#include <QtNetwork>
const bool reproduceBug = true;
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
QNetworkAccessManager nam;
QString openFileName = QFileDialog::getOpenFileName();
QFile source(openFileName);
if(!source.open(QIODevice::ReadOnly)) return 1;
QFileInfo fileInfo(openFileName);
//upload selected file using an HTTP multipart request
//based on http://doc.qt.io/qt-5/qhttpmultipart.html#details
//construct QNetworkRequest
QNetworkRequest request{QUrl("http://127.0.0.1:5000/")};
//setting up multipart content object
QHttpMultiPart * multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
//setting up attachment file part of the above request
QHttpPart attachmentFilePart;
attachmentFilePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant(QString("form-data; name=\"file\"; "
"filename=\"%1\"")
.arg(fileInfo.fileName())));
attachmentFilePart.setBodyDevice(&source);
//add attachment part to multi part content object
multiPart->append(attachmentFilePart);
QNetworkReply *reply = nam.post(request, multiPart);
multiPart->setParent(reply); //delete the multipart object with the reply
QObject::connect(reply, &QNetworkReply::uploadProgress,
[] (qint64 bytesSent, qint64 bytesTotal) {
qInfo() << "uploadProgress: " << bytesSent << " out of " << bytesTotal;
if(reproduceBug) QApplication::processEvents();
});
QObject::connect(reply, &QNetworkReply::finished, [reply] {
reply->deleteLater();
if(reply->error() == QNetworkReply::NoError)
qInfo().noquote() << reply->readAll();
else
qInfo() << "Error: " << reply->error();
//quit when the request is finished
qApp->quit();
});
return a.exec();
}
# a minimal flask server to test HTTP multipart file upload requests
# based on http://flask.pocoo.org/docs/0.12/patterns/fileuploads/
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
return 'no file part'
file = request.files['file']
# if user does not select file, browser also
# submit a empty part without filename
if file.filename == '':
return 'no file selected'
if file:
return 'uploaded successfully'
# GET request
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment