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

Side by Side Diff: net/quic/quic_headers_stream.cc

Issue 1572013002: relnote: QUIC header streams support to receive PUSH_PROMISE. Protected by --quic_supports_push_pr… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@14_CL_111507546
Patch Set: Created 4 years, 11 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/quic/quic_headers_stream.h ('k') | net/quic/quic_headers_stream_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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/quic/quic_headers_stream.h" 5 #include "net/quic/quic_headers_stream.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "net/quic/quic_bug_tracker.h" 10 #include "net/quic/quic_bug_tracker.h"
11 #include "net/quic/quic_flags.h" 11 #include "net/quic/quic_flags.h"
12 #include "net/quic/quic_headers_stream.h" 12 #include "net/quic/quic_headers_stream.h"
13 #include "net/quic/quic_spdy_session.h" 13 #include "net/quic/quic_spdy_session.h"
14 #include "net/quic/quic_time.h" 14 #include "net/quic/quic_time.h"
15 15
16 using base::StringPiece; 16 using base::StringPiece;
17 using net::HTTP2; 17 using net::HTTP2;
18 using net::SpdyFrameType; 18 using net::SpdyFrameType;
19 using std::string; 19 using std::string;
20 20
21 namespace net { 21 namespace net {
22 22
23 namespace {
24
25 const QuicStreamId kInvalidStreamId = 0;
26
27 } // namespace
28
29 // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to 23 // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to
30 // the QuicSpdyStream, and closes the connection if any unexpected frames 24 // the QuicSpdyStream, and closes the connection if any unexpected frames
31 // are received. 25 // are received.
32 class QuicHeadersStream::SpdyFramerVisitor 26 class QuicHeadersStream::SpdyFramerVisitor
33 : public SpdyFramerVisitorInterface, 27 : public SpdyFramerVisitorInterface,
34 public SpdyFramerDebugVisitorInterface { 28 public SpdyFramerDebugVisitorInterface {
35 public: 29 public:
36 explicit SpdyFramerVisitor(QuicHeadersStream* stream) : stream_(stream) {} 30 explicit SpdyFramerVisitor(QuicHeadersStream* stream) : stream_(stream) {}
37 31
38 // SpdyFramerVisitorInterface implementation 32 // SpdyFramerVisitorInterface implementation
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 stream_->OnHeaders(stream_id, has_priority, priority, fin); 131 stream_->OnHeaders(stream_id, has_priority, priority, fin);
138 } 132 }
139 133
140 void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override { 134 void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {
141 CloseConnection("SPDY WINDOW_UPDATE frame received."); 135 CloseConnection("SPDY WINDOW_UPDATE frame received.");
142 } 136 }
143 137
144 void OnPushPromise(SpdyStreamId stream_id, 138 void OnPushPromise(SpdyStreamId stream_id,
145 SpdyStreamId promised_stream_id, 139 SpdyStreamId promised_stream_id,
146 bool end) override { 140 bool end) override {
147 CloseConnection("SPDY PUSH_PROMISE frame received."); 141 if (!stream_->supports_push_promise()) {
142 CloseConnection("PUSH_PROMISE not supported.");
143 return;
144 }
145 if (!stream_->IsConnected()) {
146 return;
147 }
148 stream_->OnPushPromise(stream_id, promised_stream_id, end);
148 } 149 }
149 150
150 void OnContinuation(SpdyStreamId stream_id, bool end) override {} 151 void OnContinuation(SpdyStreamId stream_id, bool end) override {}
151 152
152 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { 153 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override {
153 CloseConnection("Unknown frame type received."); 154 CloseConnection("Unknown frame type received.");
154 return false; 155 return false;
155 } 156 }
156 157
157 // SpdyFramerDebugVisitorInterface implementation 158 // SpdyFramerDebugVisitorInterface implementation
(...skipping 21 matching lines...) Expand all
179 private: 180 private:
180 QuicHeadersStream* stream_; 181 QuicHeadersStream* stream_;
181 182
182 DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor); 183 DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor);
183 }; 184 };
184 185
185 QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session) 186 QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
186 : ReliableQuicStream(kHeadersStreamId, session), 187 : ReliableQuicStream(kHeadersStreamId, session),
187 spdy_session_(session), 188 spdy_session_(session),
188 stream_id_(kInvalidStreamId), 189 stream_id_(kInvalidStreamId),
190 promised_stream_id_(kInvalidStreamId),
189 fin_(false), 191 fin_(false),
190 frame_len_(0), 192 frame_len_(0),
191 measure_headers_hol_blocking_time_( 193 measure_headers_hol_blocking_time_(
192 FLAGS_quic_measure_headers_hol_blocking_time), 194 FLAGS_quic_measure_headers_hol_blocking_time),
195 supports_push_promise_(
196 session->perspective() == Perspective::IS_CLIENT &&
197 FLAGS_quic_supports_push_promise),
193 cur_max_timestamp_(QuicTime::Zero()), 198 cur_max_timestamp_(QuicTime::Zero()),
194 prev_max_timestamp_(QuicTime::Zero()), 199 prev_max_timestamp_(QuicTime::Zero()),
195 spdy_framer_(HTTP2), 200 spdy_framer_(HTTP2),
196 spdy_framer_visitor_(new SpdyFramerVisitor(this)) { 201 spdy_framer_visitor_(new SpdyFramerVisitor(this)) {
197 spdy_framer_.set_visitor(spdy_framer_visitor_.get()); 202 spdy_framer_.set_visitor(spdy_framer_visitor_.get());
198 spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); 203 spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
199 // The headers stream is exempt from connection level flow control. 204 // The headers stream is exempt from connection level flow control.
200 DisableConnectionFlowControlForThisStream(); 205 DisableConnectionFlowControlForThisStream();
201 } 206 }
202 207
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 } 294 }
290 spdy_session_->OnStreamHeadersPriority(stream_id, priority); 295 spdy_session_->OnStreamHeadersPriority(stream_id, priority);
291 } else { 296 } else {
292 if (session()->perspective() == Perspective::IS_SERVER) { 297 if (session()->perspective() == Perspective::IS_SERVER) {
293 CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 298 CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
294 "Client must send priorities."); 299 "Client must send priorities.");
295 return; 300 return;
296 } 301 }
297 } 302 }
298 DCHECK_EQ(kInvalidStreamId, stream_id_); 303 DCHECK_EQ(kInvalidStreamId, stream_id_);
304 DCHECK_EQ(kInvalidStreamId, promised_stream_id_);
299 stream_id_ = stream_id; 305 stream_id_ = stream_id;
300 fin_ = fin; 306 fin_ = fin;
301 } 307 }
302 308
309 void QuicHeadersStream::OnPushPromise(SpdyStreamId stream_id,
310 SpdyStreamId promised_stream_id,
311 bool end) {
312 if (!supports_push_promise_) {
313 CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
314 "SPDY PUSH_PROMISE not supported.");
315 return;
316 }
317 DCHECK_EQ(kInvalidStreamId, stream_id_);
318 DCHECK_EQ(kInvalidStreamId, promised_stream_id_);
319 stream_id_ = stream_id;
320 promised_stream_id_ = promised_stream_id;
321 }
322
303 void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id, 323 void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
304 const char* header_data, 324 const char* header_data,
305 size_t len) { 325 size_t len) {
306 DCHECK_EQ(stream_id_, stream_id); 326 DCHECK_EQ(stream_id_, stream_id);
307 if (len == 0) { 327 if (len == 0) {
308 DCHECK_NE(0u, stream_id_); 328 DCHECK_NE(0u, stream_id_);
309 DCHECK_NE(0u, frame_len_); 329 DCHECK_NE(0u, frame_len_);
310 if (measure_headers_hol_blocking_time_) { 330 if (measure_headers_hol_blocking_time_) {
311 if (prev_max_timestamp_ > cur_max_timestamp_) { 331 if (prev_max_timestamp_ > cur_max_timestamp_) {
312 // prev_max_timestamp_ > cur_max_timestamp_ implies that 332 // prev_max_timestamp_ > cur_max_timestamp_ implies that
313 // headers from lower numbered streams actually came off the 333 // headers from lower numbered streams actually came off the
314 // wire after headers for the current stream, hence there was 334 // wire after headers for the current stream, hence there was
315 // HOL blocking. 335 // HOL blocking.
316 QuicTime::Delta delta(prev_max_timestamp_.Subtract(cur_max_timestamp_)); 336 QuicTime::Delta delta(prev_max_timestamp_.Subtract(cur_max_timestamp_));
317 DVLOG(1) << "stream " << stream_id 337 DVLOG(1) << "stream " << stream_id
318 << ": Net.QuicSession.HeadersHOLBlockedTime " 338 << ": Net.QuicSession.HeadersHOLBlockedTime "
319 << delta.ToMilliseconds(); 339 << delta.ToMilliseconds();
320 spdy_session_->OnHeadersHeadOfLineBlocking(delta); 340 spdy_session_->OnHeadersHeadOfLineBlocking(delta);
321 } 341 }
322 prev_max_timestamp_ = std::max(prev_max_timestamp_, cur_max_timestamp_); 342 prev_max_timestamp_ = std::max(prev_max_timestamp_, cur_max_timestamp_);
323 cur_max_timestamp_ = QuicTime::Zero(); 343 cur_max_timestamp_ = QuicTime::Zero();
324 } 344 }
325 spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_); 345 if (promised_stream_id_ == kInvalidStreamId) {
346 spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_);
347 } else {
348 spdy_session_->OnPromiseHeadersComplete(stream_id_, promised_stream_id_,
349 frame_len_);
350 }
326 // Reset state for the next frame. 351 // Reset state for the next frame.
352 promised_stream_id_ = kInvalidStreamId;
327 stream_id_ = kInvalidStreamId; 353 stream_id_ = kInvalidStreamId;
328 fin_ = false; 354 fin_ = false;
329 frame_len_ = 0; 355 frame_len_ = 0;
330 } else { 356 } else {
331 spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len)); 357 if (promised_stream_id_ == kInvalidStreamId) {
358 spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len));
359 } else {
360 spdy_session_->OnPromiseHeaders(stream_id_,
361 StringPiece(header_data, len));
362 }
332 } 363 }
333 } 364 }
334 365
335 void QuicHeadersStream::OnCompressedFrameSize(size_t frame_len) { 366 void QuicHeadersStream::OnCompressedFrameSize(size_t frame_len) {
336 frame_len_ += frame_len; 367 frame_len_ += frame_len;
337 } 368 }
338 369
339 bool QuicHeadersStream::IsConnected() { 370 bool QuicHeadersStream::IsConnected() {
340 return session()->connection()->connected(); 371 return session()->connection()->connected();
341 } 372 }
342 373
343 } // namespace net 374 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_headers_stream.h ('k') | net/quic/quic_headers_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698