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 |