| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/spdy/buffered_spdy_framer.h" | 5 #include "net/spdy/buffered_spdy_framer.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 | 11 |
| 12 namespace net { | 12 namespace net { |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 // GOAWAY frame debug data is only buffered up to this many bytes. | 16 // GOAWAY frame debug data is only buffered up to this many bytes. |
| 17 size_t kGoAwayDebugDataMaxSize = 1024; | 17 size_t kGoAwayDebugDataMaxSize = 1024; |
| 18 | 18 |
| 19 // Initial and maximum sizes for header block buffer. | 19 // Initial and maximum sizes for header block buffer. |
| 20 size_t kHeaderBufferInitialSize = 8 * 1024; | 20 size_t kHeaderBufferInitialSize = 8 * 1024; |
| 21 size_t kHeaderBufferMaxSize = 256 * 1024; | 21 size_t kHeaderBufferMaxSize = 256 * 1024; |
| 22 | 22 |
| 23 } // namespace | 23 } // namespace |
| 24 | 24 |
| 25 SpdyMajorVersion NextProtoToSpdyMajorVersion(NextProto next_proto) { | 25 BufferedSpdyFramer::BufferedSpdyFramer() |
| 26 switch (next_proto) { | 26 : spdy_framer_(HTTP2), |
| 27 case kProtoSPDY31: | |
| 28 return SPDY3; | |
| 29 case kProtoHTTP2: | |
| 30 return HTTP2; | |
| 31 case kProtoUnknown: | |
| 32 case kProtoHTTP11: | |
| 33 case kProtoQUIC1SPDY3: | |
| 34 break; | |
| 35 } | |
| 36 NOTREACHED(); | |
| 37 return HTTP2; | |
| 38 } | |
| 39 | |
| 40 BufferedSpdyFramer::BufferedSpdyFramer(SpdyMajorVersion version) | |
| 41 : spdy_framer_(version), | |
| 42 visitor_(NULL), | 27 visitor_(NULL), |
| 43 header_buffer_valid_(false), | 28 header_buffer_valid_(false), |
| 44 header_stream_id_(SpdyFramer::kInvalidStream), | 29 header_stream_id_(SpdyFramer::kInvalidStream), |
| 45 frames_received_(0) {} | 30 frames_received_(0) {} |
| 46 | 31 |
| 47 BufferedSpdyFramer::~BufferedSpdyFramer() { | 32 BufferedSpdyFramer::~BufferedSpdyFramer() { |
| 48 } | 33 } |
| 49 | 34 |
| 50 void BufferedSpdyFramer::set_visitor( | 35 void BufferedSpdyFramer::set_visitor( |
| 51 BufferedSpdyFramerVisitorInterface* visitor) { | 36 BufferedSpdyFramerVisitorInterface* visitor) { |
| 52 visitor_ = visitor; | 37 visitor_ = visitor; |
| 53 spdy_framer_.set_visitor(this); | 38 spdy_framer_.set_visitor(this); |
| 54 } | 39 } |
| 55 | 40 |
| 56 void BufferedSpdyFramer::set_debug_visitor( | 41 void BufferedSpdyFramer::set_debug_visitor( |
| 57 SpdyFramerDebugVisitorInterface* debug_visitor) { | 42 SpdyFramerDebugVisitorInterface* debug_visitor) { |
| 58 spdy_framer_.set_debug_visitor(debug_visitor); | 43 spdy_framer_.set_debug_visitor(debug_visitor); |
| 59 } | 44 } |
| 60 | 45 |
| 61 void BufferedSpdyFramer::OnError(SpdyFramer* spdy_framer) { | 46 void BufferedSpdyFramer::OnError(SpdyFramer* spdy_framer) { |
| 62 DCHECK(spdy_framer); | 47 DCHECK(spdy_framer); |
| 63 visitor_->OnError(spdy_framer->error_code()); | 48 visitor_->OnError(spdy_framer->error_code()); |
| 64 } | 49 } |
| 65 | 50 |
| 66 void BufferedSpdyFramer::OnSynStream(SpdyStreamId stream_id, | 51 void BufferedSpdyFramer::OnSynStream(SpdyStreamId stream_id, |
| 67 SpdyStreamId associated_stream_id, | 52 SpdyStreamId associated_stream_id, |
| 68 SpdyPriority priority, | 53 SpdyPriority priority, |
| 69 bool fin, | 54 bool fin, |
| 70 bool unidirectional) { | 55 bool unidirectional) { |
| 71 frames_received_++; | 56 NOTREACHED(); |
| 72 DCHECK(!control_frame_fields_.get()); | |
| 73 control_frame_fields_.reset(new ControlFrameFields()); | |
| 74 control_frame_fields_->type = SYN_STREAM; | |
| 75 control_frame_fields_->stream_id = stream_id; | |
| 76 control_frame_fields_->associated_stream_id = associated_stream_id; | |
| 77 control_frame_fields_->priority = priority; | |
| 78 control_frame_fields_->fin = fin; | |
| 79 control_frame_fields_->unidirectional = unidirectional; | |
| 80 | |
| 81 InitHeaderStreaming(stream_id); | |
| 82 } | 57 } |
| 83 | 58 |
| 84 void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id, | 59 void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id, |
| 85 bool has_priority, | 60 bool has_priority, |
| 86 int weight, | 61 int weight, |
| 87 SpdyStreamId parent_stream_id, | 62 SpdyStreamId parent_stream_id, |
| 88 bool exclusive, | 63 bool exclusive, |
| 89 bool fin, | 64 bool fin, |
| 90 bool end) { | 65 bool end) { |
| 91 frames_received_++; | 66 frames_received_++; |
| 92 DCHECK(!control_frame_fields_.get()); | 67 DCHECK(!control_frame_fields_.get()); |
| 93 control_frame_fields_.reset(new ControlFrameFields()); | 68 control_frame_fields_.reset(new ControlFrameFields()); |
| 94 control_frame_fields_->type = HEADERS; | 69 control_frame_fields_->type = HEADERS; |
| 95 control_frame_fields_->stream_id = stream_id; | 70 control_frame_fields_->stream_id = stream_id; |
| 96 control_frame_fields_->has_priority = has_priority; | 71 control_frame_fields_->has_priority = has_priority; |
| 97 if (control_frame_fields_->has_priority) { | 72 if (control_frame_fields_->has_priority) { |
| 98 control_frame_fields_->weight = weight; | 73 control_frame_fields_->weight = weight; |
| 99 control_frame_fields_->parent_stream_id = parent_stream_id; | 74 control_frame_fields_->parent_stream_id = parent_stream_id; |
| 100 control_frame_fields_->exclusive = exclusive; | 75 control_frame_fields_->exclusive = exclusive; |
| 101 } | 76 } |
| 102 control_frame_fields_->fin = fin; | 77 control_frame_fields_->fin = fin; |
| 103 | 78 |
| 104 InitHeaderStreaming(stream_id); | 79 InitHeaderStreaming(stream_id); |
| 105 } | 80 } |
| 106 | 81 |
| 107 void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id, | 82 void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id, |
| 108 bool fin) { | 83 bool fin) { |
| 109 frames_received_++; | 84 NOTREACHED(); |
| 110 DCHECK(!control_frame_fields_.get()); | |
| 111 control_frame_fields_.reset(new ControlFrameFields()); | |
| 112 control_frame_fields_->type = SYN_REPLY; | |
| 113 control_frame_fields_->stream_id = stream_id; | |
| 114 control_frame_fields_->fin = fin; | |
| 115 | |
| 116 InitHeaderStreaming(stream_id); | |
| 117 } | 85 } |
| 118 | 86 |
| 119 bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id, | 87 bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id, |
| 120 const char* header_data, | 88 const char* header_data, |
| 121 size_t len) { | 89 size_t len) { |
| 122 CHECK_EQ(header_stream_id_, stream_id); | 90 CHECK_EQ(header_stream_id_, stream_id); |
| 123 | 91 |
| 124 if (len == 0) { | 92 if (len == 0) { |
| 125 // Indicates end-of-header-block. | 93 // Indicates end-of-header-block. |
| 126 CHECK(header_buffer_valid_); | 94 CHECK(header_buffer_valid_); |
| 127 | 95 |
| 128 SpdyHeaderBlock headers; | 96 SpdyHeaderBlock headers; |
| 129 if (!spdy_framer_.ParseHeaderBlockInBuffer( | 97 if (!spdy_framer_.ParseHeaderBlockInBuffer( |
| 130 header_buffer_.data(), header_buffer_.size(), &headers)) { | 98 header_buffer_.data(), header_buffer_.size(), &headers)) { |
| 131 visitor_->OnStreamError( | 99 visitor_->OnStreamError( |
| 132 stream_id, "Could not parse Spdy Control Frame Header."); | 100 stream_id, "Could not parse Spdy Control Frame Header."); |
| 133 return false; | 101 return false; |
| 134 } | 102 } |
| 135 DCHECK(control_frame_fields_.get()); | 103 DCHECK(control_frame_fields_.get()); |
| 136 switch (control_frame_fields_->type) { | 104 switch (control_frame_fields_->type) { |
| 137 case SYN_STREAM: | 105 case SYN_STREAM: |
| 138 visitor_->OnSynStream(control_frame_fields_->stream_id, | 106 NOTREACHED(); |
| 139 control_frame_fields_->associated_stream_id, | |
| 140 control_frame_fields_->priority, | |
| 141 control_frame_fields_->fin, | |
| 142 control_frame_fields_->unidirectional, | |
| 143 headers); | |
| 144 break; | 107 break; |
| 145 case SYN_REPLY: | 108 case SYN_REPLY: |
| 146 visitor_->OnSynReply(control_frame_fields_->stream_id, | 109 NOTREACHED(); |
| 147 control_frame_fields_->fin, | |
| 148 headers); | |
| 149 break; | 110 break; |
| 150 case HEADERS: | 111 case HEADERS: |
| 151 visitor_->OnHeaders(control_frame_fields_->stream_id, | 112 visitor_->OnHeaders(control_frame_fields_->stream_id, |
| 152 control_frame_fields_->has_priority, | 113 control_frame_fields_->has_priority, |
| 153 control_frame_fields_->weight, | 114 control_frame_fields_->weight, |
| 154 control_frame_fields_->parent_stream_id, | 115 control_frame_fields_->parent_stream_id, |
| 155 control_frame_fields_->exclusive, | 116 control_frame_fields_->exclusive, |
| 156 control_frame_fields_->fin, headers); | 117 control_frame_fields_->fin, headers); |
| 157 break; | 118 break; |
| 158 case PUSH_PROMISE: | 119 case PUSH_PROMISE: |
| 159 DCHECK_LT(SPDY3, protocol_version()); | |
| 160 visitor_->OnPushPromise(control_frame_fields_->stream_id, | 120 visitor_->OnPushPromise(control_frame_fields_->stream_id, |
| 161 control_frame_fields_->promised_stream_id, | 121 control_frame_fields_->promised_stream_id, |
| 162 headers); | 122 headers); |
| 163 break; | 123 break; |
| 164 default: | 124 default: |
| 165 DCHECK(false) << "Unexpect control frame type: " | 125 DCHECK(false) << "Unexpect control frame type: " |
| 166 << control_frame_fields_->type; | 126 << control_frame_fields_->type; |
| 167 break; | 127 break; |
| 168 } | 128 } |
| 169 control_frame_fields_.reset(NULL); | 129 control_frame_fields_.reset(NULL); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 void BufferedSpdyFramer::OnStreamEnd(SpdyStreamId stream_id) { | 166 void BufferedSpdyFramer::OnStreamEnd(SpdyStreamId stream_id) { |
| 207 visitor_->OnStreamEnd(stream_id); | 167 visitor_->OnStreamEnd(stream_id); |
| 208 } | 168 } |
| 209 | 169 |
| 210 void BufferedSpdyFramer::OnStreamPadding(SpdyStreamId stream_id, size_t len) { | 170 void BufferedSpdyFramer::OnStreamPadding(SpdyStreamId stream_id, size_t len) { |
| 211 visitor_->OnStreamPadding(stream_id, len); | 171 visitor_->OnStreamPadding(stream_id, len); |
| 212 } | 172 } |
| 213 | 173 |
| 214 SpdyHeadersHandlerInterface* BufferedSpdyFramer::OnHeaderFrameStart( | 174 SpdyHeadersHandlerInterface* BufferedSpdyFramer::OnHeaderFrameStart( |
| 215 SpdyStreamId stream_id) { | 175 SpdyStreamId stream_id) { |
| 216 coalescer_.reset(new HeaderCoalescer(protocol_version())); | 176 coalescer_.reset(new HeaderCoalescer()); |
| 217 return coalescer_.get(); | 177 return coalescer_.get(); |
| 218 } | 178 } |
| 219 | 179 |
| 220 void BufferedSpdyFramer::OnHeaderFrameEnd(SpdyStreamId stream_id, | 180 void BufferedSpdyFramer::OnHeaderFrameEnd(SpdyStreamId stream_id, |
| 221 bool end_headers) { | 181 bool end_headers) { |
| 222 if (coalescer_->error_seen()) { | 182 if (coalescer_->error_seen()) { |
| 223 visitor_->OnStreamError(stream_id, | 183 visitor_->OnStreamError(stream_id, |
| 224 "Could not parse Spdy Control Frame Header."); | 184 "Could not parse Spdy Control Frame Header."); |
| 225 return; | 185 return; |
| 226 } | 186 } |
| 227 DCHECK(control_frame_fields_.get()); | 187 DCHECK(control_frame_fields_.get()); |
| 228 switch (control_frame_fields_->type) { | 188 switch (control_frame_fields_->type) { |
| 229 case SYN_STREAM: | 189 case SYN_STREAM: |
| 230 visitor_->OnSynStream( | 190 NOTREACHED(); |
| 231 control_frame_fields_->stream_id, | |
| 232 control_frame_fields_->associated_stream_id, | |
| 233 control_frame_fields_->priority, control_frame_fields_->fin, | |
| 234 control_frame_fields_->unidirectional, coalescer_->headers()); | |
| 235 break; | 191 break; |
| 236 case SYN_REPLY: | 192 case SYN_REPLY: |
| 237 visitor_->OnSynReply(control_frame_fields_->stream_id, | 193 NOTREACHED(); |
| 238 control_frame_fields_->fin, coalescer_->headers()); | |
| 239 break; | 194 break; |
| 240 case HEADERS: | 195 case HEADERS: |
| 241 visitor_->OnHeaders(control_frame_fields_->stream_id, | 196 visitor_->OnHeaders(control_frame_fields_->stream_id, |
| 242 control_frame_fields_->has_priority, | 197 control_frame_fields_->has_priority, |
| 243 control_frame_fields_->weight, | 198 control_frame_fields_->weight, |
| 244 control_frame_fields_->parent_stream_id, | 199 control_frame_fields_->parent_stream_id, |
| 245 control_frame_fields_->exclusive, | 200 control_frame_fields_->exclusive, |
| 246 control_frame_fields_->fin, coalescer_->headers()); | 201 control_frame_fields_->fin, coalescer_->headers()); |
| 247 break; | 202 break; |
| 248 case PUSH_PROMISE: | 203 case PUSH_PROMISE: |
| 249 DCHECK_LT(SPDY3, protocol_version()); | |
| 250 visitor_->OnPushPromise(control_frame_fields_->stream_id, | 204 visitor_->OnPushPromise(control_frame_fields_->stream_id, |
| 251 control_frame_fields_->promised_stream_id, | 205 control_frame_fields_->promised_stream_id, |
| 252 coalescer_->headers()); | 206 coalescer_->headers()); |
| 253 break; | 207 break; |
| 254 default: | 208 default: |
| 255 DCHECK(false) << "Unexpect control frame type: " | 209 DCHECK(false) << "Unexpect control frame type: " |
| 256 << control_frame_fields_->type; | 210 << control_frame_fields_->type; |
| 257 break; | 211 break; |
| 258 } | 212 } |
| 259 control_frame_fields_.reset(NULL); | 213 control_frame_fields_.reset(NULL); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } | 264 } |
| 311 | 265 |
| 312 void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id, | 266 void BufferedSpdyFramer::OnWindowUpdate(SpdyStreamId stream_id, |
| 313 int delta_window_size) { | 267 int delta_window_size) { |
| 314 visitor_->OnWindowUpdate(stream_id, delta_window_size); | 268 visitor_->OnWindowUpdate(stream_id, delta_window_size); |
| 315 } | 269 } |
| 316 | 270 |
| 317 void BufferedSpdyFramer::OnPushPromise(SpdyStreamId stream_id, | 271 void BufferedSpdyFramer::OnPushPromise(SpdyStreamId stream_id, |
| 318 SpdyStreamId promised_stream_id, | 272 SpdyStreamId promised_stream_id, |
| 319 bool end) { | 273 bool end) { |
| 320 DCHECK_LT(SPDY3, protocol_version()); | |
| 321 frames_received_++; | 274 frames_received_++; |
| 322 DCHECK(!control_frame_fields_.get()); | 275 DCHECK(!control_frame_fields_.get()); |
| 323 control_frame_fields_.reset(new ControlFrameFields()); | 276 control_frame_fields_.reset(new ControlFrameFields()); |
| 324 control_frame_fields_->type = PUSH_PROMISE; | 277 control_frame_fields_->type = PUSH_PROMISE; |
| 325 control_frame_fields_->stream_id = stream_id; | 278 control_frame_fields_->stream_id = stream_id; |
| 326 control_frame_fields_->promised_stream_id = promised_stream_id; | 279 control_frame_fields_->promised_stream_id = promised_stream_id; |
| 327 | 280 |
| 328 InitHeaderStreaming(stream_id); | 281 InitHeaderStreaming(stream_id); |
| 329 } | 282 } |
| 330 | 283 |
| 331 void BufferedSpdyFramer::OnAltSvc( | 284 void BufferedSpdyFramer::OnAltSvc( |
| 332 SpdyStreamId stream_id, | 285 SpdyStreamId stream_id, |
| 333 base::StringPiece origin, | 286 base::StringPiece origin, |
| 334 const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) { | 287 const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) { |
| 335 visitor_->OnAltSvc(stream_id, origin, altsvc_vector); | 288 visitor_->OnAltSvc(stream_id, origin, altsvc_vector); |
| 336 } | 289 } |
| 337 | 290 |
| 338 void BufferedSpdyFramer::OnContinuation(SpdyStreamId stream_id, bool end) { | 291 void BufferedSpdyFramer::OnContinuation(SpdyStreamId stream_id, bool end) { |
| 339 } | 292 } |
| 340 | 293 |
| 341 bool BufferedSpdyFramer::OnUnknownFrame(SpdyStreamId stream_id, | 294 bool BufferedSpdyFramer::OnUnknownFrame(SpdyStreamId stream_id, |
| 342 int frame_type) { | 295 int frame_type) { |
| 343 return visitor_->OnUnknownFrame(stream_id, frame_type); | 296 return visitor_->OnUnknownFrame(stream_id, frame_type); |
| 344 } | 297 } |
| 345 | 298 |
| 346 SpdyMajorVersion BufferedSpdyFramer::protocol_version() { | |
| 347 return spdy_framer_.protocol_version(); | |
| 348 } | |
| 349 | |
| 350 size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) { | 299 size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) { |
| 351 return spdy_framer_.ProcessInput(data, len); | 300 return spdy_framer_.ProcessInput(data, len); |
| 352 } | 301 } |
| 353 | 302 |
| 354 void BufferedSpdyFramer::Reset() { | 303 void BufferedSpdyFramer::Reset() { |
| 355 spdy_framer_.Reset(); | 304 spdy_framer_.Reset(); |
| 356 } | 305 } |
| 357 | 306 |
| 358 SpdyFramer::SpdyError BufferedSpdyFramer::error_code() const { | 307 SpdyFramer::SpdyError BufferedSpdyFramer::error_code() const { |
| 359 return spdy_framer_.error_code(); | 308 return spdy_framer_.error_code(); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 } | 441 } |
| 493 | 442 |
| 494 void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) { | 443 void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) { |
| 495 header_buffer_.clear(); | 444 header_buffer_.clear(); |
| 496 header_buffer_valid_ = true; | 445 header_buffer_valid_ = true; |
| 497 header_stream_id_ = stream_id; | 446 header_stream_id_ = stream_id; |
| 498 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); | 447 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 499 } | 448 } |
| 500 | 449 |
| 501 } // namespace net | 450 } // namespace net |
| OLD | NEW |