This commit adds support for following HTTP redirect responses on a per
request basis.
This behavior is disabled by default. It can be switched on by
setting the QNetworkRequest::FollowRedirectAttribute to true.
2 new error codes have been added to QNetworkReply:
* TooManyRedirectsError: Set when the number of redirects exceed a
given value set by the user (defaults to 50 if not set)
* UnsecureRedirectError: Set when we are redirecting from a 'https'
to 'http' protocol.
Test cases for the following scenarios:
* Single HTTP redirect using local test server
* Changing max-redirects
* Testing all redirect related error scenarios
The next commit will extend this feature at a QNAM level.
Task-number: QTBUG-8232
Change-Id: If9e28ad12bad08bcdc5bc511b1cd59dc9d8150f0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
Qt copyrights are now in The Qt Company, so we could update the source
code headers accordingly. In the same go we should also fix the links to
point to qt.io.
Outdated header.LGPL removed (use header.LGPL21 instead)
Old header.LGPL3 renamed to header.LGPL3-COMM to match actual licensing
combination. New header.LGPL-COMM taken in the use file which were
using old header.LGPL3 (src/plugins/platforms/android/extract.cpp)
Added new header.LGPL3 containing Commercial + LGPLv3 + GPLv2 license
combination
Change-Id: I6f49b819a8a20cc4f88b794a8f6726d975e8ffbe
Reviewed-by: Matti Paaso <matti.paaso@theqtcompany.com>
... but choose HTTP/1.1 and continue connecting anyhow. According to
the NPN spec, actually we should choose SPDY:
"In the event that the client doesn't support any of server's protocols,
or the server doesn't advertise any, it SHOULD select the first protocol
that it supports."
However, some tested servers did not advertise anything and did not
support SPDY, so blindly trying the newest protocol would fail. We are
conservative in that case and choose HTTP.
Task-number: QTBUG-40714
Change-Id: Ia8aaf01fea74e13d9e4416306f85f1890b25559e
Reviewed-by: Richard J. Moore <rich@kde.org>
Expose the same kind of TLS PSK client support we already have set
in place for QSslSocket.
[ChangeLog][QtNetwork][QNetworkAccessManager] It is now possible to use
TLS PSK ciphersuites when using HTTPS (or similar protocols working over
SSL).
Change-Id: I56a048e9f4f841f886758c781af2867d18538a3e
Reviewed-by: Richard J. Moore <rich@kde.org>
The Qt bug tracker URL changes as part of the qt.io transition
Change-Id: Icb4ab198943b93639b5e3a8d99262303785c6459
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
... and not only one. This was a problem e.g. when there were several
requests to the same host and the host was not reachable; only one
reply would get an error signal in case we suppressed other errors in
"happy eyeballs" host lookup style.
Task-number: QTBUG-36890
Change-Id: I1b5757498bd644b0d773cf6c43e4950620949c5c
Reviewed-by: Richard J. Moore <rich@kde.org>
Currently the only supported SPDY version is 3.0.
The feature needs to be enabled explicitly via
QNetworkRequest::SpdyAllowedAttribute. Whether SPDY actually was used
can be determined via QNetworkRequest::SpdyWasUsedAttribute from a
QNetworkReply once it has been started (i.e. after the encrypted()
signal has been received). Whether SPDY can be used will be
determined during the SSL handshake through the TLS NPN extension
(see separate commit).
The following things from SPDY have not been enabled currently:
* server push is not implemented, it has never been seen in the wild;
in that case we just reject a stream pushed by the server, which is
legit.
* settings are not persisted across SPDY sessions. In practice this
means that the server sends a small message upon session start
telling us e.g. the number of concurrent connections.
* SSL client certificates are not supported.
Task-number: QTBUG-18714
[ChangeLog][QtNetwork] Added support for the SPDY protocol (version
3.0).
Change-Id: I81bbe0495c24ed84e9cf8af3a9dbd63ca1e93d0d
Reviewed-by: Richard J. Moore <rich@kde.org>
... to defer the decision which protocol will be used on a specific
channel. This is to allow using the SPDY protocol instead of HTTP (to
be implemented in a later commit); which protocol will be used can
only be decided after the SSL handshake.
Change-Id: I6b538320668fe4994438f0095ecdc445677cf0a6
Reviewed-by: Peter Hartmann <phartmann@blackberry.com>
Since commit f30641a7 is has been possible to issue more than one host
lookup request per HttpNetworkConnection. If the result was both an
IPv4 and IPv6 address, and we get a second similar DNS reply, we
end up triggering the assert in startNetworkLayerStateLookup().
This patch splits the InProgress state to HostLookupPending and the state
of trying both IPv4 and IPv6. This makes it possible to ignore any new DNS
replies received after the first succesfull one.
Change-Id: I0b8d6b1582fdaed69dde5926019b60bb0cbd580d
Reviewed-by: Peter Hartmann <phartmann@blackberry.com>
Default for QUrl::password() and QUrl::userName() is in Qt 5.1 QUrl::PrettyDecoded
which means the return value may contain percent-encodings. For authentication
we need the real decoded result, and should instead use QUrl::FullyDecoded.
Note this bug has already been fixed indirectly in Qt 5.2 since the default for the
two methods was changed to QUrl::FullyDecoded.
Change-Id: Ia0f38c073cb001e37ad8b3eda40b3db756bec3dc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Each pair of (normal request, preconnect request) requires only one
socket. E.g. if there is 1 preconnect request in-flight and 2 normal
requests, we need only 2 sockets in total, and not 3.
Therefore, we need to keep track of whether a request is
preconnecting or a normal one.
Task-number: QTBUG-31594
Change-Id: If92ccc35abadfa6090d64ee92bd466615909c94c
Reviewed-by: Richard J. Moore <rich@kde.org>
We do not decide which socket a HTTP request is sent on until the
socket is actually ready for sending a request (i.e. it is connected
for HTTP requests and encryption is done for HTTPS requests).
When deciding how many sockets we need for the queued requests, we
consider an in-flight socket as free if it is still connecting.
However, we considered a socket that was connected but needed to
complete encryption as busy, and would instead open another socket.
Now, we consider an encrypting socket as in-flight as well.
Change-Id: I93d6743da6fc430d1424c6965e1475865fd97243
Reviewed-by: Richard J. Moore <rich@kde.org>
If an app knows it needs to connect to a host beforehand, it can "warm up" the
connection cache by making DNS lookup, TCP (and if needed SSL) handshake before
the actual HTTP request is sent. When the HTTP request is made, it will be
considerably faster when there is already a working connection.
Here are some typical results from the benchmark:
* Linux desktop with Ethernet:
"http://www.google.com" full request: 279 ms, pre-connect request: 61 ms,
difference: 218 ms
"https://www.google.com" full request: 344 ms, pre-connect request: 60 ms,
difference: 284 ms
* mobile device (BlackBerry 10) with Wifi:
"https://www.google.com" full request: 898 ms, pre-connect request: 159 ms,
difference: 739 ms
"http://www.google.com" full request: 707 ms, pre-connect request: 200 ms,
difference: 507 ms
Task-number: QTBUG-30771
Change-Id: I3566b7f08216ab93a39e2024ae7d1ceb7ae21891
Reviewed-by: Jonas Gastal <gastal@intel.com>
Reviewed-by: Richard J. Moore <rich@kde.org>
Add an encrypted signal to QNAM and QNetworkReply to allow applications
to perform additional checks on the certificate chain beyond those done
as part of the standard SSL validation. This allows things like
certificate change notification to be implemented for QNAM as they can
be for QSSLSocket currently.
Change-Id: I693e3e6fec8b7040379b7e7f1f819550e6b2617f
Reviewed-by: Peter Hartmann <phartmann@rim.com>
This improves performance since a network round trip can be avoided.
Change-Id: I1aaff7e48ef9638cb137de0f43942c3a4dd2884a
Initial-patch-by: Markus Goetz <markus@woboq.com>
Reviewed-by: Richard J. Moore <rich@kde.org>
_q_connected checks if pendingEncrypt is false before committing the
address type. This could be used to delay the commit but nothing is done
later in _q_encrypted, so the commit is avoided completely.
This causes SSL connections on a network without IPV6 support to hang
if the domain name record contains both IPV4 and IPV6 addresses.
As SSL is handled a few layers above IP, there should be no reason to
avoid/delay committing the address type if the TCP connection was
established surccessfully. Thus this patch is removing the check completely.
Change-Id: If56a3365f9f51712b4aae3f7902711711ace86fd
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Change copyrights and license headers from Nokia to Digia
Change-Id: If1cc974286d29fd01ec6c19dd4719a67f4c3f00e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Sergio Ahumada <sergio.ahumada@digia.com>
Use an include guard in headers to ensure the header is not included
more than once. Make the header guard match its file name.
Also, cpp files should include their own headers first (but below config.h)
Change-Id: Iecf5da23c0f8e6d457f67657b88ef7557bde9669
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Using the nullary version has the advantage that multiple calls
during a program run are much more efficient, since an inlined
atomic is used to store the result. It also ensures that
Q_DECLARE_METATYPE(T) has been used, whereas qRegisterMetaType<T>("T")
will happily register anything. So I've added the macro where it
was missing, or moved it to a central place when it existed
hidden.
In tst_qnetworkreply, this became a bit tricky, because a private
header is conditionally included, so moved the Q_DECLARE_METATYPE()
into a conditional section, too.
Change-Id: I71484523e4277f4697b7d4b2ddc3505375162727
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
Change-Id: I19d3b2e9a5180b13deb828b55195404ef20be295
Reviewed-by: Daniel Teske <daniel.teske@nokia.com>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
With Happy Eyeballs we will connect one IPv4 and one IPv6 channel and
pick the network layer depending on which connects first. When the
first channel is connected we can close the other one.
Before this we let the other connection finish connecting and then
closed it. This will close the other one as soon as the first one
is connected.
Change-Id: Ib2ab3f949704fd39dc0584bd31b9bcaf75ce35f7
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
When we get a remoteHostClosed we should try to read everything from
the socket before we close the channel.
Change-Id: Iaa87d79ea16d69735f6ba3e8b3b4a0f86fbd5f73
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Reviewed-by: Prasanth Ullattil <prasanth.ullattil@nokia.com>
Reviewed-by: Richard J. Moore <rich@kde.org>
If there are still bytesAvailable on the socket and we have
nothing pipelined we should close the channel. This was not
done before as the chunked decoder did not read the last
CRLF. This has now been fixed so this close should be enabled
again.
Task-number: QTBUG-24875
Change-Id: I115b60f8d78bf1b83d3fd5887ab3eb9940b6bf00
Reviewed-by: Jonas Gastal <jgastal@profusion.mobi>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
If there are no bytesAvailable and no reply then the channel
can be closed without any need for this warning.
Task-number: QTBUG-9315
Change-Id: Ifbb1f4732d3173a7807ac5bd0dc78fb5144faaf3
Reviewed-by: Markus Goetz <markus@woboq.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Each channel will create a socket that will allocate memory for the
read and write buffers. This change will instead initialize
channels only when they are needed.
Change-Id: I112b4c7b944a7dd345414f06260c92803394eaed
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
This reverts commit ff25691d00.
The change broke qtdeclarative. Several autotests crash because
QHttpNetworkConnection::transparentProxy() calls proxy() on a
null socket.
Task-number: QTBUG-24717
Change-Id: I57e3ccf5d20683f59cf7450083d1fcb3fa1c40fe
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Each channel will create a socket that will allocate memory for the
read and write buffers. QNam generaly inits 6 sockets for each
connection. That means that by default 12 such buffers are created.
This will instead initialize channels when they are needed.
Change-Id: Ie3f2cf789e084fd3d17d3b2a9bb3d3a4370b3da4
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Change the ifdefs in our own code (except openssl backend) to use the
new configure flag.
Change-Id: I8774734771c66b22164b5fae8fdb27814ac3df7b
Reviewed-by: Richard J. Moore <rich@kde.org>
Restored the Qt4 behaviour where attempting a https request using
QNetworkAccessManager fails with ProtocolUnsupportedError instead
of timing out or hanging.
Covered by existing autotests.
Task-number: QTBUG-17189
Change-Id: Iceb1ba6558c7d2b1af8ddf8d4ea9315a5b44d970
Reviewed-by: Richard J. Moore <rich@kde.org>
As in the past, to avoid rewriting various autotests that contain
line-number information, an extra blank line has been inserted at the
end of the license text to ensure that this commit does not change the
total number of lines in the license header.
Change-Id: I311e001373776812699d6efc045b5f742890c689
Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
- Initialization order in QHttpNetworkConnectionChannel
- Potential use of uninitialized value in QNetworkReplyDataImpl
Change-Id: Ia405147ef81a3f1509149349d6b5b01bb078f853
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
When authentication is cancelled, close the channel instead of the
underlying socket.
The previous behaviour could result in further requests being sent
on the closed socket, which caused errors in case of https over a proxy.
Change-Id: I3dbfc164de4fb29a426c06acaac8f29b9da1d705
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Instead of always delaying IPv4 when we have both Ipv4 and IPv6 we
should use the order we get from getaddrinfo to descide which one
that should be delayed.
Task-number: QTBUG-23066
Change-Id: Ibe8c4d7000abd6e57fe8c6afac8a4a843e17ff27
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Modifying the proxy causes a detach(), so the socket is still using
the unmodified proxy.
Changed this to setProxy() the modified one back to the socket.
Test case tst_QNetworkReply::httpProxyCommands()
Change-Id: I448c2f2ab43ce8d78bc6edb8261599bf67372676
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Incase we have both IPv4 and IPv6 available after the host lookup
we should delay the connection attempt to IPv4.
Task-number: QTBUG-23066
Change-Id: I8c0177cf125c9daae314ada73cacef790a39b856
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
This property is no longer necessary because we can now set the user
agent directly on the proxy.
Task-number: QTBUG-17223
Change-Id: I27cb126dd401f02525290d2317650f55cae9f4ef
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
that server was found out not to support HTTP pipelining.
tested manually; for more information see the task.
Change-Id: I9120e8be1a9a05f39f99752d6426c92fa3d093f2
(cherry picked from commit ec6d7694f72498d1b156bb0ae8d305e01931f7b2)
Reviewed-by: Markus Goetz
Task-number: QTBUG-21369
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Two problems:
- The signal cacheCredidentials was not connected in the synchronous
case while it must be connected. (Regression when the threaded http
was merged)
- We cannot cache the credidentials when we proceed the url because
at that point, we do not know the realm (this basically reverts
9bc5a32b875b812c3a706034c8c27614f86bd138)
Task-number: QTBUG-18411
Change-Id: I8ea11fa23db4314c3f17ed06d2d7f9ee934ccdba
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
For the Happy eyeballs implementation we use two channels for the case
where a host lookup gives us both Ipv4 and Ipv6 addresses.
In the case where the Connection is setup to only use one channel
we can not use this solution, so in this case we should use the old
way of connecting with one channel.
Task-number: QTBUG-20981
Change-Id: I6590fb4c67d6a8261cd0e4da8f99cd3603bbb524
Reviewed-on: http://codereview.qt.nokia.com/3524
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
This eliminates some code (header parsing) that can be done by
zlib already.
Add support for 'deflate' encoding.
Also do less memory copying while uncompressing.
Change-Id: I94de21e3c58b904dd91d004c375ed8cbea56cb0b
Task-Number: QTBUG-13191
Reviewed-on: http://codereview.qt.nokia.com/1314
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Petersson <Martin.Petersson@nokia.com>
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Reviewed-by: Markus Goetz
In the cases where a DNS lookup will give you both an IPv4 and IPv6
address, this will start two connection channels at the same time.
One trying to connect using IPv4 and one on IPv6. This is done so
that we can use the fastest one for the connection. To do this we
have to do the hostlookup in the connection. The result is then
in the cache for the individual socket so it will not need to do
another lookup.
Task-number: QTBUG-16458
Change-Id: I806c20168d9c5edc2831b80f82a2bd570b36d5fa
Reviewed-on: http://codereview.qt.nokia.com/1003
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
In Qt 4.7, http network requests are assigned to http connection
channels before connecting the channel.
In Qt 4.8, channels are connected "blind" as this gives a performance
improvement in certain circumstances.
On the assumption that User-Agent should be the same for all the
requests being sent to the server in a given burst, we use the first
queued request to set the user agent for a http proxy.
Task-number: QTBUG-17223
Reviewed-by: Markus Goetz
Reviewed-by: Martin Petersson
Some proxies can discriminate based on the User-Agent when sent a
CONNECT command for establishing a HTTPS connection.
With this change, if the User-Agent header is set in the QNetworkRequest
then it will be passed to the http socket engine for use in the connect
command sent to the proxy.
As before, "Mozilla/5.0" will be used by default when no user agent
has been set.
Task-number: QTBUG-17223
Reviewed-by: Markus Goetz
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:
http://qt.gitorious.org/qt/pages/GitIntroductionWithQt
If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.
Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12