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

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

Issue 2430973004: Landing Recent QUIC changes until 10:38 AM, Oct 17, 2016 UTC-4 (Closed)
Patch Set: Improving flagsaver logging Created 4 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 unified diff | Download patch
« no previous file with comments | « net/quic/core/quic_headers_stream.h ('k') | net/quic/core/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/core/quic_headers_stream.h" 5 #include "net/quic/core/quic_headers_stream.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } 307 }
308 308
309 void OnReceiveCompressedFrame(SpdyStreamId stream_id, 309 void OnReceiveCompressedFrame(SpdyStreamId stream_id,
310 SpdyFrameType type, 310 SpdyFrameType type,
311 size_t frame_len) override { 311 size_t frame_len) override {
312 if (stream_->IsConnected()) { 312 if (stream_->IsConnected()) {
313 stream_->OnCompressedFrameSize(frame_len); 313 stream_->OnCompressedFrameSize(frame_len);
314 } 314 }
315 } 315 }
316 316
317 void set_max_uncompressed_header_bytes(
318 size_t set_max_uncompressed_header_bytes) {
319 header_list_.set_max_uncompressed_header_bytes(
320 set_max_uncompressed_header_bytes);
321 }
322
317 private: 323 private:
318 void CloseConnection(const string& details) { 324 void CloseConnection(const string& details) {
319 if (stream_->IsConnected()) { 325 if (stream_->IsConnected()) {
320 stream_->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 326 stream_->CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
321 details); 327 details);
322 } 328 }
323 } 329 }
324 330
325 private: 331 private:
326 QuicHeadersStream* stream_; 332 QuicHeadersStream* stream_;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 386
381 // PUSH_PROMISE must not be the last frame sent out, at least followed by 387 // PUSH_PROMISE must not be the last frame sent out, at least followed by
382 // response headers. 388 // response headers.
383 push_promise.set_fin(false); 389 push_promise.set_fin(false);
384 390
385 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); 391 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
386 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, nullptr); 392 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, nullptr);
387 return frame.size(); 393 return frame.size();
388 } 394 }
389 395
390 void QuicHeadersStream::WriteDataFrame(
391 QuicStreamId id,
392 StringPiece data,
393 bool fin,
394 QuicAckListenerInterface* ack_notifier_delegate) {
395 SpdyDataIR spdy_data(id, data);
396 spdy_data.set_fin(fin);
397 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data));
398 scoped_refptr<ForceHolAckListener> ack_listener;
399 if (ack_notifier_delegate != nullptr) {
400 ack_listener = new ForceHolAckListener(ack_notifier_delegate,
401 frame.size() - data.length());
402 }
403 // Use buffered writes so that coherence of framing is preserved
404 // between streams.
405 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
406 ack_listener.get());
407 }
408
409 QuicConsumedData QuicHeadersStream::WritevStreamData( 396 QuicConsumedData QuicHeadersStream::WritevStreamData(
410 QuicStreamId id, 397 QuicStreamId id,
411 QuicIOVector iov, 398 QuicIOVector iov,
412 QuicStreamOffset offset, 399 QuicStreamOffset offset,
413 bool fin, 400 bool fin,
414 QuicAckListenerInterface* ack_notifier_delegate) { 401 QuicAckListenerInterface* ack_notifier_delegate) {
415 const size_t max_len = kSpdyInitialFrameSizeLimit - 402 const size_t max_len = kSpdyInitialFrameSizeLimit -
416 SpdyConstants::GetDataFrameMinimumSize(HTTP2); 403 SpdyConstants::GetDataFrameMinimumSize(HTTP2);
417 404
418 QuicConsumedData result(0, false); 405 QuicConsumedData result(0, false);
419 size_t total_length = iov.total_length; 406 size_t total_length = iov.total_length;
420 407
421 if (!FLAGS_quic_bugfix_fhol_writev_fin_only_v2) { 408 // Encapsulate the data into HTTP/2 DATA frames. The outer loop
422 // Encapsulate the data into HTTP/2 DATA frames. The outer loop 409 // handles each element of the source iov, the inner loop handles
423 // handles each element of the source iov, the inner loop handles 410 // the possibility of fragmenting eacho of those into multiple DATA
424 // the possibility of fragmenting eacho of those into multiple DATA 411 // frames, as the DATA frames have a max size of 16KB.
425 // frames, as the DATA frames have a max size of 16KB. 412 for (int i = 0; i < iov.iov_count; i++) {
426 for (int i = 0; i < iov.iov_count; i++) { 413 size_t offset = 0;
427 size_t offset = 0; 414 const struct iovec* src_iov = &iov.iov[i];
428 const struct iovec* src_iov = &iov.iov[i]; 415 do {
429 do { 416 size_t len =
430 size_t len = std::min(std::min(src_iov->iov_len - offset, max_len), 417 std::min(std::min(src_iov->iov_len - offset, max_len), total_length);
431 total_length); 418 char* data = static_cast<char*>(src_iov->iov_base) + offset;
432 char* data = static_cast<char*>(src_iov->iov_base) + offset; 419 SpdyDataIR spdy_data(id, StringPiece(data, len));
433 SpdyDataIR spdy_data(id, StringPiece(data, len)); 420 offset += len;
434 offset += len; 421 // fin handling, set it only it only very last generated HTTP/2
435 // fin handling, only set it for the final HTTP/2 DATA frame. 422 // DATA frame.
436 bool last_iov = i == iov.iov_count - 1; 423 bool last_iov = i == iov.iov_count - 1;
437 bool last_fragment_within_iov = offset >= src_iov->iov_len; 424 bool last_fragment_within_iov = offset >= src_iov->iov_len;
438 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false; 425 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false;
439 spdy_data.set_fin(frame_fin); 426 spdy_data.set_fin(frame_fin);
440 if (frame_fin) { 427 if (frame_fin) {
441 result.fin_consumed = true; 428 result.fin_consumed = true;
442 } 429 }
443 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); 430 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data));
444 DVLOG(1) << "Encapsulating in DATA frame for stream " << id << " len " 431 DVLOG(1) << "Encapsulating in DATA frame for stream " << id << " len "
445 << len << " fin " << spdy_data.fin() << " remaining " 432 << len << " fin " << spdy_data.fin() << " remaining "
446 << src_iov->iov_len - offset; 433 << src_iov->iov_len - offset;
447 434
448 scoped_refptr<ForceHolAckListener> ack_listener; 435 scoped_refptr<ForceHolAckListener> ack_listener;
449 if (ack_notifier_delegate != nullptr) { 436 if (ack_notifier_delegate != nullptr) {
450 ack_listener = new ForceHolAckListener(ack_notifier_delegate, 437 ack_listener =
451 frame.size() - len); 438 new ForceHolAckListener(ack_notifier_delegate, frame.size() - len);
452 } 439 }
453 440
454 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, 441 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
455 ack_listener.get()); 442 ack_listener.get());
456 result.bytes_consumed += len; 443 result.bytes_consumed += len;
457 total_length -= len; 444 total_length -= len;
458 if (total_length <= 0) { 445 if (total_length <= 0) {
459 return result; 446 return result;
460 } 447 }
461 } while (offset < src_iov->iov_len); 448 } while (offset < src_iov->iov_len);
462 }
463 } else {
464 if (total_length == 0 && fin) {
465 WriteDataFrame(id, StringPiece(), true, ack_notifier_delegate);
466 result.fin_consumed = true;
467 return result;
468 }
469
470 // Encapsulate the data into HTTP/2 DATA frames. The outer loop
471 // handles each element of the source iov, the inner loop handles
472 // the possibility of fragmenting each of those into multiple DATA
473 // frames, as the DATA frames have a max size of 16KB.
474 for (int i = 0; i < iov.iov_count; i++) {
475 size_t src_iov_offset = 0;
476 const struct iovec* src_iov = &iov.iov[i];
477 do {
478 if (queued_data_bytes() > 0) {
479 // Limit the amount of buffering to the minimum needed to
480 // preserve framing.
481 return result;
482 }
483 size_t len = std::min(
484 std::min(src_iov->iov_len - src_iov_offset, max_len), total_length);
485 char* data = static_cast<char*>(src_iov->iov_base) + src_iov_offset;
486 src_iov_offset += len;
487 offset += len;
488 // fin handling, only set it for the final HTTP/2 DATA frame.
489 bool last_iov = i == iov.iov_count - 1;
490 bool last_fragment_within_iov = src_iov_offset >= src_iov->iov_len;
491 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false;
492 WriteDataFrame(id, StringPiece(data, len), frame_fin,
493 ack_notifier_delegate);
494 result.bytes_consumed += len;
495 if (frame_fin) {
496 result.fin_consumed = true;
497 }
498 DCHECK_GE(total_length, len);
499 total_length -= len;
500 if (total_length <= 0) {
501 return result;
502 }
503 } while (src_iov_offset < src_iov->iov_len);
504 }
505 } 449 }
506
507 return result; 450 return result;
508 } 451 }
509 452
510 void QuicHeadersStream::OnDataAvailable() { 453 void QuicHeadersStream::OnDataAvailable() {
511 char buffer[1024]; 454 char buffer[1024];
512 struct iovec iov; 455 struct iovec iov;
513 QuicTime timestamp(QuicTime::Zero()); 456 QuicTime timestamp(QuicTime::Zero());
514 while (true) { 457 while (true) {
515 iov.iov_base = buffer; 458 iov.iov_base = buffer;
516 iov.iov_len = arraysize(buffer); 459 iov.iov_len = arraysize(buffer);
517 if (!sequencer()->GetReadableRegion(&iov, &timestamp)) { 460 if (!sequencer()->GetReadableRegion(&iov, &timestamp)) {
518 // No more data to read. 461 // No more data to read.
519 break; 462 break;
520 } 463 }
521 DCHECK(timestamp.IsInitialized()); 464 DCHECK(timestamp.IsInitialized());
522 cur_max_timestamp_ = std::max(timestamp, cur_max_timestamp_); 465 cur_max_timestamp_ = std::max(timestamp, cur_max_timestamp_);
523 if (spdy_framer_.ProcessInput(static_cast<char*>(iov.iov_base), 466 if (spdy_framer_.ProcessInput(static_cast<char*>(iov.iov_base),
524 iov.iov_len) != iov.iov_len) { 467 iov.iov_len) != iov.iov_len) {
525 // Error processing data. 468 // Error processing data.
526 return; 469 return;
527 } 470 }
528 sequencer()->MarkConsumed(iov.iov_len); 471 sequencer()->MarkConsumed(iov.iov_len);
529 } 472 }
530 } 473 }
531 474
475 void QuicHeadersStream::set_max_uncompressed_header_bytes(
476 size_t set_max_uncompressed_header_bytes) {
477 spdy_framer_visitor_->set_max_uncompressed_header_bytes(
478 set_max_uncompressed_header_bytes);
479 }
480
532 void QuicHeadersStream::OnHeaders(SpdyStreamId stream_id, 481 void QuicHeadersStream::OnHeaders(SpdyStreamId stream_id,
533 bool has_priority, 482 bool has_priority,
534 SpdyPriority priority, 483 SpdyPriority priority,
535 bool fin) { 484 bool fin) {
536 if (has_priority) { 485 if (has_priority) {
537 if (session()->perspective() == Perspective::IS_CLIENT) { 486 if (session()->perspective() == Perspective::IS_CLIENT) {
538 CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 487 CloseConnectionWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
539 "Server must not send priorities."); 488 "Server must not send priorities.");
540 return; 489 return;
541 } 490 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 return true; 655 return true;
707 } 656 }
708 frame_len_ -= len; 657 frame_len_ -= len;
709 // Ignore fin_ while there is more data coming, if frame_len_ > 0. 658 // Ignore fin_ while there is more data coming, if frame_len_ > 0.
710 spdy_session_->OnStreamFrameData(stream_id, data, len, 659 spdy_session_->OnStreamFrameData(stream_id, data, len,
711 frame_len_ > 0 ? false : fin_); 660 frame_len_ > 0 ? false : fin_);
712 return true; 661 return true;
713 } 662 }
714 663
715 } // namespace net 664 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_headers_stream.h ('k') | net/quic/core/quic_headers_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698