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

Unified Diff: net/spdy/spdy_framer.cc

Issue 12220116: Refactor in preparation for SPDY 4, part 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Windows compile errors Created 7 years, 10 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_protocol.h » ('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 21615a0f44742f2572dd2fa921688afd08a98016..96ccf9a9b87082f1a604ac44e05b51d93c453493 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -46,6 +46,9 @@ struct DictionaryIds {
// initialized lazily to avoid static initializers.
base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
+// Used to indicate no flags in a SPDY flags field.
+const uint8 kNoFlags = 0;
+
} // namespace
const int SpdyFramer::kMinSpdyVersion = 2;
@@ -677,15 +680,13 @@ void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
}
SpdyHeaderBlock::const_iterator it;
for (it = headers->begin(); it != headers->end(); ++it) {
- bool wrote_header;
if (spdy_version < 3) {
- wrote_header = frame->WriteString(it->first);
- wrote_header &= frame->WriteString(it->second);
+ frame->WriteString(it->first);
+ frame->WriteString(it->second);
} else {
- wrote_header = frame->WriteStringPiece32(it->first);
- wrote_header &= frame->WriteStringPiece32(it->second);
+ frame->WriteStringPiece32(it->first);
+ frame->WriteStringPiece32(it->second);
}
- DCHECK(wrote_header);
}
}
@@ -1291,29 +1292,20 @@ SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
SpdyControlFlags flags,
bool compressed,
const SpdyHeaderBlock* headers) {
- DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
- DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask);
-
- // Find our length.
- size_t frame_size = SpdySynStreamControlFrame::size() +
- GetSerializedLength(spdy_version_, headers);
+ DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN & ~CONTROL_FLAG_UNIDIRECTIONAL);
- SpdyFrameBuilder frame(SYN_STREAM, flags, spdy_version_, frame_size);
- frame.WriteUInt32(stream_id);
- frame.WriteUInt32(associated_stream_id);
- // Cap as appropriate.
- if (priority > GetLowestPriority()) {
- DLOG(DFATAL) << "Priority out-of-bounds.";
- priority = GetLowestPriority();
- }
- // Priority is 2 bits for <spdy3, 3 bits otherwise.
- frame.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
- frame.WriteUInt8((spdy_version_ < 3) ? 0 : credential_slot);
- WriteHeaderBlock(&frame, spdy_version_, headers);
- DCHECK_EQ(frame.length(), frame_size);
+ SpdySynStreamIR syn_stream(stream_id);
+ syn_stream.set_associated_to_stream_id(associated_stream_id);
+ syn_stream.set_priority(priority);
+ syn_stream.set_slot(credential_slot);
+ syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0);
+ syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
+ // TODO(hkhalil): Avoid copy here.
+ *(syn_stream.GetMutableNameValueBlock()) = *headers;
scoped_ptr<SpdySynStreamControlFrame> syn_frame(
- reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
+ reinterpret_cast<SpdySynStreamControlFrame*>(
+ SerializeSynStream(syn_stream)));
if (compressed) {
return reinterpret_cast<SpdySynStreamControlFrame*>(
CompressControlFrame(*syn_frame.get(), headers));
@@ -1321,32 +1313,57 @@ SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
return syn_frame.release();
}
+SpdySerializedFrame* SpdyFramer::SerializeSynStream(
+ const SpdySynStreamIR& syn_stream) {
+ uint8 flags = 0;
+ if (syn_stream.fin()) {
+ flags |= CONTROL_FLAG_FIN;
+ }
+ if (syn_stream.unidirectional()) {
+ flags |= CONTROL_FLAG_UNIDIRECTIONAL;
+ }
+
+ // The size, in bytes, of this frame not including the variable-length
+ // name-value block. Calculated as:
+ // 8 (control frame header) + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot)
+ const size_t kSynStreamSizeBeforeNameValueBlock = 18;
+
+ // The size of this frame, including variable-length name-value block.
+ const size_t size = kSynStreamSizeBeforeNameValueBlock
+ + GetSerializedLength(protocol_version(),
+ &(syn_stream.name_value_block()));
+
+ SpdyFrameBuilder builder(SYN_STREAM, flags, protocol_version(), size);
+ builder.WriteUInt32(syn_stream.stream_id());
+ builder.WriteUInt32(syn_stream.associated_to_stream_id());
+ uint8 priority = syn_stream.priority();
+ if (priority > GetLowestPriority()) {
+ DLOG(DFATAL) << "Priority out-of-bounds.";
+ priority = GetLowestPriority();
+ }
+ builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
+ builder.WriteUInt8(syn_stream.slot());
+ DCHECK_EQ(kSynStreamSizeBeforeNameValueBlock, builder.length());
+ SerializeNameValueBlock(&builder, syn_stream);
+
+ return builder.take();
+}
+
SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
SpdyStreamId stream_id,
SpdyControlFlags flags,
bool compressed,
const SpdyHeaderBlock* headers) {
- DCHECK_GT(stream_id, 0u);
- DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
+ DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN);
- // Find our length.
- size_t frame_size = SpdySynReplyControlFrame::size() +
- GetSerializedLength(spdy_version_, headers);
- // In SPDY 2, there were 2 unused bytes before payload.
- if (spdy_version_ < 3) {
- frame_size += 2;
- }
-
- SpdyFrameBuilder frame(SYN_REPLY, flags, spdy_version_, frame_size);
- frame.WriteUInt32(stream_id);
- if (spdy_version_ < 3) {
- frame.WriteUInt16(0); // Unused
- }
- WriteHeaderBlock(&frame, spdy_version_, headers);
- DCHECK_EQ(frame.length(), frame_size);
+ SpdySynReplyIR syn_reply(stream_id);
+ syn_reply.set_fin(flags & CONTROL_FLAG_FIN);
+ // TODO(hkhalil): Avoid copy here.
+ *(syn_reply.GetMutableNameValueBlock()) = *headers;
scoped_ptr<SpdySynReplyControlFrame> reply_frame(
- reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
+ reinterpret_cast<SpdySynReplyControlFrame*>(SerializeSynReply(
+ syn_reply)));
if (compressed) {
return reinterpret_cast<SpdySynReplyControlFrame*>(
CompressControlFrame(*reply_frame.get(), headers));
@@ -1354,159 +1371,298 @@ SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
return reply_frame.release();
}
+SpdySerializedFrame* SpdyFramer::SerializeSynReply(
+ const SpdySynReplyIR& syn_reply) {
+ uint8 flags = 0;
+ if (syn_reply.fin()) {
+ flags |= CONTROL_FLAG_FIN;
+ }
+
+ // The size, in bytes, of this frame not including the variable-length
+ // name-value block. Calculated as:
+ // 8 (control frame header) + 4 (stream ID)
+ size_t syn_reply_size_before_name_value_block = 12;
+ // In SPDY 2, there were 2 unused bytes before payload.
+ if (protocol_version() < 3) {
+ syn_reply_size_before_name_value_block += 2;
+ }
+
+ // The size of this frame, including variable-length name-value block.
+ size_t size = syn_reply_size_before_name_value_block
+ + GetSerializedLength(protocol_version(),
+ &(syn_reply.name_value_block()));
+
+ SpdyFrameBuilder builder(SYN_REPLY, flags, protocol_version(), size);
+ builder.WriteUInt32(syn_reply.stream_id());
+ if (protocol_version() < 3) {
+ builder.WriteUInt16(0); // Unused.
+ }
+ DCHECK_EQ(syn_reply_size_before_name_value_block, builder.length());
+ SerializeNameValueBlock(&builder, syn_reply);
+
+ return builder.take();
+}
+
SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(
SpdyStreamId stream_id,
SpdyRstStreamStatus status) const {
- DCHECK_GT(stream_id, 0u);
- DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
- DCHECK_NE(status, RST_STREAM_INVALID);
- DCHECK_LT(status, RST_STREAM_NUM_STATUS_CODES);
-
- size_t frame_size = SpdyRstStreamControlFrame::size();
- SpdyFrameBuilder frame(RST_STREAM, CONTROL_FLAG_NONE, spdy_version_,
- frame_size);
- frame.WriteUInt32(stream_id);
- frame.WriteUInt32(status);
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take());
+ SpdyRstStreamIR rst_stream(stream_id, status);
+ return reinterpret_cast<SpdyRstStreamControlFrame*>(
+ SerializeRstStream(rst_stream));
+}
+
+SpdySerializedFrame* SpdyFramer::SerializeRstStream(
+ const SpdyRstStreamIR& rst_stream) const {
+ // Size of our RST_STREAM frame. Calculated as:
+ // 8 (control frame header) + 4 (stream id) + 4 (status code)
+ const size_t kRstStreamFrameSize = 16;
+
+ SpdyFrameBuilder builder(RST_STREAM,
+ kNoFlags,
+ protocol_version(),
+ kRstStreamFrameSize);
+ builder.WriteUInt32(rst_stream.stream_id());
+ builder.WriteUInt32(rst_stream.status());
+ DCHECK_EQ(kRstStreamFrameSize, builder.length());
+ return builder.take();
}
SpdySettingsControlFrame* SpdyFramer::CreateSettings(
const SettingsMap& values) const {
- size_t frame_size = SpdySettingsControlFrame::size() + 8 * values.size();
- SpdyFrameBuilder frame(SETTINGS, CONTROL_FLAG_NONE, spdy_version_,
- frame_size);
- frame.WriteUInt32(values.size());
+ SpdySettingsIR settings;
for (SettingsMap::const_iterator it = values.begin();
it != values.end();
- it++) {
- SettingsFlagsAndId flags_and_id(it->second.first, it->first);
- uint32 id_and_flags_wire = flags_and_id.GetWireFormat(spdy_version_);
- frame.WriteBytes(&id_and_flags_wire, 4);
- frame.WriteUInt32(it->second.second);
- }
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdySettingsControlFrame*>(frame.take());
+ ++it) {
+ settings.AddSetting(it->first,
+ (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0,
+ (it->second.first & SETTINGS_FLAG_PERSISTED) != 0,
+ it->second.second);
+ }
+ return reinterpret_cast<SpdySettingsControlFrame*>(
+ SerializeSettings(settings));
+}
+
+SpdySerializedFrame* SpdyFramer::SerializeSettings(
+ const SpdySettingsIR& settings) const {
+ uint8 flags = 0;
+ if (settings.clear_settings()) {
+ flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
+ }
+ const SpdySettingsIR::ValueMap* values = &(settings.values());
+
+ // Size, in bytes, of this SETTINGS frame not including the IDs and values
+ // from the variable-length value block. Calculated as:
+ // 8 (control frame header) + 4 (number of ID/value pairs)
+ const size_t kSettingsSizeWithoutValues = 12;
+ // Size, in bytes, of this SETTINGS frame.
+ const size_t size = kSettingsSizeWithoutValues + (values->size() * 8);
+
+ SpdyFrameBuilder builder(SETTINGS, flags, protocol_version(), size);
+ builder.WriteUInt32(values->size());
+ DCHECK_EQ(kSettingsSizeWithoutValues, builder.length());
+ for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
+ it != values->end();
+ ++it) {
+ uint8 setting_flags = 0;
+ if (it->second.persist_value) {
+ setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
+ }
+ if (it->second.persisted) {
+ setting_flags |= SETTINGS_FLAG_PERSISTED;
+ }
+ SettingsFlagsAndId flags_and_id(setting_flags, it->first);
+ uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
+ builder.WriteBytes(&id_and_flags_wire, 4);
+ builder.WriteUInt32(it->second.value);
+ }
+ DCHECK_EQ(size, builder.length());
+ return builder.take();
}
SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
- size_t frame_size = SpdyPingControlFrame::size();
- SpdyFrameBuilder frame(PING, CONTROL_FLAG_NONE, spdy_version_, frame_size);
- frame.WriteUInt32(unique_id);
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdyPingControlFrame*>(frame.take());
+ SpdyPingIR ping(unique_id);
+ return reinterpret_cast<SpdyPingControlFrame*>(SerializePing(ping));
+}
+
+SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
+ // Size, in bytes, of this PING frame. Calculated as:
+ // 8 (control frame header) + 4 (id)
+ const size_t kPingSize = 12;
+ SpdyFrameBuilder builder(PING, 0, protocol_version(), kPingSize);
+ builder.WriteUInt32(ping.id());
+ DCHECK_EQ(kPingSize, builder.length());
+ return builder.take();
}
SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway(
SpdyStreamId last_accepted_stream_id,
SpdyGoAwayStatus status) const {
- DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask);
-
- // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account for
- // this difference via a separate offset variable, since
- // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
- const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
- size_t frame_size = SpdyGoAwayControlFrame::size() - goaway_offset;
- SpdyFrameBuilder frame(GOAWAY, CONTROL_FLAG_NONE, spdy_version_, frame_size);
- frame.WriteUInt32(last_accepted_stream_id);
+ SpdyGoAwayIR goaway(last_accepted_stream_id, status);
+ return reinterpret_cast<SpdyGoAwayControlFrame*>(SerializeGoAway(goaway));
+}
+
+SpdySerializedFrame* SpdyFramer::SerializeGoAway(
+ const SpdyGoAwayIR& goaway) const {
+ // Size, in bytes, of this GOAWAY frame. Calculated as:
+ // 8 (control frame header) + 4 (last good stream id)
+ size_t size = 12;
+ // SPDY 3+ GOAWAY frames also contain a status.
+ if (protocol_version() >= 3) {
+ size += 4;
+ }
+ SpdyFrameBuilder builder(GOAWAY, 0, protocol_version(), size);
+ builder.WriteUInt32(goaway.last_good_stream_id());
if (protocol_version() >= 3) {
- frame.WriteUInt32(status);
+ builder.WriteUInt32(goaway.status());
}
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take());
+ DCHECK_EQ(size, builder.length());
+ return builder.take();
}
SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(
SpdyStreamId stream_id,
SpdyControlFlags flags,
bool compressed,
- const SpdyHeaderBlock* headers) {
+ const SpdyHeaderBlock* header_block) {
// Basically the same as CreateSynReply().
- DCHECK_GT(stream_id, 0u);
- DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
-
- // Find our length.
- size_t frame_size = SpdyHeadersControlFrame::size() +
- GetSerializedLength(spdy_version_, headers);
- // In SPDY 2, there were 2 unused bytes before payload.
- if (spdy_version_ < 3) {
- frame_size += 2;
- }
+ DCHECK_EQ(0, flags & (!CONTROL_FLAG_FIN));
- SpdyFrameBuilder frame(HEADERS, flags, spdy_version_, frame_size);
- frame.WriteUInt32(stream_id);
- if (spdy_version_ < 3) {
- frame.WriteUInt16(0); // Unused
- }
- WriteHeaderBlock(&frame, spdy_version_, headers);
- DCHECK_EQ(frame.length(), frame_size);
+ SpdyHeadersIR headers(stream_id);
+ headers.set_fin(flags & CONTROL_FLAG_FIN);
+ // TODO(hkhalil): Avoid copy here.
+ *(headers.GetMutableNameValueBlock()) = *header_block;
scoped_ptr<SpdyHeadersControlFrame> headers_frame(
- reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
+ reinterpret_cast<SpdyHeadersControlFrame*>(SerializeHeaders(headers)));
if (compressed) {
return reinterpret_cast<SpdyHeadersControlFrame*>(
- CompressControlFrame(*headers_frame.get(), headers));
+ CompressControlFrame(*headers_frame.get(),
+ headers.GetMutableNameValueBlock()));
}
return headers_frame.release();
}
+SpdySerializedFrame* SpdyFramer::SerializeHeaders(
+ const SpdyHeadersIR& headers) {
+ uint8 flags = 0;
+ if (headers.fin()) {
+ flags |= CONTROL_FLAG_FIN;
+ }
+
+ // The size, in bytes, of this frame not including the variable-length
+ // name-value block. Calculated as:
+ // 8 (control frame header) + 4 (stream ID)
+ size_t headers_size_before_name_value_block = 12;
+ // In SPDY 2, there were 2 unused bytes before payload.
+ if (protocol_version() < 3) {
+ headers_size_before_name_value_block += 2;
+ }
+
+ // The size of this frame, including variable-length name-value block.
+ size_t size = headers_size_before_name_value_block
+ + GetSerializedLength(protocol_version(),
+ &(headers.name_value_block()));
+
+ SpdyFrameBuilder builder(HEADERS, flags, protocol_version(), size);
+ builder.WriteUInt32(headers.stream_id());
+ if (protocol_version() < 3) {
+ builder.WriteUInt16(0); // Unused.
+ }
+ DCHECK_EQ(headers_size_before_name_value_block, builder.length());
+
+ SerializeNameValueBlock(&builder, headers);
+ DCHECK_EQ(size, builder.length());
+
+ return builder.take();
+}
+
SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate(
SpdyStreamId stream_id,
uint32 delta_window_size) const {
- DCHECK_GT(stream_id, 0u);
- DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
- DCHECK_GT(delta_window_size, 0u);
- DCHECK_LE(delta_window_size,
- static_cast<uint32>(kSpdyStreamMaximumWindowSize));
-
- size_t frame_size = SpdyWindowUpdateControlFrame::size();
- SpdyFrameBuilder frame(WINDOW_UPDATE, CONTROL_FLAG_NONE, spdy_version_,
- frame_size);
- frame.WriteUInt32(stream_id);
- frame.WriteUInt32(delta_window_size);
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take());
+ SpdyWindowUpdateIR window_update(stream_id, delta_window_size);
+ return reinterpret_cast<SpdyWindowUpdateControlFrame*>(
+ SerializeWindowUpdate(window_update));
+}
+
+SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
+ const SpdyWindowUpdateIR& window_update) const {
+ // Size, in bytes, of this WINDOW_UPDATE frame. Calculated as:
+ // 8 (control frame header) + 4 (stream id) + 4 (delta)
+ const size_t kWindowUpdateSize = 16;
+
+ SpdyFrameBuilder builder(WINDOW_UPDATE,
+ kNoFlags,
+ protocol_version(),
+ kWindowUpdateSize);
+ builder.WriteUInt32(window_update.stream_id());
+ builder.WriteUInt32(window_update.delta());
+ DCHECK_EQ(kWindowUpdateSize, builder.length());
+ return builder.take();
}
+// TODO(hkhalil): Gut with SpdyCredential removal.
SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame(
const SpdyCredential& credential) const {
- // Calculate the size of the frame by adding the size of the
- // variable length data to the size of the fixed length data.
- size_t frame_size = SpdyCredentialControlFrame::size() +
- credential.proof.length();
- DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u);
+ SpdyCredentialIR credential_ir(credential.slot);
+ credential_ir.set_proof(credential.proof);
for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
cert != credential.certs.end();
++cert) {
- frame_size += sizeof(uint32); // size of the cert_length field
- frame_size += cert->length(); // size of the cert_data field
+ credential_ir.AddCertificate(*cert);
}
+ return reinterpret_cast<SpdyCredentialControlFrame*>(
+ SerializeCredential(credential_ir));
+}
- SpdyFrameBuilder frame(CREDENTIAL, CONTROL_FLAG_NONE, spdy_version_,
- frame_size);
- frame.WriteUInt16(credential.slot);
- frame.WriteUInt32(credential.proof.size());
- frame.WriteBytes(credential.proof.c_str(), credential.proof.size());
- for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
- cert != credential.certs.end();
- ++cert) {
- frame.WriteUInt32(cert->length());
- frame.WriteBytes(cert->c_str(), cert->length());
+SpdySerializedFrame* SpdyFramer::SerializeCredential(
+ const SpdyCredentialIR& credential) const {
+ size_t size = 8; // Room for frame header.
+ size += 2; // Room for slot.
+ size += 4 + credential.proof().length(); // Room for proof.
+ for (SpdyCredentialIR::CertificateList::const_iterator it =
+ credential.certificates()->begin();
+ it != credential.certificates()->end();
+ ++it) {
+ size += 4 + it->length(); // Room for certificate.
+ }
+
+ SpdyFrameBuilder builder(CREDENTIAL, 0, protocol_version(), size);
+ builder.WriteUInt16(credential.slot());
+ builder.WriteStringPiece32(credential.proof());
+ for (SpdyCredentialIR::CertificateList::const_iterator it =
+ credential.certificates()->begin();
+ it != credential.certificates()->end();
+ ++it) {
+ builder.WriteStringPiece32(*it);
}
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take());
+ DCHECK_EQ(size, builder.length());
+ return builder.take();
}
SpdyDataFrame* SpdyFramer::CreateDataFrame(
- SpdyStreamId stream_id,
- const char* data,
+ SpdyStreamId stream_id, const char* data,
uint32 len, SpdyDataFlags flags) const {
- DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
- size_t frame_size = SpdyDataFrame::size() + len;
- SpdyFrameBuilder frame(stream_id, flags, frame_size);
- frame.WriteBytes(data, len);
- DCHECK_EQ(frame.length(), frame_size);
- return reinterpret_cast<SpdyDataFrame*>(frame.take());
+ DCHECK_EQ(0, flags & (!DATA_FLAG_FIN));
+
+ SpdyDataIR data_ir(stream_id, base::StringPiece(data, len));
+ data_ir.set_fin(flags & DATA_FLAG_FIN);
+ return reinterpret_cast<SpdyDataFrame*>(SerializeData(data_ir));
+}
+
+SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const {
+ // Size, in bytes, of this DATA frame. Calculated as:
+ // 4 (stream id) + 1 (flags) + 3 (length) + payload length
+ const size_t size = 8 + data.data().length();
+
+ SpdyDataFlags flags = DATA_FLAG_NONE;
+ if (data.fin()) {
+ flags = DATA_FLAG_FIN;
+ }
+
+ SpdyFrameBuilder builder(data.stream_id(), flags, size);
+ builder.WriteBytes(data.data().data(), data.data().length());
+ DCHECK_EQ(size, builder.length());
+ return builder.take();
}
// The following compression setting are based on Brian Olson's analysis. See
@@ -1912,8 +2068,30 @@ SpdyStreamId SpdyFramer::GetControlFrameStreamId(
return stream_id;
}
-void SpdyFramer::set_enable_compression(bool value) {
- enable_compression_ = value;
+void SpdyFramer::SerializeNameValueBlock(
+ SpdyFrameBuilder* builder,
+ const SpdyFrameWithNameValueBlockIR& frame) const {
+ const SpdyNameValueBlock* name_value_block = &(frame.name_value_block());
+
+ // Serialize number of headers.
+ if (protocol_version() < 3) {
+ builder->WriteUInt16(name_value_block->size());
+ } else {
+ builder->WriteUInt32(name_value_block->size());
+ }
+
+ // Serialize each header.
+ for (SpdyHeaderBlock::const_iterator it = name_value_block->begin();
+ it != name_value_block->end();
+ ++it) {
+ if (protocol_version() < 3) {
+ builder->WriteString(it->first);
+ builder->WriteString(it->second);
+ } else {
+ builder->WriteStringPiece32(it->first);
+ builder->WriteStringPiece32(it->second);
+ }
+ }
}
} // namespace net
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_protocol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698