Results 1 to 10 of 10

Thread: QHttp file upload doesn't stream?

  1. #1
    Join Date
    Sep 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Question QHttp file upload doesn't stream?

    Hi All,

    Using QT 4.5.2 on Windows XP. Code example at bottom of post.

    I have a some file upload code which uses QHttp to send a PUT request to a WebDav server. It works fine except for one major problem: it loads the entire file into memory before it uploads the file. This is a problem with large files, a show stopper if the client runs out of memory.

    Qt Code:
    1. int QHttp::request ( const QHttpRequestHeader & header, QIODevice * data = 0, QIODevice * to = 0 )
    To copy to clipboard, switch view to plain text mode 

    I'm using QHttp::request to start the request. I can't seem to come up with a device or combination of devices which will stream or otherwise buffer the file from the disk.

    My working code (which doesn't stream) just passes in the QFile:

    _httpId = _qHttp->request(header, sourceFile);

    I tried passing a QDataStream (or TextStream), which is not a QIODevice. Tried to come up with a combination of QBuffer, QFile, just to see if something would work. No luck.

    I took a look at the QT source. Interestingly, it _is_ buffering the file read in qhttp.cpp, QHttpPrivate::_q_slotBytesWritten(). The memory load looks to me like it's happening in qsslsocket.cpp, QSslSocket::writeData() when the method memcpy's the buffer.

    - Can I use QHttp to do what I want? It doesn't seem like it, but maybe I'm missing something.
    - Is this a bug (I don't think so, yet)?
    - Is it worth trying QNetworkAccessManager, or am I going to run into the same problem?
    - If I need to write custom code to support this, could someone outline a basic approach? Will I need to creat multiple requests for this kind of "chunked" transfer?

    Code snippet (builds, haven't tried to run. My actual code has a bunch of classes abstracting/wrapping a lot of this.)


    Qt Code:
    1. QUrl destUrl(QString("http://www.someDAVserver.com/someFolder/someBigFile.dat"));
    2. QFile* sourceFile = new QFile("D:\\someLocalDir\\someBigFile.dat");
    3.  
    4. if (!sourceFile->open(QIODevice::ReadOnly)) {
    5. //throw
    6. }
    7.  
    8. QHttp::ConnectionMode mode = destUrl.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
    9.  
    10. QHttp http;
    11. http.setHost(destUrl.host(), mode, destUrl.port() == -1 ? 0 : destUrl.port());
    12.  
    13. QHttpRequestHeader header("PUT", destUrl.toEncoded(QUrl::RemoveScheme|QUrl::RemoveAuthority));
    14. header.setValue("Host", destUrl.host());
    15. header.setValue("Accept-Language", QLocale::system().name());
    16. header.setValue("Content-Length", QString::number(sourceFile->size()));
    17.  
    18.  
    19. http.request(header, sourceFile);
    To copy to clipboard, switch view to plain text mode 


    Thanks in advance,

    Hawkeye Parker

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QHttp file upload doesn't stream?

    I'd try QNetworkAccessManager. QHttp is obsolete.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Oct 2009
    Posts
    22
    Thanked 1 Time in 1 Post

    Default Re: QHttp file upload doesn't stream?

    The same will happen with QNetworkAccessManager, it seems that the QSslSocket buffers all the data first.

  4. #4
    Join Date
    Sep 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: QHttp file upload doesn't stream?

    Quote Originally Posted by danc81 View Post
    The same will happen with QNetworkAccessManager, it seems that the QSslSocket buffers all the data first.
    Yes indeed. Haven't solved that problem yet, but absolutely: it's SSL that's causing the problem.

    Also, fwiw, I did try QNetworkAccessManager and had exactly the same problem...

    Hawkeye Parker
    Last edited by haughki; 6th October 2009 at 17:53.

  5. #5
    Join Date
    Oct 2009
    Posts
    22
    Thanked 1 Time in 1 Post

    Default Re: QHttp file upload doesn't stream?

    I've tracked it down to the fact that when QNativeSocketEnginePrivate::nativeWrite() calls WSASend() it returns SOCKET_ERROR and the reason is WSAEWOULDBLOCK, now this appears to be because under normal HTTP, only chunks of 4096 are sent which are fine but using SSL, chunks of 30kB are sent which causes the socket to still be busy on the next attempt. This is find expect that somewhere it seems to report that the bytes were sent and read more from the input device.

    That is as far as I've got with it.

  6. #6
    Join Date
    Sep 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: QHttp file upload doesn't stream?

    Quote Originally Posted by danc81 View Post
    I've tracked it down to the fact that when QNativeSocketEnginePrivate::nativeWrite() calls WSASend() it returns SOCKET_ERROR and the reason is WSAEWOULDBLOCK, now this appears to be because under normal HTTP, only chunks of 4096 are sent which are fine but using SSL, chunks of 30kB are sent which causes the socket to still be busy on the next attempt. This is find expect that somewhere it seems to report that the bytes were sent and read more from the input device.

    That is as far as I've got with it.
    Thanks: good to know; haven't gotten that far. We're going to have to solve this problem one way or another. I'll certainly update this post when I know more. We also have some sense that there should be a way to better configure/build OPENSSL at the client to get around this. Currently still in Google land....

  7. #7
    Join Date
    Oct 2009
    Posts
    22
    Thanked 1 Time in 1 Post

    Default Re: QHttp file upload doesn't stream?

    I don't think the problem lies with OpenSSL, I think the problem is wherever the uploadProgress() signal is fired from is incrementing the number of bytes by what should have been sent and not what was actually sent. If this is corrected (in theory a one-liner), it should at worst fire the signal too many times but with the correct information. This is only my theory and I have yet to prove it...

  8. #8
    Join Date
    Oct 2009
    Posts
    37
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Exclamation Re: QHttp file upload doesn't stream?

    Hi,

    I have the following patch for Qt 4.5.x: http://pastebin.ca/1619204
    It should apply to Qt 4.6 too.
    Could you please see if your issues are solved by this?

    Markus Goetz

  9. #9
    Join Date
    Oct 2009
    Posts
    37
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QHttp file upload doesn't stream?

    If you are not using QHttp but QNetworkAccessManager, there is a 4.5.x patch out too.
    Disclaimer: Although I work on Qt for Nokia, anything I post here is personal

  10. #10
    Join Date
    Sep 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: QHttp file upload doesn't stream?

    Quote Originally Posted by mgoetz View Post
    Hi,

    I have the following patch for Qt 4.5.x: http://pastebin.ca/1619204
    It should apply to Qt 4.6 too.
    Could you please see if your issues are solved by this?

    Markus Goetz
    Hi Markus et al.,

    We applied the patch on 4.5.2, and in "basic testing" streaming seems to be working fine now over SLL using QHttp.

    Thanks _so_ much for this patch, Markus. It's saved us a pretty big chunk of work.

    We'll be testing the patch more thoroughly in the coming weeks (as part of our normal app testing), and we'll post here if anything bad comes up.

    One note: I'm not expert with patch, but the diff you posted didn't patch smoothly for me. I ended up applying the patch manually. E.g.:

    C:\QHttpPatch>patch --dry-run < qhttp_patch.diff patching file qhttp.cpp Hunk #3 FAILED at 2660.
    Hunk #4 FAILED at 3119.
    2 out of 4 hunks FAILED -- saving rejects to file qhttp.cpp.rej

    The diff looks good to me, so I don't know why patch is complaining about hunks #3 and #4. In any case, it was very straightforward to apply the changes manually.

    Thanks again,
    Hawkeye Parker

Similar Threads

  1. QNetworkRequest file upload -- please help
    By Runtime Technologies in forum Qt Programming
    Replies: 3
    Last Post: 14th July 2009, 15:55
  2. File Binary Upload QHttp find the bug/s
    By patrik08 in forum Qt Programming
    Replies: 13
    Last Post: 10th June 2008, 07:51
  3. QHttp::post() - cannot upload file
    By arunredi in forum Qt Programming
    Replies: 5
    Last Post: 16th May 2008, 12:13
  4. Retrieving modified date of file using QHttp
    By hardgeus in forum Qt Programming
    Replies: 9
    Last Post: 3rd December 2006, 23:20
  5. QHttp "PUT METHOD" QT Problem File Upload. RFC 2616
    By patrik08 in forum Qt Programming
    Replies: 7
    Last Post: 25th October 2006, 22:02

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.