Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 8036016: Updated spdy_framer.cc with the latest code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't
6 // constantly adding and subtracting header sizes; this is ugly and error- 6 // constantly adding and subtracting header sizes; this is ugly and error-
7 // prone. 7 // prone.
8 8
9 #include "net/spdy/spdy_framer.h" 9 #include "net/spdy/spdy_framer.h"
10 10
(...skipping 11 matching lines...) Expand all
22 22
23 namespace { 23 namespace {
24 24
25 // The following compression setting are based on Brian Olson's analysis. See 25 // The following compression setting are based on Brian Olson's analysis. See
26 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2 26 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2
27 // for more details. 27 // for more details.
28 const int kCompressorLevel = 9; 28 const int kCompressorLevel = 9;
29 const int kCompressorWindowSizeInBits = 11; 29 const int kCompressorWindowSizeInBits = 11;
30 const int kCompressorMemLevel = 1; 30 const int kCompressorMemLevel = 1;
31 31
32 // Adler ID for the SPDY header compressor dictionary.
32 uLong dictionary_id = 0; 33 uLong dictionary_id = 0;
33 34
34 } // namespace 35 } // namespace
35 36
36 namespace spdy { 37 namespace spdy {
37 38
38 // This is just a hacked dictionary to use for shrinking HTTP-like headers. 39 // This is just a hacked dictionary to use for shrinking HTTP-like headers.
39 // TODO(mbelshe): Use a scientific methodology for computing the dictionary. 40 // TODO(mbelshe): Use a scientific methodology for computing the dictionary.
40 const char SpdyFramer::kDictionary[] = 41 const char SpdyFramer::kDictionary[] =
41 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" 42 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
(...skipping 17 matching lines...) Expand all
59 60
60 // The initial size of the control frame buffer; this is used internally 61 // The initial size of the control frame buffer; this is used internally
61 // as we parse through control frames. (It is exposed here for unit test 62 // as we parse through control frames. (It is exposed here for unit test
62 // purposes.) 63 // purposes.)
63 size_t SpdyFramer::kControlFrameBufferInitialSize = 8 * 1024; 64 size_t SpdyFramer::kControlFrameBufferInitialSize = 8 * 1024;
64 65
65 // The maximum size of the control frame buffer that we support. 66 // The maximum size of the control frame buffer that we support.
66 // TODO(mbelshe): We should make this stream-based so there are no limits. 67 // TODO(mbelshe): We should make this stream-based so there are no limits.
67 size_t SpdyFramer::kControlFrameBufferMaxSize = 16 * 1024; 68 size_t SpdyFramer::kControlFrameBufferMaxSize = 16 * 1024;
68 69
70 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
71 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
72
69 #ifdef DEBUG_SPDY_STATE_CHANGES 73 #ifdef DEBUG_SPDY_STATE_CHANGES
70 #define CHANGE_STATE(newstate) \ 74 #define CHANGE_STATE(newstate) \
71 { \ 75 { \
72 do { \ 76 do { \
73 LOG(INFO) << "Changing state from: " \ 77 LOG(INFO) << "Changing state from: " \
74 << StateToString(state_) \ 78 << StateToString(state_) \
75 << " to " << StateToString(newstate) << "\n"; \ 79 << " to " << StateToString(newstate) << "\n"; \
76 state_ = newstate; \ 80 state_ = newstate; \
77 } while (false); \ 81 } while (false); \
78 } 82 }
79 #else 83 #else
80 #define CHANGE_STATE(newstate) (state_ = newstate) 84 #define CHANGE_STATE(newstate) (state_ = newstate)
81 #endif 85 #endif
82 86
87 int DecompressHeaderBlockInZStream(z_stream* decompressor) {
88 int rv = inflate(decompressor, Z_SYNC_FLUSH);
89 if (rv == Z_NEED_DICT) {
90 // Need to try again with the right dictionary.
91 if (decompressor->adler == dictionary_id) {
92 rv = inflateSetDictionary(decompressor,
93 (const Bytef*)SpdyFramer::kDictionary,
94 SpdyFramer::kDictionarySize);
95 if (rv == Z_OK)
96 rv = inflate(decompressor, Z_SYNC_FLUSH);
97 }
98 }
99 return rv;
100 }
101
102 // Retrieve serialized length of SpdyHeaderBlock.
103 size_t GetSerializedLength(const SpdyHeaderBlock* headers) {
104 size_t total_length = SpdyControlFrame::kNumNameValuePairsSize;
105 SpdyHeaderBlock::const_iterator it;
106 for (it = headers->begin(); it != headers->end(); ++it) {
107 // We add space for the length of the name and the length of the value as
108 // well as the length of the name and the length of the value.
109 total_length += SpdyControlFrame::kLengthOfNameSize +
110 it->first.size() +
111 SpdyControlFrame::kLengthOfValueSize +
112 it->second.size();
113 }
114 return total_length;
115 }
116
117 // Serializes a SpdyHeaderBlock.
118 void WriteHeaderBlock(SpdyFrameBuilder* frame, const SpdyHeaderBlock* headers) {
119 frame->WriteUInt16(headers->size()); // Number of headers.
120 SpdyHeaderBlock::const_iterator it;
121 for (it = headers->begin(); it != headers->end(); ++it) {
122 bool wrote_header;
123 wrote_header = frame->WriteString(it->first);
124 wrote_header &= frame->WriteString(it->second);
125 DCHECK(wrote_header);
126 }
127 }
128
129 // Creates a FlagsAndLength.
130 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) {
131 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
132 FlagsAndLength flags_length;
133 flags_length.length_ = htonl(static_cast<uint32>(length));
134 DCHECK_EQ(0, flags & ~kControlFlagsMask);
135 flags_length.flags_[0] = flags;
136 return flags_length;
137 }
138
83 SpdyFramer::SpdyFramer() 139 SpdyFramer::SpdyFramer()
84 : state_(SPDY_RESET), 140 : state_(SPDY_RESET),
85 error_code_(SPDY_NO_ERROR), 141 error_code_(SPDY_NO_ERROR),
86 remaining_payload_(0), 142 remaining_data_(0),
87 remaining_control_payload_(0), 143 remaining_control_payload_(0),
144 remaining_control_header_(0),
88 current_frame_buffer_(NULL), 145 current_frame_buffer_(NULL),
89 current_frame_len_(0), 146 current_frame_len_(0),
90 current_frame_capacity_(0), 147 current_frame_capacity_(0),
148 validate_control_frame_sizes_(true),
91 enable_compression_(compression_default_), 149 enable_compression_(compression_default_),
92 visitor_(NULL) { 150 visitor_(NULL) {
93 } 151 }
94 152
95 SpdyFramer::~SpdyFramer() { 153 SpdyFramer::~SpdyFramer() {
96 if (header_compressor_.get()) { 154 if (header_compressor_.get()) {
97 deflateEnd(header_compressor_.get()); 155 deflateEnd(header_compressor_.get());
98 } 156 }
99 if (header_decompressor_.get()) { 157 if (header_decompressor_.get()) {
100 inflateEnd(header_decompressor_.get()); 158 inflateEnd(header_decompressor_.get());
101 } 159 }
102 CleanupStreamCompressorsAndDecompressors(); 160 CleanupStreamCompressorsAndDecompressors();
103 delete [] current_frame_buffer_; 161 delete [] current_frame_buffer_;
104 } 162 }
105 163
164 const char* SpdyFramer::StatusCodeToString(int status_code) {
165 switch (status_code) {
166 case INVALID:
167 return "INVALID";
168 case PROTOCOL_ERROR:
169 return "PROTOCOL_ERROR";
170 case INVALID_STREAM:
171 return "INVALID_STREAM";
172 case REFUSED_STREAM:
173 return "REFUSED_STREAM";
174 case UNSUPPORTED_VERSION:
175 return "UNSUPPORTED_VERSION";
176 case CANCEL:
177 return "CANCEL";
178 case INTERNAL_ERROR:
179 return "INTERNAL_ERROR";
180 case FLOW_CONTROL_ERROR:
181 return "FLOW_CONTROL_ERROR";
182 }
183 return "UNKNOWN_STATUS";
184 }
185
186 const char* SpdyFramer::ControlTypeToString(SpdyControlType type) {
187 switch (type) {
188 case SYN_STREAM:
189 return "SYN_STREAM";
190 case SYN_REPLY:
191 return "SYN_REPLY";
192 case RST_STREAM:
193 return "RST_STREAM";
194 case SETTINGS:
195 return "SETTINGS";
196 case NOOP:
197 return "NOOP";
198 case PING:
199 return "PING";
200 case GOAWAY:
201 return "GOAWAY";
202 case HEADERS:
203 return "HEADERS";
204 case WINDOW_UPDATE:
205 return "WINDOW_UPDATE";
206 case NUM_CONTROL_FRAME_TYPES:
207 break;
208 }
209 return "UNKNOWN_CONTROL_TYPE";
210 }
211
106 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { 212 size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
107 DCHECK(visitor_); 213 DCHECK(visitor_);
108 DCHECK(data); 214 DCHECK(data);
109 215
110 size_t original_len = len; 216 size_t original_len = len;
111 while (len != 0) { 217 while (len != 0) {
112 switch (state_) { 218 switch (state_) {
113 case SPDY_ERROR: 219 case SPDY_ERROR:
114 case SPDY_DONE: 220 case SPDY_DONE:
115 goto bottom; 221 goto bottom;
116 222
117 case SPDY_AUTO_RESET: 223 case SPDY_AUTO_RESET:
118 case SPDY_RESET: 224 case SPDY_RESET:
119 Reset(); 225 Reset();
120 CHANGE_STATE(SPDY_READING_COMMON_HEADER); 226 CHANGE_STATE(SPDY_READING_COMMON_HEADER);
121 continue; 227 continue;
122 228
123 case SPDY_READING_COMMON_HEADER: { 229 case SPDY_READING_COMMON_HEADER: {
124 size_t bytes_read = ProcessCommonHeader(data, len); 230 size_t bytes_read = ProcessCommonHeader(data, len);
125 len -= bytes_read; 231 len -= bytes_read;
126 data += bytes_read; 232 data += bytes_read;
127 continue; 233 continue;
128 } 234 }
129 235
130 // Arguably, this case is not necessary, as no bytes are consumed here. 236 // Arguably, this case is not necessary, as no bytes are consumed here.
131 // I felt it was a nice partitioning, however (which probably indicates 237 // I felt it was a nice partitioning, however (which probably indicates
132 // that it should be refactored into its own function!) 238 // that it should be refactored into its own function!)
239 // TODO(hkhalil): Remove -- while loop above prevents proper handling of
240 // zero-length control frames.
133 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: 241 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER:
134 ProcessControlFrameHeader(); 242 ProcessControlFrameHeader();
135 continue; 243 continue;
136 244
245 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
246 // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY,
247 // HEADERS) take a different path through the state machine - they
248 // will go:
249 // 1. SPDY_INTERPRET_CONTROL_FRAME_COMMON HEADER
250 // 2. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
251 // 3. SPDY_CONTROL_FRAME_HEADER_BLOCK
252 //
253 // All other control frames will use the alternate route:
254 // 1. SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER
255 // 2. SPDY_CONTROL_FRAME_PAYLOAD
256 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
257 len -= bytes_read;
258 data += bytes_read;
259 continue;
260 }
261
262 case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
263 int bytes_read = ProcessControlFrameHeaderBlock(data, len);
264 len -= bytes_read;
265 data += bytes_read;
266 continue;
267 }
268
137 case SPDY_CONTROL_FRAME_PAYLOAD: { 269 case SPDY_CONTROL_FRAME_PAYLOAD: {
138 size_t bytes_read = ProcessControlFramePayload(data, len); 270 size_t bytes_read = ProcessControlFramePayload(data, len);
139 len -= bytes_read; 271 len -= bytes_read;
140 data += bytes_read; 272 data += bytes_read;
141 } 273 }
142 // intentional fallthrough 274 // intentional fallthrough
143 case SPDY_IGNORE_REMAINING_PAYLOAD: 275 case SPDY_IGNORE_REMAINING_PAYLOAD:
144 // control frame has too-large payload 276 // control frame has too-large payload
145 // intentional fallthrough 277 // intentional fallthrough
146 case SPDY_FORWARD_STREAM_FRAME: { 278 case SPDY_FORWARD_STREAM_FRAME: {
147 size_t bytes_read = ProcessDataFramePayload(data, len); 279 size_t bytes_read = ProcessDataFramePayload(data, len);
148 len -= bytes_read; 280 len -= bytes_read;
149 data += bytes_read; 281 data += bytes_read;
150 continue; 282 continue;
151 } 283 }
152 default: 284 default:
153 break; 285 break;
154 } 286 }
155 } 287 }
156 bottom: 288 bottom:
157 return original_len - len; 289 return original_len - len;
158 } 290 }
159 291
160 void SpdyFramer::Reset() { 292 void SpdyFramer::Reset() {
161 state_ = SPDY_RESET; 293 state_ = SPDY_RESET;
162 error_code_ = SPDY_NO_ERROR; 294 error_code_ = SPDY_NO_ERROR;
163 remaining_payload_ = 0; 295 remaining_data_ = 0;
164 remaining_control_payload_ = 0; 296 remaining_control_payload_ = 0;
297 remaining_control_header_ = 0;
165 current_frame_len_ = 0; 298 current_frame_len_ = 0;
166 if (current_frame_capacity_ != kControlFrameBufferInitialSize) { 299 if (current_frame_capacity_ != kControlFrameBufferInitialSize) {
167 delete [] current_frame_buffer_; 300 delete [] current_frame_buffer_;
168 current_frame_buffer_ = 0; 301 current_frame_buffer_ = 0;
169 current_frame_capacity_ = 0; 302 current_frame_capacity_ = 0;
170 ExpandControlFrameBuffer(kControlFrameBufferInitialSize); 303 ExpandControlFrameBuffer(kControlFrameBufferInitialSize);
171 } 304 }
172 } 305 }
173 306
174 bool SpdyFramer::ParseHeaderBlock(const SpdyFrame* frame, 307 bool SpdyFramer::ParseHeaderBlock(const SpdyFrame* frame,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } else { 362 } else {
230 return false; 363 return false;
231 } 364 }
232 } 365 }
233 return index == num_headers && 366 return index == num_headers &&
234 iter == header_data + header_length; 367 iter == header_data + header_length;
235 } 368 }
236 return false; 369 return false;
237 } 370 }
238 371
372 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
373 size_t max_bytes) {
374 size_t bytes_to_read = std::min(*len, max_bytes);
375 DCHECK_GE(current_frame_capacity_, current_frame_len_ + bytes_to_read);
376 memcpy(&current_frame_buffer_[current_frame_len_], *data, bytes_to_read);
377 current_frame_len_ += bytes_to_read;
378 *data += bytes_to_read;
379 *len -= bytes_to_read;
380 return bytes_to_read;
381 }
382
383 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
384 size_t len) {
385 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
386 DCHECK_GT(remaining_control_header_, 0u);
387 size_t original_len = len;
388
389 if (remaining_control_header_) {
390 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
391 remaining_control_header_);
392 remaining_control_header_ -= bytes_read;
393 if (remaining_control_header_ == 0) {
394 SpdyControlFrame control_frame(current_frame_buffer_, false);
395 DCHECK(control_frame.type() == SYN_STREAM ||
396 control_frame.type() == SYN_REPLY ||
397 control_frame.type() == HEADERS);
398 visitor_->OnControl(&control_frame);
399
400 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
401 }
402 }
403 return original_len - len;
404 }
405
406 // Does not buffer the control payload. Instead, either passes directly to the
407 // visitor or decompresses and then passes directly to the visitor, via
408 // IncrementallyDeliverControlFrameHeaderData() or
409 // IncrementallyDecompressControlFrameHeaderData() respectively.
410 size_t SpdyFramer::NewProcessControlFrameHeaderBlock(const char* data,
411 size_t data_len) {
412 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
413 SpdyControlFrame control_frame(current_frame_buffer_, false);
414 bool processed_successfully = true;
415 DCHECK(control_frame.type() == SYN_STREAM ||
416 control_frame.type() == SYN_REPLY ||
417 control_frame.type() == HEADERS);
418 size_t process_bytes = std::min(data_len, remaining_control_payload_);
419 DCHECK_GT(process_bytes, 0u);
420
421 if (enable_compression_) {
422 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
423 &control_frame, data, process_bytes);
424 } else {
425 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
426 &control_frame, data, process_bytes);
427 }
428 remaining_control_payload_ -= process_bytes;
429
430 // Handle the case that there is no futher data in this frame.
431 if (remaining_control_payload_ == 0 && processed_successfully) {
432 // The complete header block has been delivered. We send a zero-length
433 // OnControlFrameHeaderData() to indicate this.
434 visitor_->OnControlFrameHeaderData(
435 GetControlFrameStreamId(&control_frame), NULL, 0);
436
437 // If this is a FIN, tell the caller.
438 if (control_frame.flags() & CONTROL_FLAG_FIN) {
439 visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame),
440 NULL, 0);
441 }
442
443 CHANGE_STATE(SPDY_RESET);
444 }
445
446 // Handle error.
447 if (!processed_successfully) {
448 return data_len;
449 }
450
451 // Return amount processed.
452 return process_bytes;
453 }
454
455 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
456 size_t data_len) {
457 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
458 size_t original_data_len = data_len;
459 SpdyControlFrame control_frame(current_frame_buffer_, false);
460 bool read_successfully = true;
461 DCHECK(control_frame.type() == SYN_STREAM ||
462 control_frame.type() == SYN_REPLY ||
463 control_frame.type() == HEADERS);
464
465 if (enable_compression_) {
466 // Note that the header block is held in the frame's payload, and is not
467 // part of the frame's headers.
468 if (remaining_control_payload_ > 0) {
469 size_t bytes_read = UpdateCurrentFrameBuffer(
470 &data,
471 &data_len,
472 remaining_control_payload_);
473 remaining_control_payload_ -= bytes_read;
474 if (remaining_control_payload_ == 0) {
475 read_successfully = IncrementallyDecompressControlFrameHeaderData(
476 &control_frame);
477 }
478 }
479 } else {
480 size_t bytes_to_send = std::min(data_len, remaining_control_payload_);
481 DCHECK_GT(bytes_to_send, 0u);
482 read_successfully = IncrementallyDeliverControlFrameHeaderData(
483 &control_frame, data, bytes_to_send);
484 data_len -= bytes_to_send;
485 remaining_control_payload_ -= bytes_to_send;
486 }
487 if (remaining_control_payload_ == 0 && read_successfully) {
488 // The complete header block has been delivered.
489 visitor_->OnControlFrameHeaderData(GetControlFrameStreamId(&control_frame),
490 NULL, 0);
491
492 // If this is a FIN, tell the caller.
493 if (control_frame.flags() & CONTROL_FLAG_FIN) {
494 visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame),
495 NULL, 0);
496 }
497
498 CHANGE_STATE(SPDY_RESET);
499 }
500 if (!read_successfully) {
501 return original_data_len;
502 }
503 return original_data_len - data_len;
504 }
505
506 /* static */
507 bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
508 size_t header_length,
509 SpdyHeaderBlock* block) {
510 SpdyFrameBuilder builder(header_data, header_length);
511 void* iter = NULL;
512 uint16 num_headers;
513 if (builder.ReadUInt16(&iter, &num_headers)) {
514 for (int index = 0; index < num_headers; ++index) {
515 std::string name;
516 std::string value;
517 if (!builder.ReadString(&iter, &name))
518 return false;
519 if (!builder.ReadString(&iter, &value))
520 return false;
521 if (block->find(name) == block->end()) {
522 (*block)[name] = value;
523 } else {
524 return false;
525 }
526 }
527 return true;
528 }
529 return false;
530 }
531
239 SpdySynStreamControlFrame* SpdyFramer::CreateSynStream( 532 SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
240 SpdyStreamId stream_id, SpdyStreamId associated_stream_id, int priority, 533 SpdyStreamId stream_id, SpdyStreamId associated_stream_id, int priority,
241 SpdyControlFlags flags, bool compressed, SpdyHeaderBlock* headers) { 534 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) {
242 SpdyFrameBuilder frame; 535 SpdyFrameBuilder frame;
243 536
244 DCHECK_GT(stream_id, static_cast<SpdyStreamId>(0)); 537 DCHECK_GT(stream_id, static_cast<SpdyStreamId>(0));
245 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 538 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
246 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); 539 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask);
247 540
248 frame.WriteUInt16(kControlFlagMask | spdy_version_); 541 frame.WriteUInt16(kControlFlagMask | spdy_version_);
249 frame.WriteUInt16(SYN_STREAM); 542 frame.WriteUInt16(SYN_STREAM);
250 frame.WriteUInt32(0); // Placeholder for the length and flags 543 frame.WriteUInt32(0); // Placeholder for the length and flags
251 frame.WriteUInt32(stream_id); 544 frame.WriteUInt32(stream_id);
252 frame.WriteUInt32(associated_stream_id); 545 frame.WriteUInt32(associated_stream_id);
253 frame.WriteUInt16(ntohs(priority) << 6); // Priority. 546 frame.WriteUInt16(ntohs(priority) << 6); // Priority.
254 547
255 frame.WriteUInt16(headers->size()); // Number of headers. 548 frame.WriteUInt16(headers->size()); // Number of headers.
256 SpdyHeaderBlock::iterator it; 549 SpdyHeaderBlock::const_iterator it;
257 for (it = headers->begin(); it != headers->end(); ++it) { 550 for (it = headers->begin(); it != headers->end(); ++it) {
258 bool wrote_header; 551 bool wrote_header;
259 wrote_header = frame.WriteString(it->first); 552 wrote_header = frame.WriteString(it->first);
260 wrote_header &= frame.WriteString(it->second); 553 wrote_header &= frame.WriteString(it->second);
261 DCHECK(wrote_header); 554 DCHECK(wrote_header);
262 } 555 }
263 556
264 // Write the length and flags. 557 // Write the length and flags.
265 size_t length = frame.length() - SpdyFrame::size(); 558 size_t length = frame.length() - SpdyFrame::size();
266 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 559 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
267 FlagsAndLength flags_length; 560 FlagsAndLength flags_length;
268 flags_length.length_ = htonl(static_cast<uint32>(length)); 561 flags_length.length_ = htonl(static_cast<uint32>(length));
269 DCHECK_EQ(0, flags & ~kControlFlagsMask); 562 DCHECK_EQ(0, flags & ~kControlFlagsMask);
270 flags_length.flags_[0] = flags; 563 flags_length.flags_[0] = flags;
271 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length)); 564 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length));
272 565
273 scoped_ptr<SpdyFrame> syn_frame(frame.take()); 566 scoped_ptr<SpdySynStreamControlFrame> syn_frame(
567 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
274 if (compressed) { 568 if (compressed) {
275 return reinterpret_cast<SpdySynStreamControlFrame*>( 569 return reinterpret_cast<SpdySynStreamControlFrame*>(
276 CompressFrame(*syn_frame.get())); 570 CompressControlFrame(*syn_frame.get()));
277 } 571 }
278 return reinterpret_cast<SpdySynStreamControlFrame*>(syn_frame.release()); 572 return syn_frame.release();
279 } 573 }
280 574
281 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(SpdyStreamId stream_id, 575 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(SpdyStreamId stream_id,
282 SpdyControlFlags flags, bool compressed, SpdyHeaderBlock* headers) { 576 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) {
283 DCHECK_GT(stream_id, 0u); 577 DCHECK_GT(stream_id, 0u);
284 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 578 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
285 579
286 SpdyFrameBuilder frame; 580 SpdyFrameBuilder frame;
287 581
288 frame.WriteUInt16(kControlFlagMask | spdy_version_); 582 frame.WriteUInt16(kControlFlagMask | spdy_version_);
289 frame.WriteUInt16(SYN_REPLY); 583 frame.WriteUInt16(SYN_REPLY);
290 frame.WriteUInt32(0); // Placeholder for the length and flags. 584 frame.WriteUInt32(0); // Placeholder for the length and flags.
291 frame.WriteUInt32(stream_id); 585 frame.WriteUInt32(stream_id);
292 frame.WriteUInt16(0); // Unused 586 frame.WriteUInt16(0); // Unused
293 587
294 frame.WriteUInt16(headers->size()); // Number of headers. 588 frame.WriteUInt16(headers->size()); // Number of headers.
295 SpdyHeaderBlock::iterator it; 589 SpdyHeaderBlock::const_iterator it;
296 for (it = headers->begin(); it != headers->end(); ++it) { 590 for (it = headers->begin(); it != headers->end(); ++it) {
297 bool wrote_header; 591 bool wrote_header;
298 wrote_header = frame.WriteString(it->first); 592 wrote_header = frame.WriteString(it->first);
299 wrote_header &= frame.WriteString(it->second); 593 wrote_header &= frame.WriteString(it->second);
300 DCHECK(wrote_header); 594 DCHECK(wrote_header);
301 } 595 }
302 596
303 // Write the length and flags. 597 // Write the length and flags.
304 size_t length = frame.length() - SpdyFrame::size(); 598 size_t length = frame.length() - SpdyFrame::size();
305 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 599 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
306 FlagsAndLength flags_length; 600 FlagsAndLength flags_length;
307 flags_length.length_ = htonl(static_cast<uint32>(length)); 601 flags_length.length_ = htonl(static_cast<uint32>(length));
308 DCHECK_EQ(0, flags & ~kControlFlagsMask); 602 DCHECK_EQ(0, flags & ~kControlFlagsMask);
309 flags_length.flags_[0] = flags; 603 flags_length.flags_[0] = flags;
310 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length)); 604 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length));
311 605
312 scoped_ptr<SpdyFrame> reply_frame(frame.take()); 606 scoped_ptr<SpdySynReplyControlFrame> reply_frame(
607 reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
313 if (compressed) { 608 if (compressed) {
314 return reinterpret_cast<SpdySynReplyControlFrame*>( 609 return reinterpret_cast<SpdySynReplyControlFrame*>(
315 CompressFrame(*reply_frame.get())); 610 CompressControlFrame(*reply_frame.get()));
316 } 611 }
317 return reinterpret_cast<SpdySynReplyControlFrame*>(reply_frame.release()); 612 return reply_frame.release();
318 } 613 }
319 614
320 /* static */ 615 /* static */
321 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(SpdyStreamId stream_id, 616 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(SpdyStreamId stream_id,
322 SpdyStatusCodes status) { 617 SpdyStatusCodes status) {
323 DCHECK_GT(stream_id, 0u); 618 DCHECK_GT(stream_id, 0u);
324 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 619 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
325 DCHECK_NE(status, INVALID); 620 DCHECK_NE(status, INVALID);
326 DCHECK_LT(status, NUM_STATUS_CODES); 621 DCHECK_LT(status, NUM_STATUS_CODES);
327 622
(...skipping 19 matching lines...) Expand all
347 SpdySettings::const_iterator it = values.begin(); 642 SpdySettings::const_iterator it = values.begin();
348 while (it != values.end()) { 643 while (it != values.end()) {
349 frame.WriteUInt32(it->first.id_); 644 frame.WriteUInt32(it->first.id_);
350 frame.WriteUInt32(it->second); 645 frame.WriteUInt32(it->second);
351 ++it; 646 ++it;
352 } 647 }
353 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); 648 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take());
354 } 649 }
355 650
356 /* static */ 651 /* static */
357 SpdyControlFrame* SpdyFramer::CreateNopFrame() { 652 SpdyNoOpControlFrame* SpdyFramer::CreateNopFrame() {
358 SpdyFrameBuilder frame; 653 SpdyFrameBuilder frame;
359 frame.WriteUInt16(kControlFlagMask | spdy_version_); 654 frame.WriteUInt16(kControlFlagMask | spdy_version_);
360 frame.WriteUInt16(NOOP); 655 frame.WriteUInt16(NOOP);
361 frame.WriteUInt32(0); 656 frame.WriteUInt32(0);
362 return reinterpret_cast<SpdyControlFrame*>(frame.take()); 657 return reinterpret_cast<SpdyNoOpControlFrame*>(frame.take());
658 }
659
660 /* static */
661 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) {
662 SpdyFrameBuilder frame;
663 frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion);
664 frame.WriteUInt16(PING);
665 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::size();
666 frame.WriteUInt32(ping_size);
667 frame.WriteUInt32(unique_id);
668 return reinterpret_cast<SpdyPingControlFrame*>(frame.take());
363 } 669 }
364 670
365 /* static */ 671 /* static */
366 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( 672 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway(
367 SpdyStreamId last_accepted_stream_id) { 673 SpdyStreamId last_accepted_stream_id) {
368 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); 674 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask);
369 675
370 SpdyFrameBuilder frame; 676 SpdyFrameBuilder frame;
371 frame.WriteUInt16(kControlFlagMask | spdy_version_); 677 frame.WriteUInt16(kControlFlagMask | spdy_version_);
372 frame.WriteUInt16(GOAWAY); 678 frame.WriteUInt16(GOAWAY);
373 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::size(); 679 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::size();
374 frame.WriteUInt32(go_away_size); 680 frame.WriteUInt32(go_away_size);
375 frame.WriteUInt32(last_accepted_stream_id); 681 frame.WriteUInt32(last_accepted_stream_id);
376 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); 682 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take());
377 } 683 }
378 684
379 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(SpdyStreamId stream_id, 685 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(SpdyStreamId stream_id,
380 SpdyControlFlags flags, bool compressed, SpdyHeaderBlock* headers) { 686 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) {
381 // Basically the same as CreateSynReply(). 687 // Basically the same as CreateSynReply().
382 DCHECK_GT(stream_id, 0u); 688 DCHECK_GT(stream_id, 0u);
383 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 689 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
384 690
385 SpdyFrameBuilder frame; 691 SpdyFrameBuilder frame;
386 frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion); 692 frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion);
387 frame.WriteUInt16(HEADERS); 693 frame.WriteUInt16(HEADERS);
388 frame.WriteUInt32(0); // Placeholder for the length and flags. 694 frame.WriteUInt32(0); // Placeholder for the length and flags.
389 frame.WriteUInt32(stream_id); 695 frame.WriteUInt32(stream_id);
390 frame.WriteUInt16(0); // Unused 696 frame.WriteUInt16(0); // Unused
391 697
392 frame.WriteUInt16(headers->size()); // Number of headers. 698 frame.WriteUInt16(headers->size()); // Number of headers.
393 SpdyHeaderBlock::iterator it; 699 SpdyHeaderBlock::const_iterator it;
394 for (it = headers->begin(); it != headers->end(); ++it) { 700 for (it = headers->begin(); it != headers->end(); ++it) {
395 bool wrote_header; 701 bool wrote_header;
396 wrote_header = frame.WriteString(it->first); 702 wrote_header = frame.WriteString(it->first);
397 wrote_header &= frame.WriteString(it->second); 703 wrote_header &= frame.WriteString(it->second);
398 DCHECK(wrote_header); 704 DCHECK(wrote_header);
399 } 705 }
400 706
401 // Write the length and flags. 707 // Write the length and flags.
402 size_t length = frame.length() - SpdyFrame::size(); 708 size_t length = frame.length() - SpdyFrame::size();
403 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 709 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
404 FlagsAndLength flags_length; 710 FlagsAndLength flags_length;
405 flags_length.length_ = htonl(static_cast<uint32>(length)); 711 flags_length.length_ = htonl(static_cast<uint32>(length));
406 DCHECK_EQ(0, flags & ~kControlFlagsMask); 712 DCHECK_EQ(0, flags & ~kControlFlagsMask);
407 flags_length.flags_[0] = flags; 713 flags_length.flags_[0] = flags;
408 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length)); 714 frame.WriteBytesToOffset(4, &flags_length, sizeof(flags_length));
409 715
410 scoped_ptr<SpdyFrame> headers_frame(frame.take()); 716 scoped_ptr<SpdyHeadersControlFrame> headers_frame(
717 reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
411 if (compressed) { 718 if (compressed) {
412 return reinterpret_cast<SpdyHeadersControlFrame*>( 719 return reinterpret_cast<SpdyHeadersControlFrame*>(
413 CompressFrame(*headers_frame.get())); 720 CompressControlFrame(*headers_frame.get()));
414 } 721 }
415 return reinterpret_cast<SpdyHeadersControlFrame*>(headers_frame.release()); 722 return headers_frame.release();
416 } 723 }
417 724
418 /* static */ 725 /* static */
419 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( 726 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate(
420 SpdyStreamId stream_id, 727 SpdyStreamId stream_id,
421 uint32 delta_window_size) { 728 uint32 delta_window_size) {
422 DCHECK_GT(stream_id, 0u); 729 DCHECK_GT(stream_id, 0u);
423 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 730 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
424 DCHECK_GT(delta_window_size, 0u); 731 DCHECK_GT(delta_window_size, 0u);
425 DCHECK_LE(delta_window_size, spdy::kSpdyStreamMaximumWindowSize); 732 DCHECK_LE(delta_window_size, spdy::kSpdyStreamMaximumWindowSize);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 FlagsAndLength flags_length; 775 FlagsAndLength flags_length;
469 flags_length.length_ = htonl(len); 776 flags_length.length_ = htonl(len);
470 DCHECK_EQ(0, flags & ~kDataFlagsMask); 777 DCHECK_EQ(0, flags & ~kDataFlagsMask);
471 flags_length.flags_[0] = flags; 778 flags_length.flags_[0] = flags;
472 frame.WriteBytes(&flags_length, sizeof(flags_length)); 779 frame.WriteBytes(&flags_length, sizeof(flags_length));
473 780
474 frame.WriteBytes(data, len); 781 frame.WriteBytes(data, len);
475 scoped_ptr<SpdyFrame> data_frame(frame.take()); 782 scoped_ptr<SpdyFrame> data_frame(frame.take());
476 SpdyDataFrame* rv; 783 SpdyDataFrame* rv;
477 if (flags & DATA_FLAG_COMPRESSED) { 784 if (flags & DATA_FLAG_COMPRESSED) {
785 // LOG(DFATAL) << "DATA_FLAG_COMPRESSED invalid for SPDY.";
willchan no longer on Chromium 2011/09/25 22:18:24 Did you add this? I'm surprised to see this.
ramant (doing other things) 2011/09/26 00:27:55 I didn't. It came from server code. Deleted the co
478 rv = reinterpret_cast<SpdyDataFrame*>(CompressFrame(*data_frame.get())); 786 rv = reinterpret_cast<SpdyDataFrame*>(CompressFrame(*data_frame.get()));
479 } else { 787 } else {
480 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release()); 788 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release());
481 } 789 }
482 790
483 if (flags & DATA_FLAG_FIN) { 791 if (flags & DATA_FLAG_FIN) {
484 CleanupCompressorForStream(stream_id); 792 CleanupCompressorForStream(stream_id);
485 } 793 }
486 794
487 return rv; 795 return rv;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 case SPDY_READING_COMMON_HEADER: 849 case SPDY_READING_COMMON_HEADER:
542 return "READING_COMMON_HEADER"; 850 return "READING_COMMON_HEADER";
543 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: 851 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER:
544 return "INTERPRET_CONTROL_FRAME_COMMON_HEADER"; 852 return "INTERPRET_CONTROL_FRAME_COMMON_HEADER";
545 case SPDY_CONTROL_FRAME_PAYLOAD: 853 case SPDY_CONTROL_FRAME_PAYLOAD:
546 return "CONTROL_FRAME_PAYLOAD"; 854 return "CONTROL_FRAME_PAYLOAD";
547 case SPDY_IGNORE_REMAINING_PAYLOAD: 855 case SPDY_IGNORE_REMAINING_PAYLOAD:
548 return "IGNORE_REMAINING_PAYLOAD"; 856 return "IGNORE_REMAINING_PAYLOAD";
549 case SPDY_FORWARD_STREAM_FRAME: 857 case SPDY_FORWARD_STREAM_FRAME:
550 return "FORWARD_STREAM_FRAME"; 858 return "FORWARD_STREAM_FRAME";
859 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
860 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
861 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
862 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
551 } 863 }
552 return "UNKNOWN_STATE"; 864 return "UNKNOWN_STATE";
553 } 865 }
554 866
555 const char* SpdyFramer::ErrorCodeToString(int error_code) { 867 const char* SpdyFramer::ErrorCodeToString(int error_code) {
556 switch (error_code) { 868 switch (error_code) {
557 case SPDY_NO_ERROR: 869 case SPDY_NO_ERROR:
558 return "NO_ERROR"; 870 return "NO_ERROR";
559 case SPDY_INVALID_CONTROL_FRAME: 871 case SPDY_INVALID_CONTROL_FRAME:
560 return "INVALID_CONTROL_FRAME"; 872 return "INVALID_CONTROL_FRAME";
(...skipping 23 matching lines...) Expand all
584 // This should only be called when we're in the SPDY_READING_COMMON_HEADER 896 // This should only be called when we're in the SPDY_READING_COMMON_HEADER
585 // state. 897 // state.
586 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); 898 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);
587 899
588 size_t original_len = len; 900 size_t original_len = len;
589 SpdyFrame current_frame(current_frame_buffer_, false); 901 SpdyFrame current_frame(current_frame_buffer_, false);
590 902
591 do { 903 do {
592 if (current_frame_len_ < SpdyFrame::size()) { 904 if (current_frame_len_ < SpdyFrame::size()) {
593 size_t bytes_desired = SpdyFrame::size() - current_frame_len_; 905 size_t bytes_desired = SpdyFrame::size() - current_frame_len_;
594 size_t bytes_to_append = std::min(bytes_desired, len); 906 UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
595 char* header_buffer = current_frame_buffer_;
596 memcpy(&header_buffer[current_frame_len_], data, bytes_to_append);
597 current_frame_len_ += bytes_to_append;
598 data += bytes_to_append;
599 len -= bytes_to_append;
600 // Check for an empty data frame. 907 // Check for an empty data frame.
601 if (current_frame_len_ == SpdyFrame::size() && 908 if (current_frame_len_ == SpdyFrame::size() &&
602 !current_frame.is_control_frame() && 909 !current_frame.is_control_frame() &&
603 current_frame.length() == 0) { 910 current_frame.length() == 0) {
604 if (current_frame.flags() & CONTROL_FLAG_FIN) { 911 if (current_frame.flags() & CONTROL_FLAG_FIN) {
605 SpdyDataFrame data_frame(current_frame_buffer_, false); 912 SpdyDataFrame data_frame(current_frame_buffer_, false);
606 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0); 913 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0);
607 } 914 }
608 CHANGE_STATE(SPDY_AUTO_RESET); 915 CHANGE_STATE(SPDY_AUTO_RESET);
609 } 916 }
610 break; 917 break;
611 } 918 }
612 remaining_payload_ = current_frame.length(); 919 remaining_data_ = current_frame.length();
613 920
614 // This is just a sanity check for help debugging early frame errors. 921 // This is just a sanity check for help debugging early frame errors.
615 if (remaining_payload_ > 1000000u) { 922 if (remaining_data_ > 1000000u) {
616 LOG(WARNING) << 923 LOG(WARNING) <<
617 "Unexpectedly large frame. Spdy session is likely corrupt."; 924 "Unexpectedly large frame. Spdy session is likely corrupt.";
618 } 925 }
619 926
620 // if we're here, then we have the common header all received. 927 // if we're here, then we have the common header all received.
621 if (!current_frame.is_control_frame()) 928 if (!current_frame.is_control_frame())
622 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 929 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
623 else 930 else
624 CHANGE_STATE(SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER); 931 CHANGE_STATE(SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER);
625 } while (false); 932 } while (false);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 case RST_STREAM: 970 case RST_STREAM:
664 if (current_control_frame.length() != 971 if (current_control_frame.length() !=
665 SpdyRstStreamControlFrame::size() - SpdyFrame::size()) 972 SpdyRstStreamControlFrame::size() - SpdyFrame::size())
666 set_error(SPDY_INVALID_CONTROL_FRAME); 973 set_error(SPDY_INVALID_CONTROL_FRAME);
667 break; 974 break;
668 case SETTINGS: 975 case SETTINGS:
669 if (current_control_frame.length() < 976 if (current_control_frame.length() <
670 SpdySettingsControlFrame::size() - SpdyControlFrame::size()) 977 SpdySettingsControlFrame::size() - SpdyControlFrame::size())
671 set_error(SPDY_INVALID_CONTROL_FRAME); 978 set_error(SPDY_INVALID_CONTROL_FRAME);
672 break; 979 break;
980 // TODO(hkhalil): Remove NOOP.
673 case NOOP: 981 case NOOP:
674 // NOOP. Swallow it. 982 // NOOP. Swallow it.
983 DLOG(INFO) << "Attempted frame size validation for NOOP. Resetting.";
675 CHANGE_STATE(SPDY_AUTO_RESET); 984 CHANGE_STATE(SPDY_AUTO_RESET);
676 return; 985 return;
677 case GOAWAY: 986 case GOAWAY:
678 if (current_control_frame.length() != 987 if (current_control_frame.length() !=
679 SpdyGoAwayControlFrame::size() - SpdyFrame::size()) 988 SpdyGoAwayControlFrame::size() - SpdyFrame::size())
680 set_error(SPDY_INVALID_CONTROL_FRAME); 989 set_error(SPDY_INVALID_CONTROL_FRAME);
681 break; 990 break;
682 case HEADERS: 991 case HEADERS:
683 if (current_control_frame.length() < 992 if (current_control_frame.length() <
684 SpdyHeadersControlFrame::size() - SpdyControlFrame::size()) 993 SpdyHeadersControlFrame::size() - SpdyControlFrame::size())
685 set_error(SPDY_INVALID_CONTROL_FRAME); 994 set_error(SPDY_INVALID_CONTROL_FRAME);
686 break; 995 break;
687 case WINDOW_UPDATE: 996 case WINDOW_UPDATE:
688 if (current_control_frame.length() != 997 if (current_control_frame.length() !=
689 SpdyWindowUpdateControlFrame::size() - SpdyControlFrame::size()) 998 SpdyWindowUpdateControlFrame::size() - SpdyControlFrame::size())
690 set_error(SPDY_INVALID_CONTROL_FRAME); 999 set_error(SPDY_INVALID_CONTROL_FRAME);
691 break; 1000 break;
1001 case PING:
1002 if (current_control_frame.length() !=
1003 SpdyPingControlFrame::size() - SpdyControlFrame::size())
1004 set_error(SPDY_INVALID_CONTROL_FRAME);
1005 break;
692 default: 1006 default:
693 LOG(WARNING) << "Valid spdy control frame with unknown type: " 1007 LOG(WARNING) << "Valid spdy control frame with unhandled type: "
694 << current_control_frame.type(); 1008 << current_control_frame.type();
695 DCHECK(false); 1009 DCHECK(false);
696 set_error(SPDY_INVALID_CONTROL_FRAME); 1010 set_error(SPDY_INVALID_CONTROL_FRAME);
697 break; 1011 break;
698 } 1012 }
699 1013
700 remaining_control_payload_ = current_control_frame.length(); 1014 remaining_control_payload_ = current_control_frame.length();
701 if (remaining_control_payload_ > kControlFrameBufferMaxSize) { 1015 if (remaining_control_payload_ > kControlFrameBufferMaxSize) {
702 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1016 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
703 return; 1017 return;
704 } 1018 }
705 1019
706 ExpandControlFrameBuffer(remaining_control_payload_); 1020 ExpandControlFrameBuffer(remaining_control_payload_);
707 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); 1021 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
708 } 1022 }
709 1023
710 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { 1024 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
711 size_t original_len = len; 1025 size_t original_len = len;
712 do { 1026 do {
713 if (remaining_control_payload_) { 1027 if (remaining_control_payload_) {
714 size_t amount_to_consume = std::min(remaining_control_payload_, len); 1028 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
715 memcpy(&current_frame_buffer_[current_frame_len_], data, 1029 remaining_control_payload_);
716 amount_to_consume); 1030 remaining_control_payload_ -= bytes_read;
717 current_frame_len_ += amount_to_consume; 1031 remaining_data_ -= bytes_read;
718 data += amount_to_consume;
719 len -= amount_to_consume;
720 remaining_control_payload_ -= amount_to_consume;
721 remaining_payload_ -= amount_to_consume;
722 if (remaining_control_payload_) 1032 if (remaining_control_payload_)
723 break; 1033 break;
724 } 1034 }
725 SpdyControlFrame control_frame(current_frame_buffer_, false); 1035 SpdyControlFrame control_frame(current_frame_buffer_, false);
726 visitor_->OnControl(&control_frame); 1036 visitor_->OnControl(&control_frame);
727 1037
728 // If this is a FIN, tell the caller. 1038 // If this is a FIN, tell the caller.
729 if (control_frame.type() == SYN_REPLY && 1039 if (control_frame.type() == SYN_REPLY &&
730 control_frame.flags() & CONTROL_FLAG_FIN) { 1040 control_frame.flags() & CONTROL_FLAG_FIN) {
731 visitor_->OnStreamFrameData(reinterpret_cast<SpdySynReplyControlFrame*>( 1041 visitor_->OnStreamFrameData(reinterpret_cast<SpdySynReplyControlFrame*>(
732 &control_frame)->stream_id(), 1042 &control_frame)->stream_id(),
733 NULL, 0); 1043 NULL, 0);
734 } 1044 }
735 1045
736 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 1046 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
737 } while (false); 1047 } while (false);
738 return original_len - len; 1048 return original_len - len;
739 } 1049 }
740 1050
741 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 1051 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
742 size_t original_len = len; 1052 size_t original_len = len;
743 1053
744 SpdyDataFrame current_data_frame(current_frame_buffer_, false); 1054 SpdyDataFrame current_data_frame(current_frame_buffer_, false);
745 if (remaining_payload_) { 1055 if (remaining_data_) {
746 size_t amount_to_forward = std::min(remaining_payload_, len); 1056 size_t amount_to_forward = std::min(remaining_data_, len);
747 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { 1057 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
748 if (current_data_frame.flags() & DATA_FLAG_COMPRESSED) { 1058 if (current_data_frame.flags() & DATA_FLAG_COMPRESSED) {
749 z_stream* decompressor = 1059 z_stream* decompressor =
750 GetStreamDecompressor(current_data_frame.stream_id()); 1060 GetStreamDecompressor(current_data_frame.stream_id());
751 if (!decompressor) 1061 if (!decompressor)
752 return 0; 1062 return 0;
753 1063
754 size_t decompressed_max_size = amount_to_forward * 100; 1064 size_t decompressed_max_size = amount_to_forward * 100;
755 scoped_array<char> decompressed(new char[decompressed_max_size]); 1065 scoped_array<char> decompressed(new char[decompressed_max_size]);
756 decompressor->next_in = reinterpret_cast<Bytef*>( 1066 decompressor->next_in = reinterpret_cast<Bytef*>(
(...skipping 21 matching lines...) Expand all
778 } else { 1088 } else {
779 // The data frame was not compressed. 1089 // The data frame was not compressed.
780 // Only inform the visitor if there is data. 1090 // Only inform the visitor if there is data.
781 if (amount_to_forward) 1091 if (amount_to_forward)
782 visitor_->OnStreamFrameData(current_data_frame.stream_id(), 1092 visitor_->OnStreamFrameData(current_data_frame.stream_id(),
783 data, amount_to_forward); 1093 data, amount_to_forward);
784 } 1094 }
785 } 1095 }
786 data += amount_to_forward; 1096 data += amount_to_forward;
787 len -= amount_to_forward; 1097 len -= amount_to_forward;
788 remaining_payload_ -= amount_to_forward; 1098 remaining_data_ -= amount_to_forward;
789 1099
790 // If the FIN flag is set, and there is no more data in this data 1100 // If the FIN flag is set, and there is no more data in this data
791 // frame, inform the visitor of EOF via a 0-length data frame. 1101 // frame, inform the visitor of EOF via a 0-length data frame.
792 if (!remaining_payload_ && 1102 if (!remaining_data_ &&
793 current_data_frame.flags() & DATA_FLAG_FIN) { 1103 current_data_frame.flags() & DATA_FLAG_FIN) {
794 visitor_->OnStreamFrameData(current_data_frame.stream_id(), NULL, 0); 1104 visitor_->OnStreamFrameData(current_data_frame.stream_id(), NULL, 0);
795 CleanupDecompressorForStream(current_data_frame.stream_id()); 1105 CleanupDecompressorForStream(current_data_frame.stream_id());
796 } 1106 }
797 } else { 1107 } else {
798 CHANGE_STATE(SPDY_AUTO_RESET); 1108 CHANGE_STATE(SPDY_AUTO_RESET);
799 } 1109 }
800 return original_len - len; 1110 return original_len - len;
801 } 1111 }
802 1112
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 1216
907 SpdyControlFrame* SpdyFramer::DecompressControlFrame( 1217 SpdyControlFrame* SpdyFramer::DecompressControlFrame(
908 const SpdyControlFrame& frame) { 1218 const SpdyControlFrame& frame) {
909 z_stream* decompressor = GetHeaderDecompressor(); 1219 z_stream* decompressor = GetHeaderDecompressor();
910 if (!decompressor) 1220 if (!decompressor)
911 return NULL; 1221 return NULL;
912 return reinterpret_cast<SpdyControlFrame*>( 1222 return reinterpret_cast<SpdyControlFrame*>(
913 DecompressFrameWithZStream(frame, decompressor)); 1223 DecompressFrameWithZStream(frame, decompressor));
914 } 1224 }
915 1225
1226 // Incrementally decompress the control frame's header block, feeding the
1227 // result to the visitor in chunks. Continue this until the visitor
1228 // indicates that it cannot process any more data, or (more commonly) we
1229 // run out of data to deliver.
1230 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
1231 const SpdyControlFrame* control_frame) {
1232 z_stream* decomp = GetHeaderDecompressor();
1233 int payload_length;
1234 int header_length;
1235 const char* payload;
1236 bool read_successfully = true;
1237 bool more = true;
1238 char buffer[kHeaderDataChunkMaxSize];
1239
1240 if (!GetFrameBoundaries(
1241 *control_frame, &payload_length, &header_length, &payload)) {
1242 DLOG(ERROR) << "Control frame of type "
1243 << SpdyFramer::ControlTypeToString(control_frame->type())
1244 <<" doesn't have headers";
1245 return false;
1246 }
1247 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
1248 decomp->avail_in = payload_length;
1249 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1250 DCHECK_LT(0u, stream_id);
1251 while (more && read_successfully) {
1252 decomp->next_out = reinterpret_cast<Bytef*>(buffer);
1253 decomp->avail_out = arraysize(buffer);
1254 int rv = DecompressHeaderBlockInZStream(decomp);
1255 if (rv != Z_OK) {
1256 set_error(SPDY_DECOMPRESS_FAILURE);
1257 DLOG(WARNING) << "inflate failure: " << rv;
1258 more = read_successfully = false;
1259 } else {
1260 DCHECK_GT(arraysize(buffer), decomp->avail_out);
1261 size_t len = arraysize(buffer) - decomp->avail_out;
1262 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, buffer,
1263 len);
1264 if (!read_successfully) {
1265 // Assume that the problem was the header block was too large for the
1266 // visitor.
1267 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1268 }
1269 more = decomp->avail_in > 0;
1270 }
1271 }
1272 return read_successfully;
1273 }
1274
1275 // Incrementally decompress the control frame's header block, feeding the
1276 // result to the visitor in chunks. Continue this until the visitor
1277 // indicates that it cannot process any more data, or (more commonly) we
1278 // run out of data to deliver.
1279 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
1280 const SpdyControlFrame* control_frame,
1281 const char* data,
1282 size_t len) {
1283 // Get a decompressor or set error.
1284 z_stream* decomp = GetHeaderDecompressor();
1285 if (decomp == NULL) {
1286 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
1287 set_error(SPDY_DECOMPRESS_FAILURE);
1288 return false;
1289 }
1290
1291 bool processed_successfully = true;
1292 char buffer[kHeaderDataChunkMaxSize];
1293
1294 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
1295 decomp->avail_in = len;
1296 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1297 DCHECK_LT(0u, stream_id);
1298 while (decomp->avail_in > 0 && processed_successfully) {
1299 decomp->next_out = reinterpret_cast<Bytef*>(buffer);
1300 decomp->avail_out = arraysize(buffer);
1301 int rv = DecompressHeaderBlockInZStream(decomp);
1302 if (rv != Z_OK) {
1303 set_error(SPDY_DECOMPRESS_FAILURE);
1304 DLOG(WARNING) << "inflate failure: " << rv;
1305 processed_successfully = false;
1306 } else {
1307 size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
1308 if (decompressed_len > 0) {
1309 processed_successfully = visitor_->OnControlFrameHeaderData(
1310 stream_id, buffer, decompressed_len);
1311 }
1312 if (!processed_successfully) {
1313 // Assume that the problem was the header block was too large for the
1314 // visitor.
1315 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1316 }
1317 }
1318 }
1319 return processed_successfully;
1320 }
1321
1322 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
1323 const SpdyControlFrame* control_frame, const char* data, size_t len) {
1324 bool read_successfully = true;
1325 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1326 DCHECK_LT(0u, stream_id);
1327 while (read_successfully && len > 0) {
1328 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
1329 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
1330 bytes_to_deliver);
1331 data += bytes_to_deliver;
1332 len -= bytes_to_deliver;
1333 if (!read_successfully) {
1334 // Assume that the problem was the header block was too large for the
1335 // visitor.
1336 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1337 }
1338 }
1339 return read_successfully;
1340 }
1341
1342 size_t SpdyFramer::GetMinimumControlFrameSize(SpdyControlType type) {
1343 switch (type) {
1344 case SYN_STREAM:
1345 return SpdySynStreamControlFrame::size();
1346 case SYN_REPLY:
1347 return SpdySynReplyControlFrame::size();
1348 case RST_STREAM:
1349 return SpdyRstStreamControlFrame::size();
1350 case SETTINGS:
1351 return SpdySettingsControlFrame::size();
1352 case NOOP:
1353 return SpdyNoOpControlFrame::size();
1354 case PING:
1355 return SpdyPingControlFrame::size();
1356 case GOAWAY:
1357 return SpdyGoAwayControlFrame::size();
1358 case HEADERS:
1359 return SpdyHeadersControlFrame::size();
1360 case WINDOW_UPDATE:
1361 return SpdyWindowUpdateControlFrame::size();
1362 case NUM_CONTROL_FRAME_TYPES:
1363 break;
1364 }
1365 LOG(ERROR) << "Unknown SPDY control frame type " << type;
1366 return 0x7FFFFFFF; // Max signed 32bit int
1367 }
1368
1369 /* static */
1370 SpdyStreamId SpdyFramer::GetControlFrameStreamId(
1371 const SpdyControlFrame* control_frame) {
1372 SpdyStreamId stream_id = kInvalidStream;
1373 if (control_frame != NULL) {
1374 switch (control_frame->type()) {
1375 case SYN_STREAM:
1376 stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>(
1377 control_frame)->stream_id();
1378 break;
1379 case SYN_REPLY:
1380 stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>(
1381 control_frame)->stream_id();
1382 break;
1383 case HEADERS:
1384 stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>(
1385 control_frame)->stream_id();
1386 break;
1387 case RST_STREAM:
1388 stream_id = reinterpret_cast<const SpdyRstStreamControlFrame*>(
1389 control_frame)->stream_id();
1390 break;
1391 case WINDOW_UPDATE:
1392 stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame*>(
1393 control_frame)->stream_id();
1394 break;
1395 // All of the following types are not part of a particular stream.
1396 // They all fall through to the invalid control frame type case.
1397 // (The default case isn't used so that the compile will break if a new
1398 // control frame type is added but not included here.)
1399 case SETTINGS:
1400 case NOOP:
1401 case PING:
1402 case GOAWAY:
1403 case NUM_CONTROL_FRAME_TYPES: // makes compiler happy
1404 break;
1405 }
1406 }
1407 return stream_id;
1408 }
1409
1410 void SpdyFramer::set_validate_control_frame_sizes(bool value) {
1411 validate_control_frame_sizes_ = value;
1412 }
1413
916 SpdyDataFrame* SpdyFramer::DecompressDataFrame(const SpdyDataFrame& frame) { 1414 SpdyDataFrame* SpdyFramer::DecompressDataFrame(const SpdyDataFrame& frame) {
917 z_stream* decompressor = GetStreamDecompressor(frame.stream_id()); 1415 z_stream* decompressor = GetStreamDecompressor(frame.stream_id());
918 if (!decompressor) 1416 if (!decompressor)
919 return NULL; 1417 return NULL;
920 return reinterpret_cast<SpdyDataFrame*>( 1418 return reinterpret_cast<SpdyDataFrame*>(
921 DecompressFrameWithZStream(frame, decompressor)); 1419 DecompressFrameWithZStream(frame, decompressor));
922 } 1420 }
923 1421
924 SpdyFrame* SpdyFramer::CompressFrameWithZStream(const SpdyFrame& frame, 1422 SpdyFrame* SpdyFramer::CompressFrameWithZStream(const SpdyFrame& frame,
925 z_stream* compressor) { 1423 z_stream* compressor) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 case SPDY_ERROR: 1606 case SPDY_ERROR:
1109 case SPDY_DONE: 1607 case SPDY_DONE:
1110 case SPDY_AUTO_RESET: 1608 case SPDY_AUTO_RESET:
1111 case SPDY_RESET: 1609 case SPDY_RESET:
1112 return 0; 1610 return 0;
1113 case SPDY_READING_COMMON_HEADER: 1611 case SPDY_READING_COMMON_HEADER:
1114 DCHECK_LT(current_frame_len_, SpdyFrame::size()); 1612 DCHECK_LT(current_frame_len_, SpdyFrame::size());
1115 return SpdyFrame::size() - current_frame_len_; 1613 return SpdyFrame::size() - current_frame_len_;
1116 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER: 1614 case SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER:
1117 return 0; 1615 return 0;
1616 // TODO(rtenneti): Add support for SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
1617 // and SPDY_CONTROL_FRAME_HEADER_BLOCK.
1618 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
1619 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
1620 return 0;
1118 case SPDY_CONTROL_FRAME_PAYLOAD: 1621 case SPDY_CONTROL_FRAME_PAYLOAD:
1119 case SPDY_IGNORE_REMAINING_PAYLOAD: 1622 case SPDY_IGNORE_REMAINING_PAYLOAD:
1120 case SPDY_FORWARD_STREAM_FRAME: 1623 case SPDY_FORWARD_STREAM_FRAME:
1121 return remaining_payload_; 1624 return remaining_data_;
1122 } 1625 }
1123 // We should never get to here. 1626 // We should never get to here.
1124 return 0; 1627 return 0;
1125 } 1628 }
1126 1629
1127 void SpdyFramer::set_error(SpdyError error) { 1630 void SpdyFramer::set_error(SpdyError error) {
1128 DCHECK(visitor_); 1631 DCHECK(visitor_);
1129 error_code_ = error; 1632 error_code_ = error;
1130 CHANGE_STATE(SPDY_ERROR); 1633 CHANGE_STATE(SPDY_ERROR);
1131 visitor_->OnError(this); 1634 visitor_->OnError(this);
1132 } 1635 }
1133 1636
1134 void SpdyFramer::ExpandControlFrameBuffer(size_t size) { 1637 void SpdyFramer::ExpandControlFrameBuffer(size_t size) {
1135 size_t alloc_size = size + SpdyFrame::size(); 1638 size_t alloc_size = size + SpdyFrame::size();
1136 DCHECK_LT(alloc_size, kControlFrameBufferMaxSize); 1639 DCHECK_LE(alloc_size, kControlFrameBufferMaxSize);
1137 if (alloc_size <= current_frame_capacity_) 1640 if (alloc_size <= current_frame_capacity_)
1138 return; 1641 return;
1139 char* new_buffer = new char[alloc_size]; 1642 char* new_buffer = new char[alloc_size];
1140 memcpy(new_buffer, current_frame_buffer_, current_frame_len_); 1643 memcpy(new_buffer, current_frame_buffer_, current_frame_len_);
1141 delete [] current_frame_buffer_; 1644 delete [] current_frame_buffer_;
1142 current_frame_capacity_ = alloc_size; 1645 current_frame_capacity_ = alloc_size;
1143 current_frame_buffer_ = new_buffer; 1646 current_frame_buffer_ = new_buffer;
1144 } 1647 }
1145 1648
1146 bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame, 1649 bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 } else { 1692 } else {
1190 frame_size = SpdyFrame::size(); 1693 frame_size = SpdyFrame::size();
1191 *header_length = frame_size; 1694 *header_length = frame_size;
1192 *payload_length = frame.length(); 1695 *payload_length = frame.length();
1193 *payload = frame.data() + SpdyFrame::size(); 1696 *payload = frame.data() + SpdyFrame::size();
1194 } 1697 }
1195 return true; 1698 return true;
1196 } 1699 }
1197 1700
1198 } // namespace spdy 1701 } // namespace spdy
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698