Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-113749

QNetworkReply stops emiting readyRead when using proxy

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.3.2, 6.5.0
    • None
    • Windows

    Description

      Description:
      When application use localhost proxy(based on boost asio) on Windows sometimes qnetworkreply stops emitting readyRead signal, after some investigation:

      Shortly how it works(just for clarification, that I understand correct):
      When using proxy QNetworkProxy::HttpProxy creates 2 QTCPSockets, 1. QHttpSocketEngine based(httpsocket) 2. QNativeSocketEngine based(nativesocket)

      httpsocket and nativesocket have buffer size 64*1024(65536) bytes, nativesocket notifies httpsocket by the qt_internal_proc->QReadNotifier->QNativeSocketEngine, after that nativesocket read from system socket and emit readyRead to httpsocket, httpsocket read from nativesocket and emit readyRead to qnetworkreply.

      In QAbstractSocketPrivate can be disabled notification from QAbstractSocketEngine(in my case it is disabled by QAbstractSocketPrivate full buffer(65536 bytes))

      After all data read from QAbstractSocketPrivate(QIODevicePrivate) buffer - buffer.isEmpty() QAbstractSocket::readData will be called and in case no any errors QAbstractSocketEngine::setReadNotificationEnabled(true) will be called and application will continue to get notifications from engine

      Problem details:
      1. nativesocket receive some data(according the attached logs 8616 bytes)(QReadNotifier::event QEvent::SockAct)
      2. httpsocket read this data from nativesocket by readyRead notification, and emits readyRead signal
      3. nativesocket next notification from system(QReadNotifier::event QEvent::SockAct)(httpsocket buffer.size() still 8616 bytes), nativesocket buffer is empty
      4. nativesocket read from system socket all available data in case of problem 65536 bytes
      5. nativesocket next notification from system(QReadNotifier::event QEvent::SockAct)
      buffer is full and notification is disabled:
      Timestamp between sockact example:
      Tue May 23 23 10:40:51.335 [3800:26892]: unknown:0[unknown]: QReadNotifier::event QEvent::SockAct
      Tue May 23 23 10:40:51.335 [3800:26892]: unknown:0[unknown]: QReadNotifier::event QEvent::SockAct
      6. httpsocket read from nativesocket data with maxSize 65536 - 8616 = 56920
      (httpsocket buffer 8616 bytes)
      7. QNativeSocketEngine notification is still disabled because buffer is not empty
      QIODevicePrivate::read:
      if (madeBufferReadsOnly && isBufferEmpty())
              q->readData(data, 0);

      QAbstractSocket::readData->
      QNativeSocketEngine::setReadNotificationEnabled(true) will not be called

      in result we have a deadlock:
      system socket buffer is full(on my system socket buffer size is 65536) server will not receive acks on tcp level, nativesocket notification is disabled because isBufferEmpty() returns false

      Fix thoughts:
      1. No limit qtcpsocket(httpsocket only if proxy is set) readbuffersize(now it is hardcoded 65536) - fixed problem for me, but not sure that no problems
      2. Not sure
      QIODevicePrivate::read:
      if (madeBufferReadsOnly)
              q->readData(data, 0);

      Attached logs and used http client

      Attachments

        1. main.cpp
          4 kB
        2. qt_logs.txt
          10.01 MB
        For Gerrit Dashboard: QTBUG-113749
        # Subject Branch Project Status CR V

        Activity

          People

            manordheim Mårten Nordheim
            evgenpervenenko Evgen Pervenenko
            Vladimir Minenko Vladimir Minenko
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There is 1 open Gerrit change