OpenCoverage

qspdyprotocolhandler.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/network/access/qspdyprotocolhandler.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2014 BlackBerry Limited. All rights reserved.-
4** Copyright (C) 2016 The Qt Company Ltd.-
5** Contact: https://www.qt.io/licensing/-
6**-
7** This file is part of the QtNetwork module of the Qt Toolkit.-
8**-
9** $QT_BEGIN_LICENSE:LGPL$-
10** Commercial License Usage-
11** Licensees holding valid commercial Qt licenses may use this file in-
12** accordance with the commercial license agreement provided with the-
13** Software or, alternatively, in accordance with the terms contained in-
14** a written agreement between you and The Qt Company. For licensing terms-
15** and conditions see https://www.qt.io/terms-conditions. For further-
16** information use the contact form at https://www.qt.io/contact-us.-
17**-
18** GNU Lesser General Public License Usage-
19** Alternatively, this file may be used under the terms of the GNU Lesser-
20** General Public License version 3 as published by the Free Software-
21** Foundation and appearing in the file LICENSE.LGPL3 included in the-
22** packaging of this file. Please review the following information to-
23** ensure the GNU Lesser General Public License version 3 requirements-
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
25**-
26** GNU General Public License Usage-
27** Alternatively, this file may be used under the terms of the GNU-
28** General Public License version 2.0 or (at your option) the GNU General-
29** Public license version 3 or any later version approved by the KDE Free-
30** Qt Foundation. The licenses are as published by the Free Software-
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
32** included in the packaging of this file. Please review the following-
33** information to ensure the GNU General Public License requirements will-
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
35** https://www.gnu.org/licenses/gpl-3.0.html.-
36**-
37** $QT_END_LICENSE$-
38**-
39****************************************************************************/-
40-
41#include <private/qspdyprotocolhandler_p.h>-
42#include <private/qnoncontiguousbytedevice_p.h>-
43#include <private/qhttpnetworkconnectionchannel_p.h>-
44#include <QtCore/QtEndian>-
45-
46#if !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)-
47-
48QT_BEGIN_NAMESPACE-
49-
50static const char spdyDictionary[] = {-
51 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti-
52 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h-
53 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p-
54 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p-
55 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de-
56 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete....-
57 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace...-
58 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept.-
59 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep-
60 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse-
61 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc-
62 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco-
63 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding....-
64 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l-
65 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage.-
66 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep-
67 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges-
68 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age.-
69 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow-
70 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth-
71 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio-
72 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac-
73 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr-
74 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co-
75 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection-
76 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont-
77 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base-
78 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont-
79 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco-
80 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding....-
81 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content--
82 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language-
83 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont-
84 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng-
85 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co-
86 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo-
87 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation..-
88 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten-
89 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5...-
90 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content-
91 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range..-
92 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten-
93 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type..-
94 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date..-
95 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag..-
96 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect-
97 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi-
98 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f-
99 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h-
100 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i-
101 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match.-
102 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo-
103 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s-
104 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince....-
105 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none--
106 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match...-
107 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang-
108 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if--
109 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi-
110 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since-
111 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last-
112 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie-
113 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc-
114 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation...-
115 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for-
116 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards...-
117 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma.-
118 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy-
119 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent-
120 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate...-
121 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a-
122 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza-
123 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion....-
124 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range...-
125 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer-
126 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr-
127 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after.-
128 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve-
129 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te.-
130 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail-
131 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr-
132 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e-
133 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding.-
134 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra-
135 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us-
136 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent-
137 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary-
138 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via.-
139 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni-
140 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww-
141 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen-
142 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate..-
143 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method-
144 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get.-
145 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu-
146 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200-
147 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v-
148 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion..-
149 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1-
150 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur-
151 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub-
152 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s-
153 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki-
154 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee-
155 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive.-
156 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi-
157 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012-
158 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205-
159 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030-
160 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043-
161 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307-
162 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540-
163 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084-
164 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411-
165 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341-
166 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164-
167 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504-
168 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N-
169 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho-
170 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative-
171 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa-
172 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204.-
173 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte-
174 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo-
175 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm-
176 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4-
177 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R-
178 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40-
179 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth-
180 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40-
181 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid-
182 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N-
183 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found-
184 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte-
185 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser-
186 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro-
187 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not-
188 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme-
189 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503.-
190 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service.-
191 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila-
192 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F-
193 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A-
194 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J-
195 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A-
196 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept.-
197 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov.-
198 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0-
199 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon-
200 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W-
201 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu.-
202 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa-
203 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun..-
204 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk-
205 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text.-
206 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima-
207 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i-
208 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg-
209 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g-
210 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli-
211 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x-
212 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli-
213 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x-
214 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml-
215 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl-
216 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text-
217 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr-
218 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ-
219 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat-
220 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age-
221 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de-
222 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd-
223 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse-
224 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c-
225 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i-
226 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859--
227 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-..-
228 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0.-
229};-
230-
231// uncomment to debug-
232//static void printHex(const QByteArray &ba)-
233//{-
234// QByteArray hex;-
235// QByteArray clearText;-
236// for (int a = 0; a < ba.count(); ++a) {-
237// QByteArray currentHexChar = QByteArray(1, ba.at(a)).toHex().rightJustified(2, ' ');-
238// QByteArray currentChar;-
239// if (ba.at(a) >= 32 && ba.at(a) < 126) { // if ASCII, print the letter-
240// currentChar = QByteArray(1, ba.at(a));-
241// } else {-
242// currentChar = " ";-
243// }-
244// clearText.append(currentChar.rightJustified(2, ' '));-
245// hex.append(currentHexChar);-
246// hex.append(' ');-
247// clearText.append(' ');-
248// }-
249// int chunkSize = 102; // 12 == 4 bytes per line-
250// for (int a = 0; a < hex.count(); a += chunkSize) {-
251// qDebug() << hex.mid(a, chunkSize);-
252// qDebug() << clearText.mid(a, chunkSize);-
253// }-
254//}-
255-
256QSpdyProtocolHandler::QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel)-
257 : QObject(0), QAbstractProtocolHandler(channel),-
258 m_nextStreamID(-1),-
259 m_maxConcurrentStreams(100), // 100 is recommended in the SPDY RFC-
260 m_initialWindowSize(0),-
261 m_waitingForCompleteStream(false)-
262{-
263 m_inflateStream.zalloc = Z_NULL;-
264 m_inflateStream.zfree = Z_NULL;-
265 m_inflateStream.opaque = Z_NULL;-
266 int zlibRet = inflateInit(&m_inflateStream);-
267 Q_ASSERT(zlibRet == Z_OK);-
268-
269 m_deflateStream.zalloc = Z_NULL;-
270 m_deflateStream.zfree = Z_NULL;-
271 m_deflateStream.opaque = Z_NULL;-
272-
273 // Do actually not compress (i.e. compression level = 0)-
274 // when sending the headers because of the CRIME attack-
275 zlibRet = deflateInit(&m_deflateStream, /* compression level = */ 0);-
276 Q_ASSERT(zlibRet == Z_OK);-
277 Q_UNUSED(zlibRet); // silence -Wunused-variable-
278}
executed 6 times by 1 test: end of block
Executed by:
  • tst_Spdy
6
279-
280QSpdyProtocolHandler::~QSpdyProtocolHandler()-
281{-
282 deflateEnd(&m_deflateStream);-
283 deflateEnd(&m_inflateStream);-
284}
executed 6 times by 2 tests: end of block
Executed by:
  • tst_Spdy
  • tst_spdy - unknown status
6
285-
286bool QSpdyProtocolHandler::sendRequest()-
287{-
288 Q_ASSERT(!m_reply);-
289-
290 int maxPossibleRequests = m_maxConcurrentStreams - m_inFlightStreams.count();-
291 Q_ASSERT(maxPossibleRequests >= 0);-
292 if (maxPossibleRequests == 0)
maxPossibleRequests == 0Description
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
293 return true; // return early if max concurrent requests are exceeded
never executed: return true;
0
294-
295 m_channel->state = QHttpNetworkConnectionChannel::WritingState;-
296-
297 int requestsToSend = qMin(m_channel->spdyRequestsToSend.size(), maxPossibleRequests);-
298-
299 QMultiMap<int, HttpMessagePair>::iterator it = m_channel->spdyRequestsToSend.begin();-
300 // requests will be ordered by priority (see QMultiMap doc)-
301 for (int a = 0; a < requestsToSend; ++a) {
a < requestsToSendDescription
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
107
302 HttpMessagePair currentPair = *it;-
303 QHttpNetworkRequest currentRequest = currentPair.first;-
304 QHttpNetworkReply *currentReply = currentPair.second;-
305-
306 currentReply->setSpdyWasUsed(true);-
307 qint32 streamID = generateNextStreamID();-
308 currentReply->setProperty("SPDYStreamID", streamID);-
309-
310 currentReply->setRequest(currentRequest);-
311 currentReply->d_func()->connection = m_connection;-
312 currentReply->d_func()->connectionChannel = m_channel;-
313 m_inFlightStreams.insert(streamID, currentPair);-
314 connect(currentReply, SIGNAL(destroyed(QObject*)), this, SLOT(_q_replyDestroyed(QObject*)));-
315-
316 sendSYN_STREAM(currentPair, streamID, /* associatedToStreamID = */ 0);-
317 m_channel->spdyRequestsToSend.erase(it++);-
318 }
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
107
319 m_channel->state = QHttpNetworkConnectionChannel::IdleState;-
320 return true;
executed 107 times by 1 test: return true;
Executed by:
  • tst_Spdy
107
321}-
322-
323void QSpdyProtocolHandler::_q_replyDestroyed(QObject* reply)-
324{-
325 qint32 streamID = reply->property("SPDYStreamID").toInt();-
326 if (m_inFlightStreams.remove(streamID))
m_inFlightStre...move(streamID)Description
TRUEnever evaluated
FALSEnever evaluated
0
327 sendRST_STREAM(streamID, RST_STREAM_CANCEL);
never executed: sendRST_STREAM(streamID, RST_STREAM_CANCEL);
0
328}
never executed: end of block
0
329-
330void QSpdyProtocolHandler::_q_receiveReply()-
331{-
332 Q_ASSERT(m_socket);-
333-
334 // only run when the QHttpNetworkConnection is not currently being destructed, e.g.-
335 // this function is called from _q_disconnected which is called because-
336 // of ~QHttpNetworkConnectionPrivate-
337 if (!qobject_cast<QHttpNetworkConnection*>(m_connection)) {
!qobject_cast<...(m_connection)Description
TRUEnever evaluated
FALSEevaluated 1373 times by 1 test
Evaluated by:
  • tst_Spdy
0-1373
338 return;
never executed: return;
0
339 }-
340-
341 if (bytesAvailable() < 8)
bytesAvailable() < 8Description
TRUEnever evaluated
FALSEevaluated 1373 times by 1 test
Evaluated by:
  • tst_Spdy
0-1373
342 return; // cannot read frame headers, wait for more data
never executed: return;
0
343-
344 char frameHeadersRaw[8];-
345 if (!readNextChunk(8, frameHeadersRaw))
!readNextChunk...ameHeadersRaw)Description
TRUEnever evaluated
FALSEevaluated 1373 times by 1 test
Evaluated by:
  • tst_Spdy
0-1373
346 return; // this should not happen, we just checked
never executed: return;
0
347-
348 const QByteArray frameHeaders(frameHeadersRaw, 8); // ### try without memcpy-
349 if (frameHeadersRaw[0] & 0x80) {
frameHeadersRaw[0] & 0x80Description
TRUEevaluated 869 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 504 times by 1 test
Evaluated by:
  • tst_Spdy
504-869
350 handleControlFrame(frameHeaders);-
351 } else {
executed 869 times by 1 test: end of block
Executed by:
  • tst_Spdy
869
352 handleDataFrame(frameHeaders);-
353 }
executed 504 times by 1 test: end of block
Executed by:
  • tst_Spdy
504
354-
355 // after handling the current frame, check whether there is more data waiting-
356 if (m_socket->bytesAvailable() > 0)
m_socket->bytesAvailable() > 0Description
TRUEnever evaluated
FALSEevaluated 1373 times by 1 test
Evaluated by:
  • tst_Spdy
0-1373
357 QMetaObject::invokeMethod(m_channel, "_q_receiveReply", Qt::QueuedConnection);
never executed: QMetaObject::invokeMethod(m_channel, "_q_receiveReply", Qt::QueuedConnection);
0
358}
executed 1373 times by 1 test: end of block
Executed by:
  • tst_Spdy
1373
359-
360void QSpdyProtocolHandler::_q_readyRead()-
361{-
362 _q_receiveReply();-
363}
executed 1373 times by 1 test: end of block
Executed by:
  • tst_Spdy
1373
364-
365static qint16 twoBytesToInt(const char *bytes)-
366{-
367 return qFromBigEndian<qint16>(bytes);
executed 1738 times by 1 test: return qFromBigEndian<qint16>(bytes);
Executed by:
  • tst_Spdy
1738
368}-
369-
370static qint32 threeBytesToInt(const char *bytes)-
371{-
372 return qFromBigEndian<qint32>(bytes) >> 8;
executed 1379 times by 1 test: return qFromBigEndian<qint32>(bytes) >> 8;
Executed by:
  • tst_Spdy
1379
373}-
374-
375static qint32 fourBytesToInt(const char *bytes)-
376{-
377 return qFromBigEndian<qint32>(bytes);
executed 3612 times by 1 test: return qFromBigEndian<qint32>(bytes);
Executed by:
  • tst_Spdy
3612
378}-
379-
380static void appendIntToThreeBytes(char *output, qint32 number)-
381{-
382 qToBigEndian<qint16>(number, output + 1);-
383 qToBigEndian<qint8>(number >> 16, output);-
384}
executed 121 times by 1 test: end of block
Executed by:
  • tst_Spdy
121
385-
386static void appendIntToFourBytes(char *output, qint32 number)-
387{-
388 qToBigEndian<qint32>(number, output);-
389}
executed 28 times by 1 test: end of block
Executed by:
  • tst_Spdy
28
390-
391static QByteArray intToFourBytes(qint32 number) // ### try to use appendIntToFourBytes where possible-
392{-
393 char data[4];-
394 qToBigEndian<qint32>(number, data);-
395 QByteArray ret(data, 4);-
396 return ret;
executed 2822 times by 1 test: return ret;
Executed by:
  • tst_Spdy
2822
397}-
398-
399static QByteArray intToThreeBytes(qint32 number)-
400{-
401 char data[4];-
402 qToBigEndian<qint32>(number << 8, data);-
403 QByteArray ret(data, 3);-
404 return ret;
executed 755 times by 1 test: return ret;
Executed by:
  • tst_Spdy
755
405}-
406-
407static qint32 getStreamID(const char *bytes)-
408{-
409 // eliminate most significant bit; it might be 0 or 1 depending on whether-
410 // we are dealing with a control or data frame-
411 return fourBytesToInt(bytes) & 0x3fffffff;
executed 1367 times by 1 test: return fourBytesToInt(bytes) & 0x3fffffff;
Executed by:
  • tst_Spdy
1367
412}-
413-
414static QByteArray headerField(const QByteArray &name, const QByteArray &value)-
415{-
416 QByteArray ret;-
417 ret.reserve(name.count() + value.count() + 8); // 4 byte for length each-
418 ret.append(intToFourBytes(name.count()));-
419 ret.append(name);-
420 ret.append(intToFourBytes(value.count()));-
421 ret.append(value);-
422 return ret;
executed 873 times by 1 test: return ret;
Executed by:
  • tst_Spdy
873
423}-
424-
425bool QSpdyProtocolHandler::uncompressHeader(const QByteArray &input, QByteArray *output)-
426{-
427 const size_t chunkSize = 1024;-
428 char outputRaw[chunkSize];-
429 // input bytes will not be changed by zlib, so it is safe to const_cast here-
430 m_inflateStream.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(input.constData()));-
431 m_inflateStream.avail_in = input.count();-
432 m_inflateStream.total_in = input.count();-
433 int zlibRet;-
434-
435 do {-
436 m_inflateStream.next_out = reinterpret_cast<Bytef *>(outputRaw);-
437 m_inflateStream.avail_out = chunkSize;-
438 zlibRet = inflate(&m_inflateStream, Z_SYNC_FLUSH);-
439 if (zlibRet == Z_NEED_DICT) {
zlibRet == 2Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
6-107
440 zlibRet = inflateSetDictionary(&m_inflateStream,-
441 reinterpret_cast<const Bytef*>(spdyDictionary),-
442 /* dictionaryLength = */ 1423);-
443 Q_ASSERT(zlibRet == Z_OK);-
444 continue;
executed 6 times by 1 test: continue;
Executed by:
  • tst_Spdy
6
445 }-
446 switch (zlibRet) {-
447 case Z_BUF_ERROR: {
never executed: case (-5):
0
448 if (m_inflateStream.avail_in == 0) {
m_inflateStream.avail_in == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
449 int outputSize = chunkSize - m_inflateStream.avail_out;-
450 output->append(outputRaw, outputSize);-
451 m_inflateStream.avail_out = chunkSize;-
452 }
never executed: end of block
0
453 break;
never executed: break;
0
454 }-
455 case Z_OK: {
executed 107 times by 1 test: case 0:
Executed by:
  • tst_Spdy
107
456 int outputSize = chunkSize - m_inflateStream.avail_out;-
457 output->append(outputRaw, outputSize);-
458 break;
executed 107 times by 1 test: break;
Executed by:
  • tst_Spdy
107
459 }-
460 default: {
never executed: default:
0
461 qWarning() << "got unexpected zlib return value:" << zlibRet;-
462 return false;
never executed: return false;
0
463 }-
464 }-
465 } while (m_inflateStream.avail_in > 0 && zlibRet != Z_STREAM_END);
m_inflateStream.avail_in > 0Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
zlibRet != 1Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEnever evaluated
0-107
466-
467 Q_ASSERT(m_inflateStream.avail_in == 0);-
468 return true;
executed 107 times by 1 test: return true;
Executed by:
  • tst_Spdy
107
469}-
470-
471QByteArray QSpdyProtocolHandler::composeHeader(const QHttpNetworkRequest &request)-
472{-
473 QByteArray uncompressedHeader;-
474 uncompressedHeader.reserve(300); // rough estimate-
475-
476 // calculate additional headers first, because we need to know the size-
477 // ### do not partially copy the list, but restrict the set header fields-
478 // in QHttpNetworkConnection-
479 QVector<QPair<QByteArray, QByteArray> > additionalHeaders;-
480 for (int a = 0; a < request.header().count(); ++a) {
a < request.header().count()Description
TRUEevaluated 552 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
107-552
481 QByteArray key = request.header().at(a).first;-
482 if (key == "Connection" || key == "Host" || key == "Keep-Alive"
key == "Connection"Description
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 445 times by 1 test
Evaluated by:
  • tst_Spdy
key == "Host"Description
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 338 times by 1 test
Evaluated by:
  • tst_Spdy
key == "Keep-Alive"Description
TRUEnever evaluated
FALSEevaluated 338 times by 1 test
Evaluated by:
  • tst_Spdy
0-445
483 || key == "Proxy-Connection" || key == "Transfer-Encoding")
key == "Proxy-Connection"Description
TRUEnever evaluated
FALSEevaluated 338 times by 1 test
Evaluated by:
  • tst_Spdy
key == "Transfer-Encoding"Description
TRUEnever evaluated
FALSEevaluated 338 times by 1 test
Evaluated by:
  • tst_Spdy
0-338
484 continue; // those headers are not valid (section 3.2.1)
executed 214 times by 1 test: continue;
Executed by:
  • tst_Spdy
214
485 additionalHeaders.append(request.header().at(a));-
486 }
executed 338 times by 1 test: end of block
Executed by:
  • tst_Spdy
338
487-
488 qint32 numberOfHeaderPairs = 5 + additionalHeaders.count(); // 5 mandatory below + the additional ones-
489 uncompressedHeader.append(intToFourBytes(numberOfHeaderPairs));-
490-
491 // mandatory header fields:-
492-
493 uncompressedHeader.append(headerField(":method", request.methodName()));-
494#ifndef QT_NO_NETWORKPROXY-
495 bool useProxy = m_connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy;-
496 uncompressedHeader.append(headerField(":path", request.uri(useProxy)));-
497#else-
498 uncompressedHeader.append(headerField(":path", request.uri(false)));-
499#endif-
500 uncompressedHeader.append(headerField(":version", "HTTP/1.1"));-
501-
502 uncompressedHeader.append(headerField(":host", request.url().authority(QUrl::FullyEncoded | QUrl::RemoveUserInfo).toLatin1()));-
503-
504 uncompressedHeader.append(headerField(":scheme", request.url().scheme().toLatin1()));-
505-
506 // end of mandatory header fields-
507-
508 // now add the additional headers-
509 for (int a = 0; a < additionalHeaders.count(); ++a) {
a < additionalHeaders.count()Description
TRUEevaluated 338 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
107-338
510 uncompressedHeader.append(headerField(additionalHeaders.at(a).first.toLower(),-
511 additionalHeaders.at(a).second));-
512 }
executed 338 times by 1 test: end of block
Executed by:
  • tst_Spdy
338
513-
514 m_deflateStream.total_in = uncompressedHeader.count();-
515 m_deflateStream.avail_in = uncompressedHeader.count();-
516 m_deflateStream.next_in = reinterpret_cast<unsigned char *>(uncompressedHeader.data());-
517 int outputBytes = uncompressedHeader.count() + 30; // 30 bytes of compression header overhead-
518 m_deflateStream.avail_out = outputBytes;-
519 unsigned char *out = new unsigned char[outputBytes];-
520 m_deflateStream.next_out = out;-
521 int availOutBefore = m_deflateStream.avail_out;-
522 int zlibRet = deflate(&m_deflateStream, Z_SYNC_FLUSH); // do everything in one go since we use no compression-
523 int compressedHeaderSize = availOutBefore - m_deflateStream.avail_out;-
524 Q_ASSERT(zlibRet == Z_OK); // otherwise, we need to allocate more outputBytes-
525 Q_UNUSED(zlibRet); // silence -Wunused-variable-
526 Q_ASSERT(m_deflateStream.avail_in == 0);-
527 QByteArray compressedHeader(reinterpret_cast<char *>(out), compressedHeaderSize);-
528 delete[] out;-
529-
530 return compressedHeader;
executed 107 times by 1 test: return compressedHeader;
Executed by:
  • tst_Spdy
107
531}-
532-
533quint64 QSpdyProtocolHandler::bytesAvailable() const-
534{-
535 Q_ASSERT(m_socket);-
536 return m_spdyBuffer.byteAmount() + m_socket->bytesAvailable();
executed 1373 times by 1 test: return m_spdyBuffer.byteAmount() + m_socket->bytesAvailable();
Executed by:
  • tst_Spdy
1373
537}-
538-
539bool QSpdyProtocolHandler::readNextChunk(qint64 length, char *sink)-
540{-
541 qint64 expectedReadBytes = length;-
542 qint64 requiredBytesFromBuffer = 0;-
543-
544 if (m_waitingForCompleteStream) {
m_waitingForCompleteStreamDescription
TRUEevaluated 312 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 2434 times by 1 test
Evaluated by:
  • tst_Spdy
312-2434
545 requiredBytesFromBuffer = qMin(length, m_spdyBuffer.byteAmount());-
546 // ### if next chunk from buffer bigger than what we want to read,-
547 // we have to call read() (which memcpy's). Otherwise, we can just-
548 // read the next chunk without memcpy'ing.-
549 qint64 bytesReadFromBuffer = m_spdyBuffer.read(sink, requiredBytesFromBuffer);-
550 Q_ASSERT(bytesReadFromBuffer == requiredBytesFromBuffer);-
551 if (length <= bytesReadFromBuffer) {
length <= bytesReadFromBufferDescription
TRUEevaluated 156 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 156 times by 1 test
Evaluated by:
  • tst_Spdy
156
552 return true; // buffer > required size -> no need to read from socket
executed 156 times by 1 test: return true;
Executed by:
  • tst_Spdy
156
553 }-
554 expectedReadBytes -= requiredBytesFromBuffer;-
555 }
executed 156 times by 1 test: end of block
Executed by:
  • tst_Spdy
156
556 qint64 readBytes = m_socket->read(sink + requiredBytesFromBuffer, expectedReadBytes);-
557-
558 if (readBytes < expectedReadBytes) {
readBytes < expectedReadBytesDescription
TRUEevaluated 156 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 2434 times by 1 test
Evaluated by:
  • tst_Spdy
156-2434
559 m_waitingForCompleteStream = true;-
560 // ### this is inefficient, we should not put back so much data into the buffer-
561 QByteArray temp(sink, requiredBytesFromBuffer + readBytes);-
562 m_spdyBuffer.append(temp);-
563 return false;
executed 156 times by 1 test: return false;
Executed by:
  • tst_Spdy
156
564 } else {-
565 return true; // buffer must be cleared by calling function
executed 2434 times by 1 test: return true;
Executed by:
  • tst_Spdy
2434
566 }-
567}-
568-
569void QSpdyProtocolHandler::sendControlFrame(FrameType type,-
570 ControlFrameFlags flags,-
571 const char *data,-
572 quint32 length)-
573{-
574 // frame type and stream ID-
575 char header[8];-
576 header[0] = 0x80u; // leftmost bit == 1 -> is a control frame-
577 header[1] = 0x03; // 3 bit == version 3-
578 header[2] = 0;-
579 switch (type) {-
580 case FrameType_CREDENTIAL: {
never executed: case FrameType_CREDENTIAL:
0
581 qWarning("sending SPDY CREDENTIAL frame is not yet implemented"); // QTBUG-36188-
582 return;
never executed: return;
0
583 }-
584 default:
executed 121 times by 1 test: default:
Executed by:
  • tst_Spdy
121
585 header[3] = type;-
586 }
executed 121 times by 1 test: end of block
Executed by:
  • tst_Spdy
121
587-
588 // flags-
589 header[4] = 0;-
590 if (flags & ControlFrame_FLAG_FIN || length == 0) {
length == 0Description
TRUEnever evaluated
FALSEevaluated 29 times by 1 test
Evaluated by:
  • tst_Spdy
0-29
591 Q_ASSERT(type == FrameType_SYN_STREAM || type == FrameType_SYN_REPLY-
592 || type == FrameType_HEADERS || length == 0);-
593 header[4] |= ControlFrame_FLAG_FIN;-
594 }
executed 92 times by 1 test: end of block
Executed by:
  • tst_Spdy
92
595 if (flags & ControlFrame_FLAG_UNIDIRECTIONAL) {
flags & Contro...UNIDIRECTIONALDescription
TRUEnever evaluated
FALSEevaluated 121 times by 1 test
Evaluated by:
  • tst_Spdy
0-121
596 Q_ASSERT(type == FrameType_SYN_STREAM);-
597 header[4] |= ControlFrame_FLAG_UNIDIRECTIONAL;-
598 }
never executed: end of block
0
599-
600 // length-
601 appendIntToThreeBytes(header + 5, length);-
602-
603 qint64 written = m_socket->write(header, 8);-
604 Q_ASSERT(written == 8);-
605 written = m_socket->write(data, length);-
606 Q_ASSERT(written == length);-
607 Q_UNUSED(written); // silence -Wunused-variable-
608}
executed 121 times by 1 test: end of block
Executed by:
  • tst_Spdy
121
609-
610void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair,-
611 qint32 streamID, qint32 associatedToStreamID)-
612{-
613 QHttpNetworkRequest request = messagePair.first;-
614 QHttpNetworkReply *reply = messagePair.second;-
615-
616 ControlFrameFlags flags = 0;-
617-
618 if (!request.uploadByteDevice()) {
!request.uploadByteDevice()Description
TRUEevaluated 92 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 15 times by 1 test
Evaluated by:
  • tst_Spdy
15-92
619 // no upload -> this is the last frame, send the FIN flag-
620 flags |= ControlFrame_FLAG_FIN;-
621 reply->d_func()->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;-
622 } else {
executed 92 times by 1 test: end of block
Executed by:
  • tst_Spdy
92
623 reply->d_func()->state = QHttpNetworkReplyPrivate::SPDYUploading;-
624-
625 // hack: set the stream ID on the device directly, so when we get-
626 // the signal for uploading we know which stream we are sending on-
627 request.uploadByteDevice()->setProperty("SPDYStreamID", streamID);-
628-
629 QObject::connect(request.uploadByteDevice(), SIGNAL(readyRead()), this,-
630 SLOT(_q_uploadDataReadyRead()), Qt::QueuedConnection);-
631 }
executed 15 times by 1 test: end of block
Executed by:
  • tst_Spdy
15
632-
633 QByteArray namesAndValues = composeHeader(request);-
634 quint32 length = namesAndValues.count() + 10; // 10 == 4 for Stream-ID + 4 for Associated-To-Stream-ID-
635 // + 2 for Priority, Unused and Slot-
636-
637 QByteArray wireData;-
638 wireData.reserve(length);-
639 wireData.append(intToFourBytes(streamID));-
640 wireData.append(intToFourBytes(associatedToStreamID));-
641-
642 // priority (3 bits) / unused (5 bits) / slot (8 bits)-
643 char prioAndSlot[2];-
644 switch (request.priority()) {-
645 case QHttpNetworkRequest::HighPriority:
never executed: case QHttpNetworkRequest::HighPriority:
0
646 prioAndSlot[0] = 0x00; // == prio 0 (highest)-
647 break;
never executed: break;
0
648 case QHttpNetworkRequest::NormalPriority:
executed 107 times by 1 test: case QHttpNetworkRequest::NormalPriority:
Executed by:
  • tst_Spdy
107
649 prioAndSlot[0] = 0x80u; // == prio 4-
650 break;
executed 107 times by 1 test: break;
Executed by:
  • tst_Spdy
107
651 case QHttpNetworkRequest::LowPriority:
never executed: case QHttpNetworkRequest::LowPriority:
0
652 prioAndSlot[0] = 0xe0u; // == prio 7 (lowest)-
653 break;
never executed: break;
0
654 }-
655 prioAndSlot[1] = 0x00; // slot in client certificates (not supported currently)-
656 wireData.append(prioAndSlot, 2);-
657-
658 wireData.append(namesAndValues);-
659-
660 sendControlFrame(FrameType_SYN_STREAM, flags, wireData.constData(), length);-
661-
662 if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYUploading)
reply->d_func(...:SPDYUploadingDescription
TRUEevaluated 15 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 92 times by 1 test
Evaluated by:
  • tst_Spdy
15-92
663 uploadData(streamID);
executed 15 times by 1 test: uploadData(streamID);
Executed by:
  • tst_Spdy
15
664}
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
107
665-
666void QSpdyProtocolHandler::sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode)-
667{-
668 char wireData[8];-
669 appendIntToFourBytes(wireData, streamID);-
670 appendIntToFourBytes(wireData + 4, statusCode);-
671 sendControlFrame(FrameType_RST_STREAM, /* flags = */ 0, wireData, /* length = */ 8);-
672}
never executed: end of block
0
673-
674void QSpdyProtocolHandler::sendPING(quint32 pingID)-
675{-
676 char rawData[4];-
677 appendIntToFourBytes(rawData, pingID);-
678 sendControlFrame(FrameType_PING, /* flags = */ 0, rawData, /* length = */ 4);-
679}
never executed: end of block
0
680-
681bool QSpdyProtocolHandler::uploadData(qint32 streamID)-
682{-
683 // we only rely on SPDY flow control here and don't care about TCP buffers-
684 if (!m_inFlightStreams.contains(streamID)) {
!m_inFlightStr...ains(streamID)Description
TRUEnever evaluated
FALSEevaluated 1475 times by 1 test
Evaluated by:
  • tst_Spdy
0-1475
685 sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);-
686 return false;
never executed: return false;
0
687 }-
688-
689 HttpMessagePair messagePair = m_inFlightStreams.value(streamID);-
690 QHttpNetworkRequest request = messagePair.first;-
691 QHttpNetworkReply *reply = messagePair.second;-
692 Q_ASSERT(reply);-
693 QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();-
694 Q_ASSERT(replyPrivate);-
695-
696 if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
reply->d_func(...SPDYHalfClosedDescription
TRUEnever evaluated
FALSEevaluated 1475 times by 1 test
Evaluated by:
  • tst_Spdy
reply->d_func(...te::SPDYClosedDescription
TRUEnever evaluated
FALSEevaluated 1475 times by 1 test
Evaluated by:
  • tst_Spdy
0-1475
697 qWarning("Trying to upload to closed stream");-
698 return false;
never executed: return false;
0
699 }-
700-
701 qint32 dataLeftInWindow = replyPrivate->windowSizeUpload-
702 - replyPrivate->currentlyUploadedDataInWindow;-
703-
704 while (dataLeftInWindow > 0 && !request.uploadByteDevice()->atEnd()) {
dataLeftInWindow > 0Description
TRUEevaluated 1496 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 719 times by 1 test
Evaluated by:
  • tst_Spdy
!request.uploa...ice()->atEnd()Description
TRUEevaluated 1495 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tst_Spdy
1-1496
705-
706 // get pointer to upload data-
707 qint64 currentReadSize = 0;-
708 const char *readPointer = request.uploadByteDevice()->readPointer(dataLeftInWindow,-
709 currentReadSize);-
710-
711 if (currentReadSize == -1) {
currentReadSize == -1Description
TRUEnever evaluated
FALSEevaluated 1495 times by 1 test
Evaluated by:
  • tst_Spdy
0-1495
712 // premature eof happened-
713 m_connection->d_func()->emitReplyError(m_socket, reply,-
714 QNetworkReply::UnknownNetworkError);-
715 return false;
never executed: return false;
0
716 } else if (readPointer == 0 || currentReadSize == 0) {
readPointer == 0Description
TRUEevaluated 755 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 740 times by 1 test
Evaluated by:
  • tst_Spdy
currentReadSize == 0Description
TRUEnever evaluated
FALSEevaluated 740 times by 1 test
Evaluated by:
  • tst_Spdy
0-755
717 // nothing to read currently, break the loop-
718 break;
executed 755 times by 1 test: break;
Executed by:
  • tst_Spdy
755
719 } else {-
720 DataFrameFlags flags = 0;-
721 // we will send the FIN flag later if appropriate-
722 qint64 currentWriteSize = sendDataFrame(streamID, flags, currentReadSize, readPointer);-
723 if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
currentWriteSize == -1Description
TRUEnever evaluated
FALSEevaluated 740 times by 1 test
Evaluated by:
  • tst_Spdy
currentWriteSi...urrentReadSizeDescription
TRUEnever evaluated
FALSEevaluated 740 times by 1 test
Evaluated by:
  • tst_Spdy
0-740
724 // socket broke down-
725 m_connection->d_func()->emitReplyError(m_socket, reply,-
726 QNetworkReply::UnknownNetworkError);-
727 return false;
never executed: return false;
0
728 } else {-
729 replyPrivate->currentlyUploadedDataInWindow += currentWriteSize;-
730 replyPrivate->totallyUploadedData += currentWriteSize;-
731 dataLeftInWindow = replyPrivate->windowSizeUpload-
732 - replyPrivate->currentlyUploadedDataInWindow;-
733 request.uploadByteDevice()->advanceReadPointer(currentWriteSize);-
734-
735 emit reply->dataSendProgress(replyPrivate->totallyUploadedData,-
736 request.contentLength());-
737 }
executed 740 times by 1 test: end of block
Executed by:
  • tst_Spdy
740
738 }-
739 }-
740 if (replyPrivate->totallyUploadedData == request.contentLength()) {
replyPrivate->...ontentLength()Description
TRUEevaluated 15 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 1460 times by 1 test
Evaluated by:
  • tst_Spdy
15-1460
741 DataFrameFlags finFlag = DataFrame_FLAG_FIN;-
742 qint64 writeSize = sendDataFrame(streamID, finFlag, 0, 0);-
743 Q_ASSERT(writeSize == 0);-
744 Q_UNUSED(writeSize); // silence -Wunused-variable-
745 replyPrivate->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;-
746 if (reply->request().uploadByteDevice())
reply->request...adByteDevice()Description
TRUEevaluated 15 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEnever evaluated
0-15
747 reply->request().uploadByteDevice()->disconnect(this);
executed 15 times by 1 test: reply->request().uploadByteDevice()->disconnect(this);
Executed by:
  • tst_Spdy
15
748 // ### this will not work if the content length is not known, but-
749 // then again many servers will fail in this case anyhow according-
750 // to the SPDY RFC-
751 }
executed 15 times by 1 test: end of block
Executed by:
  • tst_Spdy
15
752 return true;
executed 1475 times by 1 test: return true;
Executed by:
  • tst_Spdy
1475
753}-
754-
755void QSpdyProtocolHandler::_q_uploadDataReadyRead()-
756{-
757 QNonContiguousByteDevice *device = qobject_cast<QNonContiguousByteDevice *>(sender());-
758 Q_ASSERT(device);-
759 qint32 streamID = device->property("SPDYStreamID").toInt();-
760 Q_ASSERT(streamID > 0);-
761 uploadData(streamID);-
762}
executed 740 times by 1 test: end of block
Executed by:
  • tst_Spdy
740
763-
764void QSpdyProtocolHandler::sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindowSize)-
765{-
766 char windowUpdateData[8];-
767 appendIntToFourBytes(windowUpdateData, streamID);-
768 appendIntToFourBytes(windowUpdateData + 4, deltaWindowSize);-
769-
770 sendControlFrame(FrameType_WINDOW_UPDATE, /* flags = */ 0, windowUpdateData, /* length = */ 8);-
771}
executed 14 times by 1 test: end of block
Executed by:
  • tst_Spdy
14
772-
773qint64 QSpdyProtocolHandler::sendDataFrame(qint32 streamID, DataFrameFlags flags,-
774 quint32 length, const char *data)-
775{-
776 QByteArray wireData;-
777 wireData.reserve(8);-
778-
779 wireData.append(intToFourBytes(streamID));-
780 wireData.append(flags);-
781 wireData.append(intToThreeBytes(length));-
782-
783 Q_ASSERT(m_socket);-
784 m_socket->write(wireData);-
785-
786 if (data) {
dataDescription
TRUEevaluated 740 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 15 times by 1 test
Evaluated by:
  • tst_Spdy
15-740
787 qint64 ret = m_socket->write(data, length);-
788 return ret;
executed 740 times by 1 test: return ret;
Executed by:
  • tst_Spdy
740
789 } else {-
790 return 0; // nothing to write, e.g. FIN flag
executed 15 times by 1 test: return 0;
Executed by:
  • tst_Spdy
15
791 }-
792}-
793-
794void QSpdyProtocolHandler::handleControlFrame(const QByteArray &frameHeaders) // ### make it char *-
795{-
796 Q_ASSERT(frameHeaders.count() >= 8);-
797 qint16 version = twoBytesToInt(frameHeaders.constData());-
798 version &= 0x3fff; // eliminate most significant bit to determine version-
799 Q_ASSERT(version == 3);-
800-
801 qint16 type = twoBytesToInt(frameHeaders.constData() + 2);-
802-
803 char flags = frameHeaders.at(4);-
804 qint32 length = threeBytesToInt(frameHeaders.constData() + 5);-
805 Q_ASSERT(length > 0);-
806-
807 QByteArray frameData;-
808 frameData.resize(length);-
809 if (!readNextChunk(length, frameData.data())) {
!readNextChunk...meData.data())Description
TRUEnever evaluated
FALSEevaluated 869 times by 1 test
Evaluated by:
  • tst_Spdy
0-869
810 // put back the frame headers to the buffer-
811 m_spdyBuffer.prepend(frameHeaders);-
812 return; // we couldn't read the whole frame and need to wait
never executed: return;
0
813 } else {-
814 m_spdyBuffer.clear();-
815 m_waitingForCompleteStream = false;-
816 }
executed 869 times by 1 test: end of block
Executed by:
  • tst_Spdy
869
817-
818 switch (type) {-
819 case FrameType_SYN_STREAM: {
never executed: case FrameType_SYN_STREAM:
0
820 handleSYN_STREAM(flags, length, frameData);-
821 break;
never executed: break;
0
822 }-
823 case FrameType_SYN_REPLY: {
executed 107 times by 1 test: case FrameType_SYN_REPLY:
Executed by:
  • tst_Spdy
107
824 handleSYN_REPLY(flags, length, frameData);-
825 break;
executed 107 times by 1 test: break;
Executed by:
  • tst_Spdy
107
826 }-
827 case FrameType_RST_STREAM: {
never executed: case FrameType_RST_STREAM:
0
828 handleRST_STREAM(flags, length, frameData);-
829 break;
never executed: break;
0
830 }-
831 case FrameType_SETTINGS: {
executed 6 times by 1 test: case FrameType_SETTINGS:
Executed by:
  • tst_Spdy
6
832 handleSETTINGS(flags, length, frameData);-
833 break;
executed 6 times by 1 test: break;
Executed by:
  • tst_Spdy
6
834 }-
835 case FrameType_PING: {
never executed: case FrameType_PING:
0
836 handlePING(flags, length, frameData);-
837 break;
never executed: break;
0
838 }-
839 case FrameType_GOAWAY: {
never executed: case FrameType_GOAWAY:
0
840 handleGOAWAY(flags, length, frameData);-
841 break;
never executed: break;
0
842 }-
843 case FrameType_HEADERS: {
never executed: case FrameType_HEADERS:
0
844 handleHEADERS(flags, length, frameData);-
845 break;
never executed: break;
0
846 }-
847 case FrameType_WINDOW_UPDATE: {
executed 756 times by 1 test: case FrameType_WINDOW_UPDATE:
Executed by:
  • tst_Spdy
756
848 handleWINDOW_UPDATE(flags, length, frameData);-
849 break;
executed 756 times by 1 test: break;
Executed by:
  • tst_Spdy
756
850 }-
851 default:
never executed: default:
0
852 qWarning() << "cannot handle frame of type" << type;-
853 }
never executed: end of block
0
854}-
855-
856void QSpdyProtocolHandler::handleSYN_STREAM(char /*flags*/, quint32 /*length*/,-
857 const QByteArray &frameData)-
858{-
859 // not implemented; will be implemented when servers start using it-
860 // we just tell the server that we do not accept that-
861-
862 qint32 streamID = getStreamID(frameData.constData());-
863-
864 sendRST_STREAM(streamID, RST_STREAM_REFUSED_STREAM);-
865}
never executed: end of block
0
866-
867void QSpdyProtocolHandler::handleSYN_REPLY(char flags, quint32 /*length*/, const QByteArray &frameData)-
868{-
869 parseHttpHeaders(flags, frameData);-
870}
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
107
871-
872void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameData)-
873{-
874 qint32 streamID = getStreamID(frameData.constData());-
875 const auto it = m_inFlightStreams.constFind(streamID);-
876 if (it == m_inFlightStreams.cend()) {
it == m_inFlightStreams.cend()Description
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
877 sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);-
878 return;
never executed: return;
0
879 }-
880-
881 flags &= 0x3f;-
882 bool flag_fin = flags & 0x01;-
883-
884 QByteArray headerValuePairs = frameData.mid(4);-
885-
886 HttpMessagePair pair = it.value();-
887 QHttpNetworkReply *httpReply = pair.second;-
888 Q_ASSERT(httpReply != 0);-
889-
890 if (httpReply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
httpReply->d_f...te::SPDYClosedDescription
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
891 sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);-
892 return;
never executed: return;
0
893 }-
894-
895 QByteArray uncompressedHeader;-
896 if (!uncompressHeader(headerValuePairs, &uncompressedHeader)) {
!uncompressHea...pressedHeader)Description
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
897 qWarning("error reading header from SYN_REPLY message");-
898 return;
never executed: return;
0
899 }-
900-
901 qint32 headerCount = fourBytesToInt(uncompressedHeader.constData());-
902 if (headerCount * 8 > uncompressedHeader.size()) {
headerCount * ...dHeader.size()Description
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
903 qWarning("error parsing header from SYN_REPLY message");-
904 sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);-
905 return;
never executed: return;
0
906 }-
907 qint32 readPointer = 4;-
908 for (qint32 a = 0; a < headerCount; ++a) {
a < headerCountDescription
TRUEevaluated 685 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
107-685
909 qint32 count = fourBytesToInt(uncompressedHeader.constData() + readPointer);-
910 readPointer += 4;-
911 QByteArray name = uncompressedHeader.mid(readPointer, count);-
912 readPointer += count;-
913 if (readPointer > uncompressedHeader.size()) {
readPointer > ...dHeader.size()Description
TRUEnever evaluated
FALSEevaluated 685 times by 1 test
Evaluated by:
  • tst_Spdy
0-685
914 qWarning("error parsing header from SYN_REPLY message");-
915 sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);-
916 return;
never executed: return;
0
917 }-
918 count = fourBytesToInt(uncompressedHeader.constData() + readPointer);-
919 readPointer += 4;-
920 QByteArray value = uncompressedHeader.mid(readPointer, count);-
921 readPointer += count;-
922 if (readPointer > uncompressedHeader.size()) {
readPointer > ...dHeader.size()Description
TRUEnever evaluated
FALSEevaluated 685 times by 1 test
Evaluated by:
  • tst_Spdy
0-685
923 qWarning("error parsing header from SYN_REPLY message");-
924 sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);-
925 return;
never executed: return;
0
926 }-
927 if (name == ":status") {
name == ":status"Description
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 578 times by 1 test
Evaluated by:
  • tst_Spdy
107-578
928 httpReply->setStatusCode(value.left(3).toInt());-
929 httpReply->d_func()->reasonPhrase = QString::fromLatin1(value.mid(4));-
930 } else if (name == ":version") {
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
name == ":version"Description
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 471 times by 1 test
Evaluated by:
  • tst_Spdy
107-471
931 int majorVersion = value.at(5) - 48;-
932 int minorVersion = value.at(7) - 48;-
933 httpReply->d_func()->majorVersion = majorVersion;-
934 httpReply->d_func()->minorVersion = minorVersion;-
935 } else if (name == "content-length") {
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
name == "content-length"Description
TRUEevaluated 22 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 449 times by 1 test
Evaluated by:
  • tst_Spdy
22-449
936 httpReply->setContentLength(value.toLongLong());-
937 } else {
executed 22 times by 1 test: end of block
Executed by:
  • tst_Spdy
22
938 value.replace('\0', name == "set-cookie" ? "\n" : ", ");-
939 httpReply->setHeaderField(name, value);-
940 }
executed 449 times by 1 test: end of block
Executed by:
  • tst_Spdy
449
941 }-
942 emit httpReply->headerChanged();-
943-
944 if (flag_fin) {
flag_finDescription
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
945 if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
httpReply->d_f...SPDYHalfClosedDescription
TRUEnever evaluated
FALSEnever evaluated
0
946 sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
never executed: sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
0
947 replyFinished(httpReply, streamID);-
948 }
never executed: end of block
0
949}
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
107
950-
951void QSpdyProtocolHandler::handleRST_STREAM(char /*flags*/, quint32 length,-
952 const QByteArray &frameData)-
953{-
954 // flags are ignored-
955-
956 Q_ASSERT(length == 8);-
957 Q_UNUSED(length); // silence -Wunused-parameter-
958 qint32 streamID = getStreamID(frameData.constData());-
959 QHttpNetworkReply *httpReply = m_inFlightStreams.value(streamID).second;-
960-
961 qint32 statusCodeInt = fourBytesToInt(frameData.constData() + 4);-
962 RST_STREAM_STATUS_CODE statusCode = static_cast<RST_STREAM_STATUS_CODE>(statusCodeInt);-
963 QNetworkReply::NetworkError errorCode;-
964 QByteArray errorMessage;-
965-
966 switch (statusCode) {-
967 case RST_STREAM_PROTOCOL_ERROR:
never executed: case RST_STREAM_PROTOCOL_ERROR:
0
968 errorCode = QNetworkReply::ProtocolFailure;-
969 errorMessage = "SPDY protocol error";-
970 break;
never executed: break;
0
971 case RST_STREAM_INVALID_STREAM:
never executed: case RST_STREAM_INVALID_STREAM:
0
972 errorCode = QNetworkReply::ProtocolFailure;-
973 errorMessage = "SPDY stream is not active";-
974 break;
never executed: break;
0
975 case RST_STREAM_REFUSED_STREAM:
never executed: case RST_STREAM_REFUSED_STREAM:
0
976 errorCode = QNetworkReply::ProtocolFailure;-
977 errorMessage = "SPDY stream was refused";-
978 break;
never executed: break;
0
979 case RST_STREAM_UNSUPPORTED_VERSION:
never executed: case RST_STREAM_UNSUPPORTED_VERSION:
0
980 errorCode = QNetworkReply::ProtocolUnknownError;-
981 errorMessage = "SPDY version is unknown to the server";-
982 break;
never executed: break;
0
983 case RST_STREAM_CANCEL:
never executed: case RST_STREAM_CANCEL:
0
984 errorCode = QNetworkReply::ProtocolFailure;-
985 errorMessage = "SPDY stream is no longer needed";-
986 break;
never executed: break;
0
987 case RST_STREAM_INTERNAL_ERROR:
never executed: case RST_STREAM_INTERNAL_ERROR:
0
988 errorCode = QNetworkReply::InternalServerError;-
989 errorMessage = "Internal server error";-
990 break;
never executed: break;
0
991 case RST_STREAM_FLOW_CONTROL_ERROR:
never executed: case RST_STREAM_FLOW_CONTROL_ERROR:
0
992 errorCode = QNetworkReply::ProtocolFailure;-
993 errorMessage = "peer violated the flow control protocol";-
994 break;
never executed: break;
0
995 case RST_STREAM_STREAM_IN_USE:
never executed: case RST_STREAM_STREAM_IN_USE:
0
996 errorCode = QNetworkReply::ProtocolFailure;-
997 errorMessage = "server received a SYN_REPLY for an already open stream";-
998 break;
never executed: break;
0
999 case RST_STREAM_STREAM_ALREADY_CLOSED:
never executed: case RST_STREAM_STREAM_ALREADY_CLOSED:
0
1000 errorCode = QNetworkReply::ProtocolFailure;-
1001 errorMessage = "server received data or a SYN_REPLY for an already half-closed stream";-
1002 break;
never executed: break;
0
1003 case RST_STREAM_INVALID_CREDENTIALS:
never executed: case RST_STREAM_INVALID_CREDENTIALS:
0
1004 errorCode = QNetworkReply::ContentAccessDenied;-
1005 errorMessage = "server received invalid credentials";-
1006 break;
never executed: break;
0
1007 case RST_STREAM_FRAME_TOO_LARGE:
never executed: case RST_STREAM_FRAME_TOO_LARGE:
0
1008 errorCode = QNetworkReply::ProtocolFailure;-
1009 errorMessage = "server cannot process the frame because it is too large";-
1010 break;
never executed: break;
0
1011 default:
never executed: default:
0
1012 qWarning("could not understand servers RST_STREAM status code");-
1013 errorCode = QNetworkReply::ProtocolFailure;-
1014 errorMessage = "got SPDY RST_STREAM message with unknown error code";-
1015 }
never executed: end of block
0
1016 if (httpReply)
httpReplyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1017 replyFinishedWithError(httpReply, streamID, errorCode, errorMessage.constData());
never executed: replyFinishedWithError(httpReply, streamID, errorCode, errorMessage.constData());
0
1018}
never executed: end of block
0
1019-
1020void QSpdyProtocolHandler::handleSETTINGS(char flags, quint32 /*length*/, const QByteArray &frameData)-
1021{-
1022 Q_ASSERT(frameData.count() > 0);-
1023-
1024 SETTINGS_Flags settingsFlags = static_cast<SETTINGS_Flags>(flags);-
1025 if (settingsFlags & FLAG_SETTINGS_CLEAR_SETTINGS) {
settingsFlags ...CLEAR_SETTINGSDescription
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
0-6
1026 // ### clear all persistent settings; since we do not persist settings-
1027 // as of now, we don't need to clear anything either-
1028 }
never executed: end of block
0
1029-
1030 qint32 numberOfEntries = fourBytesToInt(frameData.constData());-
1031 Q_ASSERT(numberOfEntries > 0);-
1032 for (int a = 0, frameDataIndex = 4; a < numberOfEntries; ++a, frameDataIndex += 8) {
a < numberOfEntriesDescription
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
6
1033 SETTINGS_ID_Flag idFlag = static_cast<SETTINGS_ID_Flag>(frameData[frameDataIndex]);-
1034 if (idFlag & FLAG_SETTINGS_PERSIST_VALUE) {
idFlag & FLAG_..._PERSIST_VALUEDescription
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • tst_Spdy
0-6
1035 // ### we SHOULD persist the settings here according to the RFC, but we don't have to,-
1036 // so implement that later-
1037 } // the other value is only sent by us, but not received
never executed: end of block
0
1038-
1039 quint32 uniqueID = static_cast<SETTINGS_ID>(-
1040 threeBytesToInt(frameData.constData() + frameDataIndex + 1));-
1041 quint32 value = fourBytesToInt(frameData.constData() + frameDataIndex + 4);-
1042 switch (uniqueID) {-
1043 case SETTINGS_UPLOAD_BANDWIDTH: {
never executed: case SETTINGS_UPLOAD_BANDWIDTH:
0
1044 // ignored for now, just an estimated informative value-
1045 break;
never executed: break;
0
1046 }-
1047 case SETTINGS_DOWNLOAD_BANDWIDTH: {
never executed: case SETTINGS_DOWNLOAD_BANDWIDTH:
0
1048 // ignored for now, just an estimated informative value-
1049 break;
never executed: break;
0
1050 }-
1051 case SETTINGS_ROUND_TRIP_TIME: {
never executed: case SETTINGS_ROUND_TRIP_TIME:
0
1052 // ignored for now, just an estimated informative value-
1053 break;
never executed: break;
0
1054 }-
1055 case SETTINGS_MAX_CONCURRENT_STREAMS: {
executed 6 times by 1 test: case SETTINGS_MAX_CONCURRENT_STREAMS:
Executed by:
  • tst_Spdy
6
1056 m_maxConcurrentStreams = value;-
1057 break;
executed 6 times by 1 test: break;
Executed by:
  • tst_Spdy
6
1058 }-
1059 case SETTINGS_CURRENT_CWND: {
never executed: case SETTINGS_CURRENT_CWND:
0
1060 // ignored for now, just an informative value-
1061 break;
never executed: break;
0
1062 }-
1063 case SETTINGS_DOWNLOAD_RETRANS_RATE: {
never executed: case SETTINGS_DOWNLOAD_RETRANS_RATE:
0
1064 // ignored for now, just an estimated informative value-
1065 break;
never executed: break;
0
1066 }-
1067 case SETTINGS_INITIAL_WINDOW_SIZE: {
never executed: case SETTINGS_INITIAL_WINDOW_SIZE:
0
1068 m_initialWindowSize = value;-
1069 break;
never executed: break;
0
1070 }-
1071 case SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE: {
never executed: case SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE:
0
1072 // client certificates are not supported-
1073 break;
never executed: break;
0
1074 }-
1075 default:
never executed: default:
0
1076 qWarning() << "found unknown settings value" << value;-
1077 }
never executed: end of block
0
1078 }-
1079}
executed 6 times by 1 test: end of block
Executed by:
  • tst_Spdy
6
1080-
1081void QSpdyProtocolHandler::handlePING(char /*flags*/, quint32 length, const QByteArray &frameData)-
1082{-
1083 // flags are ignored-
1084-
1085 Q_ASSERT(length == 4);-
1086 Q_UNUSED(length); // silence -Wunused-parameter-
1087 quint32 pingID = fourBytesToInt(frameData.constData());-
1088-
1089 // odd numbered IDs must be ignored-
1090 if ((pingID & 1) == 0) // is even?
(pingID & 1) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1091 sendPING(pingID);
never executed: sendPING(pingID);
0
1092}
never executed: end of block
0
1093-
1094void QSpdyProtocolHandler::handleGOAWAY(char /*flags*/, quint32 /*length*/,-
1095 const QByteArray &frameData)-
1096{-
1097 // flags are ignored-
1098-
1099 qint32 statusCode = static_cast<GOAWAY_STATUS>(fourBytesToInt(frameData.constData() + 4));-
1100 QNetworkReply::NetworkError errorCode;-
1101 switch (statusCode) {-
1102 case GOAWAY_OK: {
never executed: case GOAWAY_OK:
0
1103 errorCode = QNetworkReply::NoError;-
1104 break;
never executed: break;
0
1105 }-
1106 case GOAWAY_PROTOCOL_ERROR: {
never executed: case GOAWAY_PROTOCOL_ERROR:
0
1107 errorCode = QNetworkReply::ProtocolFailure;-
1108 break;
never executed: break;
0
1109 }-
1110 case GOAWAY_INTERNAL_ERROR: {
never executed: case GOAWAY_INTERNAL_ERROR:
0
1111 errorCode = QNetworkReply::InternalServerError;-
1112 break;
never executed: break;
0
1113 }-
1114 default:
never executed: default:
0
1115 qWarning() << "unexpected status code" << statusCode;-
1116 errorCode = QNetworkReply::ProtocolUnknownError;-
1117 }
never executed: end of block
0
1118-
1119 qint32 lastGoodStreamID = getStreamID(frameData.constData());-
1120-
1121 // emit errors for all replies after the last good stream ID-
1122 Q_ASSERT(m_connection);-
1123 for (qint32 currentStreamID = lastGoodStreamID + 2; currentStreamID <= m_nextStreamID;
currentStreamI...m_nextStreamIDDescription
TRUEnever evaluated
FALSEnever evaluated
0
1124 ++currentStreamID) {-
1125 QHttpNetworkReply *reply = m_inFlightStreams.value(currentStreamID).second;-
1126 Q_ASSERT(reply);-
1127 m_connection->d_func()->emitReplyError(m_socket, reply, errorCode);-
1128 }
never executed: end of block
0
1129 // ### we could make sure a new session is initiated anyhow-
1130}
never executed: end of block
0
1131-
1132void QSpdyProtocolHandler::handleHEADERS(char flags, quint32 /*length*/,-
1133 const QByteArray &frameData)-
1134{-
1135 parseHttpHeaders(flags, frameData);-
1136}
never executed: end of block
0
1137-
1138void QSpdyProtocolHandler::handleWINDOW_UPDATE(char /*flags*/, quint32 /*length*/,-
1139 const QByteArray &frameData)-
1140{-
1141 qint32 streamID = getStreamID(frameData.constData());-
1142 qint32 deltaWindowSize = fourBytesToInt(frameData.constData() + 4);-
1143-
1144 const auto it = m_inFlightStreams.constFind(streamID);-
1145 if (it == m_inFlightStreams.cend()) {
it == m_inFlightStreams.cend()Description
TRUEnever evaluated
FALSEevaluated 756 times by 1 test
Evaluated by:
  • tst_Spdy
0-756
1146 sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);-
1147 return;
never executed: return;
0
1148 }-
1149-
1150 QHttpNetworkReply *reply = it.value().second;-
1151 Q_ASSERT(reply);-
1152 QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();-
1153 Q_ASSERT(replyPrivate);-
1154-
1155 // Ignore WINDOW_UPDATE if we are already done.-
1156 if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed)
replyPrivate->...SPDYHalfClosedDescription
TRUEevaluated 36 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 720 times by 1 test
Evaluated by:
  • tst_Spdy
replyPrivate->...te::SPDYClosedDescription
TRUEnever evaluated
FALSEevaluated 720 times by 1 test
Evaluated by:
  • tst_Spdy
0-720
1157 return;
executed 36 times by 1 test: return;
Executed by:
  • tst_Spdy
36
1158-
1159 replyPrivate->currentlyUploadedDataInWindow = replyPrivate->windowSizeUpload - deltaWindowSize;-
1160 uploadData(streamID); // we hopefully can continue to upload-
1161}
executed 720 times by 1 test: end of block
Executed by:
  • tst_Spdy
720
1162-
1163-
1164void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)-
1165{-
1166 Q_ASSERT(frameHeaders.count() >= 8);-
1167-
1168 qint32 streamID = getStreamID(frameHeaders.constData());-
1169 const auto it = m_inFlightStreams.constFind(streamID);-
1170 if (it == m_inFlightStreams.cend()) {
it == m_inFlightStreams.cend()Description
TRUEnever evaluated
FALSEevaluated 504 times by 1 test
Evaluated by:
  • tst_Spdy
0-504
1171 sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM);-
1172 return;
never executed: return;
0
1173 }-
1174-
1175 unsigned char flags = static_cast<unsigned char>(frameHeaders.at(4));-
1176 flags &= 0x3f;-
1177 bool flag_fin = flags & 0x01;-
1178 bool flag_compress = flags & 0x02;-
1179 qint32 length = threeBytesToInt(frameHeaders.constData() + 5);-
1180-
1181 QByteArray data;-
1182 data.resize(length);-
1183 if (!readNextChunk(length, data.data())) {
!readNextChunk..., data.data())Description
TRUEevaluated 156 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
156-348
1184 // put back the frame headers to the buffer-
1185 m_spdyBuffer.prepend(frameHeaders);-
1186 return; // we couldn't read the whole frame and need to wait
executed 156 times by 1 test: return;
Executed by:
  • tst_Spdy
156
1187 } else {-
1188 m_spdyBuffer.clear();-
1189 m_waitingForCompleteStream = false;-
1190 }
executed 348 times by 1 test: end of block
Executed by:
  • tst_Spdy
348
1191-
1192 HttpMessagePair pair = it.value();-
1193 QHttpNetworkRequest httpRequest = pair.first;-
1194 QHttpNetworkReply *httpReply = pair.second;-
1195 Q_ASSERT(httpReply != 0);-
1196-
1197 QHttpNetworkReplyPrivate *replyPrivate = httpReply->d_func();-
1198-
1199 if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed) {
replyPrivate->...te::SPDYClosedDescription
TRUEnever evaluated
FALSEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
0-348
1200 sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);-
1201 return;
never executed: return;
0
1202 }-
1203-
1204 // check whether we need to send WINDOW_UPDATE (i.e. tell the sender it can send more)-
1205 replyPrivate->currentlyReceivedDataInWindow += length;-
1206 qint32 dataLeftInWindow = replyPrivate->windowSizeDownload - replyPrivate->currentlyReceivedDataInWindow;-
1207-
1208 if (replyPrivate->currentlyReceivedDataInWindow > 0
replyPrivate->...taInWindow > 0Description
TRUEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEnever evaluated
0-348
1209 && dataLeftInWindow < replyPrivate->windowSizeDownload / 2) {
dataLeftInWind...zeDownload / 2Description
TRUEevaluated 14 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 334 times by 1 test
Evaluated by:
  • tst_Spdy
14-334
1210-
1211 // socket read buffer size is 64K actually, hard coded in the channel-
1212 // We can read way more than 64K per socket, because the window size-
1213 // here is per stream.-
1214 if (replyPrivate->windowSizeDownload >= m_socket->readBufferSize()) {
replyPrivate->...adBufferSize()Description
TRUEevaluated 14 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEnever evaluated
0-14
1215 replyPrivate->windowSizeDownload = m_socket->readBufferSize();-
1216 } else {
executed 14 times by 1 test: end of block
Executed by:
  • tst_Spdy
14
1217 replyPrivate->windowSizeDownload *= 1.5;-
1218 }
never executed: end of block
0
1219 QMetaObject::invokeMethod(this, "sendWINDOW_UPDATE", Qt::QueuedConnection,-
1220 Q_ARG(qint32, streamID),-
1221 Q_ARG(quint32, replyPrivate->windowSizeDownload));-
1222 // setting the current data count to 0 is a race condition,-
1223 // because we call sendWINDOW_UPDATE through the event loop.-
1224 // But then again, the whole situation is a race condition because-
1225 // we don't know when the packet will arrive at the server; so-
1226 // this is most likely good enough here.-
1227 replyPrivate->currentlyReceivedDataInWindow = 0;-
1228 }
executed 14 times by 1 test: end of block
Executed by:
  • tst_Spdy
14
1229-
1230 httpReply->d_func()->compressedData.append(data);-
1231-
1232-
1233 replyPrivate->totalProgress += length;-
1234-
1235 if (httpRequest.d->autoDecompress && httpReply->d_func()->isCompressed()) {
httpRequest.d->autoDecompressDescription
TRUEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEnever evaluated
httpReply->d_f...isCompressed()Description
TRUEnever evaluated
FALSEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
0-348
1236 QByteDataBuffer inDataBuffer; // ### should we introduce one in the http reply?-
1237 inDataBuffer.append(data);-
1238 qint64 compressedCount = httpReply->d_func()->uncompressBodyData(&inDataBuffer,-
1239 &replyPrivate->responseData);-
1240 Q_ASSERT(compressedCount >= 0);-
1241 Q_UNUSED(compressedCount); // silence -Wunused-variable-
1242 } else {
never executed: end of block
0
1243 replyPrivate->responseData.append(data);-
1244 }
executed 348 times by 1 test: end of block
Executed by:
  • tst_Spdy
348
1245-
1246 if (replyPrivate->shouldEmitSignals()) {
replyPrivate->...dEmitSignals()Description
TRUEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEnever evaluated
0-348
1247 emit httpReply->readyRead();-
1248 emit httpReply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);-
1249 }
executed 348 times by 1 test: end of block
Executed by:
  • tst_Spdy
348
1250-
1251 if (flag_compress) {
flag_compressDescription
TRUEnever evaluated
FALSEevaluated 348 times by 1 test
Evaluated by:
  • tst_Spdy
0-348
1252 qWarning("SPDY level compression is not supported");-
1253 }
never executed: end of block
0
1254-
1255 if (flag_fin) {
flag_finDescription
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 241 times by 1 test
Evaluated by:
  • tst_Spdy
107-241
1256 if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
httpReply->d_f...SPDYHalfClosedDescription
TRUEnever evaluated
FALSEevaluated 107 times by 1 test
Evaluated by:
  • tst_Spdy
0-107
1257 sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
never executed: sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
0
1258 replyFinished(httpReply, streamID);-
1259 }
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
107
1260}
executed 348 times by 1 test: end of block
Executed by:
  • tst_Spdy
348
1261-
1262void QSpdyProtocolHandler::replyFinished(QHttpNetworkReply *httpReply, qint32 streamID)-
1263{-
1264 httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed;-
1265 httpReply->disconnect(this);-
1266 if (httpReply->request().uploadByteDevice())
httpReply->req...adByteDevice()Description
TRUEevaluated 15 times by 1 test
Evaluated by:
  • tst_Spdy
FALSEevaluated 92 times by 1 test
Evaluated by:
  • tst_Spdy
15-92
1267 httpReply->request().uploadByteDevice()->disconnect(this);
executed 15 times by 1 test: httpReply->request().uploadByteDevice()->disconnect(this);
Executed by:
  • tst_Spdy
15
1268 int streamsRemoved = m_inFlightStreams.remove(streamID);-
1269 Q_ASSERT(streamsRemoved == 1);-
1270 Q_UNUSED(streamsRemoved); // silence -Wunused-variable-
1271 emit httpReply->finished();-
1272}
executed 107 times by 1 test: end of block
Executed by:
  • tst_Spdy
107
1273-
1274void QSpdyProtocolHandler::replyFinishedWithError(QHttpNetworkReply *httpReply, qint32 streamID,-
1275 QNetworkReply::NetworkError errorCode, const char *errorMessage)-
1276{-
1277 Q_ASSERT(httpReply);-
1278 httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed;-
1279 httpReply->disconnect(this);-
1280 if (httpReply->request().uploadByteDevice())
httpReply->req...adByteDevice()Description
TRUEnever evaluated
FALSEnever evaluated
0
1281 httpReply->request().uploadByteDevice()->disconnect(this);
never executed: httpReply->request().uploadByteDevice()->disconnect(this);
0
1282 int streamsRemoved = m_inFlightStreams.remove(streamID);-
1283 Q_ASSERT(streamsRemoved == 1);-
1284 Q_UNUSED(streamsRemoved); // silence -Wunused-variable-
1285 emit httpReply->finishedWithError(errorCode, QSpdyProtocolHandler::tr(errorMessage));-
1286}
never executed: end of block
0
1287-
1288qint32 QSpdyProtocolHandler::generateNextStreamID()-
1289{-
1290 // stream IDs initiated by the client must be odd-
1291 m_nextStreamID += 2;-
1292 return m_nextStreamID;
executed 107 times by 1 test: return m_nextStreamID;
Executed by:
  • tst_Spdy
107
1293}-
1294-
1295QT_END_NAMESPACE-
1296-
1297#endif // !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9