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