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

Unified Diff: net/spdy/spdy_framer.cc

Issue 664803003: Update from chromium a8e7c94b1b79a0948d05a1fcfff53391d22ce37a (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_framer.cc
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 9d7ea876bb5164f9b397998db5fe54b4d07f5ade..fae97e8e3e53085e1c75d03da18a8f391d825d11 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -70,6 +70,9 @@ const uint8 kNoFlags = 0;
const size_t kPriorityDependencyPayloadSize = 4;
const size_t kPriorityWeightPayloadSize = 1;
+// Wire size of pad length field.
+const size_t kPadLengthFieldSize = 1;
+
} // namespace
const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1);
@@ -379,8 +382,8 @@ const char* SpdyFramer::StateToString(int state) {
return "READING_COMMON_HEADER";
case SPDY_CONTROL_FRAME_PAYLOAD:
return "CONTROL_FRAME_PAYLOAD";
- case SPDY_READ_PADDING_LENGTH:
- return "SPDY_READ_PADDING_LENGTH";
+ case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
+ return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
case SPDY_CONSUME_PADDING:
return "SPDY_CONSUME_PADDING";
case SPDY_IGNORE_REMAINING_PAYLOAD:
@@ -601,8 +604,8 @@ size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
break;
}
- case SPDY_READ_PADDING_LENGTH: {
- size_t bytes_read = ProcessFramePaddingLength(data, len);
+ case SPDY_READ_DATA_FRAME_PADDING_LENGTH: {
+ size_t bytes_read = ProcessDataFramePaddingLength(data, len);
len -= bytes_read;
data += bytes_read;
break;
@@ -809,7 +812,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
remaining_data_length_,
current_frame_flags_ & DATA_FLAG_FIN);
if (remaining_data_length_ > 0) {
- CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
+ CHANGE_STATE(SPDY_READ_DATA_FRAME_PADDING_LENGTH);
} else {
// Empty data frame.
if (current_frame_flags_ & DATA_FLAG_FIN) {
@@ -1083,15 +1086,23 @@ void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
break;
case HEADERS:
frame_size_without_variable_data = GetHeadersMinimumSize();
- if (protocol_version() > SPDY3 &&
- current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
+ if (protocol_version() > SPDY3) {
+ if (current_frame_flags_ & HEADERS_FLAG_PADDED) {
+ frame_size_without_variable_data += kPadLengthFieldSize;
+ }
+ if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
frame_size_without_variable_data +=
kPriorityDependencyPayloadSize +
kPriorityWeightPayloadSize;
+ }
}
break;
case PUSH_PROMISE:
frame_size_without_variable_data = GetPushPromiseMinimumSize();
+ if (protocol_version() > SPDY3 &&
+ current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
+ frame_size_without_variable_data += kPadLengthFieldSize;
+ }
break;
case CONTINUATION:
frame_size_without_variable_data = GetContinuationMinimumSize();
@@ -1457,6 +1468,14 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
expect_continuation_ = current_frame_stream_id_;
end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
}
+ if (protocol_version() > SPDY3 &&
+ current_frame_flags_ & HEADERS_FLAG_PADDED) {
+ uint8 pad_payload_len = 0;
+ DCHECK_EQ(remaining_padding_payload_length_, 0u);
+ successful_read = reader.ReadUInt8(&pad_payload_len);
+ DCHECK(successful_read);
+ remaining_padding_payload_length_ = pad_payload_len;
+ }
const bool has_priority =
(current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
uint32 priority = 0;
@@ -1502,7 +1521,7 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
expect_continuation_ == 0);
}
}
- CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
+ CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
break;
case PUSH_PROMISE:
{
@@ -1511,6 +1530,17 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
set_error(SPDY_INVALID_CONTROL_FRAME);
break;
}
+ bool successful_read = true;
+ if (protocol_version() > SPDY3 &&
+ current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
+ DCHECK_EQ(remaining_padding_payload_length_, 0u);
+ uint8 pad_payload_len = 0;
+ successful_read = reader.ReadUInt8(&pad_payload_len);
+ DCHECK(successful_read);
+ remaining_padding_payload_length_ = pad_payload_len;
+ }
+ }
+ {
SpdyStreamId promised_stream_id = kInvalidStream;
bool successful_read = reader.ReadUInt31(&promised_stream_id);
DCHECK(successful_read);
@@ -1533,7 +1563,7 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
(current_frame_flags_ &
PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
}
- CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
+ CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
break;
case CONTINUATION:
{
@@ -2120,11 +2150,10 @@ size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) {
return processed_bytes;
}
-// TODO(raullenchai): ProcessFramePaddingLength should be able to deal with
-// HEADERS_FLAG_PADDED and PUSH_PROMISE_FLAG_PADDED as well (see b/15777051).
-size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
- DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
- DCHECK_EQ(remaining_padding_payload_length_, 0u);
+size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) {
+ DCHECK_EQ(SPDY_READ_DATA_FRAME_PADDING_LENGTH, state_);
+ DCHECK_EQ(0u, remaining_padding_payload_length_);
+ DCHECK_EQ(DATA, current_frame_type_);
size_t original_len = len;
if (current_frame_flags_ & DATA_FLAG_PADDED) {
@@ -2149,16 +2178,7 @@ size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
return 0;
}
- if (current_frame_type_ == DATA) {
- CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
- } else {
- DCHECK(current_frame_type_ == HEADERS ||
- current_frame_type_ == PUSH_PROMISE ||
- current_frame_type_ == SYN_STREAM ||
- current_frame_type_ == SYN_REPLY)
- << current_frame_type_;
- CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
- }
+ CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
return original_len - len;
}
@@ -2606,11 +2626,20 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders(
if (headers.has_priority()) {
flags |= HEADERS_FLAG_PRIORITY;
}
+ if (headers.padded()) {
+ flags |= HEADERS_FLAG_PADDED;
+ }
}
- // The size of this frame, including variable-length name-value block.
+ // The size of this frame, including padding (if there is any)
+ // and variable-length name-value block.
size_t size = GetHeadersMinimumSize();
+ if (protocol_version() > SPDY3 && headers.padded()) {
+ size += kPadLengthFieldSize;
+ size += headers.padding_payload_len();
+ }
+
uint32 priority = headers.priority();
if (headers.has_priority()) {
if (priority > GetLowestPriority()) {
@@ -2655,6 +2684,11 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders(
DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
if (protocol_version() > SPDY3) {
+ int padding_payload_len = 0;
+ if (headers.padded()) {
+ builder.WriteUInt8(headers.padding_payload_len());
+ padding_payload_len = headers.padding_payload_len();
+ }
if (headers.has_priority()) {
// TODO(jgraettinger): Plumb priorities and stream dependencies.
builder.WriteUInt32(0); // Non-exclusive bit and root stream ID.
@@ -2663,7 +2697,8 @@ SpdySerializedFrame* SpdyFramer::SerializeHeaders(
WritePayloadWithContinuation(&builder,
hpack_encoding,
headers.stream_id(),
- HEADERS);
+ HEADERS,
+ padding_payload_len);
} else {
SerializeNameValueBlock(&builder, headers);
}
@@ -2717,6 +2752,12 @@ SpdyFrame* SpdyFramer::SerializePushPromise(
// The size of this frame, including variable-length name-value block.
size_t size = GetPushPromiseMinimumSize();
+ if (push_promise.padded()) {
+ flags |= PUSH_PROMISE_FLAG_PADDED;
+ size += kPadLengthFieldSize;
+ size += push_promise.padding_payload_len();
+ }
+
string hpack_encoding;
if (enable_compression_) {
GetHpackEncoder()->EncodeHeaderSet(
@@ -2737,13 +2778,24 @@ SpdyFrame* SpdyFramer::SerializePushPromise(
PUSH_PROMISE,
flags,
push_promise.stream_id());
- builder.WriteUInt32(push_promise.promised_stream_id());
- DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
+ int padding_payload_len = 0;
+ if (push_promise.padded()) {
+ builder.WriteUInt8(push_promise.padding_payload_len());
+ builder.WriteUInt32(push_promise.promised_stream_id());
+ DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize,
+ builder.length());
+
+ padding_payload_len = push_promise.padding_payload_len();
+ } else {
+ builder.WriteUInt32(push_promise.promised_stream_id());
+ DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
+ }
WritePayloadWithContinuation(&builder,
hpack_encoding,
push_promise.stream_id(),
- PUSH_PROMISE);
+ PUSH_PROMISE,
+ padding_payload_len);
if (debug_visitor_) {
// SPDY4 uses HPACK for header compression. However, continue to
@@ -2923,32 +2975,34 @@ size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
const string& hpack_encoding,
SpdyStreamId stream_id,
- SpdyFrameType type) {
+ SpdyFrameType type,
+ int padding_payload_len) {
const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize();
- // In addition to the prefix, fixed_field_size includes the size of
- // any fields that come before the variable-length name/value block.
- size_t fixed_field_size = 0;
uint8 end_flag = 0;
uint8 flags = 0;
if (type == HEADERS) {
- fixed_field_size = GetHeadersMinimumSize();
end_flag = HEADERS_FLAG_END_HEADERS;
} else if (type == PUSH_PROMISE) {
- fixed_field_size = GetPushPromiseMinimumSize();
end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
} else {
DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
<< FrameTypeToString(type);
}
- // Write as much of the payload as possible into the initial frame.
- size_t bytes_remaining = hpack_encoding.size() -
- std::min(hpack_encoding.size(),
- kMaxControlFrameSize - fixed_field_size);
+ // Write all the padding payload and as much of the data payload as possible
+ // into the initial frame.
+ size_t bytes_remaining = 0;
+ bytes_remaining = hpack_encoding.size() -
+ std::min(hpack_encoding.size(),
+ kMaxControlFrameSize - builder->length() -
+ padding_payload_len);
builder->WriteBytes(&hpack_encoding[0],
hpack_encoding.size() - bytes_remaining);
-
+ if (padding_payload_len > 0) {
+ string padding = string(padding_payload_len, 0);
+ builder->WriteBytes(padding.data(), padding.length());
+ }
if (bytes_remaining > 0) {
builder->OverwriteLength(*this,
kMaxControlFrameSize - GetControlFrameHeaderSize());
« 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