OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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_spdy_session.h" | 5 #include "net/quic/core/quic_spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstdint> | 8 #include <cstdint> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "net/quic/core/quic_flags.h" | 12 #include "net/quic/core/quic_flags.h" |
13 #include "net/quic/core/quic_headers_stream.h" | 13 #include "net/quic/core/quic_headers_stream.h" |
14 #include "net/quic/platform/api/quic_bug_tracker.h" | 14 #include "net/quic/platform/api/quic_bug_tracker.h" |
15 #include "net/quic/platform/api/quic_logging.h" | 15 #include "net/quic/platform/api/quic_logging.h" |
16 #include "net/quic/platform/api/quic_str_cat.h" | 16 #include "net/quic/platform/api/quic_str_cat.h" |
17 | 17 |
18 using base::StringPiece; | |
19 using std::string; | 18 using std::string; |
20 | 19 |
21 namespace net { | 20 namespace net { |
22 | 21 |
23 namespace { | 22 namespace { |
24 | 23 |
25 class HeaderTableDebugVisitor | 24 class HeaderTableDebugVisitor |
26 : public HpackHeaderTable::DebugVisitorInterface { | 25 : public HpackHeaderTable::DebugVisitorInterface { |
27 public: | 26 public: |
28 HeaderTableDebugVisitor(const QuicClock* clock, | 27 HeaderTableDebugVisitor(const QuicClock* clock, |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 SpdyPriority priority, | 402 SpdyPriority priority, |
404 QuicReferenceCountedPointer<QuicAckListenerInterface> | 403 QuicReferenceCountedPointer<QuicAckListenerInterface> |
405 ack_notifier_delegate) { | 404 ack_notifier_delegate) { |
406 SpdyHeadersIR headers_frame(id, std::move(headers)); | 405 SpdyHeadersIR headers_frame(id, std::move(headers)); |
407 headers_frame.set_fin(fin); | 406 headers_frame.set_fin(fin); |
408 if (perspective() == Perspective::IS_CLIENT) { | 407 if (perspective() == Perspective::IS_CLIENT) { |
409 headers_frame.set_has_priority(true); | 408 headers_frame.set_has_priority(true); |
410 headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority)); | 409 headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority)); |
411 } | 410 } |
412 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); | 411 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); |
413 headers_stream_->WriteOrBufferData(StringPiece(frame.data(), frame.size()), | 412 headers_stream_->WriteOrBufferData( |
414 false, std::move(ack_notifier_delegate)); | 413 QuicStringPiece(frame.data(), frame.size()), false, |
| 414 std::move(ack_notifier_delegate)); |
415 return frame.size(); | 415 return frame.size(); |
416 } | 416 } |
417 | 417 |
418 size_t QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id, | 418 size_t QuicSpdySession::WritePushPromise(QuicStreamId original_stream_id, |
419 QuicStreamId promised_stream_id, | 419 QuicStreamId promised_stream_id, |
420 SpdyHeaderBlock headers) { | 420 SpdyHeaderBlock headers) { |
421 if (perspective() == Perspective::IS_CLIENT) { | 421 if (perspective() == Perspective::IS_CLIENT) { |
422 QUIC_BUG << "Client shouldn't send PUSH_PROMISE"; | 422 QUIC_BUG << "Client shouldn't send PUSH_PROMISE"; |
423 return 0; | 423 return 0; |
424 } | 424 } |
425 | 425 |
426 SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id, | 426 SpdyPushPromiseIR push_promise(original_stream_id, promised_stream_id, |
427 std::move(headers)); | 427 std::move(headers)); |
428 // PUSH_PROMISE must not be the last frame sent out, at least followed by | 428 // PUSH_PROMISE must not be the last frame sent out, at least followed by |
429 // response headers. | 429 // response headers. |
430 push_promise.set_fin(false); | 430 push_promise.set_fin(false); |
431 | 431 |
432 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); | 432 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); |
433 headers_stream_->WriteOrBufferData(StringPiece(frame.data(), frame.size()), | 433 headers_stream_->WriteOrBufferData( |
434 false, nullptr); | 434 QuicStringPiece(frame.data(), frame.size()), false, nullptr); |
435 return frame.size(); | 435 return frame.size(); |
436 } | 436 } |
437 | 437 |
438 void QuicSpdySession::WriteDataFrame( | 438 void QuicSpdySession::WriteDataFrame( |
439 QuicStreamId id, | 439 QuicStreamId id, |
440 StringPiece data, | 440 QuicStringPiece data, |
441 bool fin, | 441 bool fin, |
442 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 442 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
443 // Note that certain SpdyDataIR constructors perform a deep copy of |data| | 443 // Note that certain SpdyDataIR constructors perform a deep copy of |data| |
444 // which should be avoided here. | 444 // which should be avoided here. |
445 SpdyDataIR spdy_data(id); | 445 SpdyDataIR spdy_data(id); |
446 spdy_data.SetDataShallow(data); | 446 spdy_data.SetDataShallow(data); |
447 spdy_data.set_fin(fin); | 447 spdy_data.set_fin(fin); |
448 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); | 448 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); |
449 QuicReferenceCountedPointer<ForceHolAckListener> force_hol_ack_listener; | 449 QuicReferenceCountedPointer<ForceHolAckListener> force_hol_ack_listener; |
450 if (ack_listener != nullptr) { | 450 if (ack_listener != nullptr) { |
451 force_hol_ack_listener = new ForceHolAckListener( | 451 force_hol_ack_listener = new ForceHolAckListener( |
452 std::move(ack_listener), frame.size() - data.length()); | 452 std::move(ack_listener), frame.size() - data.length()); |
453 } | 453 } |
454 // Use buffered writes so that coherence of framing is preserved | 454 // Use buffered writes so that coherence of framing is preserved |
455 // between streams. | 455 // between streams. |
456 headers_stream_->WriteOrBufferData(StringPiece(frame.data(), frame.size()), | 456 headers_stream_->WriteOrBufferData( |
457 false, std::move(force_hol_ack_listener)); | 457 QuicStringPiece(frame.data(), frame.size()), false, |
| 458 std::move(force_hol_ack_listener)); |
458 } | 459 } |
459 | 460 |
460 QuicConsumedData QuicSpdySession::WritevStreamData( | 461 QuicConsumedData QuicSpdySession::WritevStreamData( |
461 QuicStreamId id, | 462 QuicStreamId id, |
462 QuicIOVector iov, | 463 QuicIOVector iov, |
463 QuicStreamOffset offset, | 464 QuicStreamOffset offset, |
464 bool fin, | 465 bool fin, |
465 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 466 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
466 const size_t max_len = | 467 const size_t max_len = |
467 kSpdyInitialFrameSizeLimit - kDataFrameMinimumSize; | 468 kSpdyInitialFrameSizeLimit - kDataFrameMinimumSize; |
468 | 469 |
469 QuicConsumedData result(0, false); | 470 QuicConsumedData result(0, false); |
470 size_t total_length = iov.total_length; | 471 size_t total_length = iov.total_length; |
471 | 472 |
472 if (total_length == 0 && fin) { | 473 if (total_length == 0 && fin) { |
473 WriteDataFrame(id, StringPiece(), true, std::move(ack_listener)); | 474 WriteDataFrame(id, QuicStringPiece(), true, std::move(ack_listener)); |
474 result.fin_consumed = true; | 475 result.fin_consumed = true; |
475 return result; | 476 return result; |
476 } | 477 } |
477 | 478 |
478 // Encapsulate the data into HTTP/2 DATA frames. The outer loop | 479 // Encapsulate the data into HTTP/2 DATA frames. The outer loop |
479 // handles each element of the source iov, the inner loop handles | 480 // handles each element of the source iov, the inner loop handles |
480 // the possibility of fragmenting each of those into multiple DATA | 481 // the possibility of fragmenting each of those into multiple DATA |
481 // frames, as the DATA frames have a max size of 16KB. | 482 // frames, as the DATA frames have a max size of 16KB. |
482 for (int i = 0; i < iov.iov_count; i++) { | 483 for (int i = 0; i < iov.iov_count; i++) { |
483 size_t src_iov_offset = 0; | 484 size_t src_iov_offset = 0; |
484 const struct iovec* src_iov = &iov.iov[i]; | 485 const struct iovec* src_iov = &iov.iov[i]; |
485 do { | 486 do { |
486 if (headers_stream_->queued_data_bytes() > 0) { | 487 if (headers_stream_->queued_data_bytes() > 0) { |
487 // Limit the amount of buffering to the minimum needed to | 488 // Limit the amount of buffering to the minimum needed to |
488 // preserve framing. | 489 // preserve framing. |
489 return result; | 490 return result; |
490 } | 491 } |
491 size_t len = std::min( | 492 size_t len = std::min( |
492 std::min(src_iov->iov_len - src_iov_offset, max_len), total_length); | 493 std::min(src_iov->iov_len - src_iov_offset, max_len), total_length); |
493 char* data = static_cast<char*>(src_iov->iov_base) + src_iov_offset; | 494 char* data = static_cast<char*>(src_iov->iov_base) + src_iov_offset; |
494 src_iov_offset += len; | 495 src_iov_offset += len; |
495 offset += len; | 496 offset += len; |
496 // fin handling, only set it for the final HTTP/2 DATA frame. | 497 // fin handling, only set it for the final HTTP/2 DATA frame. |
497 bool last_iov = i == iov.iov_count - 1; | 498 bool last_iov = i == iov.iov_count - 1; |
498 bool last_fragment_within_iov = src_iov_offset >= src_iov->iov_len; | 499 bool last_fragment_within_iov = src_iov_offset >= src_iov->iov_len; |
499 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false; | 500 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false; |
500 WriteDataFrame(id, StringPiece(data, len), frame_fin, ack_listener); | 501 WriteDataFrame(id, QuicStringPiece(data, len), frame_fin, ack_listener); |
501 result.bytes_consumed += len; | 502 result.bytes_consumed += len; |
502 if (frame_fin) { | 503 if (frame_fin) { |
503 result.fin_consumed = true; | 504 result.fin_consumed = true; |
504 } | 505 } |
505 DCHECK_GE(total_length, len); | 506 DCHECK_GE(total_length, len); |
506 total_length -= len; | 507 total_length -= len; |
507 if (total_length <= 0) { | 508 if (total_length <= 0) { |
508 return result; | 509 return result; |
509 } | 510 } |
510 } while (src_iov_offset < src_iov->iov_len); | 511 } while (src_iov_offset < src_iov->iov_len); |
511 } | 512 } |
512 | 513 |
513 return result; | 514 return result; |
514 } | 515 } |
515 | 516 |
516 size_t QuicSpdySession::SendMaxHeaderListSize(size_t value) { | 517 size_t QuicSpdySession::SendMaxHeaderListSize(size_t value) { |
517 SpdySettingsIR settings_frame; | 518 SpdySettingsIR settings_frame; |
518 settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, value); | 519 settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, value); |
519 | 520 |
520 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(settings_frame)); | 521 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(settings_frame)); |
521 headers_stream_->WriteOrBufferData(StringPiece(frame.data(), frame.size()), | 522 headers_stream_->WriteOrBufferData( |
522 false, nullptr); | 523 QuicStringPiece(frame.data(), frame.size()), false, nullptr); |
523 return frame.size(); | 524 return frame.size(); |
524 } | 525 } |
525 | 526 |
526 void QuicSpdySession::OnHeadersHeadOfLineBlocking(QuicTime::Delta delta) { | 527 void QuicSpdySession::OnHeadersHeadOfLineBlocking(QuicTime::Delta delta) { |
527 // Implemented in Chromium for stats tracking. | 528 // Implemented in Chromium for stats tracking. |
528 } | 529 } |
529 | 530 |
530 void QuicSpdySession::RegisterStreamPriority(QuicStreamId id, | 531 void QuicSpdySession::RegisterStreamPriority(QuicStreamId id, |
531 SpdyPriority priority) { | 532 SpdyPriority priority) { |
532 write_blocked_streams()->RegisterStream(id, priority); | 533 write_blocked_streams()->RegisterStream(id, priority); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 void QuicSpdySession::OnStreamFrameData(QuicStreamId stream_id, | 594 void QuicSpdySession::OnStreamFrameData(QuicStreamId stream_id, |
594 const char* data, | 595 const char* data, |
595 size_t len, | 596 size_t len, |
596 bool fin) { | 597 bool fin) { |
597 QuicSpdyStream* stream = GetSpdyDataStream(stream_id); | 598 QuicSpdyStream* stream = GetSpdyDataStream(stream_id); |
598 if (stream == nullptr) { | 599 if (stream == nullptr) { |
599 return; | 600 return; |
600 } | 601 } |
601 const QuicStreamOffset offset = | 602 const QuicStreamOffset offset = |
602 stream->flow_controller()->highest_received_byte_offset(); | 603 stream->flow_controller()->highest_received_byte_offset(); |
603 const QuicStreamFrame frame(stream_id, fin, offset, StringPiece(data, len)); | 604 const QuicStreamFrame frame(stream_id, fin, offset, |
| 605 QuicStringPiece(data, len)); |
604 QUIC_DVLOG(1) << "De-encapsulating DATA frame for stream " << stream_id | 606 QUIC_DVLOG(1) << "De-encapsulating DATA frame for stream " << stream_id |
605 << " offset " << offset << " len " << len << " fin " << fin; | 607 << " offset " << offset << " len " << len << " fin " << fin; |
606 OnStreamFrame(frame); | 608 OnStreamFrame(frame); |
607 } | 609 } |
608 | 610 |
609 bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() { | 611 bool QuicSpdySession::ShouldReleaseHeadersStreamSequencerBuffer() { |
610 return false; | 612 return false; |
611 } | 613 } |
612 | 614 |
613 void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, | 615 void QuicSpdySession::OnHeaders(SpdyStreamId stream_id, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 set_max_uncompressed_header_bytes); | 745 set_max_uncompressed_header_bytes); |
744 } | 746 } |
745 | 747 |
746 void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error, | 748 void QuicSpdySession::CloseConnectionWithDetails(QuicErrorCode error, |
747 const string& details) { | 749 const string& details) { |
748 connection()->CloseConnection( | 750 connection()->CloseConnection( |
749 error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 751 error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
750 } | 752 } |
751 | 753 |
752 } // namespace net | 754 } // namespace net |
OLD | NEW |