1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2014 BlackBerry Limited. All rights reserved. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtNetwork module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QSPDYPROTOCOLHANDLER_H 41 #define QSPDYPROTOCOLHANDLER_H 42 43 // 44 // W A R N I N G 45 // ------------- 46 // 47 // This file is not part of the Qt API. It exists for the convenience 48 // of the Network Access API. This header file may change from 49 // version to version without notice, or even be removed. 50 // 51 // We mean it. 52 // 53 54 #include <QtNetwork/private/qtnetworkglobal_p.h> 55 #include <private/qabstractprotocolhandler_p.h> 56 #include <QtNetwork/qnetworkreply.h> 57 #include <private/qbytedata_p.h> 58 59 #include <zlib.h> 60 61 QT_REQUIRE_CONFIG(http); 62 63 #if !defined(QT_NO_SSL) 64 65 QT_BEGIN_NAMESPACE 66 67 class QHttpNetworkRequest; 68 69 #ifndef HttpMessagePair 70 typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair; 71 #endif 72 73 class QSpdyProtocolHandler : public QObject, public QAbstractProtocolHandler { 74 Q_OBJECT 75 public: 76 QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel); 77 ~QSpdyProtocolHandler(); 78 79 enum DataFrameFlag { 80 DataFrame_FLAG_FIN = 0x01, 81 DataFrame_FLAG_COMPRESS = 0x02 82 }; 83 84 Q_DECLARE_FLAGS(DataFrameFlags, DataFrameFlag) 85 86 enum ControlFrameFlag { 87 ControlFrame_FLAG_FIN = 0x01, 88 ControlFrame_FLAG_UNIDIRECTIONAL = 0x02 89 }; 90 91 Q_DECLARE_FLAGS(ControlFrameFlags, ControlFrameFlag) 92 93 enum SETTINGS_Flag { 94 FLAG_SETTINGS_CLEAR_SETTINGS = 0x01 95 }; 96 97 Q_DECLARE_FLAGS(SETTINGS_Flags, SETTINGS_Flag) 98 99 enum SETTINGS_ID_Flag { 100 FLAG_SETTINGS_PERSIST_VALUE = 0x01, 101 FLAG_SETTINGS_PERSISTED = 0x02 102 }; 103 104 Q_DECLARE_FLAGS(SETTINGS_ID_Flags, SETTINGS_ID_Flag) 105 106 virtual void _q_receiveReply() override; 107 virtual void _q_readyRead() override; 108 virtual bool sendRequest() override; 109 110 private slots: 111 void _q_uploadDataReadyRead(); 112 void _q_replyDestroyed(QObject*); 113 void _q_uploadDataDestroyed(QObject *); 114 115 private: 116 117 enum FrameType { 118 FrameType_SYN_STREAM = 1, 119 FrameType_SYN_REPLY = 2, 120 FrameType_RST_STREAM = 3, 121 FrameType_SETTINGS = 4, 122 FrameType_PING = 6, 123 FrameType_GOAWAY = 7, 124 FrameType_HEADERS = 8, 125 FrameType_WINDOW_UPDATE = 9, 126 FrameType_CREDENTIAL // has a special type 127 }; 128 129 enum StatusCode { 130 StatusCode_PROTOCOL_ERROR = 1, 131 StatusCode_INVALID_STREAM = 2, 132 StatusCode_REFUSED_STREAM = 3, 133 StatusCode_UNSUPPORTED_VERSION = 4, 134 StatusCode_CANCEL = 5, 135 StatusCode_INTERNAL_ERROR = 6, 136 StatusCode_FLOW_CONTROL_ERROR = 7, 137 StatusCode_STREAM_IN_USE = 8, 138 StatusCode_STREAM_ALREADY_CLOSED = 9, 139 StatusCode_INVALID_CREDENTIALS = 10, 140 StatusCode_FRAME_TOO_LARGE = 11 141 }; 142 143 enum SETTINGS_ID { 144 SETTINGS_UPLOAD_BANDWIDTH = 1, 145 SETTINGS_DOWNLOAD_BANDWIDTH = 2, 146 SETTINGS_ROUND_TRIP_TIME = 3, 147 SETTINGS_MAX_CONCURRENT_STREAMS = 4, 148 SETTINGS_CURRENT_CWND = 5, 149 SETTINGS_DOWNLOAD_RETRANS_RATE = 6, 150 SETTINGS_INITIAL_WINDOW_SIZE = 7, 151 SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8 152 }; 153 154 enum GOAWAY_STATUS { 155 GOAWAY_OK = 0, 156 GOAWAY_PROTOCOL_ERROR = 1, 157 GOAWAY_INTERNAL_ERROR = 11 158 }; 159 160 enum RST_STREAM_STATUS_CODE { 161 RST_STREAM_PROTOCOL_ERROR = 1, 162 RST_STREAM_INVALID_STREAM = 2, 163 RST_STREAM_REFUSED_STREAM = 3, 164 RST_STREAM_UNSUPPORTED_VERSION = 4, 165 RST_STREAM_CANCEL = 5, 166 RST_STREAM_INTERNAL_ERROR = 6, 167 RST_STREAM_FLOW_CONTROL_ERROR = 7, 168 RST_STREAM_STREAM_IN_USE = 8, 169 RST_STREAM_STREAM_ALREADY_CLOSED = 9, 170 RST_STREAM_INVALID_CREDENTIALS = 10, 171 RST_STREAM_FRAME_TOO_LARGE = 11 172 }; 173 174 quint64 bytesAvailable() const; 175 bool readNextChunk(qint64 length, char *sink); 176 177 void sendControlFrame(FrameType type, ControlFrameFlags flags, const char *data, quint32 length); 178 179 void sendSYN_STREAM(const HttpMessagePair &pair, qint32 streamID, 180 qint32 associatedToStreamID); 181 void sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode); 182 void sendPING(quint32 pingID); 183 184 bool uploadData(qint32 streamID); 185 Q_INVOKABLE void sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindowSize); 186 187 qint64 sendDataFrame(qint32 streamID, DataFrameFlags flags, quint32 length, 188 const char *data); 189 190 QByteArray composeHeader(const QHttpNetworkRequest &request); 191 bool uncompressHeader(const QByteArray &input, QByteArray *output); 192 193 void handleControlFrame(const QByteArray &frameHeaders); 194 void handleDataFrame(const QByteArray &frameHeaders); 195 196 void handleSYN_STREAM(char, quint32, const QByteArray &frameData); 197 void handleSYN_REPLY(char flags, quint32, const QByteArray &frameData); 198 void handleRST_STREAM(char flags, quint32 length, const QByteArray &frameData); 199 void handleSETTINGS(char flags, quint32 length, const QByteArray &frameData); 200 void handlePING(char, quint32 length, const QByteArray &frameData); 201 void handleGOAWAY(char flags, quint32, const QByteArray &frameData); 202 void handleHEADERS(char flags, quint32, const QByteArray &frameData); 203 void handleWINDOW_UPDATE(char, quint32, const QByteArray &frameData); 204 205 qint32 generateNextStreamID(); 206 void parseHttpHeaders(char flags, const QByteArray &frameData); 207 208 void replyFinished(QHttpNetworkReply *httpReply, qint32 streamID); 209 void replyFinishedWithError(QHttpNetworkReply *httpReply, qint32 streamID, 210 QNetworkReply::NetworkError errorCode, const char *errorMessage); 211 212 qint32 m_nextStreamID; 213 QHash<quint32, HttpMessagePair> m_inFlightStreams; 214 qint32 m_maxConcurrentStreams; 215 quint32 m_initialWindowSize; 216 QByteDataBuffer m_spdyBuffer; 217 bool m_waitingForCompleteStream; 218 z_stream m_deflateStream; 219 z_stream m_inflateStream; 220 QHash<QObject *, qint32> m_streamIDs; 221 }; 222 223 Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::DataFrameFlags) 224 Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::ControlFrameFlags) 225 Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_Flags) 226 Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_ID_Flags) 227 228 QT_END_NAMESPACE 229 230 #endif // !defined(QT_NO_SSL) 231 232 #endif // QSPDYPROTOCOLHANDLER_H 233