Qt Commercial Support Weekly #14 - Introducing QHttpMultiPart


This week we have been dealing with quite a variety of different components in support. Quite a number of things have been reported as bugs and we have been supplying fixes and workarounds to those wherever we can.  Since July 2011, we have been going at a steady increase in the percentages of bugs being fixed and we are edging closer to 80% of all bugs reported to Qt Support get fixed or given a workaround from someone in the support team.  This is not to say that the other things don't get fixed at all. All bugs that are still outstanding are passed on to the R&D team so that they can look into fixing them too, as Qt Commercial is dedicated to getting these issues fixed as well as implementing new features.


Note: This blog is best viewed with Mozilla Firefox. Internet Explorer is giving errors on the code snippet.


Now that shameless marketing on my side is out of the way it is on to the latest technical nugget of information for the week.


With the release of Qt Commercial 4.8.0 a new network related class somewhat sneaked under the radar, which makes things easier when it comes to uploading files via a form or similar on a HTML webpage.  This class is called QHttpMultiPart and comes with another helper class called QHttpPart.  It is a relatively straight-forward class to use, in fact, as the bulk of it is done for you once you specify the file to be sent with it.  So, if you want to upload data via a form then you would do something like:



  QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType, this);


Then, for each element you want to pass up you would create a QHttpPart and tell it the data you want to send.  Since it takes a QIODevice you are not restricted to using a QFile. You can use your own QIODevice subclass, or even a QNetworkReply, if you are so inclined.  You can also pass the data directly.  In the code below we are going to pass an image, so we need to set the headers to  indicate that it is an image being sent.



  QHttpPart filePath;

  filePath.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));

  filePath.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form.data; name="image""));

  QFile *file = new QFile("image.png");





Now we just tie the two together with and post it to the QNetworkRequest for our url:



   QNetworkReply *reply = manager.post(request, multiPart);



You are not restricted to just one QHttpPart here. You can append as many as you want to the QHttpMultiPart and they will be sent all in the same QHttpMultiPart data packets.  


One thing to remember and watch out for is the QIODevice that you have set as the body device is not owned by the QHttpPart, so you need to delete it after it has been finished with.  One approach to this would be to call setParent() on the iodevices and pass the QNetworkReply as the parent.  So, when the QNetworkReply is finished with it would delete the body parts for you. 



Until next week, happy coding :)