Landing Recent QUIC changes until 4/15/2016 17:20 UTC
Fix a few spurious string allocations in QuicCryptoServerStream and QuicCryptoStream. No functional change. Not flag protected.
Merge internal change: 119967190
https://codereview.chromium.org/1906803004/
Quic will push urls in x-associate-content and link headers upon ResponseHeadersComplete(). Change AcceptQuicClient() to start the request pipeline from PICKING_SERVICE for server push stream. Protected by FLAGS_quic_server_push.
Implemented server push feature in QUIC. This feature will be enabled by
both flag and connection option "kSPSH".
Merge internal change: 119871679
https://codereview.chromium.org/1905073002/
Split out QuicAlarm creation from QuicConnectionHelper to new QuicAlarmFactory. No behavior change, not protected.
This is in preparation for gRPC-over-QUIC to use a separate
QuicAlarmFactory for each GrpcQuicConnection. Currently there exists a
single Helper (and after this CL a single AlarmFactory) per Dispatcher,
and this is used to create alarms for all Connections.
gRPC-over-QUIC needs to add per-connection locking to connection alarms
before firing them, and a followup CL will create a different
AlarmFactory for each gRPC-over-QUIC connection, each with its own
mutex (rather than sharing one mutex across the alarms of connections
which is obviously terrible).
Merge internal change: 119778209
https://codereview.chromium.org/1905843003/
Make QuicDispatcher's helper argument be a unique_ptr to make ownership clear. No behavior change.
(also removes very out of date QuicDispatcher constructor comment)
Merge internal change: 119753783
https://codereview.chromium.org/1907773002/
Deprecate FLAGS_quic_sslr_byte_conservation.
Merge internal change: 119678304
https://codereview.chromium.org/1906703002/
Deprecate FLAGS_quic_consolidate_onstreamframe_errors
Merge internal change: 119653892
https://codereview.chromium.org/1906473004/
Add a server push disabled test.
Merge internal change: 119645068
https://codereview.chromium.org/1911653003/
Cleanup: Migrate references from scoped_ptr to std::unique_ptr. scoped_ptr is now just an alias for unique_ptr, so this is a purely textual change. base/scoped_ptr.h will be removed soon.
Merge internal change: 119583512
https://codereview.chromium.org/1909453005/
Cleanup: Migrate references from scoped_ptr to std::unique_ptr. scoped_ptr is now just an alias for unique_ptr, so this is a purely textual change. base/scoped_ptr.h will be removed soon.
Merge internal change: 119581790
https://codereview.chromium.org/1911653002/
Cleanup: Migrate references from scoped_ptr to std::unique_ptr. scoped_ptr is now just an alias for unique_ptr, so this is a purely textual change. base/scoped_ptr.h will be removed soon.
Merge internal change: 119576588
https://codereview.chromium.org/1908723002/
Plumbs new SpdyFramerVisitorInterface method handling through QUIC test utilities, including the test client and test server. Preparation for CL 103292114.
Merge internal change: 119568788
https://codereview.chromium.org/1910593004/
Fixes QuicSpdyStream::ConsumeHeaderList to prod the sequencer when headers are consumed. Not yet used in production.
Merge internal change: 119562680
https://codereview.chromium.org/1910483004/
Stop returning unused return value from QuicPacketCreator::CopyToBuffer. No functional change. Not flag protected.
Merge internal change: 119557380
https://codereview.chromium.org/1897153007/
ignore invalid error code in QuicFramer when process GoAway, ConnectionClose, RstStream frames to do normal goaway, connection close, and stream reset. Flag protected by FLAGS_quic_ignore_invalid_error_code.
Merge internal change: 119551887
https://codereview.chromium.org/1904833002/
Adds a DebugString() method to QuicHeaderList.
Merge internal change: 119529330
https://codereview.chromium.org/1907683002/
Review URL: https://codereview.chromium.org/1908103002
Cr-Commit-Position: refs/heads/master@{#389035}
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 9f90d926..4f75ba3 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -24,6 +24,7 @@
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/crypto/quic_server_info.h"
+#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_chromium_client_stream.h"
#include "net/quic/quic_chromium_connection_helper.h"
@@ -329,10 +330,11 @@
socket_data_.get(), net_log().bound().net_log()));
socket->Connect(peer_addr_);
runner_ = new TestTaskRunner(&clock_);
- helper_.reset(new QuicChromiumConnectionHelper(runner_.get(), &clock_,
- &random_generator_));
+ helper_.reset(
+ new QuicChromiumConnectionHelper(&clock_, &random_generator_));
+ alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
connection_ = new QuicConnection(
- connection_id_, peer_addr_, helper_.get(),
+ connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
new QuicChromiumPacketWriter(socket.get()), true /* owns_writer */,
Perspective::IS_CLIENT, SupportedVersions(GetParam()));
@@ -472,6 +474,7 @@
MockClock clock_;
QuicConnection* connection_;
std::unique_ptr<QuicChromiumConnectionHelper> helper_;
+ std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
TransportSecurityState transport_security_state_;
std::unique_ptr<QuicChromiumClientSession> session_;
QuicCryptoClientConfig crypto_config_;
diff --git a/net/quic/congestion_control/tcp_cubic_sender_bytes_test.cc b/net/quic/congestion_control/tcp_cubic_sender_bytes_test.cc
index 1bedee8..3bca8cb 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -5,6 +5,7 @@
#include "net/quic/congestion_control/tcp_cubic_sender_bytes.h"
#include <algorithm>
+#include <cstdint>
#include <memory>
#include "base/logging.h"
@@ -287,7 +288,6 @@
}
TEST_F(TcpCubicSenderBytesTest, SlowStartHalfPacketLossWithLargeReduction) {
- FLAGS_quic_sslr_byte_conservation = true;
QuicConfig config;
QuicTagVector options;
options.push_back(kSSLR);
diff --git a/net/quic/congestion_control/tcp_cubic_sender_packets.cc b/net/quic/congestion_control/tcp_cubic_sender_packets.cc
index e1c225fe..aee29ba1 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_packets.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_packets.cc
@@ -89,17 +89,10 @@
++stats_->slowstart_packets_lost;
stats_->slowstart_bytes_lost += lost_bytes;
if (slow_start_large_reduction_) {
- if (FLAGS_quic_sslr_byte_conservation) {
- if (stats_->slowstart_packets_lost == 1 ||
- (stats_->slowstart_bytes_lost / kDefaultTCPMSS) >
- (stats_->slowstart_bytes_lost - lost_bytes) /
- kDefaultTCPMSS) {
- // Reduce congestion window by 1 for every mss of bytes lost.
- congestion_window_ =
- max(congestion_window_ - 1, min_congestion_window_);
- }
- } else {
- // Reduce congestion window by 1 for every loss.
+ if (stats_->slowstart_packets_lost == 1 ||
+ (stats_->slowstart_bytes_lost / kDefaultTCPMSS) >
+ (stats_->slowstart_bytes_lost - lost_bytes) / kDefaultTCPMSS) {
+ // Reduce congestion window by 1 for every mss of bytes lost.
congestion_window_ =
max(congestion_window_ - 1, min_congestion_window_);
}
diff --git a/net/quic/congestion_control/tcp_cubic_sender_packets_test.cc b/net/quic/congestion_control/tcp_cubic_sender_packets_test.cc
index 18359b1..892ee04 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_packets_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_packets_test.cc
@@ -296,7 +296,6 @@
}
TEST_F(TcpCubicSenderPacketsTest, SlowStartHalfPacketLossWithLargeReduction) {
- FLAGS_quic_sslr_byte_conservation = true;
QuicConfig config;
QuicTagVector options;
options.push_back(kSSLR);
diff --git a/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc b/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc
index f045afa0..9f24aa0 100644
--- a/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc
+++ b/net/quic/crypto/aes_128_gcm_12_decrypter_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/aes_128_gcm_12_decrypter.h"
+#include <memory>
+
#include "net/quic/quic_flags.h"
#include "net/quic/test_tools/quic_test_utils.h"
diff --git a/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc b/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
index 7b61962..88e7401 100644
--- a/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
+++ b/net/quic/crypto/aes_128_gcm_12_encrypter_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
+#include <memory>
+
#include "net/quic/test_tools/quic_test_utils.h"
using base::StringPiece;
diff --git a/net/quic/crypto/cert_compressor.cc b/net/quic/crypto/cert_compressor.cc
index 0f1075d..366252b2 100644
--- a/net/quic/crypto/cert_compressor.cc
+++ b/net/quic/crypto/cert_compressor.cc
@@ -4,6 +4,7 @@
#include "net/quic/crypto/cert_compressor.h"
+#include <cstdint>
#include <memory>
#include "base/logging.h"
diff --git a/net/quic/crypto/cert_compressor_test.cc b/net/quic/crypto/cert_compressor_test.cc
index 251313b..9005086 100644
--- a/net/quic/crypto/cert_compressor_test.cc
+++ b/net/quic/crypto/cert_compressor_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/cert_compressor.h"
+#include <memory>
+
#include "base/strings/string_number_conversions.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/crypto_test_utils.h"
diff --git a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc
index ca80202..bc09d3e1 100644
--- a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc
+++ b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h"
+#include <memory>
+
#include "net/quic/quic_flags.h"
#include "net/quic/test_tools/quic_test_utils.h"
diff --git a/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc b/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc
index b9d9d47..ea55594c 100644
--- a/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc
+++ b/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_test.cc
@@ -5,6 +5,7 @@
#include "net/quic/crypto/chacha20_poly1305_rfc7539_encrypter.h"
#include <stdint.h>
+#include <memory>
#include "net/quic/crypto/chacha20_poly1305_rfc7539_decrypter.h"
#include "net/quic/test_tools/quic_test_utils.h"
diff --git a/net/quic/crypto/channel_id_test.cc b/net/quic/crypto/channel_id_test.cc
index 1453071b..bc1ca44 100644
--- a/net/quic/crypto/channel_id_test.cc
+++ b/net/quic/crypto/channel_id_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/channel_id.h"
+#include <memory>
+
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/net/quic/crypto/crypto_framer.cc b/net/quic/crypto/crypto_framer.cc
index 8e04aef..9b2fc2d8 100644
--- a/net/quic/crypto/crypto_framer.cc
+++ b/net/quic/crypto/crypto_framer.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/crypto_framer.h"
+#include <memory>
+
#include "base/strings/stringprintf.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_data_reader.h"
diff --git a/net/quic/crypto/crypto_handshake_message.cc b/net/quic/crypto/crypto_handshake_message.cc
index 05ffa67..70857ff 100644
--- a/net/quic/crypto/crypto_handshake_message.cc
+++ b/net/quic/crypto/crypto_handshake_message.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/crypto_handshake_message.h"
+#include <memory>
+
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "net/quic/crypto/crypto_framer.h"
diff --git a/net/quic/crypto/crypto_handshake_message.h b/net/quic/crypto/crypto_handshake_message.h
index 86052f2..0f7346f4 100644
--- a/net/quic/crypto/crypto_handshake_message.h
+++ b/net/quic/crypto/crypto_handshake_message.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <cstdint>
#include <memory>
#include <string>
#include <vector>
diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc
index 5dfcf51..430bcf1 100644
--- a/net/quic/crypto/crypto_server_test.cc
+++ b/net/quic/crypto/crypto_server_test.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+#include <cstdint>
+#include <memory>
#include <ostream>
#include <vector>
diff --git a/net/quic/crypto/crypto_utils.cc b/net/quic/crypto/crypto_utils.cc
index a052520..b8c63eca 100644
--- a/net/quic/crypto/crypto_utils.cc
+++ b/net/quic/crypto/crypto_utils.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/crypto_utils.h"
+#include <memory>
+
#include "crypto/hkdf.h"
#include "crypto/secure_hash.h"
#include "net/base/url_util.h"
diff --git a/net/quic/crypto/p256_key_exchange_test.cc b/net/quic/crypto/p256_key_exchange_test.cc
index 079eb40d..4972480 100644
--- a/net/quic/crypto/p256_key_exchange_test.cc
+++ b/net/quic/crypto/p256_key_exchange_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/p256_key_exchange.h"
+#include <memory>
+
#include "base/logging.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/net/quic/crypto/proof_test.cc b/net/quic/crypto/proof_test.cc
index 67af4127..5e3cd9b 100644
--- a/net/quic/crypto/proof_test.cc
+++ b/net/quic/crypto/proof_test.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include "base/files/file_path.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
diff --git a/net/quic/crypto/quic_crypto_client_config.cc b/net/quic/crypto/quic_crypto_client_config.cc
index e6dad8c1..a48560f 100644
--- a/net/quic/crypto/quic_crypto_client_config.cc
+++ b/net/quic/crypto/quic_crypto_client_config.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/quic_crypto_client_config.h"
+#include <memory>
+
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc
index b107df3..91705b1 100644
--- a/net/quic/crypto/quic_crypto_server_config.cc
+++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <algorithm>
+#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
diff --git a/net/quic/crypto/quic_crypto_server_config_test.cc b/net/quic/crypto/quic_crypto_server_config_test.cc
index 38c6d2ef..f5ca8ecf 100644
--- a/net/quic/crypto/quic_crypto_server_config_test.cc
+++ b/net/quic/crypto/quic_crypto_server_config_test.cc
@@ -6,6 +6,8 @@
#include <stdarg.h>
+#include <memory>
+
#include "base/stl_util.h"
#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
#include "net/quic/crypto/cert_compressor.h"
diff --git a/net/quic/crypto/strike_register_test.cc b/net/quic/crypto/strike_register_test.cc
index 0f63969..bff26108 100644
--- a/net/quic/crypto/strike_register_test.cc
+++ b/net/quic/crypto/strike_register_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/crypto/strike_register.h"
+#include <cstdint>
+#include <memory>
#include <set>
#include <string>
diff --git a/net/quic/p2p/quic_p2p_session_test.cc b/net/quic/p2p/quic_p2p_session_test.cc
index 02230690..1c8168b 100644
--- a/net/quic/p2p/quic_p2p_session_test.cc
+++ b/net/quic/p2p/quic_p2p_session_test.cc
@@ -18,6 +18,7 @@
#include "net/quic/crypto/quic_random.h"
#include "net/quic/p2p/quic_p2p_crypto_config.h"
#include "net/quic/p2p/quic_p2p_stream.h"
+#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_writer.h"
#include "net/quic/test_tools/quic_session_peer.h"
@@ -196,9 +197,9 @@
protected:
QuicP2PSessionTest()
- : quic_helper_(base::ThreadTaskRunnerHandle::Get().get(),
- &quic_clock_,
- QuicRandom::GetInstance()) {
+ : quic_helper_(&quic_clock_, QuicRandom::GetInstance()),
+ alarm_factory_(base::ThreadTaskRunnerHandle::Get().get(),
+ &quic_clock_) {
// Simulate out-of-bound config handshake.
CryptoHandshakeMessage hello_message;
config_.ToHandshakeMessage(&hello_message);
@@ -230,8 +231,9 @@
QuicChromiumPacketWriter* writer =
new QuicChromiumPacketWriter(socket.get());
std::unique_ptr<QuicConnection> quic_connection1(new QuicConnection(
- 0, IPEndPoint(IPAddress::IPv4AllZeros(), 0), &quic_helper_, writer,
- true /* owns_writer */, perspective, QuicSupportedVersions()));
+ 0, IPEndPoint(IPAddress::IPv4AllZeros(), 0), &quic_helper_,
+ &alarm_factory_, writer, true /* owns_writer */, perspective,
+ QuicSupportedVersions()));
writer->SetConnection(quic_connection1.get());
std::unique_ptr<QuicP2PSession> result(
@@ -247,6 +249,7 @@
QuicClock quic_clock_;
QuicChromiumConnectionHelper quic_helper_;
+ QuicChromiumAlarmFactory alarm_factory_;
QuicConfig config_;
base::WeakPtr<FakeP2PDatagramSocket> socket1_;
diff --git a/net/quic/quic_alarm_factory.h b/net/quic/quic_alarm_factory.h
new file mode 100644
index 0000000..237f2a2
--- /dev/null
+++ b/net/quic/quic_alarm_factory.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_QUIC_ALARM_FACTORY_H_
+#define NET_QUIC_QUIC_ALARM_FACTORY_H_
+
+#include "net/base/net_export.h"
+#include "net/quic/quic_alarm.h"
+#include "net/quic/quic_one_block_arena.h"
+
+namespace net {
+
+// QuicConnections currently use around 1KB of polymorphic types which would
+// ordinarily be on the heap. Instead, store them inline in an arena.
+using QuicConnectionArena = QuicOneBlockArena<1024>;
+
+// Creates platform-specific alarms used throughout QUIC.
+class NET_EXPORT_PRIVATE QuicAlarmFactory {
+ public:
+ virtual ~QuicAlarmFactory() {}
+
+ // Creates a new platform-specific alarm which will be configured to notify
+ // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
+ // Caller takes ownership of the new alarm, which will not yet be "set" to
+ // fire.
+ virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
+
+ // Creates a new platform-specific alarm which will be configured to notify
+ // |delegate| when the alarm fires. Caller takes ownership of the new alarm,
+ // which will not yet be "set" to fire. If |arena| is null, then the alarm
+ // will be created on the heap. Otherwise, it will be created in |arena|.
+ virtual QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+ QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+ QuicConnectionArena* arena) = 0;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_ALARM_FACTORY_H_
diff --git a/net/quic/quic_chromium_alarm_factory.cc b/net/quic/quic_chromium_alarm_factory.cc
new file mode 100644
index 0000000..8973b97
--- /dev/null
+++ b/net/quic/quic_chromium_alarm_factory.cc
@@ -0,0 +1,117 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_chromium_alarm_factory.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/task_runner.h"
+#include "base/time/time.h"
+
+namespace net {
+
+namespace {
+
+class QuicChromeAlarm : public QuicAlarm {
+ public:
+ QuicChromeAlarm(const QuicClock* clock,
+ base::TaskRunner* task_runner,
+ QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+ : QuicAlarm(std::move(delegate)),
+ clock_(clock),
+ task_runner_(task_runner),
+ task_deadline_(QuicTime::Zero()),
+ weak_factory_(this) {}
+
+ protected:
+ void SetImpl() override {
+ DCHECK(deadline().IsInitialized());
+ if (task_deadline_.IsInitialized()) {
+ if (task_deadline_ <= deadline()) {
+ // Since tasks can not be un-posted, OnAlarm will be invoked which
+ // will notice that deadline has not yet been reached, and will set
+ // the alarm for the new deadline.
+ return;
+ }
+ // The scheduled task is after new deadline. Invalidate the weak ptrs
+ // so that task does not execute when we're not expecting it.
+ weak_factory_.InvalidateWeakPtrs();
+ }
+
+ int64_t delay_us = deadline().Subtract(clock_->Now()).ToMicroseconds();
+ if (delay_us < 0) {
+ delay_us = 0;
+ }
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&QuicChromeAlarm::OnAlarm, weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMicroseconds(delay_us));
+ task_deadline_ = deadline();
+ }
+
+ void CancelImpl() override {
+ DCHECK(!deadline().IsInitialized());
+ // Since tasks can not be un-posted, OnAlarm will be invoked which
+ // will notice that deadline is not Initialized and will do nothing.
+ }
+
+ private:
+ void OnAlarm() {
+ DCHECK(task_deadline_.IsInitialized());
+ task_deadline_ = QuicTime::Zero();
+ // The alarm may have been cancelled.
+ if (!deadline().IsInitialized()) {
+ return;
+ }
+
+ // The alarm may have been re-set to a later time.
+ if (clock_->Now() < deadline()) {
+ SetImpl();
+ return;
+ }
+
+ Fire();
+ }
+
+ const QuicClock* clock_;
+ base::TaskRunner* task_runner_;
+ // If a task has been posted to the message loop, this is the time it
+ // was scheduled to fire. Tracking this allows us to avoid posting a
+ // new tast if the new deadline is in the future, but permits us to
+ // post a new task when the new deadline now earlier than when
+ // previously posted.
+ QuicTime task_deadline_;
+ base::WeakPtrFactory<QuicChromeAlarm> weak_factory_;
+};
+
+} // namespace
+
+QuicChromiumAlarmFactory::QuicChromiumAlarmFactory(
+ base::TaskRunner* task_runner,
+ const QuicClock* clock)
+ : task_runner_(task_runner), clock_(clock), weak_factory_(this) {}
+
+QuicChromiumAlarmFactory::~QuicChromiumAlarmFactory() {}
+
+QuicArenaScopedPtr<QuicAlarm> QuicChromiumAlarmFactory::CreateAlarm(
+ QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+ QuicConnectionArena* arena) {
+ if (arena != nullptr) {
+ return arena->New<QuicChromeAlarm>(clock_, task_runner_,
+ std::move(delegate));
+ } else {
+ return QuicArenaScopedPtr<QuicAlarm>(
+ new QuicChromeAlarm(clock_, task_runner_, std::move(delegate)));
+ }
+}
+
+QuicAlarm* QuicChromiumAlarmFactory::CreateAlarm(
+ QuicAlarm::Delegate* delegate) {
+ return new QuicChromeAlarm(clock_, task_runner_,
+ QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+}
+
+} // namespace net
diff --git a/net/quic/quic_chromium_alarm_factory.h b/net/quic/quic_chromium_alarm_factory.h
new file mode 100644
index 0000000..16345b72
--- /dev/null
+++ b/net/quic/quic_chromium_alarm_factory.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// The Chrome-specific helper for QuicConnection which uses
+// a TaskRunner for alarms, and uses a DatagramClientSocket for writing data.
+
+#ifndef NET_QUIC_QUIC_CHROMIUM_ALARM_FACTORY_H_
+#define NET_QUIC_QUIC_CHROMIUM_ALARM_FACTORY_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "net/quic/quic_alarm_factory.h"
+#include "net/quic/quic_clock.h"
+#include "net/quic/quic_protocol.h"
+#include "net/quic/quic_time.h"
+
+namespace base {
+class TaskRunner;
+} // namespace base
+
+namespace net {
+
+class NET_EXPORT_PRIVATE QuicChromiumAlarmFactory : public QuicAlarmFactory {
+ public:
+ QuicChromiumAlarmFactory(base::TaskRunner* task_runner,
+ const QuicClock* clock);
+ ~QuicChromiumAlarmFactory() override;
+
+ // QuicAlarmFactory
+ QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
+ QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+ QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+ QuicConnectionArena* arena) override;
+
+ private:
+ base::TaskRunner* task_runner_;
+ const QuicClock* clock_;
+ base::WeakPtrFactory<QuicChromiumAlarmFactory> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(QuicChromiumAlarmFactory);
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUIC_CHROMIUM_ALARM_FACTORY_H_
diff --git a/net/quic/quic_chromium_alarm_factory_test.cc b/net/quic/quic_chromium_alarm_factory_test.cc
new file mode 100644
index 0000000..d47c98e
--- /dev/null
+++ b/net/quic/quic_chromium_alarm_factory_test.cc
@@ -0,0 +1,175 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_chromium_alarm_factory.h"
+
+#include "net/quic/test_tools/mock_clock.h"
+#include "net/quic/test_tools/test_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace test {
+namespace {
+
+class TestDelegate : public QuicAlarm::Delegate {
+ public:
+ TestDelegate() : fired_(false) {}
+
+ void OnAlarm() override { fired_ = true; }
+
+ bool fired() const { return fired_; }
+ void Clear() { fired_ = false; }
+
+ private:
+ bool fired_;
+};
+
+class QuicChromiumAlarmFactoryTest : public ::testing::Test {
+ protected:
+ QuicChromiumAlarmFactoryTest()
+ : runner_(new TestTaskRunner(&clock_)),
+ alarm_factory_(runner_.get(), &clock_) {}
+
+ scoped_refptr<TestTaskRunner> runner_;
+ QuicChromiumAlarmFactory alarm_factory_;
+ MockClock clock_;
+};
+
+TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarm) {
+ TestDelegate* delegate = new TestDelegate();
+ std::unique_ptr<QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
+
+ QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+ alarm->Set(clock_.Now().Add(delta));
+
+ // Verify that the alarm task has been posted.
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+ EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
+ runner_->GetPostedTasks()[0].delay);
+
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
+ EXPECT_TRUE(delegate->fired());
+}
+
+TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndCancel) {
+ TestDelegate* delegate = new TestDelegate();
+ std::unique_ptr<QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
+
+ QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+ alarm->Set(clock_.Now().Add(delta));
+ alarm->Cancel();
+
+ // The alarm task should still be posted.
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+ EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
+ runner_->GetPostedTasks()[0].delay);
+
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
+ EXPECT_FALSE(delegate->fired());
+}
+
+TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndReset) {
+ TestDelegate* delegate = new TestDelegate();
+ std::unique_ptr<QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
+
+ QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+ alarm->Set(clock_.Now().Add(delta));
+ alarm->Cancel();
+ QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
+ alarm->Set(clock_.Now().Add(new_delta));
+
+ // The alarm task should still be posted.
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+ EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
+ runner_->GetPostedTasks()[0].delay);
+
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
+ EXPECT_FALSE(delegate->fired());
+
+ // The alarm task should be posted again.
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now());
+ EXPECT_TRUE(delegate->fired());
+}
+
+TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndResetEarlier) {
+ TestDelegate* delegate = new TestDelegate();
+ std::unique_ptr<QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
+
+ QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(3);
+ alarm->Set(clock_.Now().Add(delta));
+ alarm->Cancel();
+ QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(1);
+ alarm->Set(clock_.Now().Add(new_delta));
+
+ // Both alarm tasks will be posted.
+ ASSERT_EQ(2u, runner_->GetPostedTasks().size());
+
+ // The earlier task will execute and will fire the alarm->
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now());
+ EXPECT_TRUE(delegate->fired());
+ delegate->Clear();
+
+ // The latter task is still posted.
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+
+ // When the latter task is executed, the weak ptr will be invalid and
+ // the alarm will not fire.
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
+ EXPECT_FALSE(delegate->fired());
+}
+
+TEST_F(QuicChromiumAlarmFactoryTest, CreateAlarmAndUpdate) {
+ TestDelegate* delegate = new TestDelegate();
+ std::unique_ptr<QuicAlarm> alarm(alarm_factory_.CreateAlarm(delegate));
+
+ QuicTime start = clock_.Now();
+ QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
+ alarm->Set(clock_.Now().Add(delta));
+ QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
+ alarm->Update(clock_.Now().Add(new_delta),
+ QuicTime::Delta::FromMicroseconds(1));
+
+ // The alarm task should still be posted.
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+ EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
+ runner_->GetPostedTasks()[0].delay);
+
+ runner_->RunNextTask();
+ EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
+ EXPECT_FALSE(delegate->fired());
+
+ // Move the alarm forward 1us and ensure it doesn't move forward.
+ alarm->Update(clock_.Now().Add(new_delta),
+ QuicTime::Delta::FromMicroseconds(2));
+
+ ASSERT_EQ(1u, runner_->GetPostedTasks().size());
+ EXPECT_EQ(base::TimeDelta::FromMicroseconds(
+ new_delta.Subtract(delta).ToMicroseconds()),
+ runner_->GetPostedTasks()[0].delay);
+ runner_->RunNextTask();
+ EXPECT_EQ(start.Add(new_delta), clock_.Now());
+ EXPECT_TRUE(delegate->fired());
+
+ // Set the alarm via an update call.
+ new_delta = QuicTime::Delta::FromMicroseconds(5);
+ alarm->Update(clock_.Now().Add(new_delta),
+ QuicTime::Delta::FromMicroseconds(1));
+ EXPECT_TRUE(alarm->IsSet());
+
+ // Update it with an uninitialized time and ensure it's cancelled.
+ alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
+ EXPECT_FALSE(alarm->IsSet());
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index a17b663ce..f8e17f9 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -23,6 +23,7 @@
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/crypto/quic_server_info.h"
+#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_reader.h"
#include "net/quic/quic_chromium_packet_writer.h"
@@ -63,7 +64,8 @@
socket_data_(
new SequencedSocketData(default_read_.get(), 1, nullptr, 0)),
random_(0),
- helper_(base::ThreadTaskRunnerHandle::Get().get(), &clock_, &random_),
+ helper_(&clock_, &random_),
+ alarm_factory_(base::ThreadTaskRunnerHandle::Get().get(), &clock_),
maker_(GetParam(), 0, &clock_, kServerHostname) {
// Advance the time, because timers do not like uninitialized times.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -79,8 +81,8 @@
QuicChromiumPacketWriter* writer =
new net::QuicChromiumPacketWriter(socket.get());
QuicConnection* connection = new QuicConnection(
- 0, kIpEndPoint, &helper_, writer, true, Perspective::IS_CLIENT,
- SupportedVersions(GetParam()));
+ 0, kIpEndPoint, &helper_, &alarm_factory_, writer, true,
+ Perspective::IS_CLIENT, SupportedVersions(GetParam()));
writer->SetConnection(connection);
session_.reset(new QuicChromiumClientSession(
connection, std::move(socket),
@@ -127,6 +129,7 @@
MockClock clock_;
MockRandom random_;
QuicChromiumConnectionHelper helper_;
+ QuicChromiumAlarmFactory alarm_factory_;
TransportSecurityState transport_security_state_;
MockCryptoClientStreamFactory crypto_client_stream_factory_;
std::unique_ptr<QuicChromiumClientSession> session_;
diff --git a/net/quic/quic_chromium_client_stream_test.cc b/net/quic/quic_chromium_client_stream_test.cc
index 4b1d31ed..b7c888c 100644
--- a/net/quic/quic_chromium_client_stream_test.cc
+++ b/net/quic/quic_chromium_client_stream_test.cc
@@ -144,6 +144,7 @@
QuicChromiumClientStreamTest()
: crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
session_(new MockConnection(&helper_,
+ &alarm_factory_,
Perspective::IS_CLIENT,
SupportedVersions(GetParam())),
&push_promise_index_) {
@@ -194,6 +195,7 @@
QuicCryptoClientConfig crypto_config_;
testing::StrictMock<MockDelegate> delegate_;
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockQuicClientSessionBase session_;
QuicChromiumClientStream* stream_;
SpdyHeaderBlock headers_;
diff --git a/net/quic/quic_chromium_connection_helper.cc b/net/quic/quic_chromium_connection_helper.cc
index d88648f..9bdb407 100644
--- a/net/quic/quic_chromium_connection_helper.cc
+++ b/net/quic/quic_chromium_connection_helper.cc
@@ -4,101 +4,12 @@
#include "net/quic/quic_chromium_connection_helper.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/task_runner.h"
-#include "base/time/time.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/quic/quic_utils.h"
-
namespace net {
-namespace {
-
-class QuicChromeAlarm : public QuicAlarm {
- public:
- QuicChromeAlarm(const QuicClock* clock,
- base::TaskRunner* task_runner,
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
- : QuicAlarm(std::move(delegate)),
- clock_(clock),
- task_runner_(task_runner),
- task_deadline_(QuicTime::Zero()),
- weak_factory_(this) {}
-
- protected:
- void SetImpl() override {
- DCHECK(deadline().IsInitialized());
- if (task_deadline_.IsInitialized()) {
- if (task_deadline_ <= deadline()) {
- // Since tasks can not be un-posted, OnAlarm will be invoked which
- // will notice that deadline has not yet been reached, and will set
- // the alarm for the new deadline.
- return;
- }
- // The scheduled task is after new deadline. Invalidate the weak ptrs
- // so that task does not execute when we're not expecting it.
- weak_factory_.InvalidateWeakPtrs();
- }
-
- int64_t delay_us = deadline().Subtract(clock_->Now()).ToMicroseconds();
- if (delay_us < 0) {
- delay_us = 0;
- }
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&QuicChromeAlarm::OnAlarm, weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMicroseconds(delay_us));
- task_deadline_ = deadline();
- }
-
- void CancelImpl() override {
- DCHECK(!deadline().IsInitialized());
- // Since tasks can not be un-posted, OnAlarm will be invoked which
- // will notice that deadline is not Initialized and will do nothing.
- }
-
- private:
- void OnAlarm() {
- DCHECK(task_deadline_.IsInitialized());
- task_deadline_ = QuicTime::Zero();
- // The alarm may have been cancelled.
- if (!deadline().IsInitialized()) {
- return;
- }
-
- // The alarm may have been re-set to a later time.
- if (clock_->Now() < deadline()) {
- SetImpl();
- return;
- }
-
- Fire();
- }
-
- const QuicClock* clock_;
- base::TaskRunner* task_runner_;
- // If a task has been posted to the message loop, this is the time it
- // was scheduled to fire. Tracking this allows us to avoid posting a
- // new tast if the new deadline is in the future, but permits us to
- // post a new task when the new deadline now earlier than when
- // previously posted.
- QuicTime task_deadline_;
- base::WeakPtrFactory<QuicChromeAlarm> weak_factory_;
-};
-
-} // namespace
-
QuicChromiumConnectionHelper::QuicChromiumConnectionHelper(
- base::TaskRunner* task_runner,
const QuicClock* clock,
QuicRandom* random_generator)
- : task_runner_(task_runner),
- clock_(clock),
- random_generator_(random_generator),
- weak_factory_(this) {}
+ : clock_(clock), random_generator_(random_generator) {}
QuicChromiumConnectionHelper::~QuicChromiumConnectionHelper() {}
@@ -110,24 +21,6 @@
return random_generator_;
}
-QuicArenaScopedPtr<QuicAlarm> QuicChromiumConnectionHelper::CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) {
- if (arena != nullptr) {
- return arena->New<QuicChromeAlarm>(clock_, task_runner_,
- std::move(delegate));
- } else {
- return QuicArenaScopedPtr<QuicAlarm>(
- new QuicChromeAlarm(clock_, task_runner_, std::move(delegate)));
- }
-}
-
-QuicAlarm* QuicChromiumConnectionHelper::CreateAlarm(
- QuicAlarm::Delegate* delegate) {
- return new QuicChromeAlarm(clock_, task_runner_,
- QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
-}
-
QuicBufferAllocator* QuicChromiumConnectionHelper::GetBufferAllocator() {
return &buffer_allocator_;
}
diff --git a/net/quic/quic_chromium_connection_helper.h b/net/quic/quic_chromium_connection_helper.h
index 281a3f3..34fbe47 100644
--- a/net/quic/quic_chromium_connection_helper.h
+++ b/net/quic/quic_chromium_connection_helper.h
@@ -8,10 +8,7 @@
#ifndef NET_QUIC_QUIC_CONNECTION_HELPER_H_
#define NET_QUIC_QUIC_CONNECTION_HELPER_H_
-#include <set>
-
#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
#include "net/base/ip_endpoint.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_protocol.h"
@@ -31,26 +28,19 @@
class NET_EXPORT_PRIVATE QuicChromiumConnectionHelper
: public QuicConnectionHelperInterface {
public:
- QuicChromiumConnectionHelper(base::TaskRunner* task_runner,
- const QuicClock* clock,
+ QuicChromiumConnectionHelper(const QuicClock* clock,
QuicRandom* random_generator);
~QuicChromiumConnectionHelper() override;
// QuicConnectionHelperInterface
const QuicClock* GetClock() const override;
QuicRandom* GetRandomGenerator() override;
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override;
QuicBufferAllocator* GetBufferAllocator() override;
private:
- base::TaskRunner* task_runner_;
const QuicClock* clock_;
QuicRandom* random_generator_;
SimpleBufferAllocator buffer_allocator_;
- base::WeakPtrFactory<QuicChromiumConnectionHelper> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(QuicChromiumConnectionHelper);
};
diff --git a/net/quic/quic_chromium_connection_helper_test.cc b/net/quic/quic_chromium_connection_helper_test.cc
index 2774d17..356ac6c 100644
--- a/net/quic/quic_chromium_connection_helper_test.cc
+++ b/net/quic/quic_chromium_connection_helper_test.cc
@@ -6,33 +6,16 @@
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
-#include "net/quic/test_tools/test_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace test {
namespace {
-class TestDelegate : public QuicAlarm::Delegate {
- public:
- TestDelegate() : fired_(false) {}
-
- void OnAlarm() override { fired_ = true; }
-
- bool fired() const { return fired_; }
- void Clear() { fired_ = false; }
-
- private:
- bool fired_;
-};
-
class QuicChromiumConnectionHelperTest : public ::testing::Test {
protected:
- QuicChromiumConnectionHelperTest()
- : runner_(new TestTaskRunner(&clock_)),
- helper_(runner_.get(), &clock_, &random_generator_) {}
+ QuicChromiumConnectionHelperTest() : helper_(&clock_, &random_generator_) {}
- scoped_refptr<TestTaskRunner> runner_;
QuicChromiumConnectionHelper helper_;
MockClock clock_;
MockRandom random_generator_;
@@ -46,141 +29,6 @@
EXPECT_EQ(&random_generator_, helper_.GetRandomGenerator());
}
-TEST_F(QuicChromiumConnectionHelperTest, CreateAlarm) {
- TestDelegate* delegate = new TestDelegate();
- std::unique_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
-
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now().Add(delta));
-
- // Verify that the alarm task has been posted.
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
- runner_->GetPostedTasks()[0].delay);
-
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
- EXPECT_TRUE(delegate->fired());
-}
-
-TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndCancel) {
- TestDelegate* delegate = new TestDelegate();
- std::unique_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
-
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now().Add(delta));
- alarm->Cancel();
-
- // The alarm task should still be posted.
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
- runner_->GetPostedTasks()[0].delay);
-
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
- EXPECT_FALSE(delegate->fired());
-}
-
-TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndReset) {
- TestDelegate* delegate = new TestDelegate();
- std::unique_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
-
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now().Add(delta));
- alarm->Cancel();
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Set(clock_.Now().Add(new_delta));
-
- // The alarm task should still be posted.
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
- runner_->GetPostedTasks()[0].delay);
-
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
- EXPECT_FALSE(delegate->fired());
-
- // The alarm task should be posted again.
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
-
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now());
- EXPECT_TRUE(delegate->fired());
-}
-
-TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndResetEarlier) {
- TestDelegate* delegate = new TestDelegate();
- std::unique_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
-
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Set(clock_.Now().Add(delta));
- alarm->Cancel();
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock_.Now().Add(new_delta));
-
- // Both alarm tasks will be posted.
- ASSERT_EQ(2u, runner_->GetPostedTasks().size());
-
- // The earlier task will execute and will fire the alarm->
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now());
- EXPECT_TRUE(delegate->fired());
- delegate->Clear();
-
- // The latter task is still posted.
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
-
- // When the latter task is executed, the weak ptr will be invalid and
- // the alarm will not fire.
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
- EXPECT_FALSE(delegate->fired());
-}
-
-TEST_F(QuicChromiumConnectionHelperTest, CreateAlarmAndUpdate) {
- TestDelegate* delegate = new TestDelegate();
- std::unique_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
-
- const QuicClock* clock = helper_.GetClock();
- QuicTime start = clock->Now();
- QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
- alarm->Set(clock->Now().Add(delta));
- QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
- alarm->Update(clock->Now().Add(new_delta),
- QuicTime::Delta::FromMicroseconds(1));
-
- // The alarm task should still be posted.
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
- runner_->GetPostedTasks()[0].delay);
-
- runner_->RunNextTask();
- EXPECT_EQ(QuicTime::Zero().Add(delta), clock->Now());
- EXPECT_FALSE(delegate->fired());
-
- // Move the alarm forward 1us and ensure it doesn't move forward.
- alarm->Update(clock->Now().Add(new_delta),
- QuicTime::Delta::FromMicroseconds(2));
-
- ASSERT_EQ(1u, runner_->GetPostedTasks().size());
- EXPECT_EQ(base::TimeDelta::FromMicroseconds(
- new_delta.Subtract(delta).ToMicroseconds()),
- runner_->GetPostedTasks()[0].delay);
- runner_->RunNextTask();
- EXPECT_EQ(start.Add(new_delta), clock->Now());
- EXPECT_TRUE(delegate->fired());
-
- // Set the alarm via an update call.
- new_delta = QuicTime::Delta::FromMicroseconds(5);
- alarm->Update(clock->Now().Add(new_delta),
- QuicTime::Delta::FromMicroseconds(1));
- EXPECT_TRUE(alarm->IsSet());
-
- // Update it with an uninitialized time and ensure it's cancelled.
- alarm->Update(QuicTime::Zero(), QuicTime::Delta::FromMicroseconds(1));
- EXPECT_FALSE(alarm->IsSet());
-}
-
} // namespace
} // namespace test
} // namespace net
diff --git a/net/quic/quic_client_promised_info.cc b/net/quic/quic_client_promised_info.cc
index f4bef0bc..14cba80e 100644
--- a/net/quic/quic_client_promised_info.cc
+++ b/net/quic/quic_client_promised_info.cc
@@ -17,7 +17,6 @@
QuicStreamId id,
string url)
: session_(session),
- helper_(session->connection()->helper()),
id_(id),
url_(url),
client_request_delegate_(nullptr) {}
@@ -30,10 +29,11 @@
}
void QuicClientPromisedInfo::Init() {
- cleanup_alarm_.reset(
- helper_->CreateAlarm(new QuicClientPromisedInfo::CleanupAlarm(this)));
- cleanup_alarm_->Set(helper_->GetClock()->ApproximateNow().Add(
- QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs)));
+ cleanup_alarm_.reset(session_->connection()->alarm_factory()->CreateAlarm(
+ new QuicClientPromisedInfo::CleanupAlarm(this)));
+ cleanup_alarm_->Set(
+ session_->connection()->helper()->GetClock()->ApproximateNow().Add(
+ QuicTime::Delta::FromSeconds(kPushPromiseTimeoutSecs)));
}
void QuicClientPromisedInfo::OnPromiseHeaders(const SpdyHeaderBlock& headers) {
diff --git a/net/quic/quic_client_promised_info.h b/net/quic/quic_client_promised_info.h
index f4bb50f2..5b14d14 100644
--- a/net/quic/quic_client_promised_info.h
+++ b/net/quic/quic_client_promised_info.h
@@ -54,6 +54,8 @@
void Cancel() override;
+ void Reset(QuicRstStreamErrorCode error_code);
+
// Client requests are initially associated to promises by matching
// URL in the client request against the URL in the promise headers,
// uing the |promised_by_url| map. The push can be cross-origin, so
@@ -88,12 +90,9 @@
QuicClientPromisedInfo* promised_;
};
- void Reset(QuicRstStreamErrorCode error_code);
-
QuicAsyncStatus FinalValidation();
QuicClientSessionBase* session_;
- QuicConnectionHelperInterface* helper_;
QuicStreamId id_;
std::string url_;
std::unique_ptr<SpdyHeaderBlock> request_headers_;
diff --git a/net/quic/quic_client_promised_info_test.cc b/net/quic/quic_client_promised_info_test.cc
index df4694c..f05f8f2e 100644
--- a/net/quic/quic_client_promised_info_test.cc
+++ b/net/quic/quic_client_promised_info_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_client_promised_info.h"
+#include <memory>
+
#include "base/macros.h"
#include "base/scoped_ptr.h"
#include "net/gfe2/balsa_headers.h"
@@ -70,8 +72,9 @@
class StreamVisitor;
QuicClientPromisedInfoTest()
- : connection_(
- new StrictMock<MockConnection>(&helper_, Perspective::IS_CLIENT)),
+ : connection_(new StrictMock<MockConnection>(&helper_,
+ &alarm_factory_,
+ Perspective::IS_CLIENT)),
session_(connection_, &push_promise_index_),
body_("hello world"),
promise_id_(gfe_quic::test::kServerDataStreamId1) {
@@ -142,6 +145,7 @@
}
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
StrictMock<MockConnection>* connection_;
QuicClientPushPromiseIndex push_promise_index_;
@@ -176,7 +180,7 @@
// Fire the alarm that will cancel the promised stream.
EXPECT_CALL(*connection_,
SendRstStream(promise_id_, QUIC_STREAM_CANCELLED, 0));
- helper_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
+ alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
// Verify that the promise is gone after the alarm fires.
EXPECT_EQ(session_.GetPromisedById(promise_id_), nullptr);
diff --git a/net/quic/quic_client_push_promise_index_test.cc b/net/quic/quic_client_push_promise_index_test.cc
index 85c7f0c..672fcfc 100644
--- a/net/quic/quic_client_push_promise_index_test.cc
+++ b/net/quic/quic_client_push_promise_index_test.cc
@@ -45,8 +45,9 @@
class QuicClientPushPromiseIndexTest : public ::testing::Test {
public:
QuicClientPushPromiseIndexTest()
- : connection_(
- new StrictMock<MockConnection>(&helper_, Perspective::IS_CLIENT)),
+ : connection_(new StrictMock<MockConnection>(&helper_,
+ &alarm_factory_,
+ Perspective::IS_CLIENT)),
session_(connection_, &index_),
promised_(&session_, kServerDataStreamId1, url_) {
FLAGS_quic_supports_push_promise = true;
@@ -59,6 +60,7 @@
}
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
StrictMock<MockConnection>* connection_;
MockQuicClientSession session_;
QuicClientPushPromiseIndex index_;
diff --git a/net/quic/quic_client_session_base.cc b/net/quic/quic_client_session_base.cc
index 14c6f5e..dff71e4 100644
--- a/net/quic/quic_client_session_base.cc
+++ b/net/quic/quic_client_session_base.cc
@@ -81,6 +81,30 @@
stream->OnPromiseHeadersComplete(promised_stream_id, frame_len);
}
+void QuicClientSessionBase::OnPromiseHeaderList(
+ QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len,
+ const QuicHeaderList& header_list) {
+ if (promised_stream_id != kInvalidStreamId &&
+ promised_stream_id <= largest_promised_stream_id_) {
+ connection()->CloseConnection(
+ QUIC_INVALID_STREAM_ID,
+ "Received push stream id lesser or equal to the"
+ " last accepted before",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return;
+ }
+ largest_promised_stream_id_ = promised_stream_id;
+
+ QuicSpdyStream* stream = GetSpdyDataStream(stream_id);
+ if (!stream) {
+ // It's quite possible to receive headers after a stream has been reset.
+ return;
+ }
+ stream->OnPromiseHeaderList(promised_stream_id, frame_len, header_list);
+}
+
void QuicClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
QuicStreamId id,
const SpdyHeaderBlock& headers) {
diff --git a/net/quic/quic_client_session_base.h b/net/quic/quic_client_session_base.h
index 96231102..58c7d65b 100644
--- a/net/quic/quic_client_session_base.h
+++ b/net/quic/quic_client_session_base.h
@@ -51,12 +51,18 @@
base::StringPiece headers_data) override;
// Called by |headers_stream_| when push promise headers have been
- // completely received. |fin| will be true if the fin flag was set
- // in the headers.
+ // completely received.
void OnPromiseHeadersComplete(QuicStreamId stream_id,
QuicStreamId promised_stream_id,
size_t frame_len) override;
+ // Called by |headers_stream_| when push promise headers have been
+ // completely received.
+ void OnPromiseHeaderList(QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len,
+ const QuicHeaderList& header_list) override;
+
// Called by |QuicSpdyClientStream| on receipt of response headers,
// needed to detect promised server push streams, as part of
// client-request to push-stream rendezvous.
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 60f5395..c8a132f 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -204,6 +204,7 @@
QuicConnection::QuicConnection(QuicConnectionId connection_id,
IPEndPoint address,
QuicConnectionHelperInterface* helper,
+ QuicAlarmFactory* alarm_factory,
QuicPacketWriter* writer,
bool owns_writer,
Perspective perspective,
@@ -212,6 +213,7 @@
helper->GetClock()->ApproximateNow(),
perspective),
helper_(helper),
+ alarm_factory_(alarm_factory),
per_packet_options_(nullptr),
writer_(writer),
owns_writer_(owns_writer),
@@ -248,17 +250,22 @@
pending_retransmission_alarm_(false),
defer_send_in_response_to_packets_(false),
arena_(),
- ack_alarm_(helper->CreateAlarm(arena_.New<AckAlarm>(this), &arena_)),
+ ack_alarm_(
+ alarm_factory_->CreateAlarm(arena_.New<AckAlarm>(this), &arena_)),
retransmission_alarm_(
- helper->CreateAlarm(arena_.New<RetransmissionAlarm>(this), &arena_)),
- send_alarm_(helper->CreateAlarm(arena_.New<SendAlarm>(this), &arena_)),
+ alarm_factory_->CreateAlarm(arena_.New<RetransmissionAlarm>(this),
+ &arena_)),
+ send_alarm_(
+ alarm_factory_->CreateAlarm(arena_.New<SendAlarm>(this), &arena_)),
resume_writes_alarm_(
- helper->CreateAlarm(arena_.New<SendAlarm>(this), &arena_)),
+ alarm_factory_->CreateAlarm(arena_.New<SendAlarm>(this), &arena_)),
timeout_alarm_(
- helper->CreateAlarm(arena_.New<TimeoutAlarm>(this), &arena_)),
- ping_alarm_(helper->CreateAlarm(arena_.New<PingAlarm>(this), &arena_)),
+ alarm_factory_->CreateAlarm(arena_.New<TimeoutAlarm>(this), &arena_)),
+ ping_alarm_(
+ alarm_factory_->CreateAlarm(arena_.New<PingAlarm>(this), &arena_)),
mtu_discovery_alarm_(
- helper->CreateAlarm(arena_.New<MtuDiscoveryAlarm>(this), &arena_)),
+ alarm_factory_->CreateAlarm(arena_.New<MtuDiscoveryAlarm>(this),
+ &arena_)),
visitor_(nullptr),
debug_visitor_(nullptr),
packet_generator_(connection_id_,
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 597edd5..443aaa44 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -34,6 +34,7 @@
#include "net/base/ip_endpoint.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/quic_alarm.h"
+#include "net/quic/quic_alarm_factory.h"
#include "net/quic/quic_blocked_writer_interface.h"
#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_framer.h"
@@ -273,20 +274,6 @@
// Returns a QuicRandom to be used for all random number related functions.
virtual QuicRandom* GetRandomGenerator() = 0;
- // Creates a new platform-specific alarm which will be configured to notify
- // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
- // Caller takes ownership of the new alarm, which will not yet be "set" to
- // fire.
- virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) = 0;
-
- // Creates a new platform-specific alarm which will be configured to notify
- // |delegate| when the alarm fires. Caller takes ownership of the new alarm,
- // which will not yet be "set" to fire. If |arena| is null, then the alarm
- // will be created on the heap. Otherwise, it will be created in |arena|.
- virtual QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) = 0;
-
// Returns a QuicBufferAllocator to be used for all stream frame buffers.
virtual QuicBufferAllocator* GetBufferAllocator() = 0;
};
@@ -314,6 +301,7 @@
QuicConnection(QuicConnectionId connection_id,
IPEndPoint address,
QuicConnectionHelperInterface* helper,
+ QuicAlarmFactory* alarm_factory,
QuicPacketWriter* writer,
bool owns_writer,
Perspective perspective,
@@ -665,6 +653,7 @@
bool ack_frame_updated() const;
QuicConnectionHelperInterface* helper() { return helper_; }
+ QuicAlarmFactory* alarm_factory() { return alarm_factory_; }
base::StringPiece GetCurrentPacket();
@@ -839,6 +828,7 @@
QuicFramer framer_;
QuicConnectionHelperInterface* helper_; // Not owned.
+ QuicAlarmFactory* alarm_factory_; // Not owned.
PerPacketOptions* per_packet_options_; // Not owned.
QuicPacketWriter* writer_; // Owned or not depending on |owns_writer_|.
bool owns_writer_;
diff --git a/net/quic/quic_connection_logger_unittest.cc b/net/quic/quic_connection_logger_unittest.cc
index ebaa12d..268e7f7 100644
--- a/net/quic/quic_connection_logger_unittest.cc
+++ b/net/quic/quic_connection_logger_unittest.cc
@@ -32,7 +32,9 @@
class QuicConnectionLoggerTest : public ::testing::Test {
protected:
QuicConnectionLoggerTest()
- : session_(new MockConnection(&helper_, Perspective::IS_CLIENT)),
+ : session_(new MockConnection(&helper_,
+ &alarm_factory_,
+ Perspective::IS_CLIENT)),
logger_(&session_,
"CONNECTION_UNKNOWN",
/*socket_performance_watcher=*/nullptr,
@@ -40,6 +42,7 @@
BoundNetLog net_log_;
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockQuicSpdySession session_;
QuicConnectionLogger logger_;
};
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index cf652af1..54b6dd0 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -4,8 +4,10 @@
#include "net/quic/quic_connection.h"
+#include <errno.h>
#include <memory>
#include <ostream>
+#include <utility>
#include "base/bind.h"
#include "base/macros.h"
@@ -204,16 +206,6 @@
class TestConnectionHelper : public QuicConnectionHelperInterface {
public:
- class TestAlarm : public QuicAlarm {
- public:
- explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
- : QuicAlarm(std::move(delegate)) {}
-
- void SetImpl() override {}
- void CancelImpl() override {}
- using QuicAlarm::Fire;
- };
-
TestConnectionHelper(MockClock* clock, MockRandom* random_generator)
: clock_(clock), random_generator_(random_generator) {
clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -224,16 +216,6 @@
QuicRandom* GetRandomGenerator() override { return random_generator_; }
- QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
- return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
- }
-
- QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
- QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
- QuicConnectionArena* arena) override {
- return arena->New<TestAlarm>(std::move(delegate));
- }
-
QuicBufferAllocator* GetBufferAllocator() override {
return &buffer_allocator_;
}
@@ -246,6 +228,34 @@
DISALLOW_COPY_AND_ASSIGN(TestConnectionHelper);
};
+class TestAlarmFactory : public QuicAlarmFactory {
+ public:
+ class TestAlarm : public QuicAlarm {
+ public:
+ explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
+ : QuicAlarm(std::move(delegate)) {}
+
+ void SetImpl() override {}
+ void CancelImpl() override {}
+ using QuicAlarm::Fire;
+ };
+
+ TestAlarmFactory() {}
+
+ QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
+ return new TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
+ }
+
+ QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
+ QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
+ QuicConnectionArena* arena) override {
+ return arena->New<TestAlarm>(std::move(delegate));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestAlarmFactory);
+};
+
class TestPacketWriter : public QuicPacketWriter {
public:
TestPacketWriter(QuicVersion version, MockClock* clock)
@@ -425,12 +435,14 @@
TestConnection(QuicConnectionId connection_id,
IPEndPoint address,
TestConnectionHelper* helper,
+ TestAlarmFactory* alarm_factory,
TestPacketWriter* writer,
Perspective perspective,
QuicVersion version)
: QuicConnection(connection_id,
address,
helper,
+ alarm_factory,
writer,
/* owns_writer= */ false,
perspective,
@@ -542,38 +554,38 @@
.WillRepeatedly(Return(QuicBandwidth::FromKBytesPerSecond(10000)));
}
- TestConnectionHelper::TestAlarm* GetAckAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetAckAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetAckAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetPingAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetPingAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetPingAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetResumeWritesAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetResumeWritesAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetResumeWritesAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetRetransmissionAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetRetransmissionAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetRetransmissionAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetSendAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetSendAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetSendAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetTimeoutAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetTimeoutAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetTimeoutAlarm(this));
}
- TestConnectionHelper::TestAlarm* GetMtuDiscoveryAlarm() {
- return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ TestAlarmFactory::TestAlarm* GetMtuDiscoveryAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
}
@@ -635,6 +647,7 @@
send_algorithm_(new StrictMock<MockSendAlgorithm>),
loss_algorithm_(new MockLossAlgorithm()),
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
+ alarm_factory_(new TestAlarmFactory()),
peer_creator_(connection_id_,
&framer_,
&random_generator_,
@@ -644,6 +657,7 @@
connection_(connection_id_,
kPeerAddress,
helper_.get(),
+ alarm_factory_.get(),
writer_.get(),
Perspective::IS_CLIENT,
version()),
@@ -995,6 +1009,7 @@
MockRandom random_generator_;
SimpleBufferAllocator buffer_allocator_;
std::unique_ptr<TestConnectionHelper> helper_;
+ std::unique_ptr<TestAlarmFactory> alarm_factory_;
QuicPacketCreator peer_creator_;
std::unique_ptr<TestPacketWriter> writer_;
TestConnection connection_;
@@ -1066,7 +1081,8 @@
TEST_P(QuicConnectionTest, SmallerServerMaxPacketSize) {
QuicConnectionId connection_id = 42;
TestConnection connection(connection_id, kPeerAddress, helper_.get(),
- writer_.get(), Perspective::IS_SERVER, version());
+ alarm_factory_.get(), writer_.get(),
+ Perspective::IS_SERVER, version());
EXPECT_EQ(Perspective::IS_SERVER, connection.perspective());
EXPECT_EQ(1000u, connection.max_packet_length());
}
@@ -1154,7 +1170,8 @@
const QuicByteCount lower_max_packet_size = 1240;
writer_->set_max_packet_size(lower_max_packet_size);
TestConnection connection(connection_id, kPeerAddress, helper_.get(),
- writer_.get(), Perspective::IS_CLIENT, version());
+ alarm_factory_.get(), writer_.get(),
+ Perspective::IS_CLIENT, version());
EXPECT_EQ(Perspective::IS_CLIENT, connection.perspective());
EXPECT_EQ(lower_max_packet_size, connection.max_packet_length());
}
@@ -4509,9 +4526,11 @@
TEST_P(QuicConnectionTest, Pacing) {
TestConnection server(connection_id_, kSelfAddress, helper_.get(),
- writer_.get(), Perspective::IS_SERVER, version());
+ alarm_factory_.get(), writer_.get(),
+ Perspective::IS_SERVER, version());
TestConnection client(connection_id_, kPeerAddress, helper_.get(),
- writer_.get(), Perspective::IS_CLIENT, version());
+ alarm_factory_.get(), writer_.get(),
+ Perspective::IS_CLIENT, version());
EXPECT_FALSE(client.sent_packet_manager().using_pacing());
EXPECT_FALSE(server.sent_packet_manager().using_pacing());
}
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc
index 55f29a0..4ce3d0f 100644
--- a/net/quic/quic_crypto_client_stream.cc
+++ b/net/quic/quic_crypto_client_stream.cc
@@ -4,6 +4,7 @@
#include "net/quic/quic_crypto_client_stream.h"
+#include <memory>
#include <vector>
#include "base/metrics/histogram_macros.h"
diff --git a/net/quic/quic_crypto_client_stream.h b/net/quic/quic_crypto_client_stream.h
index f9eabbb..75913d1 100644
--- a/net/quic/quic_crypto_client_stream.h
+++ b/net/quic/quic_crypto_client_stream.h
@@ -5,8 +5,8 @@
#ifndef NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_
#define NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_
-#include <stdint.h>
-
+#include <cstdint>
+#include <memory>
#include <string>
#include "base/macros.h"
diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc
index 54ecb914..a42585a 100644
--- a/net/quic/quic_crypto_client_stream_test.cc
+++ b/net/quic/quic_crypto_client_stream_test.cc
@@ -40,7 +40,8 @@
}
void CreateConnection() {
- connection_ = new PacketSavingConnection(&helper_, Perspective::IS_CLIENT);
+ connection_ = new PacketSavingConnection(&helper_, &alarm_factory_,
+ Perspective::IS_CLIENT);
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -50,8 +51,8 @@
void CompleteCryptoHandshake() {
stream()->CryptoConnect();
- CryptoTestUtils::HandshakeWithFakeServer(&helper_, connection_, stream(),
- server_options_);
+ CryptoTestUtils::HandshakeWithFakeServer(
+ &helper_, &alarm_factory_, connection_, stream(), server_options_);
}
void ConstructHandshakeMessage() {
@@ -62,6 +63,7 @@
QuicCryptoClientStream* stream() { return session_->GetCryptoStream(); }
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
PacketSavingConnection* connection_;
std::unique_ptr<TestQuicSpdyClientSession> session_;
QuicServerId server_id_;
@@ -267,11 +269,12 @@
QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
server_id_(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED) {
TestQuicSpdyClientSession* client_session = nullptr;
- CreateClientSessionForTest(
- server_id_,
- /* supports_stateless_rejects= */ true,
- QuicTime::Delta::FromSeconds(100000), QuicSupportedVersions(), &helper_,
- &client_crypto_config_, &client_connection_, &client_session);
+ CreateClientSessionForTest(server_id_,
+ /* supports_stateless_rejects= */ true,
+ QuicTime::Delta::FromSeconds(100000),
+ QuicSupportedVersions(), &helper_,
+ &alarm_factory_, &client_crypto_config_,
+ &client_connection_, &client_session);
CHECK(client_session);
client_session_.reset(client_session);
}
@@ -290,10 +293,11 @@
// Initializes the server_stream_ for stateless rejects.
void InitializeFakeStatelessRejectServer() {
TestQuicSpdyServerSession* server_session = nullptr;
- CreateServerSessionForTest(
- server_id_, QuicTime::Delta::FromSeconds(100000),
- QuicSupportedVersions(), &helper_, &server_crypto_config_,
- &server_compressed_certs_cache_, &server_connection_, &server_session);
+ CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000),
+ QuicSupportedVersions(), &helper_,
+ &alarm_factory_, &server_crypto_config_,
+ &server_compressed_certs_cache_,
+ &server_connection_, &server_session);
CHECK(server_session);
server_session_.reset(server_session);
CryptoTestUtils::FakeServerOptions options;
@@ -304,6 +308,7 @@
}
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
// Client crypto stream state
PacketSavingConnection* client_connection_;
diff --git a/net/quic/quic_crypto_server_stream.cc b/net/quic/quic_crypto_server_stream.cc
index cee73caa..967ada03 100644
--- a/net/quic/quic_crypto_server_stream.cc
+++ b/net/quic/quic_crypto_server_stream.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_crypto_server_stream.h"
+#include <memory>
+
#include "base/base64.h"
#include "crypto/secure_hash.h"
#include "net/quic/crypto/crypto_protocol.h"
@@ -16,6 +18,7 @@
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_session.h"
+using base::StringPiece;
using std::string;
namespace net {
@@ -236,7 +239,7 @@
DVLOG(1) << "Server: Sending server config update: "
<< server_config_update_message.DebugString();
const QuicData& data = server_config_update_message.GetSerialized();
- WriteOrBufferData(string(data.data(), data.length()), false, nullptr);
+ WriteOrBufferData(StringPiece(data.data(), data.length()), false, nullptr);
++num_server_config_update_messages_sent_;
}
diff --git a/net/quic/quic_crypto_server_stream.h b/net/quic/quic_crypto_server_stream.h
index 65e8f04c3..f85a9f4 100644
--- a/net/quic/quic_crypto_server_stream.h
+++ b/net/quic/quic_crypto_server_stream.h
@@ -5,8 +5,8 @@
#ifndef NET_QUIC_QUIC_CRYPTO_SERVER_STREAM_H_
#define NET_QUIC_QUIC_CRYPTO_SERVER_STREAM_H_
-#include <stdint.h>
-
+#include <cstdint>
+#include <memory>
#include <string>
#include "base/macros.h"
diff --git a/net/quic/quic_crypto_server_stream_test.cc b/net/quic/quic_crypto_server_stream_test.cc
index b82e0c1..e5cdfe1 100644
--- a/net/quic/quic_crypto_server_stream_test.cc
+++ b/net/quic/quic_crypto_server_stream_test.cc
@@ -102,6 +102,7 @@
server_session_.reset();
client_session_.reset();
STLDeleteElements(&helpers_);
+ STLDeleteElements(&alarm_factories_);
}
// Initializes the crypto server stream state for testing. May be
@@ -109,9 +110,10 @@
void InitializeServer() {
TestQuicSpdyServerSession* server_session = nullptr;
helpers_.push_back(new MockConnectionHelper);
+ alarm_factories_.push_back(new MockAlarmFactory);
CreateServerSessionForTest(
server_id_, QuicTime::Delta::FromSeconds(100000), supported_versions_,
- helpers_.back(), &server_crypto_config_,
+ helpers_.back(), alarm_factories_.back(), &server_crypto_config_,
&server_compressed_certs_cache_, &server_connection_, &server_session);
CHECK(server_session);
server_session_.reset(server_session);
@@ -135,12 +137,13 @@
void InitializeFakeClient(bool supports_stateless_rejects) {
TestQuicSpdyClientSession* client_session = nullptr;
helpers_.push_back(new MockConnectionHelper);
- CreateClientSessionForTest(server_id_, supports_stateless_rejects,
- QuicTime::Delta::FromSeconds(100000),
- supported_versions_,
+ alarm_factories_.push_back(new MockAlarmFactory);
+ CreateClientSessionForTest(
+ server_id_, supports_stateless_rejects,
+ QuicTime::Delta::FromSeconds(100000), supported_versions_,
- helpers_.back(), &client_crypto_config_,
- &client_connection_, &client_session);
+ helpers_.back(), alarm_factories_.back(), &client_crypto_config_,
+ &client_connection_, &client_session);
CHECK(client_session);
client_session_.reset(client_session);
}
@@ -161,8 +164,8 @@
CHECK(server_connection_);
CHECK(server_session_ != nullptr);
return CryptoTestUtils::HandshakeWithFakeClient(
- helpers_.back(), server_connection_, server_stream(), server_id_,
- client_options_);
+ helpers_.back(), alarm_factories_.back(), server_connection_,
+ server_stream(), server_id_, client_options_);
}
// Performs a single round of handshake message-exchange between the
@@ -178,10 +181,12 @@
}
protected:
- // Every connection gets its own MockConnectionHelper, tracked separately
- // from the server and client state so their lifetimes persist through the
- // whole test.
+ // Every connection gets its own MockConnectionHelper and MockAlarmFactory,
+ // tracked separately from
+ // the server and client state so their lifetimes persist through the whole
+ // test.
std::vector<MockConnectionHelper*> helpers_;
+ std::vector<MockAlarmFactory*> alarm_factories_;
// Server state
PacketSavingConnection* server_connection_;
diff --git a/net/quic/quic_crypto_stream.cc b/net/quic/quic_crypto_stream.cc
index ee44b6c..f904871 100644
--- a/net/quic/quic_crypto_stream.cc
+++ b/net/quic/quic_crypto_stream.cc
@@ -72,7 +72,7 @@
session()->OnCryptoHandshakeMessageSent(message);
const QuicData& data = message.GetSerialized();
// TODO(wtc): check the return value.
- WriteOrBufferData(string(data.data(), data.length()), false, listener);
+ WriteOrBufferData(StringPiece(data.data(), data.length()), false, listener);
}
bool QuicCryptoStream::ExportKeyingMaterial(StringPiece label,
diff --git a/net/quic/quic_crypto_stream_test.cc b/net/quic/quic_crypto_stream_test.cc
index e7cc92a..326ece8c 100644
--- a/net/quic/quic_crypto_stream_test.cc
+++ b/net/quic/quic_crypto_stream_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/quic_crypto_stream.h"
+#include <cstdint>
#include <memory>
#include <string>
#include <vector>
@@ -44,7 +45,9 @@
class QuicCryptoStreamTest : public ::testing::Test {
public:
QuicCryptoStreamTest()
- : connection_(new MockConnection(&helper_, Perspective::IS_CLIENT)),
+ : connection_(new MockConnection(&helper_,
+ &alarm_factory_,
+ Perspective::IS_CLIENT)),
session_(connection_),
stream_(&session_) {
message_.set_tag(kSHLO);
@@ -60,6 +63,7 @@
protected:
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockConnection* connection_;
MockQuicSpdySession session_;
MockQuicCryptoStream stream_;
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 8778704..a4a39dcf 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -107,17 +107,13 @@
// consecutive RTOs are sent.
bool FLAGS_quic_enable_rto_timeout = true;
-// Use a byte conservation approach instead of packet conservation in the
-// Slow Start Large Reduction experiment.
-bool FLAGS_quic_sslr_byte_conservation = true;
-
// Try to use the socket timestamp to determine the time a packet was
// received instead of Now().
bool FLAGS_quic_use_socket_timestamp = true;
-// If true, handling of errors from invalid stream frames is done in
-// one place in QuicStreamSequencer::OnStreamFrame.
-bool FLAGS_quic_consolidate_onstreamframe_errors = true;
-
// Resend 0RTT requests in response to an REJ that re-establishes encryption.
bool FLAGS_quic_reply_to_rej = true;
+
+// If true, QuicFramer will ignore invalid error codes when processing GoAway,
+// ConnectionClose, and RstStream frames.
+bool FLAGS_quic_ignore_invalid_error_code = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index bfc4c18..8af48b7 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -37,9 +37,8 @@
NET_EXPORT_PRIVATE extern bool FLAGS_spdy_on_stream_end;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_cached_compressed_certs;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_rto_timeout;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_sslr_byte_conservation;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_socket_timestamp;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_consolidate_onstreamframe_errors;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_reply_to_rej;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_ignore_invalid_error_code;
#endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_flow_controller_test.cc b/net/quic/quic_flow_controller_test.cc
index b189a408..e4a53e6 100644
--- a/net/quic/quic_flow_controller_test.cc
+++ b/net/quic/quic_flow_controller_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_flow_controller.h"
+#include <memory>
+
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
#include "net/quic/quic_flags.h"
@@ -29,7 +31,7 @@
: stream_id_(1234),
send_window_(kInitialSessionFlowControlWindowForTest),
receive_window_(kInitialSessionFlowControlWindowForTest),
- connection_(&helper_, Perspective::IS_CLIENT) {}
+ connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT) {}
void Initialize() {
flow_controller_.reset(
@@ -43,6 +45,7 @@
QuicByteCount receive_window_;
std::unique_ptr<QuicFlowController> flow_controller_;
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockConnection connection_;
};
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index da91cfc..1dd00645 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -4,7 +4,8 @@
#include "net/quic/quic_framer.h"
-#include <stdint.h>
+#include <cstdint>
+#include <memory>
#include "base/compiler_specific.h"
#include "base/logging.h"
@@ -1494,8 +1495,13 @@
}
if (error_code >= QUIC_STREAM_LAST_ERROR) {
- set_detailed_error("Invalid rst stream error code.");
- return false;
+ if (FLAGS_quic_ignore_invalid_error_code) {
+ // Ignore invalid stream error code if any.
+ error_code = QUIC_STREAM_LAST_ERROR;
+ } else {
+ set_detailed_error("Invalid rst stream error code.");
+ return false;
+ }
}
frame->error_code = static_cast<QuicRstStreamErrorCode>(error_code);
@@ -1511,8 +1517,13 @@
}
if (error_code >= QUIC_LAST_ERROR) {
- set_detailed_error("Invalid error code.");
- return false;
+ if (FLAGS_quic_ignore_invalid_error_code) {
+ // Ignore invalid QUIC error code if any.
+ error_code = QUIC_LAST_ERROR;
+ } else {
+ set_detailed_error("Invalid error code.");
+ return false;
+ }
}
frame->error_code = static_cast<QuicErrorCode>(error_code);
@@ -1534,12 +1545,17 @@
set_detailed_error("Unable to read go away error code.");
return false;
}
- frame->error_code = static_cast<QuicErrorCode>(error_code);
if (error_code >= QUIC_LAST_ERROR) {
- set_detailed_error("Invalid error code.");
- return false;
+ if (FLAGS_quic_ignore_invalid_error_code) {
+ // Ignore invalid QUIC error code if any.
+ error_code = QUIC_LAST_ERROR;
+ } else {
+ set_detailed_error("Invalid error code.");
+ return false;
+ }
}
+ frame->error_code = static_cast<QuicErrorCode>(error_code);
uint32_t stream_id;
if (!reader->ReadUInt32(&stream_id)) {
diff --git a/net/quic/quic_header_list.cc b/net/quic/quic_header_list.cc
index 2edb343..4d2f3f6 100644
--- a/net/quic/quic_header_list.cc
+++ b/net/quic/quic_header_list.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_header_list.h"
+using std::string;
+
namespace net {
QuicHeaderList::QuicHeaderList() : uncompressed_header_bytes_(0) {}
@@ -37,4 +39,13 @@
uncompressed_header_bytes_ = 0;
}
+string QuicHeaderList::DebugString() const {
+ string s = "{ ";
+ for (const auto& p : *this) {
+ s.append(p.first + "=" + p.second + ", ");
+ }
+ s.append("}");
+ return s;
+}
+
} // namespace net
diff --git a/net/quic/quic_header_list.h b/net/quic/quic_header_list.h
index 3d07061..b218f35 100644
--- a/net/quic/quic_header_list.h
+++ b/net/quic/quic_header_list.h
@@ -20,6 +20,7 @@
class NET_EXPORT_PRIVATE QuicHeaderList : public SpdyHeadersHandlerInterface {
public:
typedef std::deque<std::pair<std::string, std::string>> ListType;
+ typedef ListType::const_iterator const_iterator;
QuicHeaderList();
QuicHeaderList(QuicHeaderList&& other);
@@ -35,14 +36,16 @@
void Clear();
- ListType::const_iterator begin() const { return header_list_.begin(); }
- ListType::const_iterator end() const { return header_list_.end(); }
+ const_iterator begin() const { return header_list_.begin(); }
+ const_iterator end() const { return header_list_.end(); }
bool empty() const { return header_list_.empty(); }
size_t uncompressed_header_bytes() const {
return uncompressed_header_bytes_;
}
+ std::string DebugString() const;
+
private:
std::deque<std::pair<std::string, std::string>> header_list_;
size_t uncompressed_header_bytes_;
diff --git a/net/quic/quic_header_list_test.cc b/net/quic/quic_header_list_test.cc
index bd4e560..94f82497 100644
--- a/net/quic/quic_header_list_test.cc
+++ b/net/quic/quic_header_list_test.cc
@@ -16,11 +16,7 @@
headers.OnHeader("april", "fools");
headers.OnHeader("beep", "");
- std::string accumulator;
- for (const auto& p : headers) {
- accumulator.append("(" + p.first + ", " + p.second + ") ");
- }
- EXPECT_EQ("(foo, bar) (april, fools) (beep, ) ", accumulator);
+ EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers.DebugString());
}
// This test verifies that QuicHeaderList is copyable and assignable.
@@ -33,17 +29,8 @@
QuicHeaderList headers2(headers);
QuicHeaderList headers3 = headers;
- std::string accumulator;
- for (const auto& p : headers2) {
- accumulator.append("(" + p.first + ", " + p.second + ") ");
- }
- EXPECT_EQ("(foo, bar) (april, fools) (beep, ) ", accumulator);
-
- accumulator.clear();
- for (const auto& p : headers3) {
- accumulator.append("(" + p.first + ", " + p.second + ") ");
- }
- EXPECT_EQ("(foo, bar) (april, fools) (beep, ) ", accumulator);
+ EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers2.DebugString());
+ EXPECT_EQ("{ foo=bar, april=fools, beep=, }", headers3.DebugString());
}
} // namespace net
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
index e02f530..1954d91 100644
--- a/net/quic/quic_headers_stream_test.cc
+++ b/net/quic/quic_headers_stream_test.cc
@@ -133,6 +133,7 @@
public:
QuicHeadersStreamTest()
: connection_(new StrictMock<MockConnection>(&helper_,
+ &alarm_factory_,
perspective(),
GetVersion())),
session_(connection_),
@@ -249,6 +250,7 @@
static const bool kHasPriority = true;
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
StrictMock<MockConnection>* connection_;
StrictMock<MockQuicSpdySession> session_;
QuicHeadersStream* headers_stream_;
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 4774365..395f8cc 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -29,6 +29,7 @@
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/crypto/quic_server_info.h"
+#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_chromium_client_stream.h"
#include "net/quic/quic_chromium_connection_helper.h"
@@ -74,10 +75,12 @@
QuicConnectionId connection_id,
IPEndPoint address,
QuicChromiumConnectionHelper* helper,
+ QuicChromiumAlarmFactory* alarm_factory,
QuicPacketWriter* writer)
: QuicConnection(connection_id,
address,
helper,
+ alarm_factory,
writer,
true /* owns_writer */,
Perspective::IS_CLIENT,
@@ -218,11 +221,14 @@
EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
.WillRepeatedly(Return(QuicBandwidth::Zero()));
EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
- helper_.reset(new QuicChromiumConnectionHelper(runner_.get(), &clock_,
- &random_generator_));
- connection_ = new TestQuicConnection(
- SupportedVersions(GetParam()), connection_id_, peer_addr_,
- helper_.get(), new QuicChromiumPacketWriter(socket.get()));
+ helper_.reset(
+ new QuicChromiumConnectionHelper(&clock_, &random_generator_));
+ alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
+
+ connection_ =
+ new TestQuicConnection(SupportedVersions(GetParam()), connection_id_,
+ peer_addr_, helper_.get(), alarm_factory_.get(),
+ new QuicChromiumPacketWriter(socket.get()));
connection_->set_visitor(&visitor_);
connection_->SetSendAlgorithm(send_algorithm_);
@@ -429,6 +435,7 @@
MockClock clock_;
TestQuicConnection* connection_;
std::unique_ptr<QuicChromiumConnectionHelper> helper_;
+ std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
testing::StrictMock<MockConnectionVisitor> visitor_;
std::unique_ptr<QuicHttpStream> stream_;
TransportSecurityState transport_security_state_;
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index effc787..6cd0628 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -2030,6 +2030,7 @@
TEST_P(QuicNetworkTransactionTest,
LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_ignore_invalid_error_code, false);
MockQuicData mock_quic_data;
mock_quic_data.AddWrite(
ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
index 5147b09..bb4d8e5 100644
--- a/net/quic/quic_packet_creator.cc
+++ b/net/quic/quic_packet_creator.cc
@@ -186,12 +186,12 @@
QuicFramer::GetMinStreamFrameSize(1u, offset, true);
}
-size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
- QuicIOVector iov,
- size_t iov_offset,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame) {
+void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame) {
DCHECK_GT(max_packet_length_,
StreamFramePacketOverhead(connection_id_length_, kIncludeVersion,
kIncludePathId,
@@ -208,7 +208,7 @@
QUIC_BUG_IF(!fin) << "Creating a stream frame with no data or fin.";
// Create a new packet for the fin, if necessary.
*frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece()));
- return 0;
+ return;
}
const size_t data_size = iov.total_length - iov_offset;
@@ -222,7 +222,6 @@
CopyToBuffer(iov, iov_offset, bytes_consumed, buffer.get());
*frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, bytes_consumed,
std::move(buffer)));
- return bytes_consumed;
}
// static
diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h
index b279d51..bf9035b5 100644
--- a/net/quic/quic_packet_creator.h
+++ b/net/quic/quic_packet_creator.h
@@ -214,16 +214,15 @@
// Converts a raw payload to a frame which fits into the current open
// packet. The payload begins at |iov_offset| into the |iov|.
- // Returns the number of bytes consumed from data.
// If data is empty and fin is true, the expected behavior is to consume the
// fin but return 0. If any data is consumed, it will be copied into a
// new buffer that |frame| will point to and own.
- size_t CreateStreamFrame(QuicStreamId id,
- QuicIOVector iov,
- size_t iov_offset,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame);
+ void CreateStreamFrame(QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame);
// Copies |length| bytes from iov starting at offset |iov_offset| into buffer.
// |iov| must be at least iov_offset+length total length and buffer must be
diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc
index a3e3c2a1..9731eba 100644
--- a/net/quic/quic_packet_creator_test.cc
+++ b/net/quic/quic_packet_creator_test.cc
@@ -4,7 +4,9 @@
#include "net/quic/quic_packet_creator.h"
-#include <stdint.h>
+#include <cstdint>
+#include <memory>
+#include <string>
#include "base/macros.h"
#include "base/stl_util.h"
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc
index d913672..e1d7b1e 100644
--- a/net/quic/quic_packet_generator_test.cc
+++ b/net/quic/quic_packet_generator_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_packet_generator.h"
+#include <cstdint>
+#include <memory>
#include <string>
#include "base/macros.h"
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index 7465e56..c36bab5b4 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/quic_sent_packet_manager.h"
+#include <memory>
+
#include "base/stl_util.h"
#include "net/quic/quic_flags.h"
#include "net/quic/test_tools/quic_config_peer.h"
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index 2c18073..770b15dc 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -197,6 +197,7 @@
explicit QuicSessionTestBase(Perspective perspective)
: connection_(
new StrictMock<MockConnection>(&helper_,
+ &alarm_factory_,
perspective,
SupportedVersions(GetParam()))),
session_(connection_) {
@@ -257,6 +258,7 @@
QuicVersion version() const { return connection_->version(); }
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
StrictMock<MockConnection>* connection_;
TestSession session_;
set<QuicStreamId> closed_streams_;
diff --git a/net/quic/quic_spdy_session.h b/net/quic/quic_spdy_session.h
index 2780d80b..6b671f7 100644
--- a/net/quic/quic_spdy_session.h
+++ b/net/quic/quic_spdy_session.h
@@ -7,6 +7,8 @@
#include <stddef.h>
+#include <memory>
+
#include "base/macros.h"
#include "net/quic/quic_header_list.h"
#include "net/quic/quic_headers_stream.h"
diff --git a/net/quic/quic_spdy_stream.cc b/net/quic/quic_spdy_stream.cc
index c946e0c..bf5b734 100644
--- a/net/quic/quic_spdy_stream.cc
+++ b/net/quic/quic_spdy_stream.cc
@@ -95,6 +95,8 @@
// The header block must contain the final offset for this stream, as the
// trailers may be processed out of order at the peer.
+ DVLOG(1) << "Inserting trailer: (" << kFinalOffsetHeaderKey << ", "
+ << stream_bytes_written() + queued_data_bytes() << ")";
trailer_block.insert(std::make_pair(
kFinalOffsetHeaderKey,
base::IntToString(stream_bytes_written() + queued_data_bytes())));
@@ -155,6 +157,13 @@
decompressed_trailers_.erase(0, bytes_consumed);
}
+void QuicSpdyStream::ConsumeHeaderList() {
+ header_list_.Clear();
+ if (FinishedReadingHeaders()) {
+ sequencer()->SetUnblocked();
+ }
+}
+
void QuicSpdyStream::SetPriority(SpdyPriority priority) {
DCHECK_EQ(0u, stream_bytes_written());
spdy_session_->UpdateStreamPriority(id(), priority);
diff --git a/net/quic/quic_spdy_stream.h b/net/quic/quic_spdy_stream.h
index cedc25d2..ca52cd3 100644
--- a/net/quic/quic_spdy_stream.h
+++ b/net/quic/quic_spdy_stream.h
@@ -52,6 +52,10 @@
// Called when the stream is closed.
virtual void OnClose(QuicSpdyStream* stream) = 0;
+ // Allows subclasses to override and do work.
+ virtual void OnPromiseHeadersComplete(QuicStreamId promised_id,
+ size_t frame_len) {}
+
protected:
virtual ~Visitor() {}
@@ -136,7 +140,7 @@
void MarkTrailersConsumed(size_t bytes_consumed);
// Clears |header_list_|.
- void ConsumeHeaderList() { header_list_.Clear(); }
+ void ConsumeHeaderList();
// This block of functions wraps the sequencer's functions of the same
// name. These methods return uncompressed data until that has
diff --git a/net/quic/quic_spdy_stream_test.cc b/net/quic/quic_spdy_stream_test.cc
index d01a2cd2..8edf223 100644
--- a/net/quic/quic_spdy_stream_test.cc
+++ b/net/quic/quic_spdy_stream_test.cc
@@ -4,8 +4,9 @@
#include "net/quic/quic_spdy_stream.h"
-#include "base/strings/string_number_conversions.h"
+#include <memory>
+#include "base/strings/string_number_conversions.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_utils.h"
#include "net/quic/quic_write_blocked_list.h"
@@ -97,7 +98,8 @@
void Initialize(bool stream_should_process_data) {
connection_ = new testing::StrictMock<MockConnection>(
- &helper_, Perspective::IS_SERVER, SupportedVersions(GetParam()));
+ &helper_, &alarm_factory_, Perspective::IS_SERVER,
+ SupportedVersions(GetParam()));
session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_));
stream_ = new TestStream(kClientDataStreamId1, session_.get(),
stream_should_process_data);
@@ -109,6 +111,7 @@
protected:
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockConnection* connection_;
std::unique_ptr<MockQuicSpdySession> session_;
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 46ec8f8..f572a728 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -40,6 +40,7 @@
#include "net/quic/crypto/quic_random.h"
#include "net/quic/crypto/quic_server_info.h"
#include "net/quic/port_suggester.h"
+#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_reader.h"
@@ -1546,17 +1547,21 @@
}
if (!helper_.get()) {
- helper_.reset(new QuicChromiumConnectionHelper(
- base::ThreadTaskRunnerHandle::Get().get(), clock_.get(),
- random_generator_));
+ helper_.reset(
+ new QuicChromiumConnectionHelper(clock_.get(), random_generator_));
+ }
+
+ if (!alarm_factory_.get()) {
+ alarm_factory_.reset(new QuicChromiumAlarmFactory(
+ base::ThreadTaskRunnerHandle::Get().get(), clock_.get()));
}
QuicConnectionId connection_id = random_generator_->RandUint64();
InitializeCachedStateInCryptoConfig(server_id, server_info, &connection_id);
QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(socket.get());
QuicConnection* connection = new QuicConnection(
- connection_id, addr, helper_.get(), writer, true /* owns_writer */,
- Perspective::IS_CLIENT, supported_versions_);
+ connection_id, addr, helper_.get(), alarm_factory_.get(), writer,
+ true /* owns_writer */, Perspective::IS_CLIENT, supported_versions_);
writer->SetConnection(connection);
connection->SetMaxPacketLength(max_packet_length_);
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index 75a5583..a03edf3 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -49,6 +49,7 @@
class HostResolver;
class HttpServerProperties;
class QuicClock;
+class QuicChromiumAlarmFactory;
class QuicChromiumClientSession;
class QuicChromiumConnectionHelper;
class QuicCryptoClientStreamFactory;
@@ -303,6 +304,8 @@
QuicChromiumConnectionHelper* helper() { return helper_.get(); }
+ QuicChromiumAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
+
bool enable_port_selection() const { return enable_port_selection_; }
bool has_quic_server_info_factory() {
@@ -428,6 +431,9 @@
// The helper used for all connections.
std::unique_ptr<QuicChromiumConnectionHelper> helper_;
+ // The alarm factory used for all connections.
+ std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
+
// Contains owning pointers to all sessions that currently exist.
SessionIdMap all_sessions_;
// Contains non-owning pointers to currently active session
diff --git a/net/quic/quic_stream_sequencer.cc b/net/quic/quic_stream_sequencer.cc
index b30264fa..991083b 100644
--- a/net/quic/quic_stream_sequencer.cc
+++ b/net/quic/quic_stream_sequencer.cc
@@ -43,15 +43,6 @@
++num_frames_received_;
const QuicStreamOffset byte_offset = frame.offset;
const size_t data_len = frame.frame_length;
- bool consolidate_errors = FLAGS_quic_consolidate_onstreamframe_errors;
- if (!consolidate_errors && data_len == 0 && !frame.fin) {
- // Stream frames must have data or a fin flag.
- LOG(WARNING) << "QUIC_INVALID_STREAM_FRAM: Empty stream frame "
- "without FIN set.";
- stream_->CloseConnectionWithDetails(QUIC_EMPTY_STREAM_FRAME_NO_FIN,
- "Empty stream frame without FIN set.");
- return;
- }
if (frame.fin) {
CloseStreamAtOffset(frame.offset + data_len);
@@ -64,24 +55,14 @@
QuicErrorCode result = buffered_frames_.OnStreamData(
byte_offset, StringPiece(frame.frame_buffer, frame.frame_length),
clock_->ApproximateNow(), &bytes_written, &error_details);
- if (!consolidate_errors) {
- if (result == QUIC_OVERLAPPING_STREAM_DATA) {
- LOG(WARNING) << "QUIC_INVALID_STREAM_FRAME: Stream frame "
- "overlaps with buffered data.";
- stream_->CloseConnectionWithDetails(
- QUIC_EMPTY_STREAM_FRAME_NO_FIN,
- "Stream frame overlaps with buffered data.");
- return;
- }
- } else {
- if (result != QUIC_NO_ERROR) {
- LOG(WARNING) << QuicUtils::ErrorToString(result) << ": " << error_details;
- stream_->CloseConnectionWithDetails(result, error_details);
- return;
- }
+ if (result != QUIC_NO_ERROR) {
+ DLOG(WARNING) << QuicUtils::ErrorToString(result);
+ DLOG(WARNING) << error_details;
+ stream_->CloseConnectionWithDetails(result, error_details);
+ return;
}
- if ((consolidate_errors || result == QUIC_NO_ERROR) && bytes_written == 0) {
+ if (bytes_written == 0) {
++num_duplicate_frames_received_;
// Silently ignore duplicates.
return;
diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc
index ed55119..667c044 100644
--- a/net/quic/quic_stream_sequencer_test.cc
+++ b/net/quic/quic_stream_sequencer_test.cc
@@ -4,6 +4,9 @@
#include "net/quic/quic_stream_sequencer.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
#include <utility>
#include <vector>
@@ -69,7 +72,9 @@
protected:
QuicStreamSequencerTest()
- : connection_(new MockConnection(&helper_, Perspective::IS_CLIENT)),
+ : connection_(new MockConnection(&helper_,
+ &alarm_factory_,
+ Perspective::IS_CLIENT)),
session_(connection_),
stream_(&session_, 1),
sequencer_(new QuicStreamSequencer(&stream_, &clock_)) {}
@@ -146,6 +151,7 @@
}
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockConnection* connection_;
MockClock clock_;
MockQuicSpdySession session_;
@@ -563,11 +569,8 @@
sequencer_->OnStreamFrame(frame1);
QuicStreamFrame frame2(kClientDataStreamId1, false, 2, StringPiece("hello"));
- EXPECT_CALL(stream_, CloseConnectionWithDetails(
- FLAGS_quic_consolidate_onstreamframe_errors
- ? QUIC_OVERLAPPING_STREAM_DATA
- : QUIC_EMPTY_STREAM_FRAME_NO_FIN,
- _))
+ EXPECT_CALL(stream_,
+ CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _))
.Times(1);
sequencer_->OnStreamFrame(frame2);
}
diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
index a4bd67d8..bfa8d2d 100644
--- a/net/quic/reliable_quic_stream_test.cc
+++ b/net/quic/reliable_quic_stream_test.cc
@@ -4,6 +4,8 @@
#include "net/quic/reliable_quic_stream.h"
+#include <memory>
+
#include "net/quic/quic_connection.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_utils.h"
@@ -104,7 +106,7 @@
void Initialize(bool stream_should_process_data) {
connection_ = new StrictMock<MockConnection>(
- &helper_, Perspective::IS_SERVER, supported_versions_);
+ &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions_);
session_.reset(new StrictMock<MockQuicSpdySession>(connection_));
// New streams rely on having the peer's flow control receive window
@@ -148,6 +150,7 @@
protected:
MockConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
MockConnection* connection_;
std::unique_ptr<MockQuicSpdySession> session_;
TestStream* stream_;
diff --git a/net/quic/spdy_utils.cc b/net/quic/spdy_utils.cc
index 7343ccea..bdb4a75 100644
--- a/net/quic/spdy_utils.cc
+++ b/net/quic/spdy_utils.cc
@@ -16,6 +16,7 @@
#include "net/spdy/spdy_protocol.h"
#include "url/gurl.h"
+using base::StringPiece;
using std::string;
using std::vector;
@@ -108,11 +109,76 @@
return true;
}
+bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
+ int64_t* content_length,
+ SpdyHeaderBlock* headers) {
+ for (const auto& p : header_list) {
+ const string& name = p.first;
+ if (name.empty()) {
+ DVLOG(1) << "Header name must not be empty.";
+ return false;
+ }
+
+ if (std::any_of(name.begin(), name.end(), base::IsAsciiUpper<char>)) {
+ DLOG(ERROR) << "Malformed header: Header name " << name
+ << " contains upper-case characters.";
+ return false;
+ }
+
+ if (headers->find(name) != headers->end()) {
+ DLOG(ERROR) << "Duplicate header '" << name << "' found.";
+ return false;
+ }
+
+ (*headers)[name] = p.second;
+ }
+
+ if (ContainsKey(*headers, "content-length")) {
+ // Check whether multiple values are consistent.
+ StringPiece content_length_header = (*headers)["content-length"];
+ vector<string> values =
+ base::SplitString(content_length_header, base::StringPiece("\0", 1),
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const string& value : values) {
+ int new_value;
+ if (!base::StringToInt(value, &new_value) || new_value < 0) {
+ DLOG(ERROR) << "Content length was either unparseable or negative.";
+ return false;
+ }
+ if (*content_length < 0) {
+ *content_length = new_value;
+ continue;
+ }
+ if (new_value != *content_length) {
+ DLOG(ERROR) << "Parsed content length " << new_value << " is "
+ << "inconsistent with previously detected content length "
+ << *content_length;
+ return false;
+ }
+ }
+ }
+
+ DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
+ return true;
+}
+
bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
size_t* final_byte_offset,
SpdyHeaderBlock* trailers) {
+ bool found_final_byte_offset = false;
for (const auto& p : header_list) {
const string& name = p.first;
+
+ // Pull out the final offset pseudo header which indicates the number of
+ // response body bytes expected.
+ int offset;
+ if (!found_final_byte_offset && name == kFinalOffsetHeaderKey &&
+ base::StringToInt(p.second, &offset)) {
+ *final_byte_offset = offset;
+ found_final_byte_offset = true;
+ continue;
+ }
+
if (name.empty() || name[0] == ':') {
DVLOG(1) << "Trailers must not be empty, and must not contain pseudo-"
<< "headers. Found: '" << name << "'";
@@ -133,20 +199,10 @@
(*trailers)[name] = p.second;
}
- if (trailers->empty()) {
- DVLOG(1) << "Request Trailers are invalid.";
- return false; // Trailers were invalid.
- }
-
- // Pull out the final offset pseudo header which indicates the number of
- // response body bytes expected.
- auto it = trailers->find(kFinalOffsetHeaderKey);
- if (it == trailers->end() || !StringToSizeT(it->second, final_byte_offset)) {
+ if (!found_final_byte_offset) {
DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey << "' not present";
return false;
}
- // The final offset header is no longer needed.
- trailers->erase(it->first);
// TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
diff --git a/net/quic/spdy_utils.h b/net/quic/spdy_utils.h
index 708e0c3..6a9b15e 100644
--- a/net/quic/spdy_utils.h
+++ b/net/quic/spdy_utils.h
@@ -45,7 +45,13 @@
SpdyHeaderBlock* trailers);
// Copies a list of headers to a SpdyHeaderBlock. Performs similar validation
- // to SpdyFramer::ParseHeaderBlockInBuffer.
+ // to SpdyFramer::ParseHeaderBlockInBuffer and ParseHeaders, above.
+ static bool CopyAndValidateHeaders(const QuicHeaderList& header_list,
+ int64_t* content_length,
+ SpdyHeaderBlock* headers);
+
+ // Copies a list of headers to a SpdyHeaderBlock. Performs similar validation
+ // to SpdyFramer::ParseHeaderBlockInBuffer and ParseTrailers, above.
static bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
size_t* final_byte_offset,
SpdyHeaderBlock* trailers);
diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc
index fc13ff35..38d7b2c4 100644
--- a/net/quic/test_tools/crypto_test_utils.cc
+++ b/net/quic/test_tools/crypto_test_utils.cc
@@ -4,6 +4,8 @@
#include "net/quic/test_tools/crypto_test_utils.h"
+#include <memory>
+
#include "base/strings/string_util.h"
#include "net/quic/crypto/channel_id.h"
#include "net/quic/crypto/common_cert_set.h"
@@ -128,11 +130,13 @@
// static
int CryptoTestUtils::HandshakeWithFakeServer(
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
PacketSavingConnection* client_conn,
QuicCryptoClientStream* client,
const FakeServerOptions& options) {
- PacketSavingConnection* server_conn = new PacketSavingConnection(
- helper, Perspective::IS_SERVER, client_conn->supported_versions());
+ PacketSavingConnection* server_conn =
+ new PacketSavingConnection(helper, alarm_factory, Perspective::IS_SERVER,
+ client_conn->supported_versions());
QuicConfig config = DefaultQuicConfig();
QuicCryptoServerConfig crypto_config(QuicCryptoServerConfig::TESTING,
@@ -160,12 +164,13 @@
// static
int CryptoTestUtils::HandshakeWithFakeClient(
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
PacketSavingConnection* server_conn,
QuicCryptoServerStream* server,
const QuicServerId& server_id,
const FakeClientOptions& options) {
PacketSavingConnection* client_conn =
- new PacketSavingConnection(helper, Perspective::IS_CLIENT);
+ new PacketSavingConnection(helper, alarm_factory, Perspective::IS_CLIENT);
// Advance the time, because timers do not like uninitialized times.
client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
diff --git a/net/quic/test_tools/crypto_test_utils.h b/net/quic/test_tools/crypto_test_utils.h
index 6d2ad00..c8beb60 100644
--- a/net/quic/test_tools/crypto_test_utils.h
+++ b/net/quic/test_tools/crypto_test_utils.h
@@ -86,12 +86,16 @@
// returns: the number of client hellos that the client sent.
static int HandshakeWithFakeServer(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
PacketSavingConnection* client_conn,
QuicCryptoClientStream* client,
const FakeServerOptions& options);
// returns: the number of client hellos that the client sent.
static int HandshakeWithFakeClient(MockConnectionHelper* helper,
+
+ MockAlarmFactory* alarm_factory,
+
PacketSavingConnection* server_conn,
QuicCryptoServerStream* server,
const QuicServerId& server_id,
diff --git a/net/quic/test_tools/crypto_test_utils_openssl.cc b/net/quic/test_tools/crypto_test_utils_openssl.cc
index 2c39122..1a995de 100644
--- a/net/quic/test_tools/crypto_test_utils_openssl.cc
+++ b/net/quic/test_tools/crypto_test_utils_openssl.cc
@@ -11,6 +11,8 @@
#include <openssl/obj_mac.h>
#include <openssl/sha.h>
+#include <memory>
+
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "crypto/secure_hash.h"
diff --git a/net/quic/test_tools/mock_quic_dispatcher.cc b/net/quic/test_tools/mock_quic_dispatcher.cc
index a3136519..dc8098c 100644
--- a/net/quic/test_tools/mock_quic_dispatcher.cc
+++ b/net/quic/test_tools/mock_quic_dispatcher.cc
@@ -12,8 +12,13 @@
MockQuicDispatcher::MockQuicDispatcher(
const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
- QuicConnectionHelperInterface* helper)
- : QuicDispatcher(config, crypto_config, QuicSupportedVersions(), helper) {}
+ std::unique_ptr<QuicConnectionHelperInterface> helper,
+ std::unique_ptr<QuicAlarmFactory> alarm_factory)
+ : QuicDispatcher(config,
+ crypto_config,
+ QuicSupportedVersions(),
+ std::move(helper),
+ std::move(alarm_factory)) {}
MockQuicDispatcher::~MockQuicDispatcher() {}
diff --git a/net/quic/test_tools/mock_quic_dispatcher.h b/net/quic/test_tools/mock_quic_dispatcher.h
index 05c9c9b..8d666a151 100644
--- a/net/quic/test_tools/mock_quic_dispatcher.h
+++ b/net/quic/test_tools/mock_quic_dispatcher.h
@@ -20,7 +20,8 @@
public:
MockQuicDispatcher(const QuicConfig& config,
const QuicCryptoServerConfig* crypto_config,
- QuicConnectionHelperInterface* helper);
+ std::unique_ptr<QuicConnectionHelperInterface> helper,
+ std::unique_ptr<QuicAlarmFactory> alarm_factory);
~MockQuicDispatcher() override;
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc
index 8b2407c..d57c0ce 100644
--- a/net/quic/test_tools/quic_connection_peer.cc
+++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -146,6 +146,12 @@
}
// static
+QuicAlarmFactory* QuicConnectionPeer::GetAlarmFactory(
+ QuicConnection* connection) {
+ return connection->alarm_factory_;
+}
+
+// static
QuicFramer* QuicConnectionPeer::GetFramer(QuicConnection* connection) {
return &connection->framer_;
}
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h
index d6130e9..8aaac9f 100644
--- a/net/quic/test_tools/quic_connection_peer.h
+++ b/net/quic/test_tools/quic_connection_peer.h
@@ -85,6 +85,8 @@
static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection);
+ static QuicAlarmFactory* GetAlarmFactory(QuicConnection* connection);
+
static QuicFramer* GetFramer(QuicConnection* connection);
static QuicAlarm* GetAckAlarm(QuicConnection* connection);
diff --git a/net/quic/test_tools/quic_packet_creator_peer.cc b/net/quic/test_tools/quic_packet_creator_peer.cc
index 83b783c4..90821dd1 100644
--- a/net/quic/test_tools/quic_packet_creator_peer.cc
+++ b/net/quic/test_tools/quic_packet_creator_peer.cc
@@ -70,14 +70,14 @@
}
// static
-size_t QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
- QuicStreamId id,
- QuicIOVector iov,
- size_t iov_offset,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame) {
- return creator->CreateStreamFrame(id, iov, iov_offset, offset, fin, frame);
+void QuicPacketCreatorPeer::CreateStreamFrame(QuicPacketCreator* creator,
+ QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame) {
+ creator->CreateStreamFrame(id, iov, iov_offset, offset, fin, frame);
}
// static
diff --git a/net/quic/test_tools/quic_packet_creator_peer.h b/net/quic/test_tools/quic_packet_creator_peer.h
index 6849c1f..7c56c45 100644
--- a/net/quic/test_tools/quic_packet_creator_peer.h
+++ b/net/quic/test_tools/quic_packet_creator_peer.h
@@ -37,13 +37,13 @@
static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber s);
static void FillPacketHeader(QuicPacketCreator* creator,
QuicPacketHeader* header);
- static size_t CreateStreamFrame(QuicPacketCreator* creator,
- QuicStreamId id,
- QuicIOVector iov,
- size_t iov_offset,
- QuicStreamOffset offset,
- bool fin,
- QuicFrame* frame);
+ static void CreateStreamFrame(QuicPacketCreator* creator,
+ QuicStreamId id,
+ QuicIOVector iov,
+ size_t iov_offset,
+ QuicStreamOffset offset,
+ bool fin,
+ QuicFrame* frame);
static SerializedPacket SerializeAllFrames(QuicPacketCreator* creator,
const QuicFrames& frames,
char* buffer,
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index 5fd9d7de..c9b81de 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -4,6 +4,8 @@
#include "net/quic/test_tools/quic_test_utils.h"
+#include <memory>
+
#include "base/sha1.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -199,18 +201,18 @@
return &random_generator_;
}
-QuicAlarm* MockConnectionHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
- return new MockConnectionHelper::TestAlarm(
+QuicAlarm* MockAlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
+ return new MockAlarmFactory::TestAlarm(
QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
}
-QuicArenaScopedPtr<QuicAlarm> MockConnectionHelper::CreateAlarm(
+QuicArenaScopedPtr<QuicAlarm> MockAlarmFactory::CreateAlarm(
QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
QuicConnectionArena* arena) {
if (arena != nullptr) {
- return arena->New<MockConnectionHelper::TestAlarm>(std::move(delegate));
+ return arena->New<MockAlarmFactory::TestAlarm>(std::move(delegate));
} else {
- return QuicArenaScopedPtr<MockConnectionHelper::TestAlarm>(
+ return QuicArenaScopedPtr<MockAlarmFactory::TestAlarm>(
new TestAlarm(std::move(delegate)));
}
}
@@ -224,48 +226,58 @@
}
MockConnection::MockConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective)
: MockConnection(kTestConnectionId,
IPEndPoint(TestPeerIPAddress(), kTestPort),
helper,
+ alarm_factory,
perspective,
QuicSupportedVersions()) {}
MockConnection::MockConnection(IPEndPoint address,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective)
: MockConnection(kTestConnectionId,
address,
helper,
+ alarm_factory,
perspective,
QuicSupportedVersions()) {}
MockConnection::MockConnection(QuicConnectionId connection_id,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective)
: MockConnection(connection_id,
IPEndPoint(TestPeerIPAddress(), kTestPort),
helper,
+ alarm_factory,
perspective,
QuicSupportedVersions()) {}
MockConnection::MockConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective,
const QuicVersionVector& supported_versions)
: MockConnection(kTestConnectionId,
IPEndPoint(TestPeerIPAddress(), kTestPort),
helper,
+ alarm_factory,
perspective,
supported_versions) {}
MockConnection::MockConnection(QuicConnectionId connection_id,
IPEndPoint address,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective,
const QuicVersionVector& supported_versions)
: QuicConnection(connection_id,
address,
helper,
+ alarm_factory,
new testing::NiceMock<MockPacketWriter>(),
/* owns_writer= */ true,
perspective,
@@ -282,14 +294,16 @@
}
PacketSavingConnection::PacketSavingConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective)
- : MockConnection(helper, perspective) {}
+ : MockConnection(helper, alarm_factory, perspective) {}
PacketSavingConnection::PacketSavingConnection(
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective,
const QuicVersionVector& supported_versions)
- : MockConnection(helper, perspective, supported_versions) {}
+ : MockConnection(helper, alarm_factory, perspective, supported_versions) {}
PacketSavingConnection::~PacketSavingConnection() {
STLDeleteElements(&encrypted_packets_);
@@ -759,6 +773,7 @@
QuicTime::Delta connection_start_time,
QuicVersionVector supported_versions,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
QuicCryptoClientConfig* crypto_client_config,
PacketSavingConnection** client_connection,
TestQuicSpdyClientSession** client_session) {
@@ -773,7 +788,7 @@
? DefaultQuicConfigStatelessRejects()
: DefaultQuicConfig();
*client_connection = new PacketSavingConnection(
- helper, Perspective::IS_CLIENT, supported_versions);
+ helper, alarm_factory, Perspective::IS_CLIENT, supported_versions);
*client_session = new TestQuicSpdyClientSession(
*client_connection, config, server_id, crypto_client_config);
(*client_connection)->AdvanceTime(connection_start_time);
@@ -784,6 +799,7 @@
QuicTime::Delta connection_start_time,
QuicVersionVector supported_versions,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
QuicCryptoServerConfig* server_crypto_config,
QuicCompressedCertsCache* compressed_certs_cache,
PacketSavingConnection** server_connection,
@@ -796,7 +812,7 @@
<< "strike-register will be unhappy.";
*server_connection = new PacketSavingConnection(
- helper, Perspective::IS_SERVER, supported_versions);
+ helper, alarm_factory, Perspective::IS_SERVER, supported_versions);
*server_session = new TestQuicSpdyServerSession(
*server_connection, DefaultQuicConfig(), server_crypto_config,
compressed_certs_cache);
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index 69b0b79..2e6d646c 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -10,6 +10,8 @@
#include <stddef.h>
#include <stdint.h>
+#include <cstdint>
+#include <memory>
#include <string>
#include <vector>
@@ -320,12 +322,23 @@
~MockConnectionHelper() override;
const QuicClock* GetClock() const override;
QuicRandom* GetRandomGenerator() override;
+ QuicBufferAllocator* GetBufferAllocator() override;
+ void AdvanceTime(QuicTime::Delta delta);
+
+ private:
+ MockClock clock_;
+ MockRandom random_generator_;
+ SimpleBufferAllocator buffer_allocator_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockConnectionHelper);
+};
+
+class MockAlarmFactory : public QuicAlarmFactory {
+ public:
QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
QuicConnectionArena* arena) override;
- QuicBufferAllocator* GetBufferAllocator() override;
- void AdvanceTime(QuicTime::Delta delta);
// No-op alarm implementation
class TestAlarm : public QuicAlarm {
@@ -342,38 +355,37 @@
void FireAlarm(QuicAlarm* alarm) {
reinterpret_cast<TestAlarm*>(alarm)->Fire();
}
-
- private:
- MockClock clock_;
- MockRandom random_generator_;
- SimpleBufferAllocator buffer_allocator_;
-
- DISALLOW_COPY_AND_ASSIGN(MockConnectionHelper);
};
class MockConnection : public QuicConnection {
public:
// Uses a ConnectionId of 42 and 127.0.0.1:123.
- MockConnection(MockConnectionHelper* helper, Perspective perspective);
+ MockConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
+ Perspective perspective);
// Uses a ConnectionId of 42.
MockConnection(IPEndPoint address,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective);
// Uses 127.0.0.1:123.
MockConnection(QuicConnectionId connection_id,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective);
// Uses a ConnectionId of 42, and 127.0.0.1:123.
MockConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective,
const QuicVersionVector& supported_versions);
MockConnection(QuicConnectionId connection_id,
IPEndPoint address,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective,
const QuicVersionVector& supported_versions);
@@ -437,9 +449,12 @@
class PacketSavingConnection : public MockConnection {
public:
- PacketSavingConnection(MockConnectionHelper* helper, Perspective perspective);
+ PacketSavingConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
+ Perspective perspective);
PacketSavingConnection(MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
Perspective perspective,
const QuicVersionVector& supported_versions);
@@ -488,13 +503,23 @@
void(QuicStreamId stream_id, SpdyPriority priority));
MOCK_METHOD3(OnStreamHeadersComplete,
void(QuicStreamId stream_id, bool fin, size_t frame_len));
+ MOCK_METHOD4(OnStreamHeaderList,
+ void(QuicStreamId stream_id,
+ bool fin,
+ size_t frame_len,
+ const QuicHeaderList& header_list));
+ MOCK_METHOD0(IsCryptoHandshakeConfirmed, bool());
MOCK_METHOD2(OnPromiseHeaders,
void(QuicStreamId stream_id, StringPiece headers_data));
MOCK_METHOD3(OnPromiseHeadersComplete,
void(QuicStreamId stream_id,
QuicStreamId promised_stream_id,
size_t frame_len));
- MOCK_METHOD0(IsCryptoHandshakeConfirmed, bool());
+ MOCK_METHOD4(OnPromiseHeaderList,
+ void(QuicStreamId stream_id,
+ QuicStreamId promised_stream_id,
+ size_t frame_len,
+ const QuicHeaderList& header_list));
MOCK_METHOD5(WriteHeaders,
size_t(QuicStreamId id,
const SpdyHeaderBlock& headers,
@@ -793,6 +818,7 @@
QuicTime::Delta connection_start_time,
QuicVersionVector supported_versions,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
QuicCryptoClientConfig* crypto_client_config,
PacketSavingConnection** client_connection,
TestQuicSpdyClientSession** client_session);
@@ -817,6 +843,7 @@
QuicTime::Delta connection_start_time,
QuicVersionVector supported_versions,
MockConnectionHelper* helper,
+ MockAlarmFactory* alarm_factory,
QuicCryptoServerConfig* crypto_server_config,
QuicCompressedCertsCache* compressed_certs_cache,
PacketSavingConnection** server_connection,
diff --git a/net/quic/test_tools/simple_quic_framer.cc b/net/quic/test_tools/simple_quic_framer.cc
index 62e74b61..b26b97e 100644
--- a/net/quic/test_tools/simple_quic_framer.cc
+++ b/net/quic/test_tools/simple_quic_framer.cc
@@ -4,6 +4,8 @@
#include "net/quic/test_tools/simple_quic_framer.h"
+#include <memory>
+
#include "base/macros.h"
#include "base/stl_util.h"
#include "net/quic/crypto/quic_decrypter.h"