Results 1 to 10 of 10

Thread: QT cannot read continuation or non-http traffic

  1. #1
    Join Date
    May 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Windows

    Default QT cannot read continuation or non-http traffic

    Hi

    I am trying to communicate to an AXIS product and it sends me serial data over HTTP. The sequence is:

    Qt Code:
    1. HTTP GET ->
    2. <- HTTP 204 - No Content
    3. <- HTTP Continuation or non-Http traffic
    4. <- HTTP Continuation or non-Http traffic
    5. <- HTTP Continuation or non-Http traffic
    6. etc
    To copy to clipboard, switch view to plain text mode 

    I have traced through the QT code to the function QHttpPrivate::_q_slotReadyRead(). It appears that QT thinks it must find a valid header in the " HTTP Continuation or non-Http traffic" packets. Since the code can't find the header, it returns and does not extract the data.

    Qt Code:
    1. void QHttpPrivate::_q_slotReadyRead()
    2. {
    3. Q_Q(QHttp);
    4. QHttp::State oldState = state;
    5. if (state != QHttp::Reading) {
    6. setState(QHttp::Reading);
    7. readHeader = true;
    8. headerStr = QLatin1String("");
    9. bytesDone = 0;
    10. chunkedSize = -1;
    11. repost = false;
    12. }
    13.  
    14. while (readHeader) {
    15. bool end = false;
    16. QString tmp;
    17. while (!end && socket->canReadLine()) {
    18. tmp = QString::fromAscii(socket->readLine());
    19. if (tmp == QLatin1String("\r\n") || tmp == QLatin1String("\n") || tmp.isEmpty())
    20. end = true;
    21. else
    22. headerStr += tmp;
    23. }
    24.  
    25. if (!end)
    26. return; //****This is where it returns, ARG*********
    To copy to clipboard, switch view to plain text mode 

    These packet types are apparently common (see http://ayis.javaeye.com/blog/351217), so why would QT drop them? Is there a bug in QT?

    Any help would be greatly appreciated!

  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: QT cannot read continuation or non-http traffic

    I think you are overinterpreting what you see. If what you say was true, you wouldn't be able to download anything larger than one TCP segment using QHttp which is obviously not the case. QHttp works in the application layer of the TCP/IP stack so it doesn't see segments or packets, it just sees a stream of bytes. The response has to begin with a header (that's what the HTTP protocol requires) but it doesn't mean every IP packet has to contain an HTTP header.

    Are you reading the data that comes in through QHttp? Are you sure the read buffer is not full?
    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
    May 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT cannot read continuation or non-http traffic

    Hi

    I agree that QHttp should be able to read the data from a buffer, but what I think is happening is that the response 204 causes QHttp to move from the reading state to the connected state. I'm sure that if the AXIS sent a response 200, I would be able to read the data from the buffer.

    I have set breakpoints in the code (specifically QHttpPrivate::_q_slotReadyRead()) and see it reading HTTP code 204, then transitioning to the connected state. Once there, it does not want to read.

    I also tried using QNetworkAccessManager and it has the same problem. The 204 code is preventing QTs state machine from remaining in the read state.

    I'm trying to do this now with QSslSocket. This is going to be painful. I wish I could find an example where someone DID NOT use QHttp to setup an HTTP GET.

    Thanks for your help!

  4. #4
    Join Date
    May 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT cannot read continuation or non-http traffic

    How about this idea (I'd sure appreciate a OK or NAY from a QT guru)

    1) Setup my own socket using QSslSocket
    2) Use QHttp:setSocket to get QHttp to use that socket
    3) use QSslSocket.bytesAvailable to see if I get data
    4) and if I do, use QSslSocket.read()

    I assume that read() will read the buffer and not the individual packets?

    Thanks in advance.

  5. #5
    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: QT cannot read continuation or non-http traffic

    Quote Originally Posted by SailingDreams View Post
    I have set breakpoints in the code (specifically QHttpPrivate::_q_slotReadyRead()) and see it reading HTTP code 204, then transitioning to the connected state. Once there, it does not want to read.
    According to the specification of HTTP:

    The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.
    Thus I think what QHttp does is correct... It reads headers and returns to the connected state.

    Quote Originally Posted by SailingDreams View Post
    How about this idea (I'd sure appreciate a OK or NAY from a QT guru)

    1) Setup my own socket using QSslSocket
    2) Use QHttp:setSocket to get QHttp to use that socket
    3) use QSslSocket.bytesAvailable to see if I get data
    4) and if I do, use QSslSocket.read()

    I assume that read() will read the buffer and not the individual packets?

    Thanks in advance.
    You can either read from the socket yourself or let it be managed by QHttp, not both at once.
    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.


  6. #6
    Join Date
    May 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Windows

    Red face Re: QT cannot read continuation or non-http traffic

    Thanks. Thats a great point: can't get read TCP if HTTP manages the socket.

    I will try to shut down QHttp with abort(). Hopefully, since the socket was created external to QHttp, the socket stays open and then I can use QSslSocket.bytesAvailable() and read().

    I think what AXIS is doing must be non-standard for sending serial data. They do video streams differently. For video, you do a GET and then AXIS starts streaming data in "TCP segment of a reassembled packet". Then its easy, you just use bytesAvailable() and read() to get the data. (the first TCP packet has HTTP 200 OK in it).

    I wish there were a way to make QHttp go back to the reading state once it sees the 204.

    If I am successful at shutting down QHttp with abort (it leaves the socket open), I worry that my next challenge will be TCP not reading the "HTTP Continuation or non-Http traffic
    ". I say this because these packets do not have a header termination \n\r and hence I've observed (by stepping through the code) that QHttp thinks the whole packet is a header and that the header is continued in the next packet. Hopefully QTcpSocket does not reject the data as being HTTP header info.

  7. #7
    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: QT cannot read continuation or non-http traffic

    The socket will be closed.
    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.


  8. #8
    Join Date
    May 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Windows

    Thumbs up Re: QT cannot read continuation or non-http traffic

    You are right. Arg. QHTTP::abort also kills the TCP connection. So much for their documentation:

    QHttp does not take ownership of the socket, and will not delete socket when destroyed.
    The good news is I was able to use QTcpSocket::read() and bytesAvailable() without deleting the QHttp object. I'm getting my data now!!

    Thank-you very much for your help!

  9. #9
    Join Date
    May 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT cannot read continuation or non-http traffic

    Alas, I thought I had this problem solved. Using the QTcpSocket::read() worked when I sent data that was the character pattern 0 to 9,a to z, but when I connected the AXIS serial port to the device that feeds it serial data, something in the serial data makes QT think there is a valid HTTP header and it created to new request (very strange). The output below is from slots connnected to the various QHttp signals.

    It is very strange that QT creates a Id=0 request. Why does it do that?

    Opened file serialCapture.txt
    requestStarted: request type setHost rx : id = 1 (id = 1)
    requestFinished: request setHost rx : id = 1, ID = 1, error = No error
    requestStarted: request type setSocket rx : id = 3 (id = 3)
    requestFinished: request setSocket rx : id = 3, ID = 3, error = No error
    requestStarted: request type GET rx connect : id = 4 (id = 4)
    stateChanged: request type GET rx connect : id = 4 Id=4 is changed to Sending
    stateChanged: ---reading state---
    stateChanged: request type GET rx connect : id = 4 Id=4 is changed to Reading
    readResponseHeader: code = 204 for Id = 4
    stateChanged: request type GET rx connect : id = 4 Id=4 is changed to Connected
    requestFinished: request GET rx connect : id = 4, ID = 4, error = No error
    done: No Error.
    ******I start sending my canned serial data here (which comes as HTTP continuation of data packets)**************
    stateChanged: ---reading state---
    stateChanged: request type Id=0 is changed to Reading
    readData: has read 1 packets of 51 bytes
    readData: has read 5 packets of 3807 bytes
    Closing stream capture file
    readData: has read 9 packets of 7524 bytes
    readData: has read 13 packets of 11256 bytes
    readData: has read 17 packets of 14990 bytes
    readData: has read 21 packets of 16868 bytes
    ******The device starts sending serial data here(which comes as HTTP continuation of data packets)**************

    stateChanged: request type Id=0 is changed to Closing
    stateChanged: request type Id=0 is changed to Unconnected
    *****At this point the TCP connection is closed by QHttp. Arg!********
    It looks like I have to write my own HTTP handler. Darn.

  10. #10
    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: QT cannot read continuation or non-http traffic

    You're doing something very non-standard so I wouldn't rely on QHttp behaving in a sane way in such situation.
    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.


Similar Threads

  1. HTTP GET authentication does not proceed
    By SailingDreams in forum Qt Programming
    Replies: 2
    Last Post: 1st June 2009, 01:27
  2. QIODevice read()
    By ShaChris23 in forum Newbie
    Replies: 1
    Last Post: 3rd May 2007, 00:29

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.