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

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

Issue 1852423004: Implement SpdySerializedFrame move semantics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
« 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/spdy_framer.h" 5 #include "net/spdy/spdy_framer.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <iterator> 10 #include <iterator>
(...skipping 1701 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 const SpdyHeaderBlock& block = GetHpackDecoder()->decoded_block(); 1712 const SpdyHeaderBlock& block = GetHpackDecoder()->decoded_block();
1713 if (block.empty()) { 1713 if (block.empty()) {
1714 // Special-case this to make tests happy. 1714 // Special-case this to make tests happy.
1715 ProcessControlFrameHeaderBlock(NULL, 0, false); 1715 ProcessControlFrameHeaderBlock(NULL, 0, false);
1716 return; 1716 return;
1717 } 1717 }
1718 size_t payload_len = GetSerializedLength(protocol_version_, &block); 1718 size_t payload_len = GetSerializedLength(protocol_version_, &block);
1719 SpdyFrameBuilder builder(payload_len, SPDY3); 1719 SpdyFrameBuilder builder(payload_len, SPDY3);
1720 1720
1721 SerializeHeaderBlockWithoutCompression(&builder, block); 1721 SerializeHeaderBlockWithoutCompression(&builder, block);
1722 scoped_ptr<SpdyFrame> frame(builder.take()); 1722 SpdySerializedFrame frame = builder.take();
1723 1723
1724 // Preserve padding length, and reset it after the re-entrant call. 1724 // Preserve padding length, and reset it after the re-entrant call.
1725 size_t remaining_padding = remaining_padding_payload_length_; 1725 size_t remaining_padding = remaining_padding_payload_length_;
1726 1726
1727 remaining_padding_payload_length_ = 0; 1727 remaining_padding_payload_length_ = 0;
1728 remaining_data_length_ = frame->size(); 1728 remaining_data_length_ = frame.size();
1729 1729
1730 if (payload_len != 0) { 1730 if (payload_len != 0) {
1731 int compression_pct = 100 - (100 * compressed_len) / payload_len; 1731 int compression_pct = 100 - (100 * compressed_len) / payload_len;
1732 DVLOG(1) << "Net.SpdyHpackDecompressionPercentage: " << compression_pct; 1732 DVLOG(1) << "Net.SpdyHpackDecompressionPercentage: " << compression_pct;
1733 UMA_HISTOGRAM_PERCENTAGE("Net.SpdyHpackDecompressionPercentage", 1733 UMA_HISTOGRAM_PERCENTAGE("Net.SpdyHpackDecompressionPercentage",
1734 compression_pct); 1734 compression_pct);
1735 } 1735 }
1736 1736
1737 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); 1737 ProcessControlFrameHeaderBlock(frame.data(), frame.size(), false);
1738 1738
1739 remaining_padding_payload_length_ = remaining_padding; 1739 remaining_padding_payload_length_ = remaining_padding;
1740 remaining_data_length_ = remaining_padding; 1740 remaining_data_length_ = remaining_padding;
1741 } 1741 }
1742 1742
1743 bool SpdyFramer::ProcessSetting(const char* data) { 1743 bool SpdyFramer::ProcessSetting(const char* data) {
1744 int id_field; 1744 int id_field;
1745 SpdySettingsIds id; 1745 SpdySettingsIds id;
1746 uint8_t flags = 0; 1746 uint8_t flags = 0;
1747 uint32_t value; 1747 uint32_t value;
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 if (reader.GetBytesConsumed() != header_length) { 2199 if (reader.GetBytesConsumed() != header_length) {
2200 LOG(DFATAL) << "Buffer expected to consist entirely of headers, but only " 2200 LOG(DFATAL) << "Buffer expected to consist entirely of headers, but only "
2201 << reader.GetBytesConsumed() << " bytes consumed, from " 2201 << reader.GetBytesConsumed() << " bytes consumed, from "
2202 << header_length; 2202 << header_length;
2203 return false; 2203 return false;
2204 } 2204 }
2205 2205
2206 return true; 2206 return true;
2207 } 2207 }
2208 2208
2209 SpdySerializedFrame* SpdyFramer::SerializeData( 2209 SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) const {
2210 const SpdyDataIR& data_ir) const {
2211 uint8_t flags = DATA_FLAG_NONE; 2210 uint8_t flags = DATA_FLAG_NONE;
2212 if (data_ir.fin()) { 2211 if (data_ir.fin()) {
2213 flags = DATA_FLAG_FIN; 2212 flags = DATA_FLAG_FIN;
2214 } 2213 }
2215 2214
2216 if (protocol_version_ == SPDY3) { 2215 if (protocol_version_ == SPDY3) {
2217 const size_t size = GetDataFrameMinimumSize() + data_ir.data().length(); 2216 const size_t size = GetDataFrameMinimumSize() + data_ir.data().length();
2218 SpdyFrameBuilder builder(size, protocol_version_); 2217 SpdyFrameBuilder builder(size, protocol_version_);
2219 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); 2218 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2220 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); 2219 builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
(...skipping 17 matching lines...) Expand all
2238 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); 2237 builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
2239 if (data_ir.padding_payload_len() > 0) { 2238 if (data_ir.padding_payload_len() > 0) {
2240 string padding(data_ir.padding_payload_len(), 0); 2239 string padding(data_ir.padding_payload_len(), 0);
2241 builder.WriteBytes(padding.data(), padding.length()); 2240 builder.WriteBytes(padding.data(), padding.length());
2242 } 2241 }
2243 DCHECK_EQ(size_with_padding, builder.length()); 2242 DCHECK_EQ(size_with_padding, builder.length());
2244 return builder.take(); 2243 return builder.take();
2245 } 2244 }
2246 } 2245 }
2247 2246
2248 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( 2247 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
2249 const SpdyDataIR& data_ir) const { 2248 const SpdyDataIR& data_ir) const {
2250 uint8_t flags = DATA_FLAG_NONE; 2249 uint8_t flags = DATA_FLAG_NONE;
2251 if (data_ir.fin()) { 2250 if (data_ir.fin()) {
2252 flags = DATA_FLAG_FIN; 2251 flags = DATA_FLAG_FIN;
2253 } 2252 }
2254 2253
2255 size_t frame_size = GetDataFrameMinimumSize(); 2254 size_t frame_size = GetDataFrameMinimumSize();
2256 size_t num_padding_fields = 0; 2255 size_t num_padding_fields = 0;
2257 if (protocol_version_ == HTTP2) { 2256 if (protocol_version_ == HTTP2) {
2258 if (data_ir.padded()) { 2257 if (data_ir.padded()) {
(...skipping 11 matching lines...) Expand all
2270 } 2269 }
2271 builder.OverwriteLength(*this, num_padding_fields + 2270 builder.OverwriteLength(*this, num_padding_fields +
2272 data_ir.data().length() + data_ir.padding_payload_len()); 2271 data_ir.data().length() + data_ir.padding_payload_len());
2273 } else { 2272 } else {
2274 builder.OverwriteLength(*this, data_ir.data().length()); 2273 builder.OverwriteLength(*this, data_ir.data().length());
2275 } 2274 }
2276 DCHECK_EQ(frame_size, builder.length()); 2275 DCHECK_EQ(frame_size, builder.length());
2277 return builder.take(); 2276 return builder.take();
2278 } 2277 }
2279 2278
2280 SpdySerializedFrame* SpdyFramer::SerializeSynStream( 2279 SpdySerializedFrame SpdyFramer::SerializeSynStream(
2281 const SpdySynStreamIR& syn_stream) { 2280 const SpdySynStreamIR& syn_stream) {
2282 DCHECK_EQ(SPDY3, protocol_version_); 2281 DCHECK_EQ(SPDY3, protocol_version_);
2283 uint8_t flags = 0; 2282 uint8_t flags = 0;
2284 if (syn_stream.fin()) { 2283 if (syn_stream.fin()) {
2285 flags |= CONTROL_FLAG_FIN; 2284 flags |= CONTROL_FLAG_FIN;
2286 } 2285 }
2287 if (syn_stream.unidirectional()) { 2286 if (syn_stream.unidirectional()) {
2288 flags |= CONTROL_FLAG_UNIDIRECTIONAL; 2287 flags |= CONTROL_FLAG_UNIDIRECTIONAL;
2289 } 2288 }
2290 2289
(...skipping 22 matching lines...) Expand all
2313 GetSerializedLength(protocol_version_, &(syn_stream.header_block())); 2312 GetSerializedLength(protocol_version_, &(syn_stream.header_block()));
2314 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), 2313 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
2315 SYN_STREAM, 2314 SYN_STREAM,
2316 payload_len, 2315 payload_len,
2317 builder.length()); 2316 builder.length());
2318 } 2317 }
2319 2318
2320 return builder.take(); 2319 return builder.take();
2321 } 2320 }
2322 2321
2323 SpdySerializedFrame* SpdyFramer::SerializeSynReply( 2322 SpdySerializedFrame SpdyFramer::SerializeSynReply(
2324 const SpdySynReplyIR& syn_reply) { 2323 const SpdySynReplyIR& syn_reply) {
2325 DCHECK_EQ(SPDY3, protocol_version_); 2324 DCHECK_EQ(SPDY3, protocol_version_);
2326 uint8_t flags = 0; 2325 uint8_t flags = 0;
2327 if (syn_reply.fin()) { 2326 if (syn_reply.fin()) {
2328 flags |= CONTROL_FLAG_FIN; 2327 flags |= CONTROL_FLAG_FIN;
2329 } 2328 }
2330 2329
2331 // The size of this frame, including variable-length header block. 2330 // The size of this frame, including variable-length header block.
2332 const size_t size = 2331 const size_t size =
2333 GetSynReplyMinimumSize() + GetSerializedLength(syn_reply.header_block()); 2332 GetSynReplyMinimumSize() + GetSerializedLength(syn_reply.header_block());
2334 2333
2335 SpdyFrameBuilder builder(size, protocol_version_); 2334 SpdyFrameBuilder builder(size, protocol_version_);
2336 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 2335 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
2337 builder.WriteUInt32(syn_reply.stream_id()); 2336 builder.WriteUInt32(syn_reply.stream_id());
2338 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); 2337 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
2339 SerializeHeaderBlock(&builder, syn_reply); 2338 SerializeHeaderBlock(&builder, syn_reply);
2340 2339
2341 if (debug_visitor_) { 2340 if (debug_visitor_) {
2342 const size_t payload_len = 2341 const size_t payload_len =
2343 GetSerializedLength(protocol_version_, &(syn_reply.header_block())); 2342 GetSerializedLength(protocol_version_, &(syn_reply.header_block()));
2344 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), 2343 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(),
2345 SYN_REPLY, 2344 SYN_REPLY,
2346 payload_len, 2345 payload_len,
2347 builder.length()); 2346 builder.length());
2348 } 2347 }
2349 2348
2350 return builder.take(); 2349 return builder.take();
2351 } 2350 }
2352 2351
2353 SpdySerializedFrame* SpdyFramer::SerializeRstStream( 2352 SpdySerializedFrame SpdyFramer::SerializeRstStream(
2354 const SpdyRstStreamIR& rst_stream) const { 2353 const SpdyRstStreamIR& rst_stream) const {
2355 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM 2354 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
2356 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, 2355 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
2357 // which doesn't currently include RST_STREAM payloads. GFE flags have been 2356 // which doesn't currently include RST_STREAM payloads. GFE flags have been
2358 // commented but left in place to simplify future patching. 2357 // commented but left in place to simplify future patching.
2359 // Compute the output buffer size, taking opaque data into account. 2358 // Compute the output buffer size, taking opaque data into account.
2360 size_t expected_length = GetRstStreamMinimumSize(); 2359 size_t expected_length = GetRstStreamMinimumSize();
2361 SpdyFrameBuilder builder(expected_length, protocol_version_); 2360 SpdyFrameBuilder builder(expected_length, protocol_version_);
2362 2361
2363 // Serialize the RST_STREAM frame. 2362 // Serialize the RST_STREAM frame.
2364 if (protocol_version_ == SPDY3) { 2363 if (protocol_version_ == SPDY3) {
2365 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); 2364 builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
2366 builder.WriteUInt32(rst_stream.stream_id()); 2365 builder.WriteUInt32(rst_stream.stream_id());
2367 } else { 2366 } else {
2368 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); 2367 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
2369 } 2368 }
2370 2369
2371 builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus( 2370 builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus(
2372 protocol_version_, rst_stream.status())); 2371 protocol_version_, rst_stream.status()));
2373 2372
2374 DCHECK_EQ(expected_length, builder.length()); 2373 DCHECK_EQ(expected_length, builder.length());
2375 return builder.take(); 2374 return builder.take();
2376 } 2375 }
2377 2376
2378 SpdySerializedFrame* SpdyFramer::SerializeSettings( 2377 SpdySerializedFrame SpdyFramer::SerializeSettings(
2379 const SpdySettingsIR& settings) const { 2378 const SpdySettingsIR& settings) const {
2380 uint8_t flags = 0; 2379 uint8_t flags = 0;
2381 2380
2382 if (protocol_version_ == SPDY3) { 2381 if (protocol_version_ == SPDY3) {
2383 if (settings.clear_settings()) { 2382 if (settings.clear_settings()) {
2384 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; 2383 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
2385 } 2384 }
2386 } else { 2385 } else {
2387 if (settings.is_ack()) { 2386 if (settings.is_ack()) {
2388 flags |= SETTINGS_FLAG_ACK; 2387 flags |= SETTINGS_FLAG_ACK;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 builder.WriteBytes(&id_and_flags_wire, 4); 2429 builder.WriteBytes(&id_and_flags_wire, 4);
2431 } else { 2430 } else {
2432 builder.WriteUInt16(static_cast<uint16_t>(setting_id)); 2431 builder.WriteUInt16(static_cast<uint16_t>(setting_id));
2433 } 2432 }
2434 builder.WriteUInt32(it->second.value); 2433 builder.WriteUInt32(it->second.value);
2435 } 2434 }
2436 DCHECK_EQ(size, builder.length()); 2435 DCHECK_EQ(size, builder.length());
2437 return builder.take(); 2436 return builder.take();
2438 } 2437 }
2439 2438
2440 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { 2439 SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
2441 SpdyFrameBuilder builder(GetPingSize(), protocol_version_); 2440 SpdyFrameBuilder builder(GetPingSize(), protocol_version_);
2442 if (protocol_version_ == SPDY3) { 2441 if (protocol_version_ == SPDY3) {
2443 builder.WriteControlFrameHeader(*this, PING, kNoFlags); 2442 builder.WriteControlFrameHeader(*this, PING, kNoFlags);
2444 builder.WriteUInt32(static_cast<uint32_t>(ping.id())); 2443 builder.WriteUInt32(static_cast<uint32_t>(ping.id()));
2445 } else { 2444 } else {
2446 uint8_t flags = 0; 2445 uint8_t flags = 0;
2447 if (ping.is_ack()) { 2446 if (ping.is_ack()) {
2448 flags |= PING_FLAG_ACK; 2447 flags |= PING_FLAG_ACK;
2449 } 2448 }
2450 builder.BeginNewFrame(*this, PING, flags, 0); 2449 builder.BeginNewFrame(*this, PING, flags, 0);
2451 builder.WriteUInt64(ping.id()); 2450 builder.WriteUInt64(ping.id());
2452 } 2451 }
2453 DCHECK_EQ(GetPingSize(), builder.length()); 2452 DCHECK_EQ(GetPingSize(), builder.length());
2454 return builder.take(); 2453 return builder.take();
2455 } 2454 }
2456 2455
2457 SpdySerializedFrame* SpdyFramer::SerializeGoAway( 2456 SpdySerializedFrame SpdyFramer::SerializeGoAway(
2458 const SpdyGoAwayIR& goaway) const { 2457 const SpdyGoAwayIR& goaway) const {
2459
2460 // Compute the output buffer size, take opaque data into account. 2458 // Compute the output buffer size, take opaque data into account.
2461 size_t expected_length = GetGoAwayMinimumSize(); 2459 size_t expected_length = GetGoAwayMinimumSize();
2462 if (protocol_version_ == HTTP2) { 2460 if (protocol_version_ == HTTP2) {
2463 expected_length += goaway.description().size(); 2461 expected_length += goaway.description().size();
2464 } 2462 }
2465 SpdyFrameBuilder builder(expected_length, protocol_version_); 2463 SpdyFrameBuilder builder(expected_length, protocol_version_);
2466 2464
2467 // Serialize the GOAWAY frame. 2465 // Serialize the GOAWAY frame.
2468 if (protocol_version_ == SPDY3) { 2466 if (protocol_version_ == SPDY3) {
2469 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); 2467 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
(...skipping 11 matching lines...) Expand all
2481 // In HTTP2, GOAWAY frames may also specify opaque data. 2479 // In HTTP2, GOAWAY frames may also specify opaque data.
2482 if ((protocol_version_ == HTTP2) && (goaway.description().size() > 0)) { 2480 if ((protocol_version_ == HTTP2) && (goaway.description().size() > 0)) {
2483 builder.WriteBytes(goaway.description().data(), 2481 builder.WriteBytes(goaway.description().data(),
2484 goaway.description().size()); 2482 goaway.description().size());
2485 } 2483 }
2486 2484
2487 DCHECK_EQ(expected_length, builder.length()); 2485 DCHECK_EQ(expected_length, builder.length());
2488 return builder.take(); 2486 return builder.take();
2489 } 2487 }
2490 2488
2491 SpdySerializedFrame* SpdyFramer::SerializeHeaders( 2489 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) {
2492 const SpdyHeadersIR& headers) {
2493 uint8_t flags = 0; 2490 uint8_t flags = 0;
2494 if (headers.fin()) { 2491 if (headers.fin()) {
2495 flags |= CONTROL_FLAG_FIN; 2492 flags |= CONTROL_FLAG_FIN;
2496 } 2493 }
2497 if (protocol_version_ == HTTP2) { 2494 if (protocol_version_ == HTTP2) {
2498 // This will get overwritten if we overflow into a CONTINUATION frame. 2495 // This will get overwritten if we overflow into a CONTINUATION frame.
2499 flags |= HEADERS_FLAG_END_HEADERS; 2496 flags |= HEADERS_FLAG_END_HEADERS;
2500 if (headers.has_priority()) { 2497 if (headers.has_priority()) {
2501 flags |= HEADERS_FLAG_PRIORITY; 2498 flags |= HEADERS_FLAG_PRIORITY;
2502 } 2499 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2582 GetSerializedLength(protocol_version_, &(headers.header_block())); 2579 GetSerializedLength(protocol_version_, &(headers.header_block()));
2583 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), 2580 debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
2584 HEADERS, 2581 HEADERS,
2585 payload_len, 2582 payload_len,
2586 builder.length()); 2583 builder.length());
2587 } 2584 }
2588 2585
2589 return builder.take(); 2586 return builder.take();
2590 } 2587 }
2591 2588
2592 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( 2589 SpdySerializedFrame SpdyFramer::SerializeWindowUpdate(
2593 const SpdyWindowUpdateIR& window_update) const { 2590 const SpdyWindowUpdateIR& window_update) const {
2594 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version_); 2591 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version_);
2595 if (protocol_version_ == SPDY3) { 2592 if (protocol_version_ == SPDY3) {
2596 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); 2593 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
2597 builder.WriteUInt32(window_update.stream_id()); 2594 builder.WriteUInt32(window_update.stream_id());
2598 } else { 2595 } else {
2599 builder.BeginNewFrame(*this, 2596 builder.BeginNewFrame(*this,
2600 WINDOW_UPDATE, 2597 WINDOW_UPDATE,
2601 kNoFlags, 2598 kNoFlags,
2602 window_update.stream_id()); 2599 window_update.stream_id());
2603 } 2600 }
2604 builder.WriteUInt32(window_update.delta()); 2601 builder.WriteUInt32(window_update.delta());
2605 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); 2602 DCHECK_EQ(GetWindowUpdateSize(), builder.length());
2606 return builder.take(); 2603 return builder.take();
2607 } 2604 }
2608 2605
2609 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { 2606 SpdySerializedFrame SpdyFramer::SerializeBlocked(
2607 const SpdyBlockedIR& blocked) const {
2610 DCHECK_EQ(HTTP2, protocol_version_); 2608 DCHECK_EQ(HTTP2, protocol_version_);
2611 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version_); 2609 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version_);
2612 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); 2610 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
2613 return builder.take(); 2611 return builder.take();
2614 } 2612 }
2615 2613
2616 SpdyFrame* SpdyFramer::SerializePushPromise( 2614 SpdySerializedFrame SpdyFramer::SerializePushPromise(
2617 const SpdyPushPromiseIR& push_promise) { 2615 const SpdyPushPromiseIR& push_promise) {
2618 DCHECK_EQ(HTTP2, protocol_version_); 2616 DCHECK_EQ(HTTP2, protocol_version_);
2619 uint8_t flags = 0; 2617 uint8_t flags = 0;
2620 // This will get overwritten if we overflow into a CONTINUATION frame. 2618 // This will get overwritten if we overflow into a CONTINUATION frame.
2621 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2619 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2622 // The size of this frame, including variable-length name-value block. 2620 // The size of this frame, including variable-length name-value block.
2623 size_t size = GetPushPromiseMinimumSize(); 2621 size_t size = GetPushPromiseMinimumSize();
2624 2622
2625 if (push_promise.padded()) { 2623 if (push_promise.padded()) {
2626 flags |= PUSH_PROMISE_FLAG_PADDED; 2624 flags |= PUSH_PROMISE_FLAG_PADDED;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 payload_len, 2676 payload_len,
2679 builder.length()); 2677 builder.length());
2680 } 2678 }
2681 2679
2682 return builder.take(); 2680 return builder.take();
2683 } 2681 }
2684 2682
2685 // TODO(jgraettinger): This implementation is incorrect. The continuation 2683 // TODO(jgraettinger): This implementation is incorrect. The continuation
2686 // frame continues a previously-begun HPACK encoding; it doesn't begin a 2684 // frame continues a previously-begun HPACK encoding; it doesn't begin a
2687 // new one. Figure out whether it makes sense to keep SerializeContinuation(). 2685 // new one. Figure out whether it makes sense to keep SerializeContinuation().
2688 SpdyFrame* SpdyFramer::SerializeContinuation( 2686 SpdySerializedFrame SpdyFramer::SerializeContinuation(
2689 const SpdyContinuationIR& continuation) { 2687 const SpdyContinuationIR& continuation) {
2690 CHECK_EQ(HTTP2, protocol_version_); 2688 CHECK_EQ(HTTP2, protocol_version_);
2691 uint8_t flags = 0; 2689 uint8_t flags = 0;
2692 if (continuation.end_headers()) { 2690 if (continuation.end_headers()) {
2693 flags |= HEADERS_FLAG_END_HEADERS; 2691 flags |= HEADERS_FLAG_END_HEADERS;
2694 } 2692 }
2695 2693
2696 // The size of this frame, including variable-length name-value block. 2694 // The size of this frame, including variable-length name-value block.
2697 size_t size = GetContinuationMinimumSize(); 2695 size_t size = GetContinuationMinimumSize();
2698 string hpack_encoding; 2696 string hpack_encoding;
2699 if (enable_compression_) { 2697 if (enable_compression_) {
2700 GetHpackEncoder()->EncodeHeaderSet(continuation.header_block(), 2698 GetHpackEncoder()->EncodeHeaderSet(continuation.header_block(),
2701 &hpack_encoding); 2699 &hpack_encoding);
2702 } else { 2700 } else {
2703 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( 2701 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2704 continuation.header_block(), &hpack_encoding); 2702 continuation.header_block(), &hpack_encoding);
2705 } 2703 }
2706 size += hpack_encoding.size(); 2704 size += hpack_encoding.size();
2707 2705
2708 SpdyFrameBuilder builder(size, protocol_version_); 2706 SpdyFrameBuilder builder(size, protocol_version_);
2709 builder.BeginNewFrame(*this, CONTINUATION, flags, 2707 builder.BeginNewFrame(*this, CONTINUATION, flags,
2710 continuation.stream_id()); 2708 continuation.stream_id());
2711 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); 2709 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2712 2710
2713 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2711 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2714 return builder.take(); 2712 return builder.take();
2715 } 2713 }
2716 2714
2717 SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { 2715 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) {
2718 DCHECK_EQ(HTTP2, protocol_version_); 2716 DCHECK_EQ(HTTP2, protocol_version_);
2719 2717
2720 size_t size = GetAltSvcMinimumSize(); 2718 size_t size = GetAltSvcMinimumSize();
2721 size += altsvc_ir.origin().length(); 2719 size += altsvc_ir.origin().length();
2722 string value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue( 2720 string value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
2723 altsvc_ir.altsvc_vector()); 2721 altsvc_ir.altsvc_vector());
2724 size += value.length(); 2722 size += value.length();
2725 2723
2726 SpdyFrameBuilder builder(size, protocol_version_); 2724 SpdyFrameBuilder builder(size, protocol_version_);
2727 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id()); 2725 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id());
2728 2726
2729 builder.WriteUInt16(altsvc_ir.origin().length()); 2727 builder.WriteUInt16(altsvc_ir.origin().length());
2730 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length()); 2728 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length());
2731 builder.WriteBytes(value.data(), value.length()); 2729 builder.WriteBytes(value.data(), value.length());
2732 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); 2730 DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
2733 return builder.take(); 2731 return builder.take();
2734 } 2732 }
2735 2733
2736 SpdyFrame* SpdyFramer::SerializePriority(const SpdyPriorityIR& priority) const { 2734 SpdySerializedFrame SpdyFramer::SerializePriority(
2735 const SpdyPriorityIR& priority) const {
2737 DCHECK_EQ(HTTP2, protocol_version_); 2736 DCHECK_EQ(HTTP2, protocol_version_);
2738 size_t size = GetPrioritySize(); 2737 size_t size = GetPrioritySize();
2739 2738
2740 SpdyFrameBuilder builder(size, protocol_version_); 2739 SpdyFrameBuilder builder(size, protocol_version_);
2741 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id()); 2740 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id());
2742 2741
2743 builder.WriteUInt32(PackStreamDependencyValues(priority.exclusive(), 2742 builder.WriteUInt32(PackStreamDependencyValues(priority.exclusive(),
2744 priority.parent_stream_id())); 2743 priority.parent_stream_id()));
2745 builder.WriteUInt8(priority.weight()); 2744 builder.WriteUInt8(priority.weight());
2746 DCHECK_EQ(GetPrioritySize(), builder.length()); 2745 DCHECK_EQ(GetPrioritySize(), builder.length());
2747 return builder.take(); 2746 return builder.take();
2748 } 2747 }
2749 2748
2750 namespace { 2749 namespace {
2751 2750
2752 class FrameSerializationVisitor : public SpdyFrameVisitor { 2751 class FrameSerializationVisitor : public SpdyFrameVisitor {
2753 public: 2752 public:
2754 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} 2753 explicit FrameSerializationVisitor(SpdyFramer* framer)
2754 : framer_(framer), frame_() {}
2755 ~FrameSerializationVisitor() override {} 2755 ~FrameSerializationVisitor() override {}
2756 2756
2757 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } 2757 SpdySerializedFrame ReleaseSerializedFrame() { return std::move(frame_); }
2758 2758
2759 void VisitData(const SpdyDataIR& data) override { 2759 void VisitData(const SpdyDataIR& data) override {
2760 frame_.reset(framer_->SerializeData(data)); 2760 frame_ = framer_->SerializeData(data);
2761 } 2761 }
2762 void VisitSynStream(const SpdySynStreamIR& syn_stream) override { 2762 void VisitSynStream(const SpdySynStreamIR& syn_stream) override {
2763 frame_.reset(framer_->SerializeSynStream(syn_stream)); 2763 frame_ = framer_->SerializeSynStream(syn_stream);
2764 } 2764 }
2765 void VisitSynReply(const SpdySynReplyIR& syn_reply) override { 2765 void VisitSynReply(const SpdySynReplyIR& syn_reply) override {
2766 frame_.reset(framer_->SerializeSynReply(syn_reply)); 2766 frame_ = framer_->SerializeSynReply(syn_reply);
2767 } 2767 }
2768 void VisitRstStream(const SpdyRstStreamIR& rst_stream) override { 2768 void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
2769 frame_.reset(framer_->SerializeRstStream(rst_stream)); 2769 frame_ = framer_->SerializeRstStream(rst_stream);
2770 } 2770 }
2771 void VisitSettings(const SpdySettingsIR& settings) override { 2771 void VisitSettings(const SpdySettingsIR& settings) override {
2772 frame_.reset(framer_->SerializeSettings(settings)); 2772 frame_ = framer_->SerializeSettings(settings);
2773 } 2773 }
2774 void VisitPing(const SpdyPingIR& ping) override { 2774 void VisitPing(const SpdyPingIR& ping) override {
2775 frame_.reset(framer_->SerializePing(ping)); 2775 frame_ = framer_->SerializePing(ping);
2776 } 2776 }
2777 void VisitGoAway(const SpdyGoAwayIR& goaway) override { 2777 void VisitGoAway(const SpdyGoAwayIR& goaway) override {
2778 frame_.reset(framer_->SerializeGoAway(goaway)); 2778 frame_ = framer_->SerializeGoAway(goaway);
2779 } 2779 }
2780 void VisitHeaders(const SpdyHeadersIR& headers) override { 2780 void VisitHeaders(const SpdyHeadersIR& headers) override {
2781 frame_.reset(framer_->SerializeHeaders(headers)); 2781 frame_ = framer_->SerializeHeaders(headers);
2782 } 2782 }
2783 void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override { 2783 void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
2784 frame_.reset(framer_->SerializeWindowUpdate(window_update)); 2784 frame_ = framer_->SerializeWindowUpdate(window_update);
2785 } 2785 }
2786 void VisitBlocked(const SpdyBlockedIR& blocked) override { 2786 void VisitBlocked(const SpdyBlockedIR& blocked) override {
2787 frame_.reset(framer_->SerializeBlocked(blocked)); 2787 frame_ = framer_->SerializeBlocked(blocked);
2788 } 2788 }
2789 void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override { 2789 void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
2790 frame_.reset(framer_->SerializePushPromise(push_promise)); 2790 frame_ = framer_->SerializePushPromise(push_promise);
2791 } 2791 }
2792 void VisitContinuation(const SpdyContinuationIR& continuation) override { 2792 void VisitContinuation(const SpdyContinuationIR& continuation) override {
2793 frame_.reset(framer_->SerializeContinuation(continuation)); 2793 frame_ = framer_->SerializeContinuation(continuation);
2794 } 2794 }
2795 void VisitAltSvc(const SpdyAltSvcIR& altsvc) override { 2795 void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
2796 frame_.reset(framer_->SerializeAltSvc(altsvc)); 2796 frame_ = framer_->SerializeAltSvc(altsvc);
2797 } 2797 }
2798 void VisitPriority(const SpdyPriorityIR& priority) override { 2798 void VisitPriority(const SpdyPriorityIR& priority) override {
2799 frame_.reset(framer_->SerializePriority(priority)); 2799 frame_ = framer_->SerializePriority(priority);
2800 } 2800 }
2801 2801
2802 private: 2802 private:
2803 SpdyFramer* framer_; 2803 SpdyFramer* framer_;
2804 scoped_ptr<SpdySerializedFrame> frame_; 2804 SpdySerializedFrame frame_;
2805 }; 2805 };
2806 2806
2807 } // namespace 2807 } // namespace
2808 2808
2809 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { 2809 SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
2810 FrameSerializationVisitor visitor(this); 2810 FrameSerializationVisitor visitor(this);
2811 frame.Visit(&visitor); 2811 frame.Visit(&visitor);
2812 return visitor.ReleaseSerializedFrame(); 2812 return visitor.ReleaseSerializedFrame();
2813 } 2813 }
2814 2814
2815 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { 2815 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
2816 const size_t uncompressed_length = 2816 const size_t uncompressed_length =
2817 GetSerializedLength(protocol_version_, &headers); 2817 GetSerializedLength(protocol_version_, &headers);
2818 if (!enable_compression_) { 2818 if (!enable_compression_) {
2819 return uncompressed_length; 2819 return uncompressed_length;
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 return SerializeHeaderBlockWithoutCompression(builder, 3090 return SerializeHeaderBlockWithoutCompression(builder,
3091 frame.header_block()); 3091 frame.header_block());
3092 } 3092 }
3093 3093
3094 // First build an uncompressed version to be fed into the compressor. 3094 // First build an uncompressed version to be fed into the compressor.
3095 const size_t uncompressed_len = 3095 const size_t uncompressed_len =
3096 GetSerializedLength(protocol_version_, &(frame.header_block())); 3096 GetSerializedLength(protocol_version_, &(frame.header_block()));
3097 SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version_); 3097 SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version_);
3098 SerializeHeaderBlockWithoutCompression(&uncompressed_builder, 3098 SerializeHeaderBlockWithoutCompression(&uncompressed_builder,
3099 frame.header_block()); 3099 frame.header_block());
3100 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take()); 3100 SpdySerializedFrame uncompressed_payload(uncompressed_builder.take());
3101 3101
3102 z_stream* compressor = GetHeaderCompressor(); 3102 z_stream* compressor = GetHeaderCompressor();
3103 if (!compressor) { 3103 if (!compressor) {
3104 LOG(DFATAL) << "Could not obtain compressor."; 3104 LOG(DFATAL) << "Could not obtain compressor.";
3105 return; 3105 return;
3106 } 3106 }
3107 // Create an output frame. 3107 // Create an output frame.
3108 // Since we'll be performing lots of flushes when compressing the data, 3108 // Since we'll be performing lots of flushes when compressing the data,
3109 // zlib's lower bounds may be insufficient. 3109 // zlib's lower bounds may be insufficient.
3110 // 3110 //
3111 // TODO(akalin): Avoid the duplicate calculation with 3111 // TODO(akalin): Avoid the duplicate calculation with
3112 // GetSerializedLength(const SpdyHeaderBlock&). 3112 // GetSerializedLength(const SpdyHeaderBlock&).
3113 const int compressed_max_size = 3113 const int compressed_max_size =
3114 2 * deflateBound(compressor, uncompressed_len); 3114 2 * deflateBound(compressor, uncompressed_len);
3115 3115
3116 // TODO(phajdan.jr): Clean up after we no longer need 3116 // TODO(phajdan.jr): Clean up after we no longer need
3117 // to workaround http://crbug.com/139744. 3117 // to workaround http://crbug.com/139744.
3118 #if defined(USE_SYSTEM_ZLIB) 3118 #if defined(USE_SYSTEM_ZLIB)
3119 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data()); 3119 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload.data());
3120 compressor->avail_in = uncompressed_len; 3120 compressor->avail_in = uncompressed_len;
3121 #endif // defined(USE_SYSTEM_ZLIB) 3121 #endif // defined(USE_SYSTEM_ZLIB)
3122 compressor->next_out = reinterpret_cast<Bytef*>( 3122 compressor->next_out = reinterpret_cast<Bytef*>(
3123 builder->GetWritableBuffer(compressed_max_size)); 3123 builder->GetWritableBuffer(compressed_max_size));
3124 compressor->avail_out = compressed_max_size; 3124 compressor->avail_out = compressed_max_size;
3125 3125
3126 // TODO(phajdan.jr): Clean up after we no longer need 3126 // TODO(phajdan.jr): Clean up after we no longer need
3127 // to workaround http://crbug.com/139744. 3127 // to workaround http://crbug.com/139744.
3128 #if defined(USE_SYSTEM_ZLIB) 3128 #if defined(USE_SYSTEM_ZLIB)
3129 int rv = deflate(compressor, Z_SYNC_FLUSH); 3129 int rv = deflate(compressor, Z_SYNC_FLUSH);
3130 if (rv != Z_OK) { // How can we know that it compressed everything? 3130 if (rv != Z_OK) { // How can we know that it compressed everything?
3131 // This shouldn't happen, right? 3131 // This shouldn't happen, right?
3132 LOG(WARNING) << "deflate failure: " << rv; 3132 LOG(WARNING) << "deflate failure: " << rv;
3133 // TODO(akalin): Upstream this return. 3133 // TODO(akalin): Upstream this return.
3134 return; 3134 return;
3135 } 3135 }
3136 #else 3136 #else
3137 WriteHeaderBlockToZ(&frame.header_block(), compressor); 3137 WriteHeaderBlockToZ(&frame.header_block(), compressor);
3138 #endif // defined(USE_SYSTEM_ZLIB) 3138 #endif // defined(USE_SYSTEM_ZLIB)
3139 3139
3140 int compressed_size = compressed_max_size - compressor->avail_out; 3140 int compressed_size = compressed_max_size - compressor->avail_out;
3141 builder->Seek(compressed_size); 3141 builder->Seek(compressed_size);
3142 builder->RewriteLength(*this); 3142 builder->RewriteLength(*this);
3143 } 3143 }
3144 3144
3145 } // namespace net 3145 } // namespace net
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