| 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 |