Adding an attachment using REST API and Qt

Michael C July 10, 2015

I've been trying to add an attachment to a JIRA issue using the REST API and Qt (C++), but I can't for the life of me figure out how to get it to work.

I've looked at countless examples of people doing it in JAVA, C#, php, etc, but I can't find an example of someone doing it in Qt.

So here's the code I have:

 

QString APIhandler::attachFile(QString fileloc, QString issueKey, QString cookie)
{
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"Zapotec.bmp\""));
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream;boundary=------------------------53a5a2cf4d9c8b7f"));

QFile *file = new QFile(fileloc);
file->open(QIODevice::ReadOnly); 
filePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(filePart);

QNetworkAccessManager *mngr = new QNetworkAccessManager();

QUrl issurl(baseURL + "/api/2/issue/"+ issueKey + "/attachments");

QNetworkRequest req(issurl);
QNetworkReply *reply ;
QEventLoop loop;
//add headers
req.setRawHeader("X-Atlassian-Token", "nocheck");
req.setRawHeader("cookie", "JSESSIONID = " + cookie.toUtf8()); // the session cookie
req.setRawHeader("Content-Type", "multipart/form-data;boundary=------------------------53a5a2cf4d9c8b7f");
//req.setRawHeader("Content-Length", QString::number(file->size()).toUtf8());
reply = mngr->post(req, multiPart);
multiPart->setParent(reply);
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
//read the reply
QByteArray bytes=reply->readAll();
//return the reply JSON 
return QString::fromUtf8(bytes.data(), bytes.size());
}

 

I've verified that I have the correct permissions, the file I'm trying to upload is below the maximum file size, and the request even returns a status code of 200.

Other than that, the response is just an empty array: "[]", which doesn't tell me much.

 

I assume there's something wrong with the headers or the filepart.

 

I'm using Qt 4.8.

 

Any help is greatly appreciated!

1 answer

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 10, 2015

I'm not an expert in Qt (and I don't have the time & medium to setup a c++ dev end on my machine right now), but boundaries should be calculated by the Qt framework.

Look for instance the example in the docs: http://doc.qt.io/qt-4.8/qhttpmultipart.html

BTW, shouldn't you delete some pointers here ? Just sayin' ... don't get mad ... smile

 

Michael C July 10, 2015

Without the boundary, it returns a 500 status code and complains that there isn't one. And regarding the pointers -- I'll get to that, haha. I just want to get it working first! :P

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 10, 2015

I still don't like how you specify directly the header boundary here (I'm not saying that you're wrong!) Usually, such a raw req is something like {raw} Content-Type: multipart/form-data; charset=utf-8; boundary="XXXX" --XXXX Content-Disposition: form-data; name="foo" foovalue --XXXX Content-Disposition: form-data; name="bar" barValue --XXXX-- {raw} I would call setBoundary() on it. Anyway.

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 10, 2015

BTW, you can get really mad, and use the raw representation all over. :)

Michael C July 10, 2015

So I did just go and setBoundary() all over, and it worked! Thank you so much! Words cannot describe how happy I am.

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 10, 2015

Haha. I'm bit rusty in C++ but still valid !!!

TAGS
AUG Leaders

Atlassian Community Events