summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/http2/http2protocol.cpp47
-rw-r--r--src/network/access/http2/http2protocol_p.h5
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp51
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h14
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp40
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h6
-rw-r--r--src/network/access/qhttpprotocolhandler.cpp9
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp5
8 files changed, 28 insertions, 149 deletions
diff --git a/src/network/access/http2/http2protocol.cpp b/src/network/access/http2/http2protocol.cpp
index 9f05e926c9..7f788a6f42 100644
--- a/src/network/access/http2/http2protocol.cpp
+++ b/src/network/access/http2/http2protocol.cpp
@@ -37,12 +37,9 @@
**
****************************************************************************/
-#include <QtCore/qbytearray.h>
#include <QtCore/qstring.h>
-#include "private/qhttpnetworkrequest_p.h"
#include "http2protocol_p.h"
-#include "http2frames_p.h"
QT_BEGIN_NAMESPACE
@@ -60,37 +57,6 @@ const char Http2clientPreface[clientPrefaceLength] =
0x2e, 0x30, 0x0d, 0x0a, 0x0d, 0x0a,
0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a};
-QByteArray qt_default_SETTINGS_to_Base64()
-{
- FrameWriter frame(qt_default_SETTINGS_frame());
- // SETTINGS frame's payload consists of pairs:
- // 2-byte-identifier | 4-byte-value - multiple of 6.
- // Also it's allowed to be empty.
- Q_ASSERT(!(frame.payloadSize() % 6));
- const char *src = reinterpret_cast<const char *>(&frame.rawFrameBuffer()[frameHeaderSize]);
- const QByteArray wrapper(QByteArray::fromRawData(src, int(frame.payloadSize())));
- // 3.2.1
- // The content of the HTTP2-Settings header field is the payload
- // of a SETTINGS frame (Section 6.5), encoded as a base64url string
- // (that is, the URL- and filename-safe Base64 encoding described in
- // Section 5 of [RFC4648], with any trailing '=' characters omitted).
- return wrapper.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
-}
-
-void qt_add_ProtocolUpgradeRequest(QHttpNetworkRequest &request)
-{
- // RFC 2616, 14.10
- QByteArray value(request.headerField("Connection"));
- if (value.size())
- value += ", ";
-
- value += "Upgrade, HTTP2-Settings";
- request.setHeaderField("Connection", value);
- // This we just (re)write.
- request.setHeaderField("Upgrade", "h2c");
- // This we just (re)write.
- request.setHeaderField("HTTP2-Settings", qt_default_SETTINGS_to_Base64());
-}
void qt_error(quint32 errorCode, QNetworkReply::NetworkError &error,
QString &errorMessage)
@@ -185,19 +151,6 @@ QNetworkReply::NetworkError qt_error(quint32 errorCode)
return error;
}
-FrameWriter qt_default_SETTINGS_frame()
-{
- // 6.5 SETTINGS
- FrameWriter frame(FrameType::SETTINGS, FrameFlag::EMPTY, connectionStreamID);
- // MAX frame size (16 kb), disable PUSH
- frame.append(Settings::MAX_FRAME_SIZE_ID);
- frame.append(quint32(maxFrameSize));
- frame.append(Settings::ENABLE_PUSH_ID);
- frame.append(quint32(0));
-
- return frame;
-}
-
}
QT_END_NAMESPACE
diff --git a/src/network/access/http2/http2protocol_p.h b/src/network/access/http2/http2protocol_p.h
index e49e9f1218..5c46949e23 100644
--- a/src/network/access/http2/http2protocol_p.h
+++ b/src/network/access/http2/http2protocol_p.h
@@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE
-class QHttpNetworkRequest;
-class QByteArray;
class QString;
namespace Http2
@@ -130,7 +128,6 @@ enum Http2PredefinedParameters
};
extern const Q_AUTOTEST_EXPORT char Http2clientPreface[clientPrefaceLength];
-void qt_add_ProtocolUpgradeRequest(QHttpNetworkRequest &request);
enum class FrameStatus
{
@@ -169,8 +166,6 @@ void qt_error(quint32 errorCode, QNetworkReply::NetworkError &error, QString &er
QString qt_error_string(quint32 errorCode);
QNetworkReply::NetworkError qt_error(quint32 errorCode);
-class FrameWriter qt_default_SETTINGS_frame();
-
}
Q_DECLARE_LOGGING_CATEGORY(QT_HTTP2)
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 2cf44521eb..937686920c 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -40,7 +40,7 @@
#include "qhttpnetworkconnection_p.h"
#include "qhttp2protocolhandler_p.h"
-#if !defined(QT_NO_HTTP)
+#if !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
#include "http2/bitstreams_p.h"
@@ -54,7 +54,6 @@
#include <QtCore/qurl.h>
#include <algorithm>
-#include <utility>
#include <vector>
QT_BEGIN_NAMESPACE
@@ -134,28 +133,6 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan
continuedFrames.reserve(20);
}
-QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *channel,
- const HttpMessagePair &message)
- : QAbstractProtocolHandler(channel),
- prefaceSent(false),
- waitingForSettingsACK(false),
- decoder(HPack::FieldLookupTable::DefaultSize),
- encoder(HPack::FieldLookupTable::DefaultSize, true)
-{
- // That's a protocol upgrade scenario - 3.2.
- //
- // We still have to send settings and the preface
- // (though SETTINGS was a part of the first HTTP/1.1
- // request "HTTP2-Settings" field).
- //
- // We pass 'false' for upload data, this was done by HTTP/1.1 protocol
- // handler for us while sending the first request.
- const quint32 initialStreamID = createNewStream(message, false);
- Q_ASSERT(initialStreamID == 1);
- Stream &stream = activeStreams[initialStreamID];
- stream.state = Stream::halfClosedLocal;
-}
-
void QHttp2ProtocolHandler::_q_uploadDataReadyRead()
{
auto data = qobject_cast<QNonContiguousByteDevice *>(sender());
@@ -270,7 +247,7 @@ bool QHttp2ProtocolHandler::sendRequest()
auto it = requests.begin();
m_channel->state = QHttpNetworkConnectionChannel::WritingState;
for (quint32 i = 0; i < streamsToUse; ++i) {
- const qint32 newStreamID = createNewStream(*it, true /* upload data */);
+ const qint32 newStreamID = createNewStream(*it);
if (!newStreamID) {
// TODO: actually we have to open a new connection.
qCCritical(QT_HTTP2, "sendRequest: out of stream IDs");
@@ -301,6 +278,7 @@ bool QHttp2ProtocolHandler::sendRequest()
return true;
}
+
bool QHttp2ProtocolHandler::sendClientPreface()
{
// 3.5 HTTP/2 Connection Preface
@@ -315,8 +293,12 @@ bool QHttp2ProtocolHandler::sendClientPreface()
return false;
// 6.5 SETTINGS
- outboundFrame = Http2::qt_default_SETTINGS_frame();
- Q_ASSERT(outboundFrame.payloadSize());
+ outboundFrame.start(FrameType::SETTINGS, FrameFlag::EMPTY, Http2::connectionStreamID);
+ // MAX frame size (16 kb), disable PUSH
+ outboundFrame.append(Settings::MAX_FRAME_SIZE_ID);
+ outboundFrame.append(quint32(Http2::maxFrameSize));
+ outboundFrame.append(Settings::ENABLE_PUSH_ID);
+ outboundFrame.append(quint32(0));
if (!outboundFrame.write(*m_socket))
return false;
@@ -1040,8 +1022,7 @@ void QHttp2ProtocolHandler::finishStreamWithError(Stream &stream, QNetworkReply:
emit httpReply->finishedWithError(error, message);
}
-quint32 QHttp2ProtocolHandler::createNewStream(const HttpMessagePair &message,
- bool uploadData)
+quint32 QHttp2ProtocolHandler::createNewStream(const HttpMessagePair &message)
{
const qint32 newStreamID = allocateStreamID();
if (!newStreamID)
@@ -1062,12 +1043,10 @@ quint32 QHttp2ProtocolHandler::createNewStream(const HttpMessagePair &message,
streamInitialSendWindowSize,
streamInitialRecvWindowSize);
- if (uploadData) {
- if (auto src = newStream.data()) {
- connect(src, SIGNAL(readyRead()), this,
- SLOT(_q_uploadDataReadyRead()), Qt::QueuedConnection);
- src->setProperty("HTTP2StreamID", newStreamID);
- }
+ if (auto src = newStream.data()) {
+ connect(src, SIGNAL(readyRead()), this,
+ SLOT(_q_uploadDataReadyRead()), Qt::QueuedConnection);
+ src->setProperty("HTTP2StreamID", newStreamID);
}
activeStreams.insert(newStreamID, newStream);
@@ -1235,4 +1214,4 @@ void QHttp2ProtocolHandler::closeSession()
QT_END_NAMESPACE
-#endif // !defined(QT_NO_HTTP)
+#endif // !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index e41b1360bf..b146e37dd3 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -55,7 +55,7 @@
#include <private/qabstractprotocolhandler_p.h>
#include <private/qhttpnetworkrequest_p.h>
-#if !defined(QT_NO_HTTP)
+#if !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
#include "http2/http2protocol_p.h"
#include "http2/http2streams_p.h"
@@ -81,15 +81,7 @@ class QHttp2ProtocolHandler : public QObject, public QAbstractProtocolHandler
Q_OBJECT
public:
- // "TLS + ALPN/NPN" case:
QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *channel);
- // HTTP2 without TLS - the first request was sent as an HTTP/1.1 request
- // with Upgrade:h2c header. That serves as an implicit HTTP/2 request
- // on a stream with ID 1 (it will be created in this ctor in a
- // 'half-closed-local' state); reply, if server supports HTTP/2,
- // will be HTTP/2 frame(s):
- QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *channel,
- const HttpMessagePair &message);
QHttp2ProtocolHandler(const QHttp2ProtocolHandler &rhs) = delete;
QHttp2ProtocolHandler(QHttp2ProtocolHandler &&rhs) = delete;
@@ -141,7 +133,7 @@ private:
const QString &message);
// Stream's lifecycle management:
- quint32 createNewStream(const HttpMessagePair &message, bool uploadData);
+ quint32 createNewStream(const HttpMessagePair &message);
void addToSuspended(Stream &stream);
void markAsReset(quint32 streamID);
quint32 popStreamToResume();
@@ -210,6 +202,6 @@ private:
QT_END_NAMESPACE
-#endif // !defined(QT_NO_HTTP)
+#endif // !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
#endif
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 3d35fe5f04..3a780f636b 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -50,7 +50,6 @@
#include <private/qhttp2protocolhandler_p.h>
#include <private/qhttpprotocolhandler_p.h>
#include <private/qspdyprotocolhandler_p.h>
-#include <private/http2protocol_p.h>
#ifndef QT_NO_SSL
# include <private/qsslsocket_p.h>
@@ -181,9 +180,6 @@ void QHttpNetworkConnectionChannel::init()
sslSocket->setSslConfiguration(sslConfiguration);
} else {
#endif // QT_NO_SSL
- // Even if connection->connectionType is ConnectionTypeHTTP2,
- // we first start as HTTP/1.1, asking for a protocol upgrade
- // in the first response.
protocolHandler.reset(new QHttpProtocolHandler(this));
#ifndef QT_NO_SSL
}
@@ -839,16 +835,6 @@ void QHttpNetworkConnectionChannel::_q_connected()
#endif
} else {
state = QHttpNetworkConnectionChannel::IdleState;
- if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
- Q_ASSERT(spdyRequestsToSend.size());
- auto it = spdyRequestsToSend.begin();
- // Let's inject some magic fields, requesting a protocol upgrade:
- Http2::qt_add_ProtocolUpgradeRequest(it->first);
- connection->d_func()->requeueRequest(*it);
- // Remove it, we never send it again as HTTP/2.
- spdyRequestsToSend.erase(it);
- }
-
if (!reply)
connection->d_func()->dequeueRequest(socket);
if (reply)
@@ -986,12 +972,9 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
}
} while (!connection->d_func()->highPriorityQueue.isEmpty()
|| !connection->d_func()->lowPriorityQueue.isEmpty());
-
- if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
#ifndef QT_NO_SSL
- || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY
-#endif
- ) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY ||
+ connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
for (int a = 0; a < spdyPairs.count(); ++a) {
// emit error for all replies
@@ -1000,6 +983,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
emit currentReply->finishedWithError(errorCode, errorString);
}
}
+#endif // QT_NO_SSL
// send the next request
QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
@@ -1018,31 +1002,23 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
}
}
-void QHttpNetworkConnectionChannel::_q_protocolSwitch()
-{
- Q_ASSERT(connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2);
- Q_ASSERT(reply);
- Q_ASSERT(reply->statusCode() == 101);
- protocolHandler.reset(new QHttp2ProtocolHandler(this, HttpMessagePair(request, reply)));
- protocolHandler->_q_receiveReply();
-}
-
#ifndef QT_NO_NETWORKPROXY
void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth)
{
- if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
#ifndef QT_NO_SSL
- || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY
-#endif
- ) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY ||
+ connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
} else { // HTTP
+#endif // QT_NO_SSL
// Need to dequeue the request before we can emit the error.
if (!reply)
connection->d_func()->dequeueRequest(socket);
if (reply)
connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
+#ifndef QT_NO_SSL
}
+#endif // QT_NO_SSL
}
#endif
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index a20cc1beb8..d7d5d86a7a 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -121,14 +121,11 @@ public:
bool authenticationCredentialsSent;
bool proxyCredentialsSent;
QScopedPointer<QAbstractProtocolHandler> protocolHandler;
- // SPDY or HTTP/2 requests; SPDY is TLS-only, but
- // HTTP/2 can be cleartext also, that's why it's
- // outside of QT_NO_SSL section. Sorted by priority:
- QMultiMap<int, HttpMessagePair> spdyRequestsToSend;
#ifndef QT_NO_SSL
bool ignoreAllSslErrors;
QList<QSslError> ignoreSslErrorsList;
QSslConfiguration sslConfiguration;
+ QMultiMap<int, HttpMessagePair> spdyRequestsToSend; // sorted by priority
void ignoreSslErrors();
void ignoreSslErrors(const QList<QSslError> &errors);
void setSslConfiguration(const QSslConfiguration &config);
@@ -195,7 +192,6 @@ public:
void _q_disconnected(); // disconnected from host
void _q_connected(); // start sending request
void _q_error(QAbstractSocket::SocketError); // error from socket
- void _q_protocolSwitch(); // HTTP/2 was negotiated to replace HTTP/1.1
#ifndef QT_NO_NETWORKPROXY
void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy
#endif
diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp
index ab136af083..b486b75449 100644
--- a/src/network/access/qhttpprotocolhandler.cpp
+++ b/src/network/access/qhttpprotocolhandler.cpp
@@ -129,15 +129,6 @@ void QHttpProtocolHandler::_q_receiveReply()
} else {
replyPrivate->autoDecompress = false;
}
- if (m_connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
- if (replyPrivate->statusCode == 101) {
- QMetaObject::invokeMethod(m_channel, "_q_protocolSwitch", Qt::QueuedConnection);
- return;
- }
-
- // HTTP/2 is not supported? TODO - but can it be something else?
- m_channel->requeueSpdyRequests();
- }
if (replyPrivate->statusCode == 100) {
replyPrivate->clearHttpLayerInformation();
replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 8b200ebc04..e16519c2f2 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -286,12 +286,9 @@ void QHttpThreadDelegate::startRequest()
QHttpNetworkConnection::ConnectionType connectionType
= QHttpNetworkConnection::ConnectionTypeHTTP;
-
- if (httpRequest.isHTTP2Allowed())
- connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2;
-
#ifndef QT_NO_SSL
if (httpRequest.isHTTP2Allowed() && ssl) {
+ connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2;
QList<QByteArray> protocols;
protocols << QSslConfiguration::ALPNProtocolHTTP2
<< QSslConfiguration::NextProtocolHttp1_1;