Wednesday, May 5, 2010

Simple download manager in Qt with puase/ resume support

Update: Here is link to my full working code sample.

Recently I needed to create simple download manager that support pause/ resume.

I was using Qt's network module (QNetworkAccessManager to be specific) to download media content, but QNetworkAccessManager class by itself does not support pause/resume feature.

But with little effort we can make it to support pause/resume. Trick it to set "Range" header while making HTTP request.

Please visit RFC 2616 for more information related to Range header.

To implement download manager, I have used example code from Qt 4.6 (http://doc.qt.nokia.com/4.6/network-downloadmanager.html) and then added code to support pause and resume.

In my code when user pause download I am saving current request and on resume I am adding Range header to saved request then starting download using that saved request.

downloadSizeAtPause = _currentRequest->_device->size();
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(downloadSizeAtPause) + "-"; 

_currentRequest->_request.setRawHeader("Range",rangeHeaderValue);

QTimer::singleShot(0,this,SLOT(startNextDownload()));

So here is simple download manager.



 

20 comments:

  1. could explain more how work this code?, I don´t understand what's "downloadSizeAtPause" or "setRawHeader"

    ReplyDelete
  2. downloadSizeAtPause is just int variable to get current download size when item was paused.

    setRawHeader is Qt API to set HTTP Header.

    ReplyDelete
  3. ok thanks!, excuse me for other question: how I can restart the download using a Range header?, I'm searching but I don't found any function that make this or maybe I don't see it.

    ReplyDelete
  4. Hi,
    here _currentRequest->_request is QNetworkRequest

    and by following statement you are setting range header on QNetworkRequest.

    _currentRequest->_request.setRawHeader("Range",rangeHeaderValue);

    After setting range header, you can use get method of QNetworkAccessManager with this QNetworkRequest to restart your paused download.

    ReplyDelete
  5. thanks!!!

    very usefull.

    NEMO, from Costa Rica

    ReplyDelete
  6. Hi Kunal,

    I have added your code in download manager example, however It still not working. Might you send me your code.

    Thank you very much!
    Hugo

    ReplyDelete
  7. Hi,
    I will try to provide working sample code asap.
    Thanks
    Kunal

    ReplyDelete
  8. Hi,
    code is uploaded here. http://kunalmaemo.blogspot.com/2011/07/simple-download-manager-with-pause.html

    Thanks for visiting my blog. Hope you find above information useful.

    ~Kunal

    ReplyDelete
  9. Hi Kunal,

    Thank you very much! I got your code already.It's very helpful. I am going to implement a upload manager with pause/resume. If I get problems, hope you help me.

    Best regards,
    Hugo

    ReplyDelete
  10. heu kunal:
    can this be used for any type of files zip tar.gz i mean binaries

    ReplyDelete
  11. yes, it should work with any kind of file. As you see in video, I am downloading and exe file.

    ReplyDelete
    Replies
    1. thanks man for replying are u intrested in working in a download manager

      Delete
    2. I did not get you question clearly ?

      Delete
  12. i am working in a download manager are you intrested in joining that project

    ReplyDelete
  13. I am sorry, But I think I will not be able to commit enough time for your project. Thanks for your offer :)

    ReplyDelete
  14. Note the number of bytes returned by QIODevice.size() may not represent the actual bytes transmitted ,The reason for this is that there may be protocol overhead or the data may be compressed during the download.

    ReplyDelete
  15. thanks for sharing the implementation.

    now most of the download managers support downloading in multiple streams at once. I understand that the rangeHeaderValue can be used to download multiple streams of download. but does one combine all streams into one at the end ?

    any thoughts would be appreciated

    ReplyDelete
    Replies
    1. I never tried that my self, but yes I believe one has to combine all part to one at end, I think writing individual chunk to separate file first, once al chunks are downloaded combine them to final output file, will be good strategy.

      Delete