Qt Network in Qt 6
October 05, 2020 by Mårten Nordheim, Timur Pocheptsov | Comments
In this blog post we want to tell you about some of the recent updates and changes that Qt Network module received in Qt 6, and also about some potential future developments.
QNetworkAccessBackend
QNetworkAccessBackend is an abstract base class used to interface with our cache, file and ftp backends. We have had QNetworkAccessBackend in Qt for a while, but it was not possible to use outside Qt Network in any reasonable way. Now it is! With Qt 6 we planned to move the ftp backend out of Qt Network and to distribute it separately as a plugin. To do this, we made QNetworkAccessBackend more friendly to use from the outside and gave QNetworkAccessManager the ability to load these plugins at runtime. As with some of our other plugin interfaces, it does not have the strict backwards-compatibility promises that Qt itself has, and it requires linking to QtNetworkPrivate to be able to use it.
We wanted to be able to specialize some of the behavior of various backends. For example, a non-network backend doesn't need us to prepare a list of proxies for the target URL. For this we added three different enumerations with a few values in each:
- TargetType
- SecurityFeatures
- IOFeatures
Of these, only 'TargetType' is required, currently only specifying if the backend's supported targets are networked and/or local.
Due to this approach some functions may not do anything if certain features aren’t enabled. One such example is the IO feature 'ZeroCopy' which enables the functions readPointer() and advanceReadPointer(). If it is not enabled these two functions will not be called. The main idea of having this feature system is that we can make these kinds of improvements without breaking any existing code. New code would have to opt in to the new feature. Although, to reiterate: we cannot guarantee the same level of backwards-compatibility for network access backend plugins as for applications made with Qt.
To implement a network access backend plugin you'll need to implement a class inheriting from QNetworkAccessBackendFactory. This class will do the work of creating the backend if the requested scheme is supported. You will also need to create a class inheriting from QNetworkAccessBackend, and override all pure-virtual functions, as well as 'read()', or 'readPointer()' and 'advanceReadPointer()' if your class supports the 'ZeroCopy' feature. As for existing uses, both the QNetworkAccessCacheBackend and the QNetworkAccessFileBackend are updated to use the new interface, although those are directly compiled into Qt rather than being distributed as plugins at the moment.
Protocols
In Qt 6 we dropped SPDY support. SPDY was an experimental protocol with an open specification, and it was developed primarily at Google. SPDY became the predecessor and prototype for the HTTP/2 protocol; the introduction of HTTP/2 obsoleted SPDY, and today SPDY is deprecated.
While maintaining compatibility with HTTP/1.1 (for example with methods, status codes, URIs, and most header fields) , HTTP/2 also adds:
- data compression of HTTP headers
- multiplexing multiple requests over a single TCP connection
- HTTP/2 Server Push
- Negotiation mechanisms that allow client and server to select HTTP/2 or HTTP/1.1
Prior to Qt 6, HTTP/2 protocol had to be manually enabled by setting one of these attributes:
- QNetworkRequest::Http2AllowedAttribute
- QNetworkRequest::Http2DirectAttribute,
E.g.:
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true);
For 'Http2AllowedAttribute', QNetworkAccessManager uses Application Layer Protocol Negotiation for 'https' scheme and protocol upgrade header 'h2c' for 'http' scheme. The second attribute is useful if you know in advance that the server supports HTTP/2 in so-called 'direct' mode, without protocol negotiation.
In Qt 6, HTTP/2 support is enabled by default: this means the attribute 'Http2AllowedAttribute' is set to 'true'. If HTTP/2 cannot be negotiated, QNetworkAccessManager will fall back to HTTP/1.1. If your application can only use HTTP/1.1, you can set the attribute 'Http2AllowedAttribute' to 'false' for a new network request:
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
There is an exception to this 'enabled by default' rule:
QNetworkAccessManager::connectToHostEncrypted(host, port, configuration);
Using this function an application can pre-connect to a server without sending any requests. If we were to enable HTTP/2 on such a connection, this connection would be useless for an application that wants to work with HTTP/1.1 and disables HTTP/2 by using request attributes. HTTP/2 can be enabled explicitly by setting the desired list of protocol in the 'configuration' parameter, e.g.:
auto tlsConfig = QSslConfiguration::defaultConfiguration();
tlsConfig.setAllowedNextProtocols({QSslConfiguration::ALPNProtocolHTTP2});
manager.connectToHostEncrypted(host, port, tlsConfig);
Default redirect policy changed
Another change that may affect your networking code is the default redirect policy that QNetworkAccessManager uses in Qt 6. The policy API was first introduced in Qt 5, with the idea in mind of switching to default automatic redirect handling in Qt 6.
QNetworkAccessManager supports several redirect policies, described by the enumeration QNetworkRequest::RedirectPolicy. These policies are:
- ManualRedirectPolicy,
- NoLessSafeRedirectPolicy
- SameOriginRedirectPolicy
- UserVerifiedRedirectPolicy
Starting from Qt 6 the default redirect policy that QNetworkAccessManager will use when making requests is QNetworkRequest::NoLessSafeRedirectPolicy (the policy that prohibits redirects from 'https' to 'http').
In case you have an application, that relies on a slot connected to QNetworkReply::redirected() to handle redirects, you will have to set the policy to QNetworkRequest::ManualRedirectPolicy with Qt 6:
req.setAttribute(RedirectPolicyAttribute, ManualRedirectPolicy);
Bearer management was removed
Bearer management was the name given to the machinery that was historically needed to support roaming and manage connectivity on certain devices. It could also select which of the device's network interfaces to use when connecting to the internet. Today this is no longer the case since operating systems typically handle roaming on their own and will automatically choose the best network interface to send data over, often providing no way (or no convenient way) for an application to influence these choices.
Although QNetworkManager provided APIs to chose which interface to use or to configure the interface in use, this new reality meant that no currently supported platforms provided a reliable way for Qt to do as requested. At the same time, the attempt to keep track of network status triggered various issues, such as heavy Wifi traffic on Windows causing high ping-times, or, after a brief network outage, this could keep Qt from recognising that the network was back, causing all subsequent requests to fail.
Given that the new reality also makes bearer management largely redundant, we decided that it was time to retire this part of Qt Network.
One feature that was still useful was the ability to check connectivity and get notified of connectivity changes. So far in Qt 6.0 it has not seen a replacement, although we've gathered up some use-cases and hope to have a replacement for that functionality in the coming minor releases. If you have specific use-cases you would like to see covered, or you want to track this task's progress, then please head over to QTBUG-86966.
QSslSocket
In Qt 6 QSslSocket received an additional API, providing information about alert messages which were received or sent as a part of the TLS protocol. We have two new enumerations:
- QSsl::AlertLevel describes how serious problem is
- QSsl::AlertType indicates the type of problem
There are two new signals in QSslSocket:
- QSslSocket::alertSent()
- QSslSocket::alertReceived()
When possible, these signals also report the textual description of the problem (if provided by the TLS library).
Another change, related to TLS handshake, is the ability to report errors encountered during handshake early, while the handshake is still in progress. These errors are reported directly from the verification callback. QSslConfiguration has a new getter and setter:
- bool QSslConfiguration::handshakeMustInterruptOnError() const;
- void QSslConfiguration::setHandshakeMustInterruptOnError() const;
And QSslSocket has a new signal:
- void handshakeInterruptedOnError();
and a function to say the error must ignored:
- void continueInterruptedHandshake();
If errors are not ignored, the underlying TLS library will send alert message to the peer.
This API is a little low-level and not of much interest for an application that uses QNetworkAccessManager. But it can be quite handy for debugging purposes or when implementing some error or warning handling logic, if you work with QSslSocket directly. This change at the moment is working with our OpenSSL backend; other TLS libraries we use do not have required API or do not provide the complete information we need.
TLS 1.3 and above
Well, this part is not exactly about what Qt 6 already has. It's also about possible future developments. As of now, Qt 6 supports the latest version of TLS protocol, which is 1.3, thanks to our OpenSSL back-end (Qt 5 also supports TLS 1.3). We are working on enabling TLS 1.3 in the Schannel backend too. Unfortunately, SecureTransport was deprecated by Apple with no available TLS library as a replacement, only some higher-level frameworks built on top of BoringSSL (note the irony of this!). This means that for our Darwin users we will provide an alternative in future. And in case of QNetworkAccessManager, a new QNetworkAccessBackend implemented on top of Apple's classes like NSUrlSession can be quite handy (with TLS 1.3 and experimental HTTP/3 support as a bonus included!).
Thank you for reading this blog post. Do not hesitate and share your opinion, comments or suggest an improvement!
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.8 Now!
Download the latest release here: www.qt.io/download.
Qt 6.8 release focuses on technology trends like spatial computing & XR, complex data visualization in 2D & 3D, and ARM-based development for desktop.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Wow, great demo. QML is really coming along!
Penguin doing Kecak Dance (http://en.wikipedia.org/wik...?) Very nice!!!
Still waiting when QML published.
If it is really as easy as it looks, we're gonna have a hell of fantastic tool for 3D graphics and animation.
This really looks like a nice way of specifying a 3D scenegraph. I'll check out the code later today. I take it this uses the Qt-scenegraph project in the implementation? Is it possible to reference {vertex|geometry|pixel} shaders from the qml document yet? I'm looking forward to see how this project evolves over the coming months.
Wouah !!!
I am loved that simple tutorials, you have no idea how many times I had to bang my head against the wall trying to debug an OpenGL low level issues, not even to mention portability. My concern here is that this is all pure QML, can any of these be actually coded ? A lot of time you want to generate dynamic content and not just pre-code it in QML, are you offering any alternative for that ?
Regards
I see you have 3ds model loading, do you have/are you planning support for Collada (or other less restrictive formats)?
Are the 3d objects already clickable/selectable etc ?
I'm interested to see how the trolls are planning on describing 3D interaction with qml.
Most entertaining coding demo I've ever seen.
jawdrop
Will this come out with 4.7? Or be an add-on library for 4.7, that will be included in 4.8?
Can you define "imminent"? As in later this month, or next?
Is Qt going to be cleaned up to consolidate all of its redundant graphical paths, esp those not used? For instance if we're using exclusively QML and 3D, the 2D widgets, 2D rasterer, and non-OpenGL code paths are still there, taking up a LOT of room (in QtGUI.dll) for instance.
This may not matter on desktops, but in Mobile and especially in Windows Mobile and Embedded, 3MB Core + 9MB Gui + QML support + threed + system = ~16MB of ram used. When the environment has maybe 32MB of ram per process or total, half of it gobbled up by Qt with major sections being legacy, unused code-paths is Ridiculous. And this is after qconfig shaving.
Is it the same weighty issues similiar to MFC where the class-inheritance hierarchy adds a lot of overhead when Curiously Recurring Template Pattern could lighten it up a large magnitude as WTL does?
Very nice demo. Quite impressive. I like the incremental adding of complexity as the whole file is built-before-your-very-eyes (really nice presentation pace, great content).
I'd similarly be very interested in a future demo of clickable/selectable interactivity, and programatically creating/generating the 3d objects ...
Sean Harmer: "I take it this uses the Qt-scenegraph project in the implementation?"
At the moment it works with the QGraphicsView-based implementation of QML that will be shipped with Qt 4.7, so no scenegraph required (yet). We will of course change the back-end implementation when QML/2D does.
Sean: "Is it possible to reference {vertex|geometry|pixel} shaders from the qml document yet?"
Vertex and fragment shaders, yes! The "ShaderProgram" item can be used to define an effect with raw shader code, and even hook its uniform variables up to QML animation items. See "demos/declarative/teapot-shader-animation.qml" in the Qt/3D source tree. We're working on some better tutorial material for this - stay tuned!
BlackCoder: "My concern here is that this is all pure QML, can any of these be actually coded ? A lot of time you want to generate dynamic content and not just pre-code it in QML, are you offering any alternative for that ?"
QML has mechanisms already for generating QML items on the fly. They should "just work" with QML/3D. http://doc.trolltech.com/4....
sandsmark: "I see you have 3ds model loading, do you have/are you planning support for Collada (or other less restrictive formats)?"
We have a little bit of support for COLLADA-FX, and we've discussed expanding that to full COLLADA, but it is a very big spec. Any assistance we can get from the community for that would be appreciated (it is fairly easy to add a new model loader - http://doc.qt.nokia.com/qt3...). Blender support would also be cool.
muenalan: "Are the 3d objects already clickable/selectable etc ?"
vpicaver: "I'm interested to see how the trolls are planning on describing 3D interaction with qml."
See the "teaservice.qml" demo in the Qt/3D sources for the basic clickable/selectable stuff we have implemented at the moment. We're also investigating how to write more complex interaction styles directly in JavaScript using a QML MouseArea. It's still a hot topic for research right now.
scorp1us: "Will this come out with 4.7? Or be an add-on library for 4.7, that will be included in 4.8? Can you define "imminent"? As in later this month, or next?"
It is available as an add-on library for 4.7 now, as part of Qt/3D. See http://doc.qt.nokia.com/qt3... for instructions for getting Qt/3D, building, and installing it. We're looking to mature QML/3D during the remainder of this year to get it ready for some future official Qt release.
We also have a public mailing list for those who wish to help out, ask questions, etc: http://lists.trolltech.com/...
Seriously, it like Qt/Trolls have discovered Nirvana with QML.
This demo looks very good!!! :)
Great demo, Danny!
You take lot of difficultiness out of 3d programming and add bunch of happiness to it. wtg +1
Can't wait to have my hands on QML!
QML has definitely come a long way - very impressive. Love that you were able to sneak in the Kecak chant at the end - http://vimeo.com/8935708 ;)
Last I checked, Qt3D was wholly incompatible with Qt4.7.
Rhys Weatherley accepted some of my patchs (thanks!) to help remedy that, but there were texture dependencies on 4.8/master still.
NuShrike: please log any problems you are still having in the Qt bug tracker at http://bugreports.qt.nokia.... (Qt3D component).
Note that Qt/3D usually cannot be built with an SDK version of Qt because it relies upon private headers in QtGui and QtOpenGL. Perhaps that is the "incompatibility" you are referring to? I use Qt/3D with 4.7 every day - a 4.7 I built myself from sources - same with 4.8. There is a plan to ship the private headers with the SDK in the future, but it didn't make it into 4.7.0.
R.Weatherley: I take it back, it was QtSceneGraph that's Qt/master only, not Qt3D, due to QGLTextureGlyphCache dependency issues.
It's been over a month since I've committed a number of patches to Qt/4.7, Qt/master and Qt/3D with only Qt/3D changes merged, so I'm a bit fuzzy now and my time isn't a generous it was. I was getting frustrated by the glacial pace of patch acceptance though, and no movement on my previous bug reports.
I would still like to see dll/memory usage reduced in line with this QML/3D work. Besides my own projects, there's current evaluation of QtWebkit going on for ... but it's not going well with how much ram QtWebKit/Core/Gui takes up for embedded. We may just go custom or look at Android instead.
muenalan: "Are the 3d objects already clickable/selectable etc ?"
vpicaver: "I'm interested to see how the trolls are planning on describing 3D interaction with qml."
Further to Rhys' response, it's also worth pointing out that if you have complex models in .3ds files and so on, it is possible to implement QML/3d apps where you can click on individual sub-components of the model as separate sub-items, allowing complex clickable objects.
(by that last comment I mean that clicking different bits of the model can make the app do different things... in case I was unclear)
NuShrike: "I was getting frustrated by the glacial pace of patch acceptance though"
It is usually a good idea to file a bug at the same time as making a merge request. Or drop us a line on the mailing list I mentioned above. The Gitorious system does not reliably send e-mail notifications to project owners about new merge requests, so it is easy for them to become lost. The bug reporting system is better at notifying component owners. Sorry about the delay in processing your Qt/3D merge requests - they went unnoticed due to the lack of notification messages.
regardings new 3D format (Collada, ...), I suggest take a look at :
- http://www.opencollada.org/
and http://assimp.sourceforge.net/
theses two library are a good starting point to add 3D import to QT/3D
What's the current state of play with OpenGL on Symbian with Qt? The examples in the SDK don't compile (e.g., hellogl_es), and various forum posts suggest OpenGL isn't yet supported in the SDK for Symbian...?
Great demo! It's promising to see the featureset of QML grow constantly. Keep on going.
BTW: The monkey is called Suzanne and is part of the Bender project.
http://en.wikipedia.org/wik...
Very nice!
Is adding a music loop and sounds for the penguins feet hitting the ground also that easy? :)
@bryanrieger: nice to see that the kecak chant is recognised: the movie Ice Age 2 also has an entertaining scene which references the same thing... except with pleistocene era sloths.
@Mark: OpenGL on Symbian is, to some degree, still a work in progress. Devices such as the upcoming N8 will have opengl on symbian working nicely. I'm no expert on other devices, though I'll look into it.
@jastockhausen: glad to see that the viewers recognise the work of the good people at the Blender foundation - I really should have acknowledged their fine work in the credits - thanks for pointing it out.
@panzi: Actually we're hoping to do exactly that :)