OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/core/quic_spdy_session.h" | 5 #include "net/quic/core/quic_spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstdint> | 8 #include <cstdint> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 header_list_.Clear(); | 117 header_list_.Clear(); |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 void OnStreamFrameData(SpdyStreamId stream_id, | 121 void OnStreamFrameData(SpdyStreamId stream_id, |
122 const char* data, | 122 const char* data, |
123 size_t len) override { | 123 size_t len) override { |
124 if (session_->OnStreamFrameData(stream_id, data, len)) { | 124 if (session_->OnStreamFrameData(stream_id, data, len)) { |
125 return; | 125 return; |
126 } | 126 } |
127 CloseConnection("SPDY DATA frame received."); | 127 CloseConnection("SPDY DATA frame received.", |
| 128 QUIC_INVALID_HEADERS_STREAM_DATA); |
128 } | 129 } |
129 | 130 |
130 void OnStreamEnd(SpdyStreamId stream_id) override { | 131 void OnStreamEnd(SpdyStreamId stream_id) override { |
131 // The framer invokes OnStreamEnd after processing a frame that had the fin | 132 // The framer invokes OnStreamEnd after processing a frame that had the fin |
132 // bit set. | 133 // bit set. |
133 } | 134 } |
134 | 135 |
135 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { | 136 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { |
136 CloseConnection("SPDY frame padding received."); | 137 CloseConnection("SPDY frame padding received.", |
| 138 QUIC_INVALID_HEADERS_STREAM_DATA); |
137 } | 139 } |
138 | 140 |
139 void OnError(SpdyFramer* framer) override { | 141 void OnError(SpdyFramer* framer) override { |
140 CloseConnection(QuicStrCat( | 142 QuicErrorCode code = QUIC_INVALID_HEADERS_STREAM_DATA; |
141 "SPDY framing error: ", | 143 SpdyFramer::SpdyFramerError error = framer->spdy_framer_error(); |
142 SpdyFramer::SpdyFramerErrorToString(framer->spdy_framer_error()))); | 144 switch (error) { |
| 145 case SpdyFramer::SpdyFramerError::SPDY_DECOMPRESS_FAILURE: |
| 146 code = QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE; |
| 147 break; |
| 148 default: |
| 149 break; |
| 150 } |
| 151 CloseConnection(QuicStrCat("SPDY framing error: ", |
| 152 SpdyFramer::SpdyFramerErrorToString(error)), |
| 153 code); |
143 } | 154 } |
144 | 155 |
145 void OnDataFrameHeader(SpdyStreamId stream_id, | 156 void OnDataFrameHeader(SpdyStreamId stream_id, |
146 size_t length, | 157 size_t length, |
147 bool fin) override { | 158 bool fin) override { |
148 if (session_->OnDataFrameHeader(stream_id, length, fin)) { | 159 if (session_->OnDataFrameHeader(stream_id, length, fin)) { |
149 return; | 160 return; |
150 } | 161 } |
151 CloseConnection("SPDY DATA frame received."); | 162 CloseConnection("SPDY DATA frame received.", |
| 163 QUIC_INVALID_HEADERS_STREAM_DATA); |
152 } | 164 } |
153 | 165 |
154 void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override { | 166 void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override { |
155 CloseConnection("SPDY RST_STREAM frame received."); | 167 CloseConnection("SPDY RST_STREAM frame received.", |
| 168 QUIC_INVALID_HEADERS_STREAM_DATA); |
156 } | 169 } |
157 | 170 |
158 void OnSetting(SpdySettingsIds id, uint32_t value) override { | 171 void OnSetting(SpdySettingsIds id, uint32_t value) override { |
159 if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { | 172 if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { |
160 CloseConnection("SPDY SETTINGS frame received."); | 173 CloseConnection("SPDY SETTINGS frame received.", |
| 174 QUIC_INVALID_HEADERS_STREAM_DATA); |
161 return; | 175 return; |
162 } | 176 } |
163 switch (id) { | 177 switch (id) { |
164 case SETTINGS_HEADER_TABLE_SIZE: | 178 case SETTINGS_HEADER_TABLE_SIZE: |
165 session_->UpdateHeaderEncoderTableSize(value); | 179 session_->UpdateHeaderEncoderTableSize(value); |
166 break; | 180 break; |
167 case SETTINGS_ENABLE_PUSH: | 181 case SETTINGS_ENABLE_PUSH: |
168 if (FLAGS_quic_reloadable_flag_quic_enable_server_push_by_default && | 182 if (FLAGS_quic_reloadable_flag_quic_enable_server_push_by_default && |
169 session_->perspective() == Perspective::IS_SERVER) { | 183 session_->perspective() == Perspective::IS_SERVER) { |
170 // See rfc7540, Section 6.5.2. | 184 // See rfc7540, Section 6.5.2. |
171 if (value > 1) { | 185 if (value > 1) { |
172 CloseConnection( | 186 CloseConnection( |
173 QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value)); | 187 QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value), |
| 188 QUIC_INVALID_HEADERS_STREAM_DATA); |
174 return; | 189 return; |
175 } | 190 } |
176 session_->UpdateEnableServerPush(value > 0); | 191 session_->UpdateEnableServerPush(value > 0); |
177 break; | 192 break; |
178 } else { | 193 } else { |
179 CloseConnection( | 194 CloseConnection( |
180 QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id)); | 195 QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id), |
| 196 QUIC_INVALID_HEADERS_STREAM_DATA); |
181 } | 197 } |
182 break; | 198 break; |
183 // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when | 199 // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when |
184 // clients are actually sending it. | 200 // clients are actually sending it. |
185 case SETTINGS_MAX_HEADER_LIST_SIZE: | 201 case SETTINGS_MAX_HEADER_LIST_SIZE: |
186 if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) { | 202 if (FLAGS_quic_reloadable_flag_quic_send_max_header_list_size) { |
187 break; | 203 break; |
188 } | 204 } |
189 default: | 205 default: |
190 CloseConnection( | 206 CloseConnection( |
191 QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id)); | 207 QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id), |
| 208 QUIC_INVALID_HEADERS_STREAM_DATA); |
192 } | 209 } |
193 } | 210 } |
194 | 211 |
195 void OnSettingsAck() override { | 212 void OnSettingsAck() override { |
196 if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { | 213 if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { |
197 CloseConnection("SPDY SETTINGS frame received."); | 214 CloseConnection("SPDY SETTINGS frame received.", |
| 215 QUIC_INVALID_HEADERS_STREAM_DATA); |
198 } | 216 } |
199 } | 217 } |
200 | 218 |
201 void OnSettingsEnd() override { | 219 void OnSettingsEnd() override { |
202 if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { | 220 if (!FLAGS_quic_reloadable_flag_quic_respect_http2_settings_frame) { |
203 CloseConnection("SPDY SETTINGS frame received."); | 221 CloseConnection("SPDY SETTINGS frame received.", |
| 222 QUIC_INVALID_HEADERS_STREAM_DATA); |
204 } | 223 } |
205 } | 224 } |
206 | 225 |
207 void OnPing(SpdyPingId unique_id, bool is_ack) override { | 226 void OnPing(SpdyPingId unique_id, bool is_ack) override { |
208 CloseConnection("SPDY PING frame received."); | 227 CloseConnection("SPDY PING frame received.", |
| 228 QUIC_INVALID_HEADERS_STREAM_DATA); |
209 } | 229 } |
210 | 230 |
211 void OnGoAway(SpdyStreamId last_accepted_stream_id, | 231 void OnGoAway(SpdyStreamId last_accepted_stream_id, |
212 SpdyErrorCode error_code) override { | 232 SpdyErrorCode error_code) override { |
213 CloseConnection("SPDY GOAWAY frame received."); | 233 CloseConnection("SPDY GOAWAY frame received.", |
| 234 QUIC_INVALID_HEADERS_STREAM_DATA); |
214 } | 235 } |
215 | 236 |
216 void OnHeaders(SpdyStreamId stream_id, | 237 void OnHeaders(SpdyStreamId stream_id, |
217 bool has_priority, | 238 bool has_priority, |
218 int weight, | 239 int weight, |
219 SpdyStreamId /*parent_stream_id*/, | 240 SpdyStreamId /*parent_stream_id*/, |
220 bool /*exclusive*/, | 241 bool /*exclusive*/, |
221 bool fin, | 242 bool fin, |
222 bool end) override { | 243 bool end) override { |
223 if (!session_->IsConnected()) { | 244 if (!session_->IsConnected()) { |
224 return; | 245 return; |
225 } | 246 } |
226 | 247 |
227 // TODO(mpw): avoid down-conversion and plumb SpdyStreamPrecedence through | 248 // TODO(mpw): avoid down-conversion and plumb SpdyStreamPrecedence through |
228 // QuicHeadersStream. | 249 // QuicHeadersStream. |
229 SpdyPriority priority = | 250 SpdyPriority priority = |
230 has_priority ? Http2WeightToSpdy3Priority(weight) : 0; | 251 has_priority ? Http2WeightToSpdy3Priority(weight) : 0; |
231 session_->OnHeaders(stream_id, has_priority, priority, fin); | 252 session_->OnHeaders(stream_id, has_priority, priority, fin); |
232 } | 253 } |
233 | 254 |
234 void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override { | 255 void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override { |
235 CloseConnection("SPDY WINDOW_UPDATE frame received."); | 256 CloseConnection("SPDY WINDOW_UPDATE frame received.", |
| 257 QUIC_INVALID_HEADERS_STREAM_DATA); |
236 } | 258 } |
237 | 259 |
238 void OnPushPromise(SpdyStreamId stream_id, | 260 void OnPushPromise(SpdyStreamId stream_id, |
239 SpdyStreamId promised_stream_id, | 261 SpdyStreamId promised_stream_id, |
240 bool end) override { | 262 bool end) override { |
241 if (!session_->supports_push_promise()) { | 263 if (!session_->supports_push_promise()) { |
242 CloseConnection("PUSH_PROMISE not supported."); | 264 CloseConnection("PUSH_PROMISE not supported.", |
| 265 QUIC_INVALID_HEADERS_STREAM_DATA); |
243 return; | 266 return; |
244 } | 267 } |
245 if (!session_->IsConnected()) { | 268 if (!session_->IsConnected()) { |
246 return; | 269 return; |
247 } | 270 } |
248 session_->OnPushPromise(stream_id, promised_stream_id, end); | 271 session_->OnPushPromise(stream_id, promised_stream_id, end); |
249 } | 272 } |
250 | 273 |
251 void OnContinuation(SpdyStreamId stream_id, bool end) override {} | 274 void OnContinuation(SpdyStreamId stream_id, bool end) override {} |
252 | 275 |
253 void OnPriority(SpdyStreamId stream_id, | 276 void OnPriority(SpdyStreamId stream_id, |
254 SpdyStreamId parent_id, | 277 SpdyStreamId parent_id, |
255 int weight, | 278 int weight, |
256 bool exclusive) override { | 279 bool exclusive) override { |
257 CloseConnection("SPDY PRIORITY frame received."); | 280 CloseConnection("SPDY PRIORITY frame received.", |
| 281 QUIC_INVALID_HEADERS_STREAM_DATA); |
258 } | 282 } |
259 | 283 |
260 bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override { | 284 bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override { |
261 CloseConnection("Unknown frame type received."); | 285 CloseConnection("Unknown frame type received.", |
| 286 QUIC_INVALID_HEADERS_STREAM_DATA); |
262 return false; | 287 return false; |
263 } | 288 } |
264 | 289 |
265 // SpdyFramerDebugVisitorInterface implementation | 290 // SpdyFramerDebugVisitorInterface implementation |
266 void OnSendCompressedFrame(SpdyStreamId stream_id, | 291 void OnSendCompressedFrame(SpdyStreamId stream_id, |
267 SpdyFrameType type, | 292 SpdyFrameType type, |
268 size_t payload_len, | 293 size_t payload_len, |
269 size_t frame_len) override { | 294 size_t frame_len) override { |
270 if (payload_len == 0) { | 295 if (payload_len == 0) { |
271 QUIC_BUG << "Zero payload length."; | 296 QUIC_BUG << "Zero payload length."; |
(...skipping 11 matching lines...) Expand all Loading... |
283 } | 308 } |
284 } | 309 } |
285 | 310 |
286 void set_max_uncompressed_header_bytes( | 311 void set_max_uncompressed_header_bytes( |
287 size_t set_max_uncompressed_header_bytes) { | 312 size_t set_max_uncompressed_header_bytes) { |
288 header_list_.set_max_uncompressed_header_bytes( | 313 header_list_.set_max_uncompressed_header_bytes( |
289 set_max_uncompressed_header_bytes); | 314 set_max_uncompressed_header_bytes); |
290 } | 315 } |
291 | 316 |
292 private: | 317 private: |
293 void CloseConnection(const string& details) { | 318 void CloseConnection(const string& details, QuicErrorCode code) { |
294 if (session_->IsConnected()) { | 319 if (session_->IsConnected()) { |
295 session_->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, | 320 session_->CloseConnectionWithDetails(code, details); |
296 details); | |
297 } | 321 } |
298 } | 322 } |
299 | 323 |
300 private: | 324 private: |
301 QuicSpdySession* session_; | 325 QuicSpdySession* session_; |
302 QuicHeaderList header_list_; | 326 QuicHeaderList header_list_; |
303 | 327 |
304 DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor); | 328 DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor); |
305 }; | 329 }; |
306 | 330 |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 set_max_uncompressed_header_bytes); | 769 set_max_uncompressed_header_bytes); |
746 } | 770 } |
747 | 771 |
748 void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error, | 772 void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error, |
749 const string& details) { | 773 const string& details) { |
750 connection()->CloseConnection( | 774 connection()->CloseConnection( |
751 error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 775 error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
752 } | 776 } |
753 | 777 |
754 } // namespace net | 778 } // namespace net |
OLD | NEW |