diff options
author | Liang Qi <liang.qi@qt.io> | 2017-03-21 19:07:53 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-03-21 19:07:53 +0100 |
commit | 65faf4565595d91996ddec4af25af5e97c7f0317 (patch) | |
tree | a7415e90db3fa1e46f638e1c31d2f2b9a5d0ec4a /src/network | |
parent | a9383ef99a29c333a1edd32695ddc29ea0ba805d (diff) | |
parent | 26bc4ac5cb56ce8f2d3d10125fa9c6a72140573a (diff) |
Merge remote-tracking branch 'origin/5.8' into 5.9
Conflicts:
src/plugins/platforms/eglfs/eglfs-plugin.pro
Change-Id: Id76cdbb41b7758572a3b8ea4dcb40d49bac968db
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 54 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnection_p.h | 3 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 30 | ||||
-rw-r--r-- | src/network/network.pro | 22 |
4 files changed, 71 insertions, 38 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index c2458152a3..72feffda8c 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -82,27 +82,31 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host : state(RunningState), networkLayerState(Unknown), hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true) + , activeChannelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2 #ifndef QT_NO_SSL -, channelCount((type == QHttpNetworkConnection::ConnectionTypeSPDY || type == QHttpNetworkConnection::ConnectionTypeHTTP2) - ? 1 : defaultHttpChannelCount) -#else -, channelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2 ? 1 : defaultHttpChannelCount) -#endif // QT_NO_SSL + || type == QHttpNetworkConnection::ConnectionTypeSPDY +#endif + ? 1 : defaultHttpChannelCount) + , channelCount(defaultHttpChannelCount) #ifndef QT_NO_NETWORKPROXY , networkProxy(QNetworkProxy::NoProxy) #endif , preConnectRequests(0) , connectionType(type) { + // We allocate all 6 channels even if it's SPDY or HTTP/2 enabled + // connection: in case the protocol negotiation via NPN/ALPN fails, + // we will have normally working HTTP/1.1. + Q_ASSERT(channelCount >= activeChannelCount); channels = new QHttpNetworkConnectionChannel[channelCount]; } -QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, +QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, QHttpNetworkConnection::ConnectionType type) : state(RunningState), networkLayerState(Unknown), hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true), - channelCount(channelCount) + activeChannelCount(connectionCount), channelCount(connectionCount) #ifndef QT_NO_NETWORKPROXY , networkProxy(QNetworkProxy::NoProxy) #endif @@ -147,7 +151,7 @@ void QHttpNetworkConnectionPrivate::pauseConnection() state = PausedState; // Disable all socket notifiers - for (int i = 0; i < channelCount; i++) { + for (int i = 0; i < activeChannelCount; i++) { if (channels[i].socket) { #ifndef QT_NO_SSL if (encrypt) @@ -163,7 +167,7 @@ void QHttpNetworkConnectionPrivate::resumeConnection() { state = RunningState; // Enable all socket notifiers - for (int i = 0; i < channelCount; i++) { + for (int i = 0; i < activeChannelCount; i++) { if (channels[i].socket) { #ifndef QT_NO_SSL if (encrypt) @@ -184,7 +188,7 @@ void QHttpNetworkConnectionPrivate::resumeConnection() int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const { - for (int i = 0; i < channelCount; ++i) + for (int i = 0; i < activeChannelCount; ++i) if (channels[i].socket == socket) return i; @@ -210,7 +214,7 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock channels[otherSocket].ensureConnection(); } - if (channelCount == 1) { + if (activeChannelCount < channelCount) { if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6) networkLayerState = QHttpNetworkConnectionPrivate::Unknown; channels[0].close(); @@ -405,7 +409,7 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica // select another channel QAuthenticator* otherAuth = 0; - for (int i = 0; i < channelCount; ++i) { + for (int i = 0; i < activeChannelCount; ++i) { if (i == fromChannel) continue; if (isProxy) @@ -900,7 +904,7 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) Q_Q(QHttpNetworkConnection); // check if the reply is currently being processed or it is pipelined in - for (int i = 0; i < channelCount; ++i) { + for (int i = 0; i < activeChannelCount; ++i) { // is the reply associated the currently processing of this channel? if (channels[i].reply == reply) { channels[i].reply = 0; @@ -1003,7 +1007,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() return; //resend the necessary ones. - for (int i = 0; i < channelCount; ++i) { + for (int i = 0; i < activeChannelCount; ++i) { if (channels[i].resendCurrent && (channels[i].state != QHttpNetworkConnectionChannel::ClosingState)) { channels[i].resendCurrent = false; @@ -1023,7 +1027,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() return; // try to get a free AND connected socket - for (int i = 0; i < channelCount; ++i) { + for (int i = 0; i < activeChannelCount; ++i) { if (channels[i].socket) { if (!channels[i].reply && !channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) { if (dequeueRequest(channels[i].socket)) @@ -1061,7 +1065,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() // return fast if there is nothing to pipeline if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty()) return; - for (int i = 0; i < channelCount; i++) + for (int i = 0; i < activeChannelCount; i++) if (channels[i].socket && channels[i].socket->state() == QAbstractSocket::ConnectedState) fillPipeline(channels[i].socket); @@ -1077,7 +1081,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() int normalRequests = queuedRequests - preConnectRequests; neededOpenChannels = qMax(normalRequests, preConnectRequests); } - for (int i = 0; i < channelCount && neededOpenChannels > 0; ++i) { + for (int i = 0; i < activeChannelCount && neededOpenChannels > 0; ++i) { bool connectChannel = false; if (channels[i].socket) { if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) @@ -1107,7 +1111,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply) { - for (int i = 0 ; i < channelCount; ++i) { + for (int i = 0 ; i < activeChannelCount; ++i) { if (channels[i].reply == reply) { // emulate a readyRead() from the socket QMetaObject::invokeMethod(&channels[i], "_q_readyRead", Qt::QueuedConnection); @@ -1226,7 +1230,7 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info) // connection will then be disconnected. void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup() { - if (channelCount > 1) { + if (activeChannelCount > 1) { // At this time all channels should be unconnected. Q_ASSERT(!channels[0].isSocketBusy()); Q_ASSERT(!channels[1].isSocketBusy()); @@ -1264,7 +1268,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup() void QHttpNetworkConnectionPrivate::networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol) { - for (int i = 0 ; i < channelCount; ++i) { + for (int i = 0 ; i < activeChannelCount; ++i) { if ((channels[i].networkLayerPreference != protocol) && (channels[i].state == QHttpNetworkConnectionChannel::ConnectingState)) { channels[i].close(); } @@ -1361,7 +1365,7 @@ void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy) d->networkProxy = networkProxy; // update the authenticator if (!d->networkProxy.user().isEmpty()) { - for (int i = 0; i < d->channelCount; ++i) { + for (int i = 0; i < d->activeChannelCount; ++i) { d->channels[i].proxyAuthenticator.setUser(d->networkProxy.user()); d->channels[i].proxyAuthenticator.setPassword(d->networkProxy.password()); } @@ -1377,7 +1381,7 @@ QNetworkProxy QHttpNetworkConnection::cacheProxy() const void QHttpNetworkConnection::setTransparentProxy(const QNetworkProxy &networkProxy) { Q_D(QHttpNetworkConnection); - for (int i = 0; i < d->channelCount; ++i) + for (int i = 0; i < d->activeChannelCount; ++i) d->channels[i].setProxy(networkProxy); } @@ -1409,7 +1413,7 @@ void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config return; // set the config on all channels - for (int i = 0; i < d->channelCount; ++i) + for (int i = 0; i < d->activeChannelCount; ++i) d->channels[i].setSslConfiguration(config); } @@ -1432,7 +1436,7 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel) return; if (channel == -1) { // ignore for all channels - for (int i = 0; i < d->channelCount; ++i) { + for (int i = 0; i < d->activeChannelCount; ++i) { d->channels[i].ignoreSslErrors(); } @@ -1448,7 +1452,7 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int return; if (channel == -1) { // ignore for all channels - for (int i = 0; i < d->channelCount; ++i) { + for (int i = 0; i < d->activeChannelCount; ++i) { d->channels[i].ignoreSslErrors(errors); } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 430c715717..3dd9bde9bd 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -243,6 +243,9 @@ public: bool encrypt; bool delayIpv4; + // Number of channels we are trying to use at the moment: + int activeChannelCount; + // The total number of channels we reserved: const int channelCount; QTimer delayedConnectionTimer; QHttpNetworkConnectionChannel *channels; // parallel connections to the server diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 668409a988..c86cc9d8c9 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -1083,12 +1083,36 @@ void QHttpNetworkConnectionChannel::_q_encrypted() } } Q_FALLTHROUGH(); - case QSslConfiguration::NextProtocolNegotiationNone: + case QSslConfiguration::NextProtocolNegotiationNone: { protocolHandler.reset(new QHttpProtocolHandler(this)); + + QList<QByteArray> protocols = sslConfiguration.allowedNextProtocols(); + const int nProtocols = protocols.size(); + // Clear the protocol that we failed to negotiate, so we do not try + // it again on other channels that our connection can create/open. + if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) + protocols.removeAll(QSslConfiguration::ALPNProtocolHTTP2); + else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) + protocols.removeAll(QSslConfiguration::NextProtocolSpdy3_0); + + if (nProtocols > protocols.size()) { + sslConfiguration.setAllowedNextProtocols(protocols); + const int channelCount = connection->d_func()->channelCount; + for (int i = 0; i < channelCount; ++i) + connection->d_func()->channels[i].setSslConfiguration(sslConfiguration); + } + connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP); - // re-queue requests from SPDY queue to HTTP queue, if any - requeueSpdyRequests(); + // We use only one channel for SPDY or HTTP/2, but normally six for + // HTTP/1.1 - let's restore this number to the reserved number of + // channels: + if (connection->d_func()->activeChannelCount < connection->d_func()->channelCount) { + connection->d_func()->activeChannelCount = connection->d_func()->channelCount; + // re-queue requests from SPDY queue to HTTP queue, if any + requeueSpdyRequests(); + } break; + } default: emitFinishedWithError(QNetworkReply::SslHandshakeFailedError, "detected unknown Next Protocol Negotiation protocol"); diff --git a/src/network/network.pro b/src/network/network.pro index 75105bd681..98fbf82275 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -22,16 +22,18 @@ include(ssl/ssl.pri) QMAKE_LIBS += $$QMAKE_LIBS_NETWORK -ANDROID_BUNDLED_JAR_DEPENDENCIES = \ - jar/QtAndroidBearer-bundled.jar -ANDROID_JAR_DEPENDENCIES = \ - jar/QtAndroidBearer.jar -ANDROID_LIB_DEPENDENCIES = \ - plugins/bearer/libqandroidbearer.so -MODULE_PLUGIN_TYPES = \ - bearer -ANDROID_PERMISSIONS += \ - android.permission.ACCESS_NETWORK_STATE +qtConfig(bearermanagement) { + ANDROID_BUNDLED_JAR_DEPENDENCIES = \ + jar/QtAndroidBearer-bundled.jar + ANDROID_JAR_DEPENDENCIES = \ + jar/QtAndroidBearer.jar + ANDROID_LIB_DEPENDENCIES = \ + plugins/bearer/libqandroidbearer.so + MODULE_PLUGIN_TYPES = \ + bearer + ANDROID_PERMISSIONS += \ + android.permission.ACCESS_NETWORK_STATE +} MODULE_WINRT_CAPABILITIES = \ internetClient \ |