| 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 | 8 |
| 9 namespace net { | 9 namespace net { |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 control_frame_fields_->type = SYN_STREAM; | 68 control_frame_fields_->type = SYN_STREAM; |
| 69 control_frame_fields_->stream_id = stream_id; | 69 control_frame_fields_->stream_id = stream_id; |
| 70 control_frame_fields_->associated_stream_id = associated_stream_id; | 70 control_frame_fields_->associated_stream_id = associated_stream_id; |
| 71 control_frame_fields_->priority = priority; | 71 control_frame_fields_->priority = priority; |
| 72 control_frame_fields_->fin = fin; | 72 control_frame_fields_->fin = fin; |
| 73 control_frame_fields_->unidirectional = unidirectional; | 73 control_frame_fields_->unidirectional = unidirectional; |
| 74 | 74 |
| 75 InitHeaderStreaming(stream_id); | 75 InitHeaderStreaming(stream_id); |
| 76 } | 76 } |
| 77 | 77 |
| 78 void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id, | 78 void BufferedSpdyFramer::OnHeaders(SpdyStreamId stream_id, bool fin, bool end) { |
| 79 bool fin, | |
| 80 bool end) { | |
| 81 frames_received_++; | 79 frames_received_++; |
| 82 DCHECK(!control_frame_fields_.get()); | 80 DCHECK(!control_frame_fields_.get()); |
| 83 control_frame_fields_.reset(new ControlFrameFields()); | 81 control_frame_fields_.reset(new ControlFrameFields()); |
| 84 control_frame_fields_->type = HEADERS; | 82 control_frame_fields_->type = HEADERS; |
| 85 control_frame_fields_->stream_id = stream_id; | 83 control_frame_fields_->stream_id = stream_id; |
| 86 control_frame_fields_->fin = fin; | 84 control_frame_fields_->fin = fin; |
| 87 | 85 |
| 88 InitHeaderStreaming(stream_id); | 86 InitHeaderStreaming(stream_id); |
| 89 } | 87 } |
| 90 | 88 |
| 91 void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id, | 89 void BufferedSpdyFramer::OnSynReply(SpdyStreamId stream_id, bool fin) { |
| 92 bool fin) { | |
| 93 frames_received_++; | 90 frames_received_++; |
| 94 DCHECK(!control_frame_fields_.get()); | 91 DCHECK(!control_frame_fields_.get()); |
| 95 control_frame_fields_.reset(new ControlFrameFields()); | 92 control_frame_fields_.reset(new ControlFrameFields()); |
| 96 control_frame_fields_->type = SYN_REPLY; | 93 control_frame_fields_->type = SYN_REPLY; |
| 97 control_frame_fields_->stream_id = stream_id; | 94 control_frame_fields_->stream_id = stream_id; |
| 98 control_frame_fields_->fin = fin; | 95 control_frame_fields_->fin = fin; |
| 99 | 96 |
| 100 InitHeaderStreaming(stream_id); | 97 InitHeaderStreaming(stream_id); |
| 101 } | 98 } |
| 102 | 99 |
| 103 bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id, | 100 bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id, |
| 104 const char* header_data, | 101 const char* header_data, |
| 105 size_t len) { | 102 size_t len) { |
| 106 CHECK_EQ(header_stream_id_, stream_id); | 103 CHECK_EQ(header_stream_id_, stream_id); |
| 107 | 104 |
| 108 if (len == 0) { | 105 if (len == 0) { |
| 109 // Indicates end-of-header-block. | 106 // Indicates end-of-header-block. |
| 110 CHECK(header_buffer_valid_); | 107 CHECK(header_buffer_valid_); |
| 111 | 108 |
| 112 SpdyHeaderBlock headers; | 109 SpdyHeaderBlock headers; |
| 113 size_t parsed_len = spdy_framer_.ParseHeaderBlockInBuffer( | 110 size_t parsed_len = spdy_framer_.ParseHeaderBlockInBuffer( |
| 114 header_buffer_, header_buffer_used_, &headers); | 111 header_buffer_, header_buffer_used_, &headers); |
| 115 // TODO(rch): this really should be checking parsed_len != len, | 112 // TODO(rch): this really should be checking parsed_len != len, |
| 116 // but a bunch of tests fail. Need to figure out why. | 113 // but a bunch of tests fail. Need to figure out why. |
| 117 if (parsed_len == 0) { | 114 if (parsed_len == 0) { |
| 118 visitor_->OnStreamError( | 115 visitor_->OnStreamError(stream_id, |
| 119 stream_id, "Could not parse Spdy Control Frame Header."); | 116 "Could not parse Spdy Control Frame Header."); |
| 120 return false; | 117 return false; |
| 121 } | 118 } |
| 122 DCHECK(control_frame_fields_.get()); | 119 DCHECK(control_frame_fields_.get()); |
| 123 switch (control_frame_fields_->type) { | 120 switch (control_frame_fields_->type) { |
| 124 case SYN_STREAM: | 121 case SYN_STREAM: |
| 125 visitor_->OnSynStream(control_frame_fields_->stream_id, | 122 visitor_->OnSynStream(control_frame_fields_->stream_id, |
| 126 control_frame_fields_->associated_stream_id, | 123 control_frame_fields_->associated_stream_id, |
| 127 control_frame_fields_->priority, | 124 control_frame_fields_->priority, |
| 128 control_frame_fields_->fin, | 125 control_frame_fields_->fin, |
| 129 control_frame_fields_->unidirectional, | 126 control_frame_fields_->unidirectional, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 144 << control_frame_fields_->type; | 141 << control_frame_fields_->type; |
| 145 break; | 142 break; |
| 146 } | 143 } |
| 147 control_frame_fields_.reset(NULL); | 144 control_frame_fields_.reset(NULL); |
| 148 return true; | 145 return true; |
| 149 } | 146 } |
| 150 | 147 |
| 151 const size_t available = kHeaderBufferSize - header_buffer_used_; | 148 const size_t available = kHeaderBufferSize - header_buffer_used_; |
| 152 if (len > available) { | 149 if (len > available) { |
| 153 header_buffer_valid_ = false; | 150 header_buffer_valid_ = false; |
| 154 visitor_->OnStreamError( | 151 visitor_->OnStreamError(stream_id, |
| 155 stream_id, "Received more data than the allocated size."); | 152 "Received more data than the allocated size."); |
| 156 return false; | 153 return false; |
| 157 } | 154 } |
| 158 memcpy(header_buffer_ + header_buffer_used_, header_data, len); | 155 memcpy(header_buffer_ + header_buffer_used_, header_data, len); |
| 159 header_buffer_used_ += len; | 156 header_buffer_used_ += len; |
| 160 return true; | 157 return true; |
| 161 } | 158 } |
| 162 | 159 |
| 163 void BufferedSpdyFramer::OnDataFrameHeader(SpdyStreamId stream_id, | 160 void BufferedSpdyFramer::OnDataFrameHeader(SpdyStreamId stream_id, |
| 164 size_t length, | 161 size_t length, |
| 165 bool fin) { | 162 bool fin) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 syn_stream.set_priority(priority); | 259 syn_stream.set_priority(priority); |
| 263 syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0); | 260 syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0); |
| 264 syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0); | 261 syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0); |
| 265 // TODO(hkhalil): Avoid copy here. | 262 // TODO(hkhalil): Avoid copy here. |
| 266 syn_stream.set_name_value_block(*headers); | 263 syn_stream.set_name_value_block(*headers); |
| 267 return spdy_framer_.SerializeSynStream(syn_stream); | 264 return spdy_framer_.SerializeSynStream(syn_stream); |
| 268 } | 265 } |
| 269 | 266 |
| 270 // TODO(jgraettinger): Eliminate uses of this method (prefer | 267 // TODO(jgraettinger): Eliminate uses of this method (prefer |
| 271 // SpdySynReplyIR). | 268 // SpdySynReplyIR). |
| 272 SpdyFrame* BufferedSpdyFramer::CreateSynReply( | 269 SpdyFrame* BufferedSpdyFramer::CreateSynReply(SpdyStreamId stream_id, |
| 273 SpdyStreamId stream_id, | 270 SpdyControlFlags flags, |
| 274 SpdyControlFlags flags, | 271 const SpdyHeaderBlock* headers) { |
| 275 const SpdyHeaderBlock* headers) { | |
| 276 SpdySynReplyIR syn_reply(stream_id); | 272 SpdySynReplyIR syn_reply(stream_id); |
| 277 syn_reply.set_fin(flags & CONTROL_FLAG_FIN); | 273 syn_reply.set_fin(flags & CONTROL_FLAG_FIN); |
| 278 // TODO(hkhalil): Avoid copy here. | 274 // TODO(hkhalil): Avoid copy here. |
| 279 syn_reply.set_name_value_block(*headers); | 275 syn_reply.set_name_value_block(*headers); |
| 280 return spdy_framer_.SerializeSynReply(syn_reply); | 276 return spdy_framer_.SerializeSynReply(syn_reply); |
| 281 } | 277 } |
| 282 | 278 |
| 283 // TODO(jgraettinger): Eliminate uses of this method (prefer | 279 // TODO(jgraettinger): Eliminate uses of this method (prefer |
| 284 // SpdyRstStreamIR). | 280 // SpdyRstStreamIR). |
| 285 SpdyFrame* BufferedSpdyFramer::CreateRstStream( | 281 SpdyFrame* BufferedSpdyFramer::CreateRstStream( |
| 286 SpdyStreamId stream_id, | 282 SpdyStreamId stream_id, |
| 287 SpdyRstStreamStatus status) const { | 283 SpdyRstStreamStatus status) const { |
| 288 SpdyRstStreamIR rst_ir(stream_id, status, "RST"); | 284 SpdyRstStreamIR rst_ir(stream_id, status, "RST"); |
| 289 return spdy_framer_.SerializeRstStream(rst_ir); | 285 return spdy_framer_.SerializeRstStream(rst_ir); |
| 290 } | 286 } |
| 291 | 287 |
| 292 // TODO(jgraettinger): Eliminate uses of this method (prefer | 288 // TODO(jgraettinger): Eliminate uses of this method (prefer |
| 293 // SpdySettingsIR). | 289 // SpdySettingsIR). |
| 294 SpdyFrame* BufferedSpdyFramer::CreateSettings( | 290 SpdyFrame* BufferedSpdyFramer::CreateSettings(const SettingsMap& values) const { |
| 295 const SettingsMap& values) const { | |
| 296 SpdySettingsIR settings_ir; | 291 SpdySettingsIR settings_ir; |
| 297 for (SettingsMap::const_iterator it = values.begin(); | 292 for (SettingsMap::const_iterator it = values.begin(); it != values.end(); |
| 298 it != values.end(); | |
| 299 ++it) { | 293 ++it) { |
| 300 settings_ir.AddSetting( | 294 settings_ir.AddSetting( |
| 301 it->first, | 295 it->first, |
| 302 (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0, | 296 (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0, |
| 303 (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, | 297 (it->second.first & SETTINGS_FLAG_PERSISTED) != 0, |
| 304 it->second.second); | 298 it->second.second); |
| 305 } | 299 } |
| 306 return spdy_framer_.SerializeSettings(settings_ir); | 300 return spdy_framer_.SerializeSettings(settings_ir); |
| 307 } | 301 } |
| 308 | 302 |
| 309 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyPingIR). | 303 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyPingIR). |
| 310 SpdyFrame* BufferedSpdyFramer::CreatePingFrame(uint32 unique_id, | 304 SpdyFrame* BufferedSpdyFramer::CreatePingFrame(uint32 unique_id, |
| 311 bool is_ack) const { | 305 bool is_ack) const { |
| 312 SpdyPingIR ping_ir(unique_id); | 306 SpdyPingIR ping_ir(unique_id); |
| 313 ping_ir.set_is_ack(is_ack); | 307 ping_ir.set_is_ack(is_ack); |
| 314 return spdy_framer_.SerializePing(ping_ir); | 308 return spdy_framer_.SerializePing(ping_ir); |
| 315 } | 309 } |
| 316 | 310 |
| 317 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyGoAwayIR). | 311 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyGoAwayIR). |
| 318 SpdyFrame* BufferedSpdyFramer::CreateGoAway( | 312 SpdyFrame* BufferedSpdyFramer::CreateGoAway( |
| 319 SpdyStreamId last_accepted_stream_id, | 313 SpdyStreamId last_accepted_stream_id, |
| 320 SpdyGoAwayStatus status) const { | 314 SpdyGoAwayStatus status) const { |
| 321 SpdyGoAwayIR go_ir(last_accepted_stream_id, status, ""); | 315 SpdyGoAwayIR go_ir(last_accepted_stream_id, status, ""); |
| 322 return spdy_framer_.SerializeGoAway(go_ir); | 316 return spdy_framer_.SerializeGoAway(go_ir); |
| 323 } | 317 } |
| 324 | 318 |
| 325 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyHeadersIR). | 319 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyHeadersIR). |
| 326 SpdyFrame* BufferedSpdyFramer::CreateHeaders( | 320 SpdyFrame* BufferedSpdyFramer::CreateHeaders(SpdyStreamId stream_id, |
| 327 SpdyStreamId stream_id, | 321 SpdyControlFlags flags, |
| 328 SpdyControlFlags flags, | 322 const SpdyHeaderBlock* headers) { |
| 329 const SpdyHeaderBlock* headers) { | |
| 330 SpdyHeadersIR headers_ir(stream_id); | 323 SpdyHeadersIR headers_ir(stream_id); |
| 331 headers_ir.set_fin((flags & CONTROL_FLAG_FIN) != 0); | 324 headers_ir.set_fin((flags & CONTROL_FLAG_FIN) != 0); |
| 332 headers_ir.set_name_value_block(*headers); | 325 headers_ir.set_name_value_block(*headers); |
| 333 return spdy_framer_.SerializeHeaders(headers_ir); | 326 return spdy_framer_.SerializeHeaders(headers_ir); |
| 334 } | 327 } |
| 335 | 328 |
| 336 // TODO(jgraettinger): Eliminate uses of this method (prefer | 329 // TODO(jgraettinger): Eliminate uses of this method (prefer |
| 337 // SpdyWindowUpdateIR). | 330 // SpdyWindowUpdateIR). |
| 338 SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate( | 331 SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate( |
| 339 SpdyStreamId stream_id, | 332 SpdyStreamId stream_id, |
| 340 uint32 delta_window_size) const { | 333 uint32 delta_window_size) const { |
| 341 SpdyWindowUpdateIR update_ir(stream_id, delta_window_size); | 334 SpdyWindowUpdateIR update_ir(stream_id, delta_window_size); |
| 342 return spdy_framer_.SerializeWindowUpdate(update_ir); | 335 return spdy_framer_.SerializeWindowUpdate(update_ir); |
| 343 } | 336 } |
| 344 | 337 |
| 345 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyDataIR). | 338 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyDataIR). |
| 346 SpdyFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id, | 339 SpdyFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id, |
| 347 const char* data, | 340 const char* data, |
| 348 uint32 len, | 341 uint32 len, |
| 349 SpdyDataFlags flags) { | 342 SpdyDataFlags flags) { |
| 350 SpdyDataIR data_ir(stream_id, | 343 SpdyDataIR data_ir(stream_id, base::StringPiece(data, len)); |
| 351 base::StringPiece(data, len)); | |
| 352 data_ir.set_fin((flags & DATA_FLAG_FIN) != 0); | 344 data_ir.set_fin((flags & DATA_FLAG_FIN) != 0); |
| 353 return spdy_framer_.SerializeData(data_ir); | 345 return spdy_framer_.SerializeData(data_ir); |
| 354 } | 346 } |
| 355 | 347 |
| 356 SpdyPriority BufferedSpdyFramer::GetHighestPriority() const { | 348 SpdyPriority BufferedSpdyFramer::GetHighestPriority() const { |
| 357 return spdy_framer_.GetHighestPriority(); | 349 return spdy_framer_.GetHighestPriority(); |
| 358 } | 350 } |
| 359 | 351 |
| 360 void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) { | 352 void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) { |
| 361 memset(header_buffer_, 0, kHeaderBufferSize); | 353 memset(header_buffer_, 0, kHeaderBufferSize); |
| 362 header_buffer_used_ = 0; | 354 header_buffer_used_ = 0; |
| 363 header_buffer_valid_ = true; | 355 header_buffer_valid_ = true; |
| 364 header_stream_id_ = stream_id; | 356 header_stream_id_ = stream_id; |
| 365 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); | 357 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 366 } | 358 } |
| 367 | 359 |
| 368 } // namespace net | 360 } // namespace net |
| OLD | NEW |