简体   繁体   中英

Adding attachment to JIRA issue using the REST API and Qt with QNetworkRequest

I'm trying to add an attacment to an existing JIRA issue using the REST API and Qt.

When I run the code below, the reply is an empty array ("[]").

edit: updated the code

QString APIhandler::attachFile(QString fileloc, QString issueKey, QString cookie)
{

//create multiPart
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

QFile *file = new QFile(fileloc);
//create httpPart for file
QHttpPart filePart;

filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+ file->fileName()+ "\""));



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("cookie", "JSESSIONID = " + cookie.toUtf8()); // the session cookie
req.setRawHeader("X-Atlassian-Token", "nocheck");
req.setRawHeader("Content-Type", "multipart/form-data; boundary=------------------------53a5a2cd1d9c8b7f");
//req.setRawHeader("Content-Length", postDataSize);

reply = mngr->post(req, multiPart);
multiPart->setParent(reply);
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));

loop.exec();


return reply->readAll();

}

I am using the JIRA REST API documentation and qt documentation for reference, and looking off of this java implementation (which I've tried to replicate).

It seems like I'm either missing a header, or adding the file incorrectly.

Any help is greatly appreciated!

EDIT - Here's part of a wireshark comparing the example from the api using curl (LEFT) , and my code (RIGHT). The one on the left works, and clearly has different MIME data, but I'm not sure how to implement that in Qt

在此处输入图片说明

Okay, so I figured it out. I might be the only one on earth who is using (or will use) Qt to interact with the JIRA API, but for posterity, here's what I came up with:

QString APIhandler::attachFile(QString fileloc, QString issueKey, QString cookie)
{

    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart filePart;
    QFileInfo fileInfo(fileloc);

    //what I wasn't doing before!
    multiPart->setBoundary("------------------------53a5a2cf4d9c8b7f");

    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+fileInfo.fileName() +"\""));
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));

    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");

    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());

    delete file;
    delete multiPart;
    delete reply;
    delete mngr;

}

The key part here, and what I was doing wrong, was the way in which I set the boundary for the multipart. Instead of setting it in the header, I should have used:

multipart->setBoundary()

Which you can see reflected above.

If you're coming across this and are going to use it, I'd recommend cleaning it up a bit, first. But it works!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM