Priority: P2: Important
Affects Version/s: 5.11.2
Fix Version/s: None
Component/s: Network: HTTP
Qt 5.11.2 Commercial
Update: I believe this is closely related to https://bugreports.qt.io/browse/QTBUG-47966
When you start an XMLHttpRequest, you can abort it and the underlying QQmlXMLHttpRequest and QNetworkReplyHttpImpl are properly cleaned up. However, this code:
Does not actually result in the connected slot QHttpThreadDelegate::abortRequest firing. Instead, the QHttpThreadDelegate continues to run after the XMLHttpRequest has been aborted. If the QHttpThreadDelegate hangs (for instance due to a network change) this seems to cause subsequent XMLHttpRequest's to the same URL to fail to return their responses even though a network sniffer and the debugger shows they were successfully received by the app.
— ORIGINAL TEXT BELOW —
I have a QML application using XMLHttpRequest. This QML application needs to talk to a hardware device that presents a WiFi AP and has a well-know private address.
The application starts off running on a WiFi network with full Internet connectivity. At a certain point, the user is instructed to switch WiFi networks to the hardware device's AP. If the QML app waits and initiates an XMLHttpRequest to the device after the WiFi network has switched, everything works fine.
The problem is that this is not good UX. So, the app starts polling for the private address while waiting for the user to switch the WiFi networks.
To restate, the QML app intentionally starts connecting to the private address (with a short timeout and abort) while on the wrong, Internet-connected WiFi network. The user switches to the hardware device's WiFi network. The expectation is the next HTTP request started by the QML app will succeed.
This is where it gets weird.
When the app initiates polling while on the wrong network, and then the user switches to the correct network, I can see with a packet sniffer (plaintext HTTP) that requests are making it from my QML app to the device, a response is sent back and the connection shuts cleanly. However, the response never makes it back up and out of XMLHttpRequest in the QML application.
I've narrowed it down to QHttpThreadDelegate::finishedSlot and this call:
For some strange reason, under these changing network conditions, even though I step through the code and see this signal getting connected to QNetworkReplyHttpImplPrivate::replyFinished, replyFinished doesn't fire when downloadFinished is emitted. This goes on for 20 seconds or so as each request is timed out and aborted – and then it just suddenly starts working.
I've debugged all through qqmlxmlhttprequest.cpp, qnetworkaccessmanager.cpp, qnetworkreplyhttpimpl.cpp, qhttpthreaddelegate.cpp and qhttpnetworkconnection.cpp as control hops around. I've also rebuilt Qt with -no-feature-bearermanagement and had no luck finding a root cause for this.
I'm not sure how to make this reproducible since this hardware device is involved. Can anybody suggest where else to look or other ways to narrow down the root cause?