diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-03 13:42:47 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:27:51 +0000 |
commit | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (patch) | |
tree | d29d987c4d7b173cf853279b79a51598f104b403 /chromium/net/spdy | |
parent | 830c9e163d31a9180fadca926b3e1d7dfffb5021 (diff) | |
download | qtwebengine-chromium-8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec.tar.gz |
BASELINE: Update Chromium to 66.0.3359.156
Change-Id: I0c9831ad39911a086b6377b16f995ad75a51e441
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/net/spdy')
64 files changed, 2128 insertions, 1476 deletions
diff --git a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc index 616f1673fb1..4069f33e7c9 100644 --- a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc +++ b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc @@ -75,11 +75,13 @@ void BidirectionalStreamSpdyImpl::Start( request_info_ = request_info; + // TODO(https://crbug.com/656607): Add proper annotation here. int rv = stream_request_.StartRequest( SPDY_BIDIRECTIONAL_STREAM, spdy_session_, request_info_->url, - request_info_->priority, net_log, + request_info_->priority, request_info_->socket_tag, net_log, base::Bind(&BidirectionalStreamSpdyImpl::OnStreamInitialized, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr()), + NO_TRAFFIC_ANNOTATION_BUG_656607); if (rv != ERR_IO_PENDING) OnStreamInitialized(rv); } @@ -289,8 +291,8 @@ int BidirectionalStreamSpdyImpl::SendRequestHeadersHelper() { http_request_info.method = request_info_->method; http_request_info.extra_headers = request_info_->extra_headers; - CreateSpdyHeadersFromHttpRequest( - http_request_info, http_request_info.extra_headers, true, &headers); + CreateSpdyHeadersFromHttpRequest(http_request_info, + http_request_info.extra_headers, &headers); written_end_of_stream_ = request_info_->end_stream_on_headers; return stream_->SendRequestHeaders(std::move(headers), request_info_->end_stream_on_headers diff --git a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc index a92c30472e3..76a50ac83c5 100644 --- a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc +++ b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc @@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" #include "base/time/time.h" #include "base/timer/mock_timer.h" #include "net/base/load_timing_info.h" @@ -16,6 +17,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/log/test_net_log.h" +#include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" #include "net/spdy/chromium/spdy_session.h" #include "net/spdy/chromium/spdy_test_util_common.h" @@ -233,7 +235,10 @@ class BidirectionalStreamSpdyImplTest : public testing::TestWithParam<bool> { BidirectionalStreamSpdyImplTest() : default_url_(kDefaultUrl), host_port_pair_(HostPortPair::FromURL(default_url_)), - key_(host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED), + key_(host_port_pair_, + ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, + SocketTag()), ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { ssl_data_.next_proto = kProtoHTTP2; ssl_data_.ssl_info.cert = @@ -281,7 +286,7 @@ TEST_F(BidirectionalStreamSpdyImplTest, SimplePostRequest) { SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( kDefaultUrl, 1, kBodyDataSize, LOW, nullptr, 0)); SpdySerializedFrame data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, kBodyData, kBodyDataSize, /*fin=*/true)); + 1, base::StringPiece(kBodyData, kBodyDataSize), /*fin=*/true)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3), }; @@ -329,9 +334,9 @@ TEST_F(BidirectionalStreamSpdyImplTest, SimplePostRequest) { TEST_F(BidirectionalStreamSpdyImplTest, LoadTimingTwoRequests) { SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/1, LOW, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/1, LOW)); SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/3, LOW, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/3, LOW)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(req2, 2), }; diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer.cc b/chromium/net/spdy/chromium/buffered_spdy_framer.cc index 71a0eb36147..a797362361a 100644 --- a/chromium/net/spdy/chromium/buffered_spdy_framer.cc +++ b/chromium/net/spdy/chromium/buffered_spdy_framer.cc @@ -9,7 +9,6 @@ #include "base/logging.h" #include "base/strings/string_util.h" -#include "net/spdy/chromium/spdy_flags.h" #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" namespace net { @@ -24,7 +23,6 @@ size_t kGoAwayDebugDataMaxSize = 1024; BufferedSpdyFramer::BufferedSpdyFramer(uint32_t max_header_list_size, const NetLogWithSource& net_log) : spdy_framer_(SpdyFramer::ENABLE_COMPRESSION), - deframer_(FLAGS_chromium_http2_flag_h2_on_stream_pad_length), visitor_(NULL), frames_received_(0), max_header_list_size_(max_header_list_size), @@ -142,7 +140,7 @@ void BufferedSpdyFramer::OnSettings() { visitor_->OnSettings(); } -void BufferedSpdyFramer::OnSetting(SpdySettingsIds id, uint32_t value) { +void BufferedSpdyFramer::OnSetting(SpdyKnownSettingsId id, uint32_t value) { visitor_->OnSetting(id, value); } diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer.h b/chromium/net/spdy/chromium/buffered_spdy_framer.h index 84604467826..71ae7836626 100644 --- a/chromium/net/spdy/chromium/buffered_spdy_framer.h +++ b/chromium/net/spdy/chromium/buffered_spdy_framer.h @@ -72,7 +72,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface { // Called when an individual setting within a SETTINGS frame has been parsed // and validated. - virtual void OnSetting(SpdySettingsIds id, uint32_t value) = 0; + virtual void OnSetting(SpdyKnownSettingsId id, uint32_t value) = 0; // Called when a SETTINGS frame is received with the ACK flag set. virtual void OnSettingsAck() = 0; @@ -158,7 +158,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer SpdyStreamId stream_id) override; void OnHeaderFrameEnd(SpdyStreamId stream_id) override; void OnSettings() override; - void OnSetting(SpdySettingsIds id, uint32_t value) override; + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override; void OnSettingsAck() override; void OnSettingsEnd() override; void OnPing(SpdyPingId unique_id, bool is_ack) override; diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc b/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc index 0343c00df17..b9a983a8645 100644 --- a/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc +++ b/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc @@ -80,7 +80,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { void OnSettingsEnd() override {} - void OnSetting(SpdySettingsIds id, uint32_t value) override { + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override { setting_count_++; } diff --git a/chromium/net/spdy/chromium/header_coalescer.cc b/chromium/net/spdy/chromium/header_coalescer.cc index 50683491ff9..38fa22d98b5 100644 --- a/chromium/net/spdy/chromium/header_coalescer.cc +++ b/chromium/net/spdy/chromium/header_coalescer.cc @@ -8,7 +8,9 @@ #include <utility> #include "base/bind.h" +#include "base/callback.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/values.h" #include "net/base/escape.h" #include "net/http/http_log_util.h" @@ -119,9 +121,12 @@ bool HeaderCoalescer::AddHeader(SpdyStringPiece key, SpdyStringPiece value) { // Therefore allowed characters are '\t' (HTAB), x20 (SP), x21-7E, and x80-FF. for (const unsigned char c : value) { if (c < '\t' || ('\t' < c && c < 0x20) || c == 0x7f) { + std::string error_line; + base::StringAppendF(&error_line, + "Invalid character 0x%02X in header value.", c); net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_INVALID_HEADER, base::Bind(&ElideNetLogHeaderCallback, key, value, - "Invalid character in header value.")); + error_line.c_str())); return false; } } diff --git a/chromium/net/spdy/chromium/header_coalescer_test.cc b/chromium/net/spdy/chromium/header_coalescer_test.cc index e5f945573f8..1ec5058bb89 100644 --- a/chromium/net/spdy/chromium/header_coalescer_test.cc +++ b/chromium/net/spdy/chromium/header_coalescer_test.cc @@ -140,19 +140,19 @@ TEST_F(HeaderCoalescerTest, HeaderValueValid) { TEST_F(HeaderCoalescerTest, HeaderValueContainsLF) { header_coalescer_.OnHeader("foo", "bar\nbaz"); EXPECT_TRUE(header_coalescer_.error_seen()); - ExpectEntry("foo", "bar%0Abaz", "Invalid character in header value."); + ExpectEntry("foo", "bar%0Abaz", "Invalid character 0x0A in header value."); } TEST_F(HeaderCoalescerTest, HeaderValueContainsCR) { header_coalescer_.OnHeader("foo", "bar\rbaz"); EXPECT_TRUE(header_coalescer_.error_seen()); - ExpectEntry("foo", "bar%0Dbaz", "Invalid character in header value."); + ExpectEntry("foo", "bar%0Dbaz", "Invalid character 0x0D in header value."); } TEST_F(HeaderCoalescerTest, HeaderValueContains0x7f) { header_coalescer_.OnHeader("foo", "bar\x7f baz"); EXPECT_TRUE(header_coalescer_.error_seen()); - ExpectEntry("foo", "bar%7F%20baz", "Invalid character in header value."); + ExpectEntry("foo", "bar%7F%20baz", "Invalid character 0x7F in header value."); } } // namespace test diff --git a/chromium/net/spdy/chromium/http2_priority_dependencies.cc b/chromium/net/spdy/chromium/http2_priority_dependencies.cc index 5874511ea6e..7a0c3585f5a 100644 --- a/chromium/net/spdy/chromium/http2_priority_dependencies.cc +++ b/chromium/net/spdy/chromium/http2_priority_dependencies.cc @@ -11,21 +11,28 @@ Http2PriorityDependencies::Http2PriorityDependencies() = default; Http2PriorityDependencies::~Http2PriorityDependencies() = default; -void Http2PriorityDependencies::OnStreamCreation( - SpdyStreamId id, - SpdyPriority priority, - SpdyStreamId* dependent_stream_id, - bool* exclusive) { +void Http2PriorityDependencies::OnStreamCreation(SpdyStreamId id, + SpdyPriority priority, + SpdyStreamId* parent_stream_id, + int* weight, + bool* exclusive) { if (entry_by_stream_id_.find(id) != entry_by_stream_id_.end()) return; - *dependent_stream_id = 0ul; + *parent_stream_id = 0; *exclusive = true; + // Since the generated dependency graph is a single linked list, the value + // of weight should not actually matter, and perhaps the default weight of 16 + // from the HTTP/2 spec would be reasonable. However, there are some servers + // which currently interpret the weight field like an old SPDY priority value. + // As long as those servers need to be supported, weight should be set to + // a value those servers will interpret correctly. + *weight = Spdy3PriorityToHttp2Weight(priority); // Dependent on the lowest-priority stream that has a priority >= |priority|. IdList::iterator parent; if (PriorityLowerBound(priority, &parent)) { - *dependent_stream_id = parent->first; + *parent_stream_id = parent->first; } id_priority_lists_[priority].push_back(std::make_pair(id, priority)); @@ -128,18 +135,20 @@ Http2PriorityDependencies::OnStreamUpdate(SpdyStreamId id, // |old_parent|. IdList::iterator old_child; if (ChildOfStream(id, &old_child)) { + int weight = Spdy3PriorityToHttp2Weight(old_child->second); if (old_has_parent) { - result.push_back({old_child->first, old_parent->first, true}); + result.push_back({old_child->first, old_parent->first, weight, true}); } else { - result.push_back({old_child->first, 0, true}); + result.push_back({old_child->first, 0, weight, true}); } } + int weight = Spdy3PriorityToHttp2Weight(new_priority); // |id| moves to be dependent on |new_parent|. if (new_has_parent) { - result.push_back({id, new_parent->first, true}); + result.push_back({id, new_parent->first, weight, true}); } else { - result.push_back({id, 0, true}); + result.push_back({id, 0, weight, true}); } } diff --git a/chromium/net/spdy/chromium/http2_priority_dependencies.h b/chromium/net/spdy/chromium/http2_priority_dependencies.h index e4ae005ee1d..4b3346f0a77 100644 --- a/chromium/net/spdy/chromium/http2_priority_dependencies.h +++ b/chromium/net/spdy/chromium/http2_priority_dependencies.h @@ -15,9 +15,13 @@ namespace net { -// A helper class encapsulating the state and logic to set dependencies of -// HTTP2 streams based on their SpdyPriority and the ordering -// of creation and deletion of the streams. +// A helper class encapsulating the state and logic to set the priority fields +// for HTTP/2 streams based on their SpdyPriority and the ordering of creation +// and deletion of the streams. This implentation includes a gross hack in which +// the HTTP/2 weight is set to a transformation of the SpdyPriority value +// in order to support servers which do not honor HTTP/2 stream dependencies +// and instead treat the weight value like a SPDY/3 priority. +// TODO(rch): Eliminate this gross hack when servers no longer act like this. class NET_EXPORT_PRIVATE Http2PriorityDependencies { public: Http2PriorityDependencies(); @@ -25,12 +29,14 @@ class NET_EXPORT_PRIVATE Http2PriorityDependencies { // Called when a stream is created. This is used for both client-initiated // and server-initiated (pushed) streams. - // On return, |*dependent_stream_id| is set to the stream id that - // this stream should be made dependent on, and |*exclusive| set to - // whether that dependency should be exclusive. + // On return, |*parent_stream_id| is set to the stream id that should become + // the parent of this stream, |*exclusive| is set to whether that dependency + // should be exclusive, and |*weight| is set to the relative weight for the + // created stream given this priority. void OnStreamCreation(SpdyStreamId id, SpdyPriority priority, - SpdyStreamId* dependent_stream_id, + SpdyStreamId* parent_stream_id, + int* weight, bool* exclusive); // Called when a stream is destroyed. @@ -38,7 +44,8 @@ class NET_EXPORT_PRIVATE Http2PriorityDependencies { struct DependencyUpdate { SpdyStreamId id; - SpdyStreamId dependent_stream_id; + SpdyStreamId parent_stream_id; + int weight; bool exclusive; }; diff --git a/chromium/net/spdy/chromium/http2_priority_dependencies_unittest.cc b/chromium/net/spdy/chromium/http2_priority_dependencies_unittest.cc index 001433ed90c..f6544713224 100644 --- a/chromium/net/spdy/chromium/http2_priority_dependencies_unittest.cc +++ b/chromium/net/spdy/chromium/http2_priority_dependencies_unittest.cc @@ -15,15 +15,15 @@ namespace net { bool operator==(const Http2PriorityDependencies::DependencyUpdate& a, const Http2PriorityDependencies::DependencyUpdate& b) { - return a.id == b.id && a.dependent_stream_id == b.dependent_stream_id && - a.exclusive == b.exclusive; + return a.id == b.id && a.parent_stream_id == b.parent_stream_id && + a.weight == b.weight && a.exclusive == b.exclusive; } std::ostream& operator<<( std::ostream& os, const std::vector<Http2PriorityDependencies::DependencyUpdate>& v) { for (auto e : v) { - os << "{" << e.id << "," << e.dependent_stream_id << "," + os << "{" << e.id << "," << e.parent_stream_id << "," << e.weight << "," << (e.exclusive ? "true" : "false") << "}"; } return os; @@ -45,22 +45,29 @@ class HttpPriorityDependencyTest : public PlatformTest { void TestStreamCreation(SpdyStreamId new_id, SpdyPriority priority, - SpdyStreamId expected_dependent_id) { - SpdyStreamId dependent_id = 999u; + SpdyStreamId expected_parent_id) { + int expected_weight = Spdy3PriorityToHttp2Weight(priority); + + SpdyStreamId parent_id = 999u; + int weight = -1; bool exclusive = false; - dependency_state_.OnStreamCreation(new_id, priority, &dependent_id, + dependency_state_.OnStreamCreation(new_id, priority, &parent_id, &weight, &exclusive); - if (expected_dependent_id != dependent_id || !exclusive) { + if (expected_parent_id != parent_id || !exclusive || + expected_weight != weight) { ADD_FAILURE() << "OnStreamCreation(" << new_id << ", " << int(priority) << ")\n" - << " Got: (" << dependent_id << ", " << exclusive << ")\n" - << " Want: (" << expected_dependent_id << ", true)\n"; + << " Got: (" << parent_id << ", " << weight << ", " + << exclusive << ")\n" + << " Want: (" << expected_parent_id << ", " + << expected_weight << ", true)\n"; } } struct ExpectedDependencyUpdate { SpdyStreamId id; SpdyStreamId parent_id; + int weight; }; void TestStreamUpdate(SpdyStreamId id, @@ -69,7 +76,8 @@ class HttpPriorityDependencyTest : public PlatformTest { auto value = dependency_state_.OnStreamUpdate(id, new_priority); std::vector<Http2PriorityDependencies::DependencyUpdate> expected_value; for (auto e : expected) { - expected_value.push_back({e.id, e.parent_id, true /* exclusive */}); + expected_value.push_back( + {e.id, e.parent_id, e.weight, true /* exclusive */}); } if (value != expected_value) { ADD_FAILURE() << "OnStreamUpdate(" << id << ", " << int(new_priority) @@ -204,6 +212,10 @@ TEST_F(HttpPriorityDependencyTest, UpdateThreeStreams) { TestStreamCreation(second_id, MEDIUM, first_id); TestStreamCreation(third_id, LOWEST, second_id); + const int highest_weight = Spdy3PriorityToHttp2Weight(HIGHEST); + const int medium_weight = Spdy3PriorityToHttp2Weight(MEDIUM); + const int lowest_weight = Spdy3PriorityToHttp2Weight(LOWEST); + std::vector<ExpectedDependencyUpdate> empty; // no-op: still at top. @@ -216,16 +228,22 @@ TEST_F(HttpPriorityDependencyTest, UpdateThreeStreams) { TestStreamUpdate(third_id, LOWEST, empty); // second moves to top, first moves below second. - TestStreamUpdate(first_id, MEDIUM, {{second_id, 0}, {first_id, second_id}}); + TestStreamUpdate( + first_id, MEDIUM, + {{second_id, 0, medium_weight}, {first_id, second_id, medium_weight}}); // third moves to top. - TestStreamUpdate(third_id, HIGHEST, {{third_id, 0}}); + TestStreamUpdate(third_id, HIGHEST, {{third_id, 0, highest_weight}}); // third moves to bottom. - TestStreamUpdate(third_id, LOWEST, {{second_id, 0}, {third_id, first_id}}); + TestStreamUpdate( + third_id, LOWEST, + {{second_id, 0, medium_weight}, {third_id, first_id, lowest_weight}}); // first moves to top. - TestStreamUpdate(first_id, HIGHEST, {{third_id, second_id}, {first_id, 0}}); + TestStreamUpdate( + first_id, HIGHEST, + {{third_id, second_id, lowest_weight}, {first_id, 0, highest_weight}}); } // A more complex example parallel to a simple web page with pushed responses. @@ -246,15 +264,20 @@ TEST_F(HttpPriorityDependencyTest, UpdateComplex) { TestStreamCreation(sixth_id, MEDIUM, fifth_id); TestStreamCreation(seventh_id, LOW, sixth_id); + const int highest_weight = Spdy3PriorityToHttp2Weight(HIGHEST); + const int medium_weight = Spdy3PriorityToHttp2Weight(MEDIUM); + const int lowest_weight = Spdy3PriorityToHttp2Weight(LOWEST); + // second matches a HIGHEST priority response. // 3 moves under 7 // 2 moves under 4 TestStreamUpdate(second_id, HIGHEST, - {{third_id, seventh_id}, {second_id, fourth_id}}); + {{third_id, seventh_id, lowest_weight}, + {second_id, fourth_id, highest_weight}}); // third matches a MEDIUM priority response. // 3 moves under 6 - TestStreamUpdate(third_id, MEDIUM, {{third_id, sixth_id}}); + TestStreamUpdate(third_id, MEDIUM, {{third_id, sixth_id, medium_weight}}); } } // namespace net diff --git a/chromium/net/spdy/chromium/http2_push_promise_index_test.cc b/chromium/net/spdy/chromium/http2_push_promise_index_test.cc index 6777cb50b37..39d9d8384a0 100644 --- a/chromium/net/spdy/chromium/http2_push_promise_index_test.cc +++ b/chromium/net/spdy/chromium/http2_push_promise_index_test.cc @@ -6,6 +6,7 @@ #include "net/base/host_port_pair.h" #include "net/base/privacy_mode.h" +#include "net/socket/socket_tag.h" #include "net/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -58,10 +59,12 @@ class Http2PushPromiseIndexTest : public testing::Test { url2_("https://mail.example.com"), key1_(HostPortPair::FromURL(url1_), ProxyServer::Direct(), - PRIVACY_MODE_ENABLED), + PRIVACY_MODE_ENABLED, + SocketTag()), key2_(HostPortPair::FromURL(url2_), ProxyServer::Direct(), - PRIVACY_MODE_ENABLED) {} + PRIVACY_MODE_ENABLED, + SocketTag()) {} const GURL url1_; const GURL url2_; diff --git a/chromium/net/spdy/chromium/spdy_buffer_unittest.cc b/chromium/net/spdy/chromium/spdy_buffer_unittest.cc index 6fd1a99b5d0..8140049b25d 100644 --- a/chromium/net/spdy/chromium/spdy_buffer_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_buffer_unittest.cc @@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/callback.h" #include "base/memory/ref_counted.h" #include "net/base/io_buffer.h" #include "net/spdy/core/spdy_protocol.h" diff --git a/chromium/net/spdy/chromium/spdy_flags.cc b/chromium/net/spdy/chromium/spdy_flags.cc deleted file mode 100644 index fd4a669fcf9..00000000000 --- a/chromium/net/spdy/chromium/spdy_flags.cc +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 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/spdy/chromium/spdy_flags.h" - -namespace net { - -// Deliver OnPaddingLength separately from OnPadding. -bool FLAGS_chromium_http2_flag_h2_on_stream_pad_length = true; - -} // namespace net diff --git a/chromium/net/spdy/chromium/spdy_flags.h b/chromium/net/spdy/chromium/spdy_flags.h deleted file mode 100644 index 5b188d3b8df..00000000000 --- a/chromium/net/spdy/chromium/spdy_flags.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2016 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_SPDY_CHROMIUM_SPDY_FLAGS_H_ -#define NET_SPDY_CHROMIUM_SPDY_FLAGS_H_ - -#include "net/base/net_export.h" - -namespace net { - -NET_EXPORT_PRIVATE extern bool - FLAGS_chromium_http2_flag_h2_on_stream_pad_length; - -} // namespace net - -#endif // NET_SPDY_CHROMIUM_SPDY_FLAGS_H_ diff --git a/chromium/net/spdy/chromium/spdy_http_stream.cc b/chromium/net/spdy/chromium/spdy_http_stream.cc index c8207afd236..df05b4fed71 100644 --- a/chromium/net/spdy/chromium/spdy_http_stream.cc +++ b/chromium/net/spdy/chromium/spdy_http_stream.cc @@ -34,7 +34,6 @@ const size_t SpdyHttpStream::kRequestBodyBufferSize = 1 << 14; // 16KB SpdyHttpStream::SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, SpdyStreamId pushed_stream_id, - bool direct, NetLogSource source_dependency) : MultiplexedHttpStream( std::make_unique<MultiplexedSessionHandle>(spdy_session)), @@ -56,7 +55,6 @@ SpdyHttpStream::SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, request_body_buf_size_(0), buffered_read_callback_pending_(false), more_read_data_pending_(false), - direct_(direct), was_alpn_negotiated_(false), weak_factory_(this) { DCHECK(spdy_session_.get()); @@ -73,7 +71,7 @@ int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, bool can_send_early, RequestPriority priority, const NetLogWithSource& stream_net_log, - const CompletionCallback& callback) { + CompletionOnceCallback callback) { DCHECK(!stream_); if (!spdy_session_) return ERR_CONNECTION_CLOSED; @@ -94,11 +92,13 @@ int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, } } + // TODO(https://crbug.com/656607): Add proper annotation here. int rv = stream_request_.StartRequest( - SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url, - priority, stream_net_log, - base::Bind(&SpdyHttpStream::OnStreamCreated, - weak_factory_.GetWeakPtr(), callback)); + SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url, priority, + request_info_->socket_tag, stream_net_log, + base::BindOnce(&SpdyHttpStream::OnStreamCreated, + weak_factory_.GetWeakPtr(), std::move(callback)), + NO_TRAFFIC_ANNOTATION_BUG_656607); if (rv == OK) { stream_ = stream_request_.ReleaseStream().get(); @@ -108,7 +108,7 @@ int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, return rv; } -int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { +int SpdyHttpStream::ReadResponseHeaders(CompletionOnceCallback callback) { CHECK(!callback.is_null()); if (stream_closed_) return closed_stream_status_; @@ -123,12 +123,13 @@ int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { // Still waiting for the response, return IO_PENDING. CHECK(response_callback_.is_null()); - response_callback_ = callback; + response_callback_ = std::move(callback); return ERR_IO_PENDING; } -int SpdyHttpStream::ReadResponseBody( - IOBuffer* buf, int buf_len, const CompletionCallback& callback) { +int SpdyHttpStream::ReadResponseBody(IOBuffer* buf, + int buf_len, + CompletionOnceCallback callback) { if (stream_) CHECK(!stream_->IsIdle()); @@ -147,7 +148,7 @@ int SpdyHttpStream::ReadResponseBody( CHECK(!user_buffer_.get()); CHECK_EQ(0, user_buffer_len_); - response_callback_ = callback; + response_callback_ = std::move(callback); user_buffer_ = buf; user_buffer_len_ = buf_len; return ERR_IO_PENDING; @@ -213,7 +214,7 @@ bool SpdyHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, HttpResponseInfo* response, - const CompletionCallback& callback) { + CompletionOnceCallback callback) { if (stream_closed_) { return closed_stream_status_; } @@ -266,13 +267,12 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, // non-push behavior. The callback will be called when the // response is received. CHECK(response_callback_.is_null()); - response_callback_ = callback; + response_callback_ = std::move(callback); return ERR_IO_PENDING; } SpdyHeaderBlock headers; - CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, direct_, - &headers); + CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, &headers); stream_->net_log().AddEvent( NetLogEventType::HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS, base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); @@ -283,7 +283,7 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, if (result == ERR_IO_PENDING) { CHECK(request_callback_.is_null()); - request_callback_ = callback; + request_callback_ = std::move(callback); } return result; } @@ -370,19 +370,19 @@ void SpdyHttpStream::OnDataSent() { void SpdyHttpStream::OnTrailers(const SpdyHeaderBlock& trailers) {} void SpdyHttpStream::OnClose(int status) { + DCHECK(stream_); + // Cancel any pending reads from the upload data stream. if (request_info_ && request_info_->upload_data_stream) request_info_->upload_data_stream->Reset(); - if (stream_) { - stream_closed_ = true; - closed_stream_status_ = status; - closed_stream_id_ = stream_->stream_id(); - closed_stream_has_load_timing_info_ = - stream_->GetLoadTimingInfo(&closed_stream_load_timing_info_); - closed_stream_received_bytes_ = stream_->raw_received_bytes(); - closed_stream_sent_bytes_ = stream_->raw_sent_bytes(); - } + stream_closed_ = true; + closed_stream_status_ = status; + closed_stream_id_ = stream_->stream_id(); + closed_stream_has_load_timing_info_ = + stream_->GetLoadTimingInfo(&closed_stream_load_timing_info_); + closed_stream_received_bytes_ = stream_->raw_received_bytes(); + closed_stream_sent_bytes_ = stream_->raw_sent_bytes(); stream_ = nullptr; // Callbacks might destroy |this|. @@ -418,14 +418,12 @@ bool SpdyHttpStream::HasUploadData() const { request_info_->upload_data_stream->is_chunked()); } -void SpdyHttpStream::OnStreamCreated( - const CompletionCallback& callback, - int rv) { +void SpdyHttpStream::OnStreamCreated(CompletionOnceCallback callback, int rv) { if (rv == OK) { stream_ = stream_request_.ReleaseStream().get(); InitializeStreamHelper(); } - callback.Run(rv); + std::move(callback).Run(rv); } void SpdyHttpStream::ReadAndSendRequestBodyData() { @@ -446,11 +444,10 @@ void SpdyHttpStream::ReadAndSendRequestBodyData() { } // Read the data from the request body stream. - const int rv = request_info_->upload_data_stream - ->Read(request_body_buf_.get(), - request_body_buf_->size(), - base::Bind(&SpdyHttpStream::OnRequestBodyReadCompleted, - weak_factory_.GetWeakPtr())); + const int rv = request_info_->upload_data_stream->Read( + request_body_buf_.get(), request_body_buf_->size(), + base::BindOnce(&SpdyHttpStream::OnRequestBodyReadCompleted, + weak_factory_.GetWeakPtr())); if (rv != ERR_IO_PENDING) OnRequestBodyReadCompleted(rv); @@ -476,8 +473,8 @@ void SpdyHttpStream::OnRequestBodyReadCompleted(int status) { MaybePostRequestCallback(status); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SpdyHttpStream::ResetStreamInternal, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&SpdyHttpStream::ResetStreamInternal, + weak_factory_.GetWeakPtr())); return; } @@ -508,8 +505,9 @@ void SpdyHttpStream::ScheduleBufferedReadCallback() { buffered_read_callback_pending_ = true; const base::TimeDelta kBufferTime = base::TimeDelta::FromMilliseconds(1); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&SpdyHttpStream::DoBufferedReadCallback, - weak_factory_.GetWeakPtr()), + FROM_HERE, + base::BindOnce(&SpdyHttpStream::DoBufferedReadCallback, + weak_factory_.GetWeakPtr()), kBufferTime); } @@ -530,13 +528,11 @@ void SpdyHttpStream::DoBufferedReadCallback() { // If the transaction is cancelled or errored out, we don't need to complete // the read. - if (!stream_ && !stream_closed_) - return; - - int stream_status = - stream_closed_ ? closed_stream_status_ : stream_->response_status(); - if (stream_status != OK) + if (stream_closed_ && closed_stream_status_ != OK) { + if (response_callback_) + DoResponseCallback(closed_stream_status_); return; + } // When more_read_data_pending_ is true, it means that more data has // arrived since we started waiting. Wait a little longer and continue @@ -546,15 +542,20 @@ void SpdyHttpStream::DoBufferedReadCallback() { return; } - int rv = 0; - if (user_buffer_.get()) { - rv = ReadResponseBody(user_buffer_.get(), user_buffer_len_, - response_callback_); - CHECK_NE(rv, ERR_IO_PENDING); - user_buffer_ = NULL; + if (!user_buffer_.get()) + return; + + if (!response_body_queue_.IsEmpty()) { + int rv = + response_body_queue_.Dequeue(user_buffer_->data(), user_buffer_len_); + user_buffer_ = nullptr; user_buffer_len_ = 0; DoResponseCallback(rv); + return; } + + if (stream_closed_ && response_callback_) + DoResponseCallback(closed_stream_status_); } void SpdyHttpStream::DoRequestCallback(int rv) { @@ -575,8 +576,8 @@ void SpdyHttpStream::MaybePostRequestCallback(int rv) { CHECK_NE(ERR_IO_PENDING, rv); if (request_callback_) base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SpdyHttpStream::MaybeDoRequestCallback, - weak_factory_.GetWeakPtr(), rv)); + FROM_HERE, base::BindOnce(&SpdyHttpStream::MaybeDoRequestCallback, + weak_factory_.GetWeakPtr(), rv)); } void SpdyHttpStream::DoResponseCallback(int rv) { diff --git a/chromium/net/spdy/chromium/spdy_http_stream.h b/chromium/net/spdy/chromium/spdy_http_stream.h index 4eb48c522e6..eab0f110584 100644 --- a/chromium/net/spdy/chromium/spdy_http_stream.h +++ b/chromium/net/spdy/chromium/spdy_http_stream.h @@ -13,7 +13,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "net/base/completion_callback.h" +#include "net/base/completion_once_callback.h" #include "net/base/net_export.h" #include "net/log/net_log_source.h" #include "net/spdy/chromium/multiplexed_http_stream.h" @@ -37,7 +37,6 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, // |spdy_session| must not be NULL. SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, SpdyStreamId pushed_stream_id, - bool direct, NetLogSource source_dependency); ~SpdyHttpStream() override; @@ -52,15 +51,15 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, bool can_send_early, RequestPriority priority, const NetLogWithSource& net_log, - const CompletionCallback& callback) override; + CompletionOnceCallback callback) override; int SendRequest(const HttpRequestHeaders& headers, HttpResponseInfo* response, - const CompletionCallback& callback) override; - int ReadResponseHeaders(const CompletionCallback& callback) override; + CompletionOnceCallback callback) override; + int ReadResponseHeaders(CompletionOnceCallback callback) override; int ReadResponseBody(IOBuffer* buf, int buf_len, - const CompletionCallback& callback) override; + CompletionOnceCallback callback) override; void Close(bool not_reusable) override; bool IsResponseBodyComplete() const override; @@ -104,7 +103,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, // Must be called only when |request_info_| is non-NULL. bool HasUploadData() const; - void OnStreamCreated(const CompletionCallback& callback, int rv); + void OnStreamCreated(CompletionOnceCallback callback, int rv); // Reads the remaining data (whether chunked or not) from the // request body stream and sends it if there's any. The read and @@ -188,8 +187,8 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, // We buffer the response body as it arrives asynchronously from the stream. SpdyReadQueue response_body_queue_; - CompletionCallback request_callback_; - CompletionCallback response_callback_; + CompletionOnceCallback request_callback_; + CompletionOnceCallback response_callback_; // User provided buffer for the ReadResponseBody() response. scoped_refptr<IOBuffer> user_buffer_; @@ -205,9 +204,6 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, // scheduled read callback. bool more_read_data_pending_; - // Is this spdy stream direct to the origin server (or to a proxy). - bool direct_; - bool was_alpn_negotiated_; base::WeakPtrFactory<SpdyHttpStream> weak_factory_; diff --git a/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc b/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc index 83f92b9580a..ecd3db54a53 100644 --- a/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc @@ -22,6 +22,7 @@ #include "net/http/http_response_info.h" #include "net/log/net_log_with_source.h" #include "net/log/test_net_log.h" +#include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" #include "net/spdy/chromium/spdy_http_utils.h" #include "net/spdy/chromium/spdy_test_util_common.h" @@ -83,8 +84,8 @@ class ReadErrorUploadDataStream : public UploadDataStream { int ReadInternal(IOBuffer* buf, int buf_len) override { if (async_ == FailureMode::ASYNC) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead, - weak_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead, + weak_factory_.GetWeakPtr())); return ERR_IO_PENDING; } return ERR_FAILED; @@ -125,7 +126,10 @@ class SpdyHttpStreamTest : public testing::Test { SpdyHttpStreamTest() : url_(kDefaultUrl), host_port_pair_(HostPortPair::FromURL(url_)), - key_(host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED), + key_(host_port_pair_, + ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, + SocketTag()), ssl_(SYNCHRONOUS, OK) { session_deps_.net_log = &net_log_; } @@ -178,8 +182,7 @@ class SpdyHttpStreamTest : public testing::Test { }; TEST_F(SpdyHttpStreamTest, SendRequest) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -198,13 +201,13 @@ TEST_F(SpdyHttpStreamTest, SendRequest) { HttpRequestHeaders headers; NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); // Make sure getting load timing information the stream early does not crash. LoadTimingInfo load_timing_info; EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); ASSERT_THAT(http_stream->InitializeStream(&request, true, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); @@ -234,11 +237,10 @@ TEST_F(SpdyHttpStreamTest, SendRequest) { } TEST_F(SpdyHttpStreamTest, RequestInfoDestroyedBeforeRead) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); - SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, "", 0, true)); + SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, "", true)); MockRead reads[] = { CreateMockRead(resp, 1), CreateMockRead(body, 2), MockRead(ASYNC, 0, 3) // EOF @@ -255,11 +257,11 @@ TEST_F(SpdyHttpStreamTest, RequestInfoDestroyedBeforeRead) { HttpRequestHeaders headers; NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT( http_stream->InitializeStream(request.get(), true, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT(http_stream->SendRequest(headers, &response, callback.callback()), IsError(ERR_IO_PENDING)); @@ -291,17 +293,15 @@ TEST_F(SpdyHttpStreamTest, RequestInfoDestroyedBeforeRead) { } TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) { - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); - SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "", 0, true)); + SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "", true)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); - SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "", 0, true)); + SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, "", true)); MockRead reads[] = { CreateMockRead(resp1, 2), CreateMockRead(body1, 3), CreateMockRead(resp2, 4), CreateMockRead(body2, 5), @@ -318,7 +318,7 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) { HttpRequestHeaders headers1; NetLogWithSource net_log; auto http_stream1 = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); HttpRequestInfo request2; request2.method = "GET"; @@ -327,11 +327,11 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) { HttpResponseInfo response2; HttpRequestHeaders headers2; auto http_stream2 = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); // First write. ASSERT_THAT(http_stream1->InitializeStream(&request1, true, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT( http_stream1->SendRequest(headers1, &response1, callback1.callback()), @@ -348,7 +348,7 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) { // Second write. ASSERT_THAT(http_stream2->InitializeStream(&request2, true, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT( http_stream2->SendRequest(headers2, &response2, callback2.callback()), @@ -390,7 +390,6 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) { TEST_F(SpdyHttpStreamTest, SendChunkedPost) { SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, kUploadData, - kUploadDataSize, /*fin=*/true)); MockWrite writes[] = { CreateMockWrite(req, 0), // request @@ -424,10 +423,9 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPost) { HttpResponseInfo response; HttpRequestHeaders headers; NetLogWithSource net_log; - SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true, - net_log.source()); + SpdyHttpStream http_stream(session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT(http_stream.SendRequest(headers, &response, callback.callback()), @@ -449,8 +447,7 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPost) { // This unittest tests the request callback is properly called and handled. TEST_F(SpdyHttpStreamTest, SendChunkedPostLastEmpty) { SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); - SpdySerializedFrame chunk( - spdy_util_.ConstructSpdyDataFrame(1, nullptr, 0, true)); + SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame(1, "", true)); MockWrite writes[] = { CreateMockWrite(req, 0), // request CreateMockWrite(chunk, 1), @@ -480,10 +477,9 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPostLastEmpty) { HttpResponseInfo response; HttpRequestHeaders headers; NetLogWithSource net_log; - SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true, - net_log.source()); + SpdyHttpStream http_stream(session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT(http_stream.SendRequest(headers, &response, callback.callback()), IsError(ERR_IO_PENDING)); @@ -504,7 +500,6 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPostLastEmpty) { TEST_F(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) { SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, kUploadData, - kUploadDataSize, /*fin=*/false)); MockWrite writes[] = { CreateMockWrite(req, 0), // Request @@ -535,10 +530,9 @@ TEST_F(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) { HttpResponseInfo response; HttpRequestHeaders headers; NetLogWithSource net_log; - SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true, - net_log.source()); + SpdyHttpStream http_stream(session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT(http_stream.SendRequest(headers, &response, callback.callback()), @@ -574,8 +568,8 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPost) { const int kUploadData1Size = arraysize(kUploadData1)-1; SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); SpdySerializedFrame chunk1(spdy_util_.ConstructSpdyDataFrame(1, false)); - SpdySerializedFrame chunk2(spdy_util_.ConstructSpdyDataFrame( - 1, kUploadData1, kUploadData1Size, false)); + SpdySerializedFrame chunk2( + spdy_util_.ConstructSpdyDataFrame(1, kUploadData1, false)); SpdySerializedFrame chunk3(spdy_util_.ConstructSpdyDataFrame(1, true)); MockWrite writes[] = { CreateMockWrite(req, 0), @@ -605,9 +599,9 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPost) { NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); TestCompletionCallback callback; @@ -672,7 +666,7 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPost) { TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); SpdySerializedFrame chunk1(spdy_util_.ConstructSpdyDataFrame(1, false)); - SpdySerializedFrame chunk2(spdy_util_.ConstructSpdyDataFrame(1, "", 0, true)); + SpdySerializedFrame chunk2(spdy_util_.ConstructSpdyDataFrame(1, "", true)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(chunk1, 1), // POST upload frames @@ -700,9 +694,9 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); TestCompletionCallback callback; @@ -758,7 +752,7 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { // payload. Unclear if this is a case worth supporting. TEST_F(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) { SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); - SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame(1, "", 0, true)); + SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame(1, "", true)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(chunk, 1), }; @@ -784,9 +778,9 @@ TEST_F(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) { NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); TestCompletionCallback callback; @@ -844,9 +838,9 @@ TEST_F(SpdyHttpStreamTest, SpdyURLTest) { HttpRequestHeaders headers; NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream->InitializeStream(&request, true, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); EXPECT_THAT(http_stream->SendRequest(headers, &response, callback.callback()), @@ -897,9 +891,9 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) { NetLogWithSource net_log; auto http_stream = std::make_unique<SpdyHttpStream>( - session_, kNoPushedStreamFound, true, net_log.source()); + session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream->InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); HttpRequestHeaders headers; @@ -1001,10 +995,9 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorSynchronous) { HttpResponseInfo response; HttpRequestHeaders headers; NetLogWithSource net_log; - SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true, - net_log.source()); + SpdyHttpStream http_stream(session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); int result = http_stream.SendRequest(headers, &response, callback.callback()); @@ -1055,10 +1048,9 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorAsynchronous) { HttpResponseInfo response; HttpRequestHeaders headers; NetLogWithSource net_log; - SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true, - net_log.source()); + SpdyHttpStream http_stream(session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); int result = http_stream.SendRequest(headers, &response, callback.callback()); @@ -1076,8 +1068,7 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorAsynchronous) { // Regression test for https://crbug.com/622447. TEST_F(SpdyHttpStreamTest, RequestCallbackCancelsStream) { SpdySerializedFrame req(spdy_util_.ConstructChunkedSpdyPost(nullptr, 0)); - SpdySerializedFrame chunk( - spdy_util_.ConstructSpdyDataFrame(1, nullptr, 0, true)); + SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame(1, "", true)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(chunk, 1), @@ -1098,10 +1089,9 @@ TEST_F(SpdyHttpStreamTest, RequestCallbackCancelsStream) { upload_stream.AppendData("", 0, true); NetLogWithSource net_log; - SpdyHttpStream http_stream(session_, kNoPushedStreamFound, true, - net_log.source()); + SpdyHttpStream http_stream(session_, kNoPushedStreamFound, net_log.source()); ASSERT_THAT(http_stream.InitializeStream(&request, false, DEFAULT_PRIORITY, - net_log, CompletionCallback()), + net_log, CompletionOnceCallback()), IsOk()); CancelStreamCallback callback(&http_stream); diff --git a/chromium/net/spdy/chromium/spdy_http_utils.cc b/chromium/net/spdy/chromium/spdy_http_utils.cc index 7af36e3e19f..0cb8c3a26cb 100644 --- a/chromium/net/spdy/chromium/spdy_http_utils.cc +++ b/chromium/net/spdy/chromium/spdy_http_utils.cc @@ -87,7 +87,6 @@ bool SpdyHeadersToHttpResponse(const SpdyHeaderBlock& headers, void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info, const HttpRequestHeaders& request_headers, - bool direct, SpdyHeaderBlock* headers) { (*headers)[kHttp2MethodHeader] = info.method; if (info.method == "CONNECT") { @@ -110,6 +109,28 @@ void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info, } } +void CreateSpdyHeadersFromHttpRequestForWebSocket( + const GURL& url, + const HttpRequestHeaders& request_headers, + SpdyHeaderBlock* headers) { + (*headers)[kHttp2MethodHeader] = "CONNECT"; + (*headers)[kHttp2AuthorityHeader] = GetHostAndPort(url); + (*headers)[kHttp2SchemeHeader] = "https"; + (*headers)[kHttp2PathHeader] = url.PathForRequest(); + (*headers)[kHttp2ProtocolHeader] = "websocket"; + + HttpRequestHeaders::Iterator it(request_headers); + while (it.GetNext()) { + SpdyString name = base::ToLowerASCII(it.name()); + if (name.empty() || name[0] == ':' || name == "upgrade" || + name == "connection" || name == "proxy-connection" || + name == "transfer-encoding" || name == "host") { + continue; + } + AddSpdyHeader(name, it.value(), headers); + } +} + static_assert(HIGHEST - LOWEST < 4 && HIGHEST - MINIMUM_PRIORITY < 6, "request priority incompatible with spdy"); diff --git a/chromium/net/spdy/chromium/spdy_http_utils.h b/chromium/net/spdy/chromium/spdy_http_utils.h index c777190f591..fa10b9129df 100644 --- a/chromium/net/spdy/chromium/spdy_http_utils.h +++ b/chromium/net/spdy/chromium/spdy_http_utils.h @@ -31,7 +31,13 @@ NET_EXPORT bool SpdyHeadersToHttpResponse( NET_EXPORT void CreateSpdyHeadersFromHttpRequest( const HttpRequestInfo& info, const HttpRequestHeaders& request_headers, - bool direct, + SpdyHeaderBlock* headers); + +// Create a SpdyHeaderBlock from HttpRequestInfo and HttpRequestHeaders for a +// WebSockets over HTTP/2 request. +NET_EXPORT void CreateSpdyHeadersFromHttpRequestForWebSocket( + const GURL& url, + const HttpRequestHeaders& request_headers, SpdyHeaderBlock* headers); // Create HttpRequestHeaders from SpdyHeaderBlock. diff --git a/chromium/net/spdy/chromium/spdy_http_utils_unittest.cc b/chromium/net/spdy/chromium/spdy_http_utils_unittest.cc index 67a90a05366..94c9141ad87 100644 --- a/chromium/net/spdy/chromium/spdy_http_utils_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_http_utils_unittest.cc @@ -15,12 +15,6 @@ namespace net { -namespace { - -bool kDirect = true; - -} // namespace - TEST(SpdyHttpUtilsTest, ConvertRequestPriorityToSpdy3Priority) { EXPECT_EQ(0, ConvertRequestPriorityToSpdyPriority(HIGHEST)); EXPECT_EQ(1, ConvertRequestPriorityToSpdyPriority(MEDIUM)); @@ -51,25 +45,7 @@ TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestHTTP2) { request.url = url; request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, "Chrome/1.1"); SpdyHeaderBlock headers; - CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, kDirect, - &headers); - EXPECT_EQ("GET", headers[":method"]); - EXPECT_EQ("https", headers[":scheme"]); - EXPECT_EQ("www.google.com", headers[":authority"]); - EXPECT_EQ("/index.html", headers[":path"]); - EXPECT_TRUE(headers.end() == headers.find(":version")); - EXPECT_EQ("Chrome/1.1", headers["user-agent"]); -} - -TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestProxyHTTP2) { - GURL url("https://www.google.com/index.html"); - HttpRequestInfo request; - request.method = "GET"; - request.url = url; - request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, "Chrome/1.1"); - SpdyHeaderBlock headers; - CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, !kDirect, - &headers); + CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, &headers); EXPECT_EQ("GET", headers[":method"]); EXPECT_EQ("https", headers[":scheme"]); EXPECT_EQ("www.google.com", headers[":authority"]); @@ -85,8 +61,7 @@ TEST(SpdyHttpUtilsTest, CreateSpdyHeadersFromHttpRequestConnectHTTP2) { request.url = url; request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent, "Chrome/1.1"); SpdyHeaderBlock headers; - CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, kDirect, - &headers); + CreateSpdyHeadersFromHttpRequest(request, request.extra_headers, &headers); EXPECT_EQ("CONNECT", headers[":method"]); EXPECT_TRUE(headers.end() == headers.find(":scheme")); EXPECT_EQ("www.google.com:443", headers[":authority"]); diff --git a/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc b/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc index 0da92cf6a27..3fdf3e5198a 100644 --- a/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc @@ -12,12 +12,14 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" +#include "base/strings/string_piece.h" #include "base/test/test_file_util.h" #include "base/threading/thread_task_runner_handle.h" #include "net/base/auth.h" #include "net/base/chunked_upload_data_stream.h" #include "net/base/elements_upload_data_stream.h" #include "net/base/proxy_delegate.h" +#include "net/base/proxy_server.h" #include "net/base/request_priority.h" #include "net/base/test_proxy_delegate.h" #include "net/base/upload_bytes_element_reader.h" @@ -34,9 +36,9 @@ #include "net/log/test_net_log.h" #include "net/log/test_net_log_entry.h" #include "net/log/test_net_log_util.h" -#include "net/proxy/proxy_server.h" #include "net/socket/client_socket_pool_base.h" #include "net/socket/next_proto.h" +#include "net/socket/socket_tag.h" #include "net/spdy/chromium/buffered_spdy_framer.h" #include "net/spdy/chromium/spdy_http_stream.h" #include "net/spdy/chromium/spdy_http_utils.h" @@ -53,6 +55,7 @@ #include "net/test/test_data_directory.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" +#include "net/websockets/websocket_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/platform_test.h" @@ -88,6 +91,8 @@ class SpdyNetworkTransactionTest : public ::testing::Test { void SetUp() override { request_.method = "GET"; request_.url = GURL(kDefaultUrl); + request_.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } @@ -272,7 +277,9 @@ class SpdyNetworkTransactionTest : public ::testing::Test { HttpRequestInfo CreateGetPushRequest() const WARN_UNUSED_RESULT { HttpRequestInfo request; request.method = "GET"; - request.url = GURL(GetDefaultUrlWithPath("/foo.dat")); + request.url = GURL("https://www.example.org/foo.dat"); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); return request; } @@ -304,6 +311,8 @@ class SpdyNetworkTransactionTest : public ::testing::Test { request_.method = "POST"; request_.upload_data_stream = upload_data_stream_.get(); + request_.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); } void UseUnreadableFilePostRequest() { @@ -387,11 +396,13 @@ class SpdyNetworkTransactionTest : public ::testing::Test { // session. Once we have the session, we verify that the streams are // all closed and not leaked at this point. SpdySessionKey key(HostPortPair::FromURL(request_.url), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, + SocketTag()); HttpNetworkSession* session = helper.session(); base::WeakPtr<SpdySession> spdy_session = session->spdy_session_pool()->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, log_); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); ASSERT_TRUE(spdy_session); EXPECT_EQ(0u, num_active_streams(spdy_session)); EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session)); @@ -506,6 +517,8 @@ class SpdyNetworkTransactionTest : public ::testing::Test { TestCompletionCallback callback; request.method = "GET"; request.url = url; + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); int rv = trans.Start(&request, callback.callback(), log); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); callback.WaitForResult(); @@ -515,10 +528,6 @@ class SpdyNetworkTransactionTest : public ::testing::Test { return upload_chunked_data_stream_.get(); } - SpdyString GetDefaultUrlWithPath(const char* path) const { - return SpdyString(kDefaultUrl) + path; - } - size_t num_active_streams(base::WeakPtr<SpdySession> session) { return session->active_streams_.size(); } @@ -564,8 +573,7 @@ TEST_F(SpdyNetworkTransactionTest, Constructor) { TEST_F(SpdyNetworkTransactionTest, Get) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -590,8 +598,7 @@ TEST_F(SpdyNetworkTransactionTest, GetAtEachPriority) { SpdyTestUtil spdy_test_util; // Construct the request. - SpdySerializedFrame req( - spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, p, true)); + SpdySerializedFrame req(spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, p)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdyPriority spdy_prio = 0; @@ -653,20 +660,17 @@ TEST_F(SpdyNetworkTransactionTest, GetAtEachPriority) { // can allow multiple streams in flight. TEST_F(SpdyNetworkTransactionTest, ThreeGets) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false)); SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true)); - SpdySerializedFrame req3( - spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true)); + SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST)); SpdySerializedFrame resp3(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5)); SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, false)); SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(5, true)); @@ -736,14 +740,12 @@ TEST_F(SpdyNetworkTransactionTest, ThreeGets) { } TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBinding) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false)); SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true)); @@ -811,14 +813,12 @@ TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBinding) { } TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false)); SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true)); @@ -902,22 +902,19 @@ TEST_F(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { // Construct the request. // Each request fully completes before the next starts. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false)); SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true)); spdy_util_.UpdateWithStreamDestruction(3); - SpdySerializedFrame req3( - spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true)); + SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST)); SpdySerializedFrame resp3(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5)); SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, false)); SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(5, true)); @@ -1021,28 +1018,24 @@ TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { // the response from the server. TEST_F(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false)); SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true)); spdy_util_.UpdateWithStreamDestruction(3); - SpdySerializedFrame req4( - spdy_util_.ConstructSpdyGet(nullptr, 0, 5, HIGHEST, true)); + SpdySerializedFrame req4(spdy_util_.ConstructSpdyGet(nullptr, 0, 5, HIGHEST)); SpdySerializedFrame resp4(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5)); SpdySerializedFrame fbody4(spdy_util_.ConstructSpdyDataFrame(5, true)); spdy_util_.UpdateWithStreamDestruction(5); - SpdySerializedFrame req3( - spdy_util_.ConstructSpdyGet(nullptr, 0, 7, LOWEST, true)); + SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(nullptr, 0, 7, LOWEST)); SpdySerializedFrame resp3(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 7)); SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(7, false)); SpdySerializedFrame fbody3(spdy_util_.ConstructSpdyDataFrame(7, true)); @@ -1163,15 +1156,13 @@ TEST_F(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { // the spdy_session TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fbody(spdy_util_.ConstructSpdyDataFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, false)); SpdySerializedFrame fbody2(spdy_util_.ConstructSpdyDataFrame(3, true)); @@ -1283,15 +1274,13 @@ class KillerCallback : public TestCompletionCallbackBase { // a pending stream creation. http://crbug.com/52901 TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, false)); SpdySerializedFrame fin_body(spdy_util_.ConstructSpdyDataFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); SettingsMap settings; @@ -1719,8 +1708,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) { // socket causes the TCP write to return zero. This test checks that the client // tries to queue up the RST_STREAM frame again. TEST_F(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL)); MockWrite writes[] = { @@ -1756,8 +1744,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithoutHeaders) { CreateMockRead(body, 1), MockRead(ASYNC, 0, 3) // EOF }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = { @@ -1773,8 +1760,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithoutHeaders) { // Test that the transaction doesn't crash when we get two replies on the same // stream ID. See http://crbug.com/45639. TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = { @@ -1816,8 +1802,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { TEST_F(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = { @@ -1846,8 +1831,7 @@ TEST_F(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { TEST_F(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame rst( @@ -1861,9 +1845,8 @@ TEST_F(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { const char* const headers[] = { "transfer-encoding", "chunked" }; - SpdySerializedFrame push( - spdy_util_.ConstructSpdyPush(headers, arraysize(headers) / 2, 2, 1, - GetDefaultUrlWithPath("/1").c_str())); + SpdySerializedFrame push(spdy_util_.ConstructSpdyPush( + headers, arraysize(headers) / 2, 2, 1, "https://www.example.org/1")); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true)); MockRead reads[] = { CreateMockRead(resp, 1), CreateMockRead(push, 2), CreateMockRead(body, 4), @@ -1884,8 +1867,7 @@ TEST_F(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(req), }; @@ -1921,8 +1903,7 @@ TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { // Verify that the client sends a Rst Frame upon cancelling the stream. TEST_F(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL)); MockWrite writes[] = { @@ -1957,8 +1938,7 @@ TEST_F(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { // to start another transaction on a session that is closing down. See // http://crbug.com/47455 TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req)}; MockWrite writes2[] = {CreateMockWrite(req, 0), MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3)}; @@ -2021,8 +2001,7 @@ TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { // transaction. Failures will usually be valgrind errors. See // http://crbug.com/46925 TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -2077,7 +2056,7 @@ TEST_F(SpdyNetworkTransactionTest, TestRawHeaderSizeSuccessfullRequest) { SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame response_body_frame( - spdy_util_.ConstructSpdyDataFrame(1, "should not include", 18, true)); + spdy_util_.ConstructSpdyDataFrame(1, "should not include", true)); MockRead response_headers(CreateMockRead(resp, 1)); MockRead reads[] = { @@ -2129,7 +2108,7 @@ TEST_F(SpdyNetworkTransactionTest, SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame response_body_frame( - spdy_util_.ConstructSpdyDataFrame(1, "should not include", 18, true)); + spdy_util_.ConstructSpdyDataFrame(1, "should not include", true)); SpdyHeaderBlock push_headers; push_headers[":method"] = "GET"; @@ -2142,8 +2121,8 @@ TEST_F(SpdyNetworkTransactionTest, SpdySerializedFrame push_headers_frame( spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0)); - SpdySerializedFrame push_body_frame(spdy_util_.ConstructSpdyDataFrame( - 2, "should not include either", 25, false)); + SpdySerializedFrame push_body_frame( + spdy_util_.ConstructSpdyDataFrame(2, "should not include either", false)); MockRead push_init_read(CreateMockRead(push_init_frame, 1)); MockRead response_headers(CreateMockRead(resp, 5)); @@ -2356,7 +2335,7 @@ TEST_F(SpdyNetworkTransactionTest, RedirectServerPush) { TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -2366,11 +2345,11 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2), CreateMockRead(stream1_body, 4), CreateMockRead(stream2_body, 5), @@ -2396,15 +2375,14 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { } TEST_F(SpdyNetworkTransactionTest, ServerPushHeadMethod) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 2)}; SpdyHeaderBlock push_promise_header_block; push_promise_header_block[kHttp2MethodHeader] = "HEAD"; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/foo.dat", &push_promise_header_block); SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise( 1, 2, std::move(push_promise_header_block))); @@ -2436,6 +2414,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushHeadMethod) { HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session()); HttpRequestInfo request = CreateGetPushRequest(); request.method = "HEAD"; + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); TestCompletionCallback callback; int rv = trans.Start(&request, callback.callback(), log_); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2456,19 +2436,18 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushHeadMethod) { } TEST_F(SpdyNetworkTransactionTest, ServerPushHeadDoesNotMatchGetRequest) { - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); spdy_util_.UpdateWithStreamDestruction(1); SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet( - GetDefaultUrlWithPath("/foo.dat").c_str(), 3, LOWEST)); + "https://www.example.org/foo.dat", 3, LOWEST)); MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(priority, 2), CreateMockWrite(req2, 6)}; SpdyHeaderBlock push_promise_header_block; push_promise_header_block[kHttp2MethodHeader] = "HEAD"; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/foo.dat", &push_promise_header_block); SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise( 1, 2, std::move(push_promise_header_block))); @@ -2529,7 +2508,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushHeadDoesNotMatchGetRequest) { TEST_F(SpdyNetworkTransactionTest, ServerPushBeforeHeaders) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -2537,13 +2516,13 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushBeforeHeaders) { }; SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(stream2_syn, 1), CreateMockRead(stream1_reply, 3), @@ -2572,7 +2551,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushBeforeHeaders) { TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -2582,10 +2561,10 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); MockRead reads[] = { CreateMockRead(stream1_reply, 1), @@ -2615,11 +2594,11 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { TEST_F(SpdyNetworkTransactionTest, ServerPushUpdatesPriority) { SpdySerializedFrame stream1_headers( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST)); SpdySerializedFrame stream3_headers( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM)); SpdySerializedFrame stream5_headers( - spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM)); // Stream 1 pushes two streams that are initially prioritized below stream 5. // Stream 2 is later prioritized below stream 1 after it matches a request. @@ -2650,9 +2629,9 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushUpdatesPriority) { spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5)); SpdySerializedFrame stream2_push(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream4_push(spdy_util_.ConstructSpdyPush( - nullptr, 0, 4, 1, GetDefaultUrlWithPath("/bar.dat").c_str())); + nullptr, 0, 4, 1, "https://www.example.org/bar.dat")); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(2, true)); @@ -2720,7 +2699,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushUpdatesPriority) { TEST_F(SpdyNetworkTransactionTest, ServerPushServerAborted) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -2730,7 +2709,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushServerAborted) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream2_rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_PROTOCOL_ERROR)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); @@ -2772,7 +2751,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushServerAborted) { // if the server pushes the same stream twice. TEST_F(SpdyNetworkTransactionTest, ServerPushDuplicate) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame stream3_rst( @@ -2785,14 +2764,14 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushDuplicate) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream3_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 4, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 4, 1, "https://www.example.org/foo.dat")); const char kPushedData[] = "pushed"; SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(stream1_reply, 1), @@ -2823,7 +2802,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushDuplicate) { TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -2833,10 +2812,10 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); - static const char kPushedData[] = "pushed my darling hello my baby"; - SpdySerializedFrame stream2_body_base(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); + static const char kPushedData[] = "pushed payload for chunked test"; + SpdySerializedFrame stream2_body_base( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); const size_t kChunkSize = strlen(kPushedData) / 4; SpdySerializedFrame stream2_body1(stream2_body_base.data(), kChunkSize, false); @@ -2861,7 +2840,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { HttpResponseInfo response; HttpResponseInfo response2; - SpdyString expected_push_result("pushed my darling hello my baby"); + SpdyString expected_push_result(kPushedData); SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); RunServerPushTest(&data, &response, &response2, kPushedData); @@ -2876,7 +2855,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -2886,10 +2865,10 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); - static const char kPushedData[] = "pushed my darling hello my baby"; - SpdySerializedFrame stream2_body_base(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); + static const char kPushedData[] = "pushed payload for chunked test"; + SpdySerializedFrame stream2_body_base( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); const size_t kChunkSize = strlen(kPushedData) / 4; SpdySerializedFrame stream2_body1(stream2_body_base.data(), kChunkSize, false); @@ -2957,7 +2936,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidUrl) { TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( 0, ERROR_CODE_PROTOCOL_ERROR, "Framer error: 1 (INVALID_STREAM_ID).")); MockWrite writes[] = { @@ -2967,7 +2946,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 0, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 0, "https://www.example.org/foo.dat")); MockRead reads[] = { CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2), }; @@ -2977,7 +2956,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); SpdySerializedFrame stream2_rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_STREAM_CLOSED)); @@ -2988,7 +2967,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 9, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 9, "https://www.example.org/foo.dat")); MockRead reads[] = { CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2), CreateMockRead(stream1_body, 4), @@ -3001,7 +2980,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { TEST_F(SpdyNetworkTransactionTest, ServerPushNoURL) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); SpdySerializedFrame stream2_rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM)); @@ -3029,7 +3008,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushNoURL) { // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY. TEST_F(SpdyNetworkTransactionTest, ServerPushOnPushedStream) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( @@ -3043,9 +3022,9 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnPushedStream) { SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream3_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str())); + nullptr, 0, 4, 2, "https://www.example.org/bar.dat")); MockRead reads[] = { CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2), CreateMockRead(stream3_syn, 4), @@ -3059,7 +3038,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnPushedStream) { // PUSH_PROMISE on a closed client-initiated stream should trigger RST_STREAM. TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedStream) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_STREAM_CLOSED)); MockWrite writes[] = { @@ -3070,7 +3049,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedStream) { spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); MockRead reads[] = { CreateMockRead(stream1_reply, 1), CreateMockRead(stream1_body, 2), CreateMockRead(stream2_syn, 3), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4), @@ -3104,7 +3083,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedStream) { // stream is closed. TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( @@ -3115,15 +3094,15 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) { CreateMockWrite(goaway, 8)}; SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame stream1_reply( spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); SpdySerializedFrame stream3_syn(spdy_util_.ConstructSpdyPush( - nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str())); + nullptr, 0, 4, 2, "https://www.example.org/bar.dat")); MockRead reads[] = { CreateMockRead(stream2_syn, 1), CreateMockRead(stream1_reply, 2), @@ -3165,19 +3144,18 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) { } TEST_F(SpdyNetworkTransactionTest, ServerCancelsPush) { - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); spdy_util_.UpdateWithStreamDestruction(1); SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet( - GetDefaultUrlWithPath("/foo.dat").c_str(), 3, LOWEST)); + "https://www.example.org/foo.dat", 3, LOWEST)); MockWrite writes1[] = {CreateMockWrite(req1, 0), CreateMockWrite(priority, 3), CreateMockWrite(req2, 6)}; SpdySerializedFrame reply1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame push(spdy_util_.ConstructSpdyPush( - nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); + nullptr, 0, 2, 1, "https://www.example.org/foo.dat")); SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_INTERNAL_ERROR)); @@ -3213,10 +3191,11 @@ TEST_F(SpdyNetworkTransactionTest, ServerCancelsPush) { SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); SpdySessionKey key(host_port_pair_, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> spdy_session = spdy_session_pool->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, log_); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session)); // Create request matching pushed stream. @@ -3291,9 +3270,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerCancelsCrossOriginPush) { MockWrite writes2[] = {CreateMockWrite(req2, 0)}; SpdySerializedFrame reply2(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1)); - base::StringPiece kData("Response on the second connection."); - SpdySerializedFrame body2( - spdy_util2.ConstructSpdyDataFrame(1, kData.data(), kData.size(), true)); + SpdySerializedFrame body2(spdy_util2.ConstructSpdyDataFrame( + 1, "Response on the second connection.", true)); MockRead reads2[] = {CreateMockRead(reply2, 1), CreateMockRead(body2, 2), MockRead(ASYNC, 0, 3)}; @@ -3309,6 +3287,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerCancelsCrossOriginPush) { HttpRequestInfo request1; request1.method = "GET"; request1.url = GURL(kUrl1); + request1.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); TestCompletionCallback callback1; int rv = trans1->Start(&request1, callback1.callback(), log_); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3325,25 +3305,29 @@ TEST_F(SpdyNetworkTransactionTest, ServerCancelsCrossOriginPush) { SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); SpdySessionKey key1(HostPortPair::FromURL(GURL(kUrl1)), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> spdy_session1 = spdy_session_pool->FindAvailableSession( - key1, /* enable_ip_based_pooling = */ true, log_); + key1, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session1)); // While cross-origin push for kUrl2 is allowed on spdy_session1, // a client-initiated request would not pool to this connection, // because the IP address does not match. SpdySessionKey key2(HostPortPair::FromURL(GURL(kUrl2)), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); EXPECT_FALSE(spdy_session_pool->FindAvailableSession( - key2, /* enable_ip_based_pooling = */ true, log_)); + key2, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_)); // Create request matching pushed stream. HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); HttpRequestInfo request2; request2.method = "GET"; request2.url = GURL(kUrl2); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); TestCompletionCallback callback2; rv = trans2.Start(&request2, callback2.callback(), log_); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -3376,8 +3360,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerCancelsCrossOriginPush) { // Regression test for https://crbug.com/727653. TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithNoMethod) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 3)}; @@ -3385,7 +3368,7 @@ TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithNoMethod) { SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdyHeaderBlock push_promise_header_block; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/foo.dat", &push_promise_header_block); SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise( 1, 2, std::move(push_promise_header_block))); @@ -3402,8 +3385,7 @@ TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithNoMethod) { // Regression test for https://crbug.com/727653. TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithInvalidMethod) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 3)}; @@ -3412,7 +3394,7 @@ TEST_F(SpdyNetworkTransactionTest, RejectServerPushWithInvalidMethod) { SpdyHeaderBlock push_promise_header_block; push_promise_header_block[":method"] = "POST"; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/foo.dat", &push_promise_header_block); SpdySerializedFrame push_promise(spdy_util_.ConstructSpdyPushPromise( 1, 2, std::move(push_promise_header_block))); @@ -3462,7 +3444,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseHeaders) { for (size_t i = 0; i < arraysize(test_cases); ++i) { SpdyTestUtil spdy_test_util; SpdySerializedFrame req( - spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_test_util.ConstructSpdyGetReply( @@ -3549,8 +3531,8 @@ TEST_F(SpdyNetworkTransactionTest, ResponseHeadersVary) { // Construct the request. SpdySerializedFrame frame_req(spdy_test_util.ConstructSpdyGet( - test_cases[i].extra_headers[0], test_cases[i].num_headers[0], 1, LOWEST, - true)); + test_cases[i].extra_headers[0], test_cases[i].num_headers[0], 1, + LOWEST)); MockWrite writes[] = { CreateMockWrite(frame_req, 0), @@ -3580,6 +3562,8 @@ TEST_F(SpdyNetworkTransactionTest, ResponseHeadersVary) { HttpRequestInfo request; request.method = "GET"; request.url = GURL(kDefaultUrl); + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); for (int ct = 0; ct < header_count; ct++) { const char* header_key = test_cases[i].extra_headers[0][ct * 2]; const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1]; @@ -3645,7 +3629,7 @@ TEST_F(SpdyNetworkTransactionTest, InvalidResponseHeaders) { SpdyTestUtil spdy_test_util; SpdySerializedFrame req( - spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_test_util.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = { @@ -3673,8 +3657,7 @@ TEST_F(SpdyNetworkTransactionTest, InvalidResponseHeaders) { } TEST_F(SpdyNetworkTransactionTest, CorruptFrameSessionError) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame goaway( spdy_util_.ConstructSpdyGoAway(0, ERROR_CODE_COMPRESSION_ERROR, "Framer error: 6 (DECOMPRESS_FAILURE).")); @@ -3700,8 +3683,7 @@ TEST_F(SpdyNetworkTransactionTest, CorruptFrameSessionError) { } TEST_F(SpdyNetworkTransactionTest, GoAwayOnDecompressionFailure) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame goaway( spdy_util_.ConstructSpdyGoAway(0, ERROR_CODE_COMPRESSION_ERROR, "Framer error: 6 (DECOMPRESS_FAILURE).")); @@ -3720,8 +3702,7 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayOnDecompressionFailure) { } TEST_F(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( 0, ERROR_CODE_FRAME_SIZE_ERROR, "Framer error: 15 (INVALID_CONTROL_FRAME_SIZE).")); @@ -3742,8 +3723,7 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) { // Test that we shutdown correctly on write errors. TEST_F(SpdyNetworkTransactionTest, WriteError) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = { // We'll write 10 bytes successfully MockWrite(ASYNC, req.data(), 10, 1), @@ -3771,8 +3751,7 @@ TEST_F(SpdyNetworkTransactionTest, WriteError) { // Test that partial writes work. TEST_F(SpdyNetworkTransactionTest, PartialWrite) { // Chop the HEADERS frame into 5 chunks. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); const int kChunks = 5; std::unique_ptr<MockWrite[]> writes = ChopWriteFrame(req, kChunks); for (int i = 0; i < kChunks; ++i) { @@ -3801,7 +3780,7 @@ TEST_F(SpdyNetworkTransactionTest, NetLog) { "user-agent", "Chrome", }; SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -3881,20 +3860,19 @@ TEST_F(SpdyNetworkTransactionTest, NetLog) { // on the network, but issued a Read for only 5 of those bytes) that the data // flow still works correctly. TEST_F(SpdyNetworkTransactionTest, BufferFull) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; // 2 data frames in a single read. SpdySerializedFrame data_frame_1( - spdy_util_.ConstructSpdyDataFrame(1, "goodby", 6, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "goodby", /*fin=*/false)); SpdySerializedFrame data_frame_2( - spdy_util_.ConstructSpdyDataFrame(1, "e worl", 6, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "e worl", /*fin=*/false)); SpdySerializedFrame combined_data_frames = CombineFrames({&data_frame_1, &data_frame_2}); SpdySerializedFrame last_frame( - spdy_util_.ConstructSpdyDataFrame(1, "d", 1, /*fin=*/true)); + spdy_util_.ConstructSpdyDataFrame(1, "d", /*fin=*/true)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); MockRead reads[] = { @@ -3965,15 +3943,14 @@ TEST_F(SpdyNetworkTransactionTest, BufferFull) { // at the same time, ensure that we don't notify a read completion for // each data frame individually. TEST_F(SpdyNetworkTransactionTest, Buffering) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; // 4 data frames in a single read. SpdySerializedFrame data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "message", 7, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false)); SpdySerializedFrame data_frame_fin( - spdy_util_.ConstructSpdyDataFrame(1, "message", 7, /*fin=*/true)); + spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/true)); SpdySerializedFrame combined_data_frames = CombineFrames({&data_frame, &data_frame, &data_frame, &data_frame_fin}); @@ -4046,16 +4023,15 @@ TEST_F(SpdyNetworkTransactionTest, Buffering) { // Verify the case where we buffer data but read it after it has been buffered. TEST_F(SpdyNetworkTransactionTest, BufferedAll) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; // 5 data frames in a single read. SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "message", 7, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false)); SpdySerializedFrame data_frame_fin( - spdy_util_.ConstructSpdyDataFrame(1, "message", 7, /*fin=*/true)); + spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/true)); SpdySerializedFrame combined_frames = CombineFrames( {&reply, &data_frame, &data_frame, &data_frame, &data_frame_fin}); @@ -4121,14 +4097,13 @@ TEST_F(SpdyNetworkTransactionTest, BufferedAll) { // Verify the case where we buffer data and close the connection. TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; // All data frames in a single read. // NOTE: We don't FIN the stream. SpdySerializedFrame data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "message", 7, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false)); SpdySerializedFrame combined_data_frames = CombineFrames({&data_frame, &data_frame, &data_frame, &data_frame}); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -4198,15 +4173,14 @@ TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { // Verify the case where we buffer data and cancel the transaction. TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 4)}; // NOTE: We don't FIN the stream. SpdySerializedFrame data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "message", 7, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "message", /*fin=*/false)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); MockRead reads[] = { @@ -4263,8 +4237,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { // with Last-Stream-ID lower than the stream id corresponding to the request // and with error code other than NO_ERROR. TEST_F(SpdyNetworkTransactionTest, FailOnGoAway) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame go_away( @@ -4287,8 +4260,7 @@ TEST_F(SpdyNetworkTransactionTest, RetryOnGoAway) { NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr); // First connection. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes1[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame go_away( spdy_util_.ConstructSpdyGoAway(0, ERROR_CODE_NO_ERROR, "")); @@ -4321,8 +4293,7 @@ TEST_F(SpdyNetworkTransactionTest, RetryOnGoAway) { // Transactions started before receiving such a GOAWAY frame should succeed, // but SpdySession should be unavailable for new streams. TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) { - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); spdy_util_.UpdateWithStreamDestruction(1); SpdySerializedFrame req2( spdy_util_.ConstructSpdyGet("https://www.example.org/foo", 3, LOWEST)); @@ -4354,10 +4325,11 @@ TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) { // GOAWAY frame has not yet been received, SpdySession should be available. SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); SpdySessionKey key(host_port_pair_, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> spdy_session = spdy_session_pool->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, log_); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_TRUE(spdy_session); // Start second transaction. @@ -4366,6 +4338,8 @@ TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) { HttpRequestInfo request2; request2.method = "GET"; request2.url = GURL("https://www.example.org/foo"); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); int rv = trans2.Start(&request2, callback.callback(), log_); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -4388,15 +4362,15 @@ TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) { // Graceful GOAWAY was received, SpdySession should be unavailable. spdy_session = spdy_session_pool->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, log_); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_FALSE(spdy_session); helper.VerifyDataConsumed(); } TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -4466,8 +4440,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) { auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); // Expect HTTP/2 protocols too in SSLConfig. - ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2); - ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); + ssl_provider0->next_protos_expected_in_ssl_config = + NextProtoVector{kProtoHTTP2, kProtoHTTP11}; // Force SPDY. ssl_provider0->next_proto = kProtoHTTP2; helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0)); @@ -4486,7 +4460,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) { auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); // Expect only HTTP/1.1 protocol in SSLConfig. - ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); + ssl_provider1->next_protos_expected_in_ssl_config = + NextProtoVector{kProtoHTTP11}; // Force HTTP/1.1. ssl_provider1->next_proto = kProtoHTTP11; helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1)); @@ -4523,7 +4498,7 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) { TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { request_.method = "GET"; auto session_deps = std::make_unique<SpdySessionDependencies>( - ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); + ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70")); // Do not force SPDY so that second socket can negotiate HTTP/1.1. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, std::move(session_deps)); @@ -4540,8 +4515,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { auto ssl_provider0 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); // Expect HTTP/2 protocols too in SSLConfig. - ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2); - ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); + ssl_provider0->next_protos_expected_in_ssl_config = + NextProtoVector{kProtoHTTP2, kProtoHTTP11}; // Force SPDY. ssl_provider0->next_proto = kProtoHTTP2; helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0)); @@ -4570,7 +4545,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { auto ssl_provider1 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); // Expect only HTTP/1.1 protocol in SSLConfig. - ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); + ssl_provider1->next_protos_expected_in_ssl_config = + NextProtoVector{kProtoHTTP11}; // Force HTTP/1.1. ssl_provider1->next_proto = kProtoHTTP11; helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1)); @@ -4610,7 +4586,7 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { // Test to make sure we can correctly connect through a proxy. TEST_F(SpdyNetworkTransactionTest, ProxyConnect) { auto session_deps = std::make_unique<SpdySessionDependencies>( - ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); + ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70")); NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, std::move(session_deps)); helper.RunPreTestSetup(); @@ -4621,8 +4597,7 @@ TEST_F(SpdyNetworkTransactionTest, ProxyConnect) { "Host: www.example.org:443\r\n" "Proxy-Connection: keep-alive\r\n\r\n"}; const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true)); @@ -4667,7 +4642,8 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { // to simply DIRECT. The reason for appending the second proxy is to verify // that the session pool key used does is just "DIRECT". auto session_deps = std::make_unique<SpdySessionDependencies>( - ProxyService::CreateFixedFromPacResult("DIRECT; PROXY myproxy:70")); + ProxyResolutionService::CreateFixedFromPacResult( + "DIRECT; PROXY myproxy:70")); // When setting up the first transaction, we store the SpdySessionPool so that // we can use the same pool in the second transaction. NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, @@ -4677,8 +4653,7 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { helper.RunPreTestSetup(); // Construct and send a simple GET request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -4712,12 +4687,12 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { // Check that the SpdySession is still in the SpdySessionPool. SpdySessionKey session_pool_key_direct(host_port_pair_, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); EXPECT_TRUE(HasSpdySession(spdy_session_pool, session_pool_key_direct)); SpdySessionKey session_pool_key_proxy( host_port_pair_, ProxyServer::FromURI("www.foo.com", ProxyServer::SCHEME_HTTP), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); EXPECT_FALSE(HasSpdySession(spdy_session_pool, session_pool_key_proxy)); // New SpdyTestUtil instance for the session that will be used for the @@ -4731,7 +4706,7 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { "Proxy-Connection: keep-alive\r\n\r\n"}; const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; SpdySerializedFrame req2(spdy_util_2.ConstructSpdyGet( - GetDefaultUrlWithPath("/foo.dat").c_str(), 1, LOWEST)); + "https://www.example.org/foo.dat", 1, LOWEST)); SpdySerializedFrame resp2(spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body2(spdy_util_2.ConstructSpdyDataFrame(1, true)); @@ -4750,9 +4725,9 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { // Create another request to www.example.org, but this time through a proxy. request_.method = "GET"; - request_.url = GURL(GetDefaultUrlWithPath("/foo.dat")); + request_.url = GURL("https://www.example.org/foo.dat"); auto session_deps_proxy = std::make_unique<SpdySessionDependencies>( - ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); + ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70")); NormalSpdyTransactionHelper helper_proxy(request_, DEFAULT_PRIORITY, log_, std::move(session_deps_proxy)); @@ -4795,13 +4770,11 @@ TEST_F(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { MockRead(ASYNC, 0, 3) // EOF }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); // In all cases the connection will be reset before req3 can be // dispatched, destroying both streams. spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req3( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); MockWrite writes1[] = {CreateMockWrite(req, 0), CreateMockWrite(req3, 5)}; MockWrite writes2[] = {CreateMockWrite(req, 0)}; @@ -4870,7 +4843,7 @@ TEST_F(SpdyNetworkTransactionTest, SpdyBasicAuth) { // The first request will be a bare GET, the second request will be a // GET with an Authorization header. SpdySerializedFrame req_get( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); // Will be refused for lack of auth. spdy_util_.UpdateWithStreamDestruction(1); const char* const kExtraAuthorizationHeaders[] = { @@ -4878,7 +4851,7 @@ TEST_F(SpdyNetworkTransactionTest, SpdyBasicAuth) { }; SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet( kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3, - LOWEST, true)); + LOWEST)); MockWrite spdy_writes[] = { CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3), }; @@ -4952,7 +4925,7 @@ TEST_F(SpdyNetworkTransactionTest, SpdyBasicAuth) { TEST_F(SpdyNetworkTransactionTest, ServerPushWithHeaders) { SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -4964,7 +4937,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushWithHeaders) { SpdyHeaderBlock initial_headers; initial_headers[":method"] = "GET"; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/foo.dat", &initial_headers); SpdySerializedFrame stream2_syn( spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(initial_headers))); @@ -4978,8 +4951,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushWithHeaders) { SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(stream1_reply, 1), @@ -5011,7 +4984,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushWithHeaders) { TEST_F(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { // We push a stream and attempt to claim it before the headers come down. SpdySerializedFrame stream1_syn( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame stream2_priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -5023,7 +4996,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdyHeaderBlock initial_headers; initial_headers[":method"] = "GET"; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/foo.dat", &initial_headers); SpdySerializedFrame stream2_syn( spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(initial_headers))); @@ -5034,8 +5007,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { SpdySerializedFrame stream2_headers(spdy_util_.ConstructSpdyResponseHeaders( 2, std::move(late_headers), false)); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(stream1_reply, 1), CreateMockRead(stream2_syn, 2), CreateMockRead(stream1_body, 4), MockRead(ASYNC, ERR_IO_PENDING, 5), @@ -5113,8 +5086,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { } TEST_F(SpdyNetworkTransactionTest, ResponseHeadersTwice) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = { @@ -5145,8 +5117,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseHeadersTwice) { // trigger a ERR_SPDY_PROTOCOL_ERROR because trailing HEADERS must not be // followed by any DATA frames. TEST_F(SpdyNetworkTransactionTest, SyncReplyDataAfterTrailers) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = { @@ -5217,8 +5188,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) { SpdySerializedFrame stream2_syn( spdy_test_util.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); const char kPushedData[] = "pushed"; - SpdySerializedFrame stream2_body(spdy_test_util.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame stream2_body( + spdy_test_util.ConstructSpdyDataFrame(2, kPushedData, true)); SpdySerializedFrame rst( spdy_test_util.ConstructSpdyRstStream(2, ERROR_CODE_CANCEL)); @@ -5301,8 +5272,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) { spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame pushed_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame pushed_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(reply, 1), CreateMockRead(push, 2, SYNCHRONOUS), @@ -5327,10 +5298,11 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) { SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); SpdySessionKey key(host_port_pair_, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> spdy_session = spdy_session_pool->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, log_); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session)); EXPECT_TRUE( @@ -5340,6 +5312,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) { HttpRequestInfo push_request; push_request.method = "GET"; push_request.url = GURL(url_to_push); + push_request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); TestCompletionCallback callback1; rv = trans1.Start(&push_request, callback1.callback(), log_); rv = callback1.GetResult(rv); @@ -5386,7 +5360,7 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { SpdySerializedFrame reply0(spdy_util_0.ConstructSpdyGetReply(nullptr, 0, 1)); const char kData0[] = "first"; SpdySerializedFrame body0( - spdy_util_0.ConstructSpdyDataFrame(1, kData0, strlen(kData0), true)); + spdy_util_0.ConstructSpdyDataFrame(1, kData0, true)); MockRead reads0[] = {CreateMockRead(reply0, 1), CreateMockRead(body0, 2), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)}; @@ -5409,10 +5383,10 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { spdy_util_1.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); const char kData1[] = "second"; SpdySerializedFrame body1( - spdy_util_1.ConstructSpdyDataFrame(1, kData1, strlen(kData1), true)); + spdy_util_1.ConstructSpdyDataFrame(1, kData1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame pushed_body(spdy_util_1.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame pushed_body( + spdy_util_1.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads1[] = { CreateMockRead(reply1, 1), @@ -5459,6 +5433,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { HttpRequestInfo request1; request1.method = "GET"; request1.url = GURL(url_to_fetch1); + request1.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); TestCompletionCallback callback1; rv = trans1.Start(&request1, callback1.callback(), log_); rv = callback1.GetResult(rv); @@ -5467,19 +5443,21 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); HostPortPair host_port_pair0("mail.example.org", 443); SpdySessionKey key0(host_port_pair0, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> spdy_session0 = spdy_session_pool->FindAvailableSession( - key0, /* enable_ip_based_pooling = */ true, log_); + key0, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_EQ(0u, num_unclaimed_pushed_streams(spdy_session0)); HostPortPair host_port_pair1("docs.example.org", 443); SpdySessionKey key1(host_port_pair1, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> spdy_session1 = spdy_session_pool->FindAvailableSession( - key1, /* enable_ip_based_pooling = */ true, log_); + key1, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session1)); EXPECT_TRUE( @@ -5490,6 +5468,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { HttpRequestInfo push_request; push_request.method = "GET"; push_request.url = GURL(url_to_push); + push_request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); TestCompletionCallback callback2; rv = trans2.Start(&push_request, callback2.callback(), log_); rv = callback2.GetResult(rv); @@ -5546,8 +5526,8 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidCrossOrigin) { spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true)); const char kPushedData[] = "pushed"; - SpdySerializedFrame pushed_body(spdy_util_.ConstructSpdyDataFrame( - 2, kPushedData, strlen(kPushedData), true)); + SpdySerializedFrame pushed_body( + spdy_util_.ConstructSpdyDataFrame(2, kPushedData, true)); MockRead reads[] = { CreateMockRead(reply, 1), CreateMockRead(push, 2, SYNCHRONOUS), @@ -5569,12 +5549,10 @@ TEST_F(SpdyNetworkTransactionTest, ServerPushInvalidCrossOrigin) { TEST_F(SpdyNetworkTransactionTest, RetryAfterRefused) { // Construct the request. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); // Will be destroyed by the RST before stream 3 starts. spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(req2, 2), }; @@ -5633,13 +5611,10 @@ TEST_F(SpdyNetworkTransactionTest, OutOfOrderHeaders) { // req1 is alive when req2 is attempted (during but not after the // |data.RunFor(2);| statement below) but not when req3 is attempted. // The call to spdy_util_.UpdateWithStreamDestruction() reflects this. - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, HIGHEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, HIGHEST)); spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req3( - spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM, true)); + SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM)); MockWrite writes[] = { MockWrite(ASYNC, ERR_IO_PENDING, 0), CreateMockWrite(req1, 1), CreateMockWrite(req2, 5), CreateMockWrite(req3, 6), @@ -5733,14 +5708,14 @@ TEST_F(SpdyNetworkTransactionTest, OutOfOrderHeaders) { // fail under specific circumstances. TEST_F(SpdyNetworkTransactionTest, WindowUpdateReceived) { static int kFrameCount = 2; - auto content = std::make_unique<SpdyString>(kMaxSpdyFrameChunkSize, 'a'); + std::string content(kMaxSpdyFrameChunkSize, 'a'); SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( kDefaultUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, nullptr, 0)); - SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame( - 1, content->c_str(), content->size(), false)); - SpdySerializedFrame body_end(spdy_util_.ConstructSpdyDataFrame( - 1, content->c_str(), content->size(), true)); + SpdySerializedFrame body( + spdy_util_.ConstructSpdyDataFrame(1, content, false)); + SpdySerializedFrame body_end( + spdy_util_.ConstructSpdyDataFrame(1, content, true)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(body, 1), @@ -5773,7 +5748,7 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdateReceived) { std::vector<std::unique_ptr<UploadElementReader>> element_readers; for (int i = 0; i < kFrameCount; ++i) { element_readers.push_back(std::make_unique<UploadBytesElementReader>( - content->c_str(), content->size())); + content.data(), content.size())); } ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -5865,8 +5840,7 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdateSent) { std::vector<MockWrite> writes; writes.push_back(CreateMockWrite(combined_frames)); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); writes.push_back(CreateMockWrite(req, writes.size())); std::vector<MockRead> reads; @@ -5877,8 +5851,8 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdateSent) { const SpdyString body_data(kChunkSize, 'x'); for (size_t remaining = kTargetSize; remaining != 0;) { size_t frame_size = std::min(remaining, body_data.size()); - body_frames.push_back(spdy_util_.ConstructSpdyDataFrame(1, body_data.data(), - frame_size, false)); + body_frames.push_back(spdy_util_.ConstructSpdyDataFrame( + 1, base::StringPiece(body_data.data(), frame_size), false)); reads.push_back( CreateMockRead(body_frames.back(), writes.size() + reads.size())); remaining -= frame_size; @@ -5959,12 +5933,12 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) { // set content-length header correctly) static int kFrameCount = 3; - auto content = std::make_unique<SpdyString>(kMaxSpdyFrameChunkSize, 'a'); + std::string content(kMaxSpdyFrameChunkSize, 'a'); SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( kDefaultUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, nullptr, 0)); - SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame( - 1, content->c_str(), content->size(), false)); + SpdySerializedFrame body( + spdy_util_.ConstructSpdyDataFrame(1, content, false)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_FLOW_CONTROL_ERROR)); @@ -5987,7 +5961,7 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) { std::vector<std::unique_ptr<UploadElementReader>> element_readers; for (int i = 0; i < kFrameCount; ++i) { element_readers.push_back(std::make_unique<UploadBytesElementReader>( - content->c_str(), content->size())); + content.data(), content.size())); } ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -6023,8 +5997,7 @@ TEST_F(SpdyNetworkTransactionTest, InitialWindowSizeOverflow) { MockRead reads[] = {CreateMockRead(window_update, 1), CreateMockRead(settings_frame, 2)}; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck()); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( 0, ERROR_CODE_FLOW_CONTROL_ERROR, @@ -6078,17 +6051,21 @@ TEST_F(SpdyNetworkTransactionTest, FlowControlStallResume) { LOWEST, nullptr, 0)); // Full frames. - SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), content.size(), false)); + SpdySerializedFrame body1( + spdy_util_.ConstructSpdyDataFrame(1, content, false)); // Last frame in each upload data buffer. SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false)); + 1, + base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize), + false)); // The very last frame before the stalled frames. SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), - initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false)); + 1, + base::StringPiece(content.data(), initial_window_size % kBufferSize % + kMaxSpdyFrameChunkSize), + false)); // Data frames to be sent once WINDOW_UPDATE frame is received. @@ -6096,8 +6073,8 @@ TEST_F(SpdyNetworkTransactionTest, FlowControlStallResume) { // we need one additional frame to send the rest of 'a'. SpdyString last_body(kBufferSize * num_upload_buffers - initial_window_size, 'a'); - SpdySerializedFrame body4(spdy_util_.ConstructSpdyDataFrame( - 1, last_body.c_str(), last_body.size(), false)); + SpdySerializedFrame body4( + spdy_util_.ConstructSpdyDataFrame(1, last_body, false)); // Also send a "hello!" after WINDOW_UPDATE. SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true)); @@ -6225,17 +6202,21 @@ TEST_F(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { LOWEST, nullptr, 0)); // Full frames. - SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), content.size(), false)); + SpdySerializedFrame body1( + spdy_util_.ConstructSpdyDataFrame(1, content, false)); // Last frame in each upload data buffer. SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false)); + 1, + base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize), + false)); // The very last frame before the stalled frames. SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), - initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false)); + 1, + base::StringPiece(content.data(), initial_window_size % kBufferSize % + kMaxSpdyFrameChunkSize), + false)); // Data frames to be sent once WINDOW_UPDATE frame is received. @@ -6243,8 +6224,8 @@ TEST_F(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { // we need one additional frame to send the rest of 'a'. SpdyString last_body(kBufferSize * num_upload_buffers - initial_window_size, 'a'); - SpdySerializedFrame body4(spdy_util_.ConstructSpdyDataFrame( - 1, last_body.c_str(), last_body.size(), false)); + SpdySerializedFrame body4( + spdy_util_.ConstructSpdyDataFrame(1, last_body, false)); // Also send a "hello!" after WINDOW_UPDATE. SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true)); @@ -6384,17 +6365,21 @@ TEST_F(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { LOWEST, nullptr, 0)); // Full frames. - SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), content.size(), false)); + SpdySerializedFrame body1( + spdy_util_.ConstructSpdyDataFrame(1, content, false)); // Last frame in each upload data buffer. SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false)); + 1, + base::StringPiece(content.data(), kBufferSize % kMaxSpdyFrameChunkSize), + false)); // The very last frame before the stalled frames. SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame( - 1, content.c_str(), - initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false)); + 1, + base::StringPiece(content.data(), initial_window_size % kBufferSize % + kMaxSpdyFrameChunkSize), + false)); // Data frames to be sent once WINDOW_UPDATE frame is received. @@ -6402,8 +6387,8 @@ TEST_F(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { // we need one additional frame to send the rest of 'a'. SpdyString last_body(kBufferSize * num_upload_buffers - initial_window_size, 'a'); - SpdySerializedFrame body4(spdy_util_.ConstructSpdyDataFrame( - 1, last_body.c_str(), last_body.size(), false)); + SpdySerializedFrame body4( + spdy_util_.ConstructSpdyDataFrame(1, last_body, false)); // Also send a "hello!" after WINDOW_UPDATE. SpdySerializedFrame body5(spdy_util_.ConstructSpdyDataFrame(1, true)); @@ -6522,8 +6507,7 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) { spdy_util_.ConstructSpdyPushPromise(1, 3, std::move(push_headers))); MockRead reads[] = {CreateMockRead(push, 1)}; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( 0, ERROR_CODE_PROTOCOL_ERROR, "Received invalid pushed stream id 3 (must be even) on stream id 1.")); @@ -6541,9 +6525,9 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) { TEST_F(SpdyNetworkTransactionTest, GoAwayOnPushStreamIdLesserOrEqualThanLastAccepted) { SpdySerializedFrame push_a(spdy_util_.ConstructSpdyPush( - nullptr, 0, 4, 1, GetDefaultUrlWithPath("/a.dat").c_str())); + nullptr, 0, 4, 1, "https://www.example.org/a.dat")); SpdyHeaderBlock push_b_headers; - spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/b.dat"), + spdy_util_.AddUrlToHeaderBlock("https://www.example.org/b.dat", &push_b_headers); SpdySerializedFrame push_b( spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_b_headers))); @@ -6551,8 +6535,7 @@ TEST_F(SpdyNetworkTransactionTest, CreateMockRead(push_a, 1), CreateMockRead(push_b, 3), }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority_a( spdy_util_.ConstructSpdyPriority(4, 1, IDLE, true)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( @@ -6641,8 +6624,7 @@ TEST_F(SpdyNetworkTransactionTest, LargeResponseHeader) { // End of line delimiter is forbidden according to RFC 7230 Section 3.2. TEST_F(SpdyNetworkTransactionTest, CRLFInHeaderValue) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_PROTOCOL_ERROR)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 2)}; @@ -6704,8 +6686,7 @@ TEST_F(SpdyNetworkTransactionTest, RstStreamNoErrorAfterResponse) { } TEST_F(SpdyNetworkTransactionTest, 100Continue) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdyHeaderBlock informational_headers; @@ -6785,8 +6766,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseAndRstStreamBeforePostDataSent) { // but is going to be used for the ORIGIN frame. // TODO(bnc): Implement ORIGIN frame support. https://crbug.com/697333 TEST_F(SpdyNetworkTransactionTest, IgnoreUnsupportedOriginFrame) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = {CreateMockWrite(req, 0)}; const char origin_frame_on_stream_zero[] = { @@ -6878,7 +6858,7 @@ TEST_F(SpdyNetworkTransactionTest, InsecureUrlCreatesSecureSpdySession) { // Need secure proxy so that insecure URL can use HTTP/2. auto session_deps = std::make_unique<SpdySessionDependencies>( - ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")); + ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70")); NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, std::move(session_deps)); @@ -6889,7 +6869,7 @@ TEST_F(SpdyNetworkTransactionTest, InsecureUrlCreatesSecureSpdySession) { TEST_F(SpdyNetworkTransactionTest, RequestHeadersCallback) { SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY)); MockWrite writes[] = {CreateMockWrite(req, 0)}; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -6924,8 +6904,7 @@ TEST_F(SpdyNetworkTransactionTest, RequestHeadersCallback) { TEST_F(SpdyNetworkTransactionTest, PushCanceledByServerAfterClaimed) { const char pushed_url[] = "https://www.example.org/a.dat"; // Construct a request to the default URL on stream 1. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(pushed_url, 3, LOWEST)); // Construct a priority frame for stream 2. SpdySerializedFrame priority( @@ -6969,11 +6948,12 @@ TEST_F(SpdyNetworkTransactionTest, PushCanceledByServerAfterClaimed) { // Get a SpdySession. SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); HttpNetworkSession* session = helper.session(); base::WeakPtr<SpdySession> spdy_session = session->spdy_session_pool()->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, log_); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); // Verify that there is one unclaimed push stream. EXPECT_EQ(1u, num_unclaimed_pushed_streams(spdy_session)); @@ -6984,6 +6964,8 @@ TEST_F(SpdyNetworkTransactionTest, PushCanceledByServerAfterClaimed) { HttpRequestInfo request2; request2.method = "GET"; request2.url = GURL(pushed_url); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); transaction2.Start(&request2, callback2.callback(), log_); base::RunLoop().RunUntilIdle(); EXPECT_EQ(3u, spdy_stream_hi_water_mark(spdy_session)); @@ -7015,4 +6997,271 @@ TEST_F(SpdyNetworkTransactionTest, PushCanceledByServerAfterClaimed) { helper.VerifyDataConsumed(); } +#if BUILDFLAG(ENABLE_WEBSOCKETS) + +TEST_F(SpdyNetworkTransactionTest, WebSocketOpensNewConnection) { + NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr); + helper.RunPreTestSetup(); + + // First request opens up an HTTP/2 connection. + SpdySerializedFrame req( + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY)); + MockWrite writes1[] = {CreateMockWrite(req, 0)}; + + SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true)); + MockRead reads1[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2), + MockRead(ASYNC, ERR_IO_PENDING, 3), + MockRead(ASYNC, 0, 4)}; + + SequencedSocketData data1(reads1, arraysize(reads1), writes1, + arraysize(writes1)); + helper.AddData(&data1); + + // WebSocket request opens a new connection with HTTP/2 disabled. + MockWrite writes2[] = { + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Origin: http://www.example.org\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Extensions: permessage-deflate; " + "client_max_window_bits\r\n\r\n")}; + + MockRead reads2[] = { + MockRead("HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")}; + + StaticSocketDataProvider data2(reads2, arraysize(reads2), writes2, + arraysize(writes2)); + + auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); + // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. + ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Force socket to use HTTP/1.1, the default protocol without ALPN. + ssl_provider2->next_proto = kProtoHTTP11; + ssl_provider2->ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); + helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2)); + + TestCompletionCallback callback1; + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + int rv = trans1.Start(&request_, callback1.callback(), log_); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + rv = callback1.WaitForResult(); + ASSERT_THAT(rv, IsOk()); + + const HttpResponseInfo* response = trans1.GetResponseInfo(); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); + + std::string response_data; + rv = ReadTransaction(&trans1, &response_data); + EXPECT_THAT(rv, IsOk()); + EXPECT_EQ("hello!", response_data); + + SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); + base::WeakPtr<SpdySession> spdy_session = + helper.session()->spdy_session_pool()->FindAvailableSession( + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); + ASSERT_TRUE(spdy_session); + EXPECT_FALSE(spdy_session->support_websocket()); + + HttpRequestInfo request2; + request2.method = "GET"; + request2.url = GURL("wss://www.example.org/"); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_TRUE(HostPortPair::FromURL(request_.url) + .Equals(HostPortPair::FromURL(request2.url))); + request2.extra_headers.SetHeader("Connection", "Upgrade"); + request2.extra_headers.SetHeader("Upgrade", "websocket"); + request2.extra_headers.SetHeader("Origin", "http://www.example.org"); + request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13"); + + TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper; + + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + trans2.SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + TestCompletionCallback callback2; + rv = trans2.Start(&request2, callback2.callback(), log_); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + rv = callback2.WaitForResult(); + ASSERT_THAT(rv, IsOk()); + + // HTTP/2 connection is still open, but WebSocket request did not pool to it. + ASSERT_TRUE(spdy_session); + + base::RunLoop().RunUntilIdle(); + data1.Resume(); + helper.VerifyDataConsumed(); +} + +TEST_F(SpdyNetworkTransactionTest, WebSocketOverHTTP2) { + auto session_deps = std::make_unique<SpdySessionDependencies>(); + session_deps->enable_websocket_over_http2 = true; + NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, + std::move(session_deps)); + helper.RunPreTestSetup(); + + SpdySerializedFrame req( + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY)); + SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck()); + + SpdyHeaderBlock websocket_request_headers; + websocket_request_headers[kHttp2MethodHeader] = "CONNECT"; + websocket_request_headers[kHttp2AuthorityHeader] = "www.example.org:443"; + websocket_request_headers[kHttp2SchemeHeader] = "https"; + websocket_request_headers[kHttp2PathHeader] = "/"; + websocket_request_headers[kHttp2ProtocolHeader] = "websocket"; + websocket_request_headers["origin"] = "http://www.example.org"; + websocket_request_headers["sec-websocket-version"] = "13"; + websocket_request_headers["sec-websocket-extensions"] = + "permessage-deflate; client_max_window_bits"; + + spdy_util_.UpdateWithStreamDestruction(1); + SpdySerializedFrame websocket_request(spdy_util_.ConstructSpdyHeaders( + 3, std::move(websocket_request_headers), DEFAULT_PRIORITY, false)); + + MockWrite writes[] = { + CreateMockWrite(req, 0), CreateMockWrite(settings_ack, 2), + CreateMockWrite(websocket_request, 5), + }; + + SettingsMap settings; + settings[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1; + SpdySerializedFrame settings_frame( + spdy_util_.ConstructSpdySettings(settings)); + SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true)); + SpdySerializedFrame websocket_response( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); + MockRead reads[] = { + CreateMockRead(settings_frame, 1), + CreateMockRead(resp1, 3), + CreateMockRead(body1, 4), + CreateMockRead(websocket_response, 6), + MockRead(ASYNC, 0, 7), + }; + + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + helper.AddData(&data); + + TestCompletionCallback callback1; + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + int rv = trans1.Start(&request_, callback1.callback(), log_); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + rv = callback1.WaitForResult(); + ASSERT_THAT(rv, IsOk()); + + const HttpResponseInfo* response = trans1.GetResponseInfo(); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); + + std::string response_data; + rv = ReadTransaction(&trans1, &response_data); + EXPECT_THAT(rv, IsOk()); + EXPECT_EQ("hello!", response_data); + + SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); + base::WeakPtr<SpdySession> spdy_session = + helper.session()->spdy_session_pool()->FindAvailableSession( + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ true, log_); + ASSERT_TRUE(spdy_session); + EXPECT_TRUE(spdy_session->support_websocket()); + + HttpRequestInfo request2; + request2.method = "GET"; + request2.url = GURL("wss://www.example.org/"); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_TRUE(HostPortPair::FromURL(request_.url) + .Equals(HostPortPair::FromURL(request2.url))); + request2.extra_headers.SetHeader("Origin", "http://www.example.org"); + request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13"); + // The following two headers must be removed by WebSocketHttp2HandshakeStream. + request2.extra_headers.SetHeader("Connection", "Upgrade"); + request2.extra_headers.SetHeader("Upgrade", "websocket"); + + TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper; + + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + trans2.SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + TestCompletionCallback callback2; + rv = trans2.Start(&request2, callback2.callback(), log_); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + rv = callback2.WaitForResult(); + ASSERT_THAT(rv, IsOk()); + + ASSERT_TRUE(spdy_session); + + base::RunLoop().RunUntilIdle(); + helper.VerifyDataConsumed(); +} + +// Regression test for https://crbug.com/819101. Open two identical plaintext +// websocket requests over proxy. The HttpStreamFactoryImpl::Job for the second +// request should reuse the first connection. +TEST_F(SpdyNetworkTransactionTest, TwoWebSocketRequestsOverHttp2Proxy) { + SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect( + nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 80))); + MockWrite writes[] = {CreateMockWrite(req, 0)}; + + SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + MockRead reads[] = {CreateMockRead(resp, 1), + MockRead(ASYNC, ERR_IO_PENDING, 2), + MockRead(ASYNC, 0, 3)}; + + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + + request_.url = GURL("ws://www.example.org/"); + auto session_deps = std::make_unique<SpdySessionDependencies>( + ProxyResolutionService::CreateFixed("https://proxy:70")); + NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, + std::move(session_deps)); + helper.RunPreTestSetup(); + helper.AddData(&data); + + HttpNetworkTransaction* trans1 = helper.trans(); + TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper; + trans1->SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + EXPECT_TRUE(helper.StartDefaultTest()); + helper.WaitForCallbackToComplete(); + EXPECT_THAT(helper.output().rv, IsError(ERR_NOT_IMPLEMENTED)); + + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + trans2.SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + TestCompletionCallback callback2; + int rv = trans2.Start(&request_, callback2.callback(), log_); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + + rv = callback2.WaitForResult(); + EXPECT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED)); + + data.Resume(); + base::RunLoop().RunUntilIdle(); + + helper.VerifyDataConsumed(); +} + +#endif // BUILDFLAG(ENABLE_WEBSOCKETS) + } // namespace net diff --git a/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc b/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc index e23640ca3f3..6e2288cc7cc 100644 --- a/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc +++ b/chromium/net/spdy/chromium/spdy_proxy_client_socket.cc @@ -77,7 +77,7 @@ SpdyProxyClientSocket::GetAuthController() const { return auth_; } -int SpdyProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { +int SpdyProxyClientSocket::RestartWithAuth(CompletionOnceCallback callback) { // A SPDY Stream can only handle a single request, so the underlying // stream may not be reused and a new SpdyProxyClientSocket must be // created (possibly on top of the same SPDY Session). @@ -119,7 +119,7 @@ int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { int rv = DoLoop(OK); if (rv == ERR_IO_PENDING) - read_callback_ = callback; + read_callback_ = std::move(callback); return rv; } @@ -195,7 +195,8 @@ void SpdyProxyClientSocket::ApplySocketTag(const SocketTag& tag) { CHECK(false); } -int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len, +int SpdyProxyClientSocket::Read(IOBuffer* buf, + int buf_len, const CompletionCallback& callback) { DCHECK(read_callback_.is_null()); DCHECK(!user_buffer_.get()); @@ -273,18 +274,16 @@ void SpdyProxyClientSocket::LogBlockedTunnelResponse() const { /* is_https_proxy = */ true); } -void SpdyProxyClientSocket::RunCallback(const CompletionCallback& callback, +void SpdyProxyClientSocket::RunCallback(CompletionOnceCallback callback, int result) const { - callback.Run(result); + std::move(callback).Run(result); } void SpdyProxyClientSocket::OnIOComplete(int result) { DCHECK_NE(STATE_DISCONNECTED, next_state_); int rv = DoLoop(result); if (rv != ERR_IO_PENDING) { - CompletionCallback c = read_callback_; - read_callback_.Reset(); - c.Run(rv); + base::ResetAndReturn(&read_callback_).Run(rv); } } @@ -369,8 +368,7 @@ int SpdyProxyClientSocket::DoSendRequest() { base::Unretained(&request_.extra_headers), &request_line)); SpdyHeaderBlock headers; - CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, true, - &headers); + CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, &headers); return spdy_stream_->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND); @@ -475,11 +473,9 @@ void SpdyProxyClientSocket::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { if (!read_callback_.is_null()) { int rv = PopulateUserReadBuffer(user_buffer_->data(), user_buffer_len_); - CompletionCallback c = read_callback_; - read_callback_.Reset(); user_buffer_ = NULL; user_buffer_len_ = 0; - c.Run(rv); + base::ResetAndReturn(&read_callback_).Run(rv); } } @@ -492,9 +488,9 @@ void SpdyProxyClientSocket::OnDataSent() { // Proxy write callbacks result in deep callback chains. Post to allow the // stream's write callback chain to unwind (see crbug.com/355511). base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SpdyProxyClientSocket::RunCallback, - write_callback_weak_factory_.GetWeakPtr(), - base::ResetAndReturn(&write_callback_), rv)); + FROM_HERE, base::BindOnce(&SpdyProxyClientSocket::RunCallback, + write_callback_weak_factory_.GetWeakPtr(), + base::ResetAndReturn(&write_callback_), rv)); } void SpdyProxyClientSocket::OnTrailers(const SpdyHeaderBlock& trailers) { @@ -515,7 +511,7 @@ void SpdyProxyClientSocket::OnClose(int status) { next_state_ = STATE_DISCONNECTED; base::WeakPtr<SpdyProxyClientSocket> weak_ptr = weak_factory_.GetWeakPtr(); - CompletionCallback write_callback = write_callback_; + CompletionOnceCallback write_callback = std::move(write_callback_); write_callback_.Reset(); write_buffer_len_ = 0; @@ -523,16 +519,14 @@ void SpdyProxyClientSocket::OnClose(int status) { // we invoke the connect callback. if (connecting) { DCHECK(!read_callback_.is_null()); - CompletionCallback read_callback = read_callback_; - read_callback_.Reset(); - read_callback.Run(status); + base::ResetAndReturn(&read_callback_).Run(status); } else if (!read_callback_.is_null()) { // If we have a read_callback_, the we need to make sure we call it back. OnDataReceived(std::unique_ptr<SpdyBuffer>()); } // This may have been deleted by read_callback_, so check first. if (weak_ptr.get() && !write_callback.is_null()) - write_callback.Run(ERR_CONNECTION_CLOSED); + std::move(write_callback).Run(ERR_CONNECTION_CLOSED); } NetLogSource SpdyProxyClientSocket::source_dependency() const { diff --git a/chromium/net/spdy/chromium/spdy_proxy_client_socket.h b/chromium/net/spdy/chromium/spdy_proxy_client_socket.h index d95589dc7a2..e24683a7c8e 100644 --- a/chromium/net/spdy/chromium/spdy_proxy_client_socket.h +++ b/chromium/net/spdy/chromium/spdy_proxy_client_socket.h @@ -15,6 +15,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "net/base/completion_callback.h" +#include "net/base/completion_once_callback.h" #include "net/base/host_port_pair.h" #include "net/base/load_timing_info.h" #include "net/base/net_export.h" @@ -59,7 +60,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, const HttpResponseInfo* GetConnectResponseInfo() const override; std::unique_ptr<HttpStream> CreateConnectResponseStream() override; const scoped_refptr<HttpAuthController>& GetAuthController() const override; - int RestartWithAuth(const CompletionCallback& callback) override; + int RestartWithAuth(CompletionOnceCallback callback) override; bool IsUsingSpdy() const override; NextProto GetProxyNegotiatedProtocol() const override; @@ -119,7 +120,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, // Calls |callback.Run(result)|. Used to run a callback posted to the // message loop. - void RunCallback(const CompletionCallback& callback, int result) const; + void RunCallback(CompletionOnceCallback callback, int result) const; void OnIOComplete(int result); @@ -141,9 +142,9 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, // Stores the callback to the layer above, called on completing Read() or // Connect(). - CompletionCallback read_callback_; + CompletionOnceCallback read_callback_; // Stores the callback to the layer above, called on completing Write(). - CompletionCallback write_callback_; + CompletionOnceCallback write_callback_; // CONNECT request and response. HttpRequestInfo request_; diff --git a/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc b/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc index e8eccf49e0e..4da373aac53 100644 --- a/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc @@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" #include "net/base/address_list.h" #include "net/base/test_completion_callback.h" @@ -23,6 +24,7 @@ #include "net/log/test_net_log_entry.h" #include "net/log/test_net_log_util.h" #include "net/socket/client_socket_factory.h" +#include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" #include "net/socket/tcp_client_socket.h" #include "net/spdy/chromium/buffered_spdy_framer.h" @@ -159,7 +161,8 @@ SpdyProxyClientSocketTest::SpdyProxyClientSocketTest() proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_), endpoint_spdy_session_key_(endpoint_host_port_pair_, proxy_, - PRIVACY_MODE_DISABLED) { + PRIVACY_MODE_DISABLED, + SocketTag()) { session_deps_.net_log = net_log_.bound().net_log(); } @@ -364,7 +367,8 @@ SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() { SpdySerializedFrame SpdyProxyClientSocketTest::ConstructBodyFrame( const char* data, int length) { - return spdy_util_.ConstructSpdyDataFrame(kStreamId, data, length, + return spdy_util_.ConstructSpdyDataFrame(kStreamId, + base::StringPiece(data, length), /*fin=*/false); } diff --git a/chromium/net/spdy/chromium/spdy_read_queue_unittest.cc b/chromium/net/spdy/chromium/spdy_read_queue_unittest.cc index dd84f5aea30..7d6a91cb45d 100644 --- a/chromium/net/spdy/chromium/spdy_read_queue_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_read_queue_unittest.cc @@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/callback.h" #include "base/stl_util.h" #include "net/spdy/chromium/spdy_buffer.h" #include "net/spdy/platform/api/spdy_string.h" diff --git a/chromium/net/spdy/chromium/spdy_session.cc b/chromium/net/spdy/chromium/spdy_session.cc index 682dde85439..588ba6f56af 100644 --- a/chromium/net/spdy/chromium/spdy_session.cc +++ b/chromium/net/spdy/chromium/spdy_session.cc @@ -27,7 +27,6 @@ #include "base/values.h" #include "crypto/ec_private_key.h" #include "crypto/ec_signature_creator.h" -#include "net/base/proxy_delegate.h" #include "net/cert/asn1_util.h" #include "net/cert/cert_verify_result.h" #include "net/cert/ct_policy_status.h" @@ -40,8 +39,8 @@ #include "net/log/net_log_event_type.h" #include "net/log/net_log_source_type.h" #include "net/log/net_log_with_source.h" -#include "net/proxy/proxy_server.h" #include "net/quic/chromium/quic_http_utils.h" +#include "net/quic/core/spdy_utils.h" #include "net/socket/socket.h" #include "net/socket/ssl_client_socket.h" #include "net/spdy/chromium/header_coalescer.h" @@ -53,6 +52,7 @@ #include "net/spdy/core/spdy_frame_builder.h" #include "net/spdy/core/spdy_protocol.h" #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" +#include "net/spdy/platform/api/spdy_string.h" #include "net/spdy/platform/api/spdy_string_utils.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/ssl_cipher_suite_names.h" @@ -63,6 +63,28 @@ namespace net { namespace { +constexpr net::NetworkTrafficAnnotationTag + kSpdySessionCommandsTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("spdy_session_control", R"( + semantics { + sender: "Spdy Session" + description: + "Sends commands to control an HTTP/2 session." + trigger: + "Required control commands like initiating stream, requesting " + "stream reset, changing priorities, etc." + data: "No user data." + destination: OTHER + destination_other: + "Any destination the HTTP/2 session is connected to." + } + policy { + cookies_allowed: NO + setting: "This feature cannot be disabled in settings." + policy_exception_justification: "Essential for network access." + } + )"); + const int kReadBufferSize = 8 * 1024; const int kDefaultConnectionAtRiskOfLossSeconds = 10; const int kHungIntervalSeconds = 10; @@ -111,12 +133,12 @@ enum PushedStreamVaryResponseHeaderValues ParseVaryInPushedResponse( SpdyHeaderBlock::iterator it = headers.find(kVary); if (it == headers.end()) return kNoVaryHeader; - base::StringPiece value(it->second); + SpdyStringPiece value(it->second); if (value.empty()) return kVaryIsEmpty; if (value == kStar) return kVaryIsStar; - std::string lowercase_value = ToLowerASCII(value); + SpdyString lowercase_value = ToLowerASCII(value); if (lowercase_value == kAcceptEncoding) return kVaryIsAcceptEncoding; // Both comma and newline delimiters occur in the wild. @@ -130,7 +152,7 @@ enum PushedStreamVaryResponseHeaderValues ParseVaryInPushedResponse( return kVaryHasNoAcceptEncoding; } -bool IsSpdySettingAtDefaultInitialValue(SpdySettingsIds setting_id, +bool IsSpdySettingAtDefaultInitialValue(SpdyKnownSettingsId setting_id, uint32_t value) { switch (setting_id) { case SETTINGS_HEADER_TABLE_SIZE: @@ -147,6 +169,8 @@ bool IsSpdySettingAtDefaultInitialValue(SpdySettingsIds setting_id, case SETTINGS_MAX_HEADER_LIST_SIZE: // There is no initial limit on the size of the header list. return false; + case SETTINGS_ENABLE_CONNECT_PROTOCOL: + return value == 0; default: // Undefined parameters have no initial value. return false; @@ -228,25 +252,22 @@ std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback( auto settings_list = std::make_unique<base::ListValue>(); for (SettingsMap::const_iterator it = settings->begin(); it != settings->end(); ++it) { - const SpdySettingsIds id = it->first; + const SpdyKnownSettingsId id = it->first; const uint32_t value = it->second; - const char* settings_string; - SettingsIdToString(id, &settings_string); - settings_list->AppendString( - SpdyStringPrintf("[id:%u (%s) value:%u]", id, settings_string, value)); + settings_list->AppendString(SpdyStringPrintf( + "[id:%u (%s) value:%u]", id, SettingsIdToString(id).c_str(), value)); } dict->Set("settings", std::move(settings_list)); return std::move(dict); } std::unique_ptr<base::Value> NetLogSpdyRecvSettingCallback( - SpdySettingsIds id, + SpdyKnownSettingsId id, uint32_t value, NetLogCaptureMode /* capture_mode */) { auto dict = std::make_unique<base::DictionaryValue>(); - const char* settings_string; - SettingsIdToString(id, &settings_string); - dict->SetString("id", SpdyStringPrintf("%u (%s)", id, settings_string)); + dict->SetString( + "id", SpdyStringPrintf("%u (%s)", id, SettingsIdToString(id).c_str())); dict->SetInteger("value", value); return std::move(dict); } @@ -592,12 +613,15 @@ SpdyStreamRequest::~SpdyStreamRequest() { CancelRequest(); } -int SpdyStreamRequest::StartRequest(SpdyStreamType type, - const base::WeakPtr<SpdySession>& session, - const GURL& url, - RequestPriority priority, - const NetLogWithSource& net_log, - const CompletionCallback& callback) { +int SpdyStreamRequest::StartRequest( + SpdyStreamType type, + const base::WeakPtr<SpdySession>& session, + const GURL& url, + RequestPriority priority, + const SocketTag& socket_tag, + const NetLogWithSource& net_log, + CompletionOnceCallback callback, + const NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(session); DCHECK(!session_); DCHECK(!stream_); @@ -607,8 +631,10 @@ int SpdyStreamRequest::StartRequest(SpdyStreamType type, session_ = session; url_ = url; priority_ = priority; + socket_tag_ = socket_tag; net_log_ = net_log; - callback_ = callback; + callback_ = std::move(callback); + traffic_annotation_ = MutableNetworkTrafficAnnotationTag(traffic_annotation); base::WeakPtr<SpdyStream> stream; int rv = session->TryCreateStream(weak_ptr_factory_.GetWeakPtr(), &stream); @@ -644,21 +670,21 @@ void SpdyStreamRequest::OnRequestCompleteSuccess( DCHECK(session_); DCHECK(!stream_); DCHECK(!callback_.is_null()); - CompletionCallback callback = callback_; + CompletionOnceCallback callback = std::move(callback_); Reset(); DCHECK(stream); stream_ = stream; - callback.Run(OK); + std::move(callback).Run(OK); } void SpdyStreamRequest::OnRequestCompleteFailure(int rv) { DCHECK(session_); DCHECK(!stream_); DCHECK(!callback_.is_null()); - CompletionCallback callback = callback_; + CompletionOnceCallback callback = std::move(callback_); Reset(); DCHECK_NE(rv, OK); - callback.Run(rv); + std::move(callback).Run(rv); } void SpdyStreamRequest::Reset() { @@ -667,8 +693,10 @@ void SpdyStreamRequest::Reset() { stream_.reset(); url_ = GURL(); priority_ = MINIMUM_PRIORITY; + socket_tag_ = SocketTag(); net_log_ = NetLogWithSource(); callback_.Reset(); + traffic_annotation_.reset(); } // static @@ -691,7 +719,7 @@ bool SpdySession::CanPool(TransportSecurityState* transport_security_state, return false; } - if (!ssl_info.cert->VerifyNameMatch(new_hostname, false)) + if (!ssl_info.cert->VerifyNameMatch(new_hostname)) return false; SpdyString pinning_failure_log; @@ -734,11 +762,11 @@ SpdySession::SpdySession( bool enable_sending_initial_data, bool enable_ping_based_connection_checking, bool support_ietf_format_quic_altsvc, + bool is_trusted_proxy, size_t session_max_recv_window_size, const SettingsMap& initial_settings, TimeFunc time_func, ServerPushDelegate* push_delegate, - ProxyDelegate* proxy_delegate, NetLog* net_log) : in_io_loop_(false), spdy_session_key_(spdy_session_key), @@ -786,10 +814,11 @@ SpdySession::SpdySession( enable_ping_based_connection_checking_( enable_ping_based_connection_checking), support_ietf_format_quic_altsvc_(support_ietf_format_quic_altsvc), + is_trusted_proxy_(is_trusted_proxy), + support_websocket_(false), connection_at_risk_of_loss_time_( base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)), - proxy_delegate_(proxy_delegate), time_func_(time_func), weak_factory_(this) { net_log_.BeginEvent( @@ -863,9 +892,7 @@ int SpdySession::GetPushedStream(const GURL& url, for (auto u : updates) { ActiveStreamMap::iterator it = active_streams_.find(u.id); DCHECK(it != active_streams_.end()); - int weight = Spdy3PriorityToHttp2Weight( - ConvertRequestPriorityToSpdyPriority(it->second->priority())); - EnqueuePriorityFrame(u.id, u.dependent_stream_id, weight, u.exclusive); + EnqueuePriorityFrame(u.id, u.parent_stream_id, u.weight, u.exclusive); } return OK; @@ -944,7 +971,8 @@ void SpdySession::EnqueueStreamWrite( std::unique_ptr<SpdyBufferProducer> producer) { DCHECK(frame_type == SpdyFrameType::HEADERS || frame_type == SpdyFrameType::DATA); - EnqueueWrite(stream->priority(), frame_type, std::move(producer), stream); + EnqueueWrite(stream->priority(), frame_type, std::move(producer), stream, + stream->traffic_annotation()); } std::unique_ptr<SpdySerializedFrame> SpdySession::CreateHeaders( @@ -963,25 +991,25 @@ std::unique_ptr<SpdySerializedFrame> SpdySession::CreateHeaders( SpdyPriority spdy_priority = ConvertRequestPriorityToSpdyPriority(priority); bool has_priority = true; - int weight = Spdy3PriorityToHttp2Weight(spdy_priority); - SpdyStreamId dependent_stream_id = 0; + int weight = 0; + SpdyStreamId parent_stream_id = 0; bool exclusive = false; - priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority, - &dependent_stream_id, &exclusive); + priority_dependency_state_.OnStreamCreation( + stream_id, spdy_priority, &parent_stream_id, &weight, &exclusive); if (net_log().IsCapturing()) { net_log().AddEvent( NetLogEventType::HTTP2_SESSION_SEND_HEADERS, base::Bind(&NetLogSpdyHeadersSentCallback, &block, (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority, - weight, dependent_stream_id, exclusive, source_dependency)); + weight, parent_stream_id, exclusive, source_dependency)); } SpdyHeadersIR headers(stream_id, std::move(block)); headers.set_has_priority(has_priority); headers.set_weight(weight); - headers.set_parent_stream_id(dependent_stream_id); + headers.set_parent_stream_id(parent_stream_id); headers.set_exclusive(exclusive); headers.set_fin((flags & CONTROL_FLAG_FIN) != 0); @@ -1422,6 +1450,25 @@ size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats, SpdyEstimateMemoryUsage(priority_dependency_state_); } +bool SpdySession::ChangeSocketTag(const SocketTag& new_tag) { + if (!IsAvailable() || !connection_->socket()) + return false; + + // Changing the tag on the underlying socket will affect all streams, + // so only allow changing the tag when there are no active streams. + if (is_active()) + return false; + + connection_->socket()->ApplySocketTag(new_tag); + + SpdySessionKey new_key(spdy_session_key_.host_port_pair(), + spdy_session_key_.proxy_server(), + spdy_session_key_.privacy_mode(), new_tag); + spdy_session_key_ = new_key; + + return true; +} + // {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is // being created in response to another being closed due to received data. @@ -1436,6 +1483,10 @@ int SpdySession::TryCreateStream( if (availability_state_ == STATE_DRAINING) return ERR_CONNECTION_CLOSED; + // Fail if ChangeSocketTag() has been called. + if (request->socket_tag_ != spdy_session_key_.socket_tag()) + return ERR_FAILED; + if ((active_streams_.size() + created_streams_.size() - num_pushed_streams_ < max_concurrent_streams_)) { return CreateStream(*request, stream); @@ -1479,7 +1530,7 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request, auto new_stream = std::make_unique<SpdyStream>( request.type(), GetWeakPtr(), request.url(), request.priority(), stream_initial_send_window_size_, stream_max_recv_window_size_, - request.net_log()); + request.net_log(), request.traffic_annotation()); *stream = new_stream->GetWeakPtr(); InsertCreatedStream(std::move(new_stream)); @@ -1604,12 +1655,22 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, streams_pushed_count_++; + // "Promised requests MUST be cacheable and MUST be safe [...]" (RFC7540 + // Section 8.2). Only cacheable safe request methods are GET and HEAD. + SpdyHeaderBlock::const_iterator it = headers.find(kHttp2MethodHeader); + if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) { + EnqueueResetStreamFrame(stream_id, request_priority, + ERROR_CODE_REFUSED_STREAM, + "Inadequate request method."); + return; + } + // Verify that the response had a URL for us. - GURL gurl = GetUrlFromHeaderBlock(headers); + GURL gurl(SpdyUtils::GetPromisedUrlFromHeaders(headers)); if (!gurl.is_valid()) { - EnqueueResetStreamFrame( - stream_id, request_priority, ERROR_CODE_REFUSED_STREAM, - "Pushed stream url was invalid: " + gurl.possibly_invalid_spec()); + EnqueueResetStreamFrame(stream_id, request_priority, + ERROR_CODE_REFUSED_STREAM, + "Invalid pushed request headers."); return; } @@ -1634,9 +1695,7 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, // Cross-origin push validation. GURL associated_url(associated_it->second->GetUrlFromHeaders()); if (associated_url.GetOrigin() != gurl.GetOrigin()) { - if (proxy_delegate_ && - proxy_delegate_->IsTrustedSpdyProxy( - ProxyServer(ProxyServer::SCHEME_HTTPS, host_port_pair()))) { + if (is_trusted_proxy_) { if (!gurl.SchemeIs(url::kHttpScheme)) { EnqueueResetStreamFrame( stream_id, request_priority, ERROR_CODE_REFUSED_STREAM, @@ -1663,16 +1722,6 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, } } - // "Promised requests MUST be cacheable and MUST be safe [...]" (RFC7540 - // Section 8.2). Only cacheable safe request methods are GET and HEAD. - SpdyHeaderBlock::const_iterator it = headers.find(kHttp2MethodHeader); - if (it == headers.end() || (it->second != "GET" && it->second != "HEAD")) { - EnqueueResetStreamFrame(stream_id, request_priority, - ERROR_CODE_REFUSED_STREAM, - "Inadequate request method."); - return; - } - // Insertion fails if there already is a pushed stream with the same path. if (!pool_->push_promise_index()->RegisterUnclaimedPushedStream( gurl, stream_id, this)) { @@ -1688,20 +1737,22 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, stream_id), base::TimeDelta::FromSeconds(kPushedStreamLifetimeSeconds)); + // TODO(https://crbug.com/656607): Add proper annotation here. auto stream = std::make_unique<SpdyStream>( SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, - stream_initial_send_window_size_, stream_max_recv_window_size_, net_log_); + stream_initial_send_window_size_, stream_max_recv_window_size_, net_log_, + NO_TRAFFIC_ANNOTATION_BUG_656607); stream->set_stream_id(stream_id); // Convert RequestPriority to a SpdyPriority to send in a PRIORITY frame. SpdyPriority spdy_priority = ConvertRequestPriorityToSpdyPriority(request_priority); SpdyStreamId dependency_id = 0; + int weight = 0; bool exclusive = false; - priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority, - &dependency_id, &exclusive); - EnqueuePriorityFrame(stream_id, dependency_id, - Spdy3PriorityToHttp2Weight(spdy_priority), exclusive); + priority_dependency_state_.OnStreamCreation( + stream_id, spdy_priority, &dependency_id, &weight, &exclusive); + EnqueuePriorityFrame(stream_id, dependency_id, weight, exclusive); // PUSH_PROMISE arrives on associated stream. associated_it->second->AddRawReceivedBytes(last_compressed_frame_len_); @@ -1722,7 +1773,8 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, net_log_); } - active_it->second->OnPushPromiseHeadersReceived(std::move(headers)); + active_it->second->OnPushPromiseHeadersReceived(std::move(headers), + std::move(gurl)); DCHECK(active_it->second->IsReservedRemote()); num_pushed_streams_++; return; @@ -1824,7 +1876,8 @@ void SpdySession::EnqueuePriorityFrame(SpdyStreamId stream_id, EnqueueWrite(HIGHEST, SpdyFrameType::PRIORITY, std::make_unique<SimpleBufferProducer>( std::make_unique<SpdyBuffer>(std::move(frame))), - base::WeakPtr<SpdyStream>()); + base::WeakPtr<SpdyStream>(), + kSpdySessionCommandsTrafficAnnotation); } void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) { @@ -2034,7 +2087,8 @@ int SpdySession::DoWrite() { SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; - if (!write_queue_.Dequeue(&frame_type, &producer, &stream)) { + if (!write_queue_.Dequeue(&frame_type, &producer, &stream, + &in_flight_write_traffic_annotation)) { write_state_ = WRITE_STATE_IDLE; return ERR_IO_PENDING; } @@ -2081,7 +2135,8 @@ int SpdySession::DoWrite() { return connection_->socket()->Write( write_io_buffer.get(), in_flight_write_->GetRemainingSize(), base::Bind(&SpdySession::PumpWriteLoop, weak_factory_.GetWeakPtr(), - WRITE_STATE_DO_WRITE_COMPLETE)); + WRITE_STATE_DO_WRITE_COMPLETE), + NetworkTrafficAnnotationTag(in_flight_write_traffic_annotation)); } int SpdySession::DoWriteComplete(int result) { @@ -2095,6 +2150,7 @@ int SpdySession::DoWriteComplete(int result) { in_flight_write_frame_type_ = SpdyFrameType::DATA; in_flight_write_frame_size_ = 0; in_flight_write_stream_.reset(); + in_flight_write_traffic_annotation.reset(); write_state_ = WRITE_STATE_DO_WRITE; DoDrainSession(static_cast<Error>(result), "Write error"); return OK; @@ -2230,6 +2286,16 @@ void SpdySession::HandleSetting(uint32_t id, uint32_t value) { NetLog::IntCallback("delta_window_size", delta_window_size)); break; } + case SETTINGS_ENABLE_CONNECT_PROTOCOL: + if ((value != 0 && value != 1) || (support_websocket_ && value == 0)) { + DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, + "Invalid value for SETTINGS_ENABLE_CONNECT_PROTOCOL."); + return; + } + if (value == 1) { + support_websocket_ = true; + } + break; } } @@ -2365,17 +2431,21 @@ void SpdySession::EnqueueSessionWrite( auto buffer = std::make_unique<SpdyBuffer>(std::move(frame)); EnqueueWrite(priority, frame_type, std::make_unique<SimpleBufferProducer>(std::move(buffer)), - base::WeakPtr<SpdyStream>()); + base::WeakPtr<SpdyStream>(), + kSpdySessionCommandsTrafficAnnotation); } -void SpdySession::EnqueueWrite(RequestPriority priority, - SpdyFrameType frame_type, - std::unique_ptr<SpdyBufferProducer> producer, - const base::WeakPtr<SpdyStream>& stream) { +void SpdySession::EnqueueWrite( + RequestPriority priority, + SpdyFrameType frame_type, + std::unique_ptr<SpdyBufferProducer> producer, + const base::WeakPtr<SpdyStream>& stream, + const NetworkTrafficAnnotationTag& traffic_annotation) { if (availability_state_ == STATE_DRAINING) return; - write_queue_.Enqueue(priority, frame_type, std::move(producer), stream); + write_queue_.Enqueue(priority, frame_type, std::move(producer), stream, + traffic_annotation); MaybePostWriteLoop(); } @@ -2831,7 +2901,7 @@ void SpdySession::OnSettingsAck() { net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS_ACK); } -void SpdySession::OnSetting(SpdySettingsIds id, uint32_t value) { +void SpdySession::OnSetting(SpdyKnownSettingsId id, uint32_t value) { CHECK(in_io_loop_); HandleSetting(id, value); @@ -2959,6 +3029,8 @@ void SpdySession::OnAltSvc( if (origin.empty()) return; const GURL gurl(origin); + if (!gurl.is_valid() || gurl.host().empty()) + return; if (!gurl.SchemeIs(url::kHttpsScheme)) return; SSLInfo ssl_info; diff --git a/chromium/net/spdy/chromium/spdy_session.h b/chromium/net/spdy/chromium/spdy_session.h index dae7d2ae9fa..09fa118c041 100644 --- a/chromium/net/spdy/chromium/spdy_session.h +++ b/chromium/net/spdy/chromium/spdy_session.h @@ -20,6 +20,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "net/base/completion_once_callback.h" #include "net/base/host_port_pair.h" #include "net/base/io_buffer.h" #include "net/base/load_states.h" @@ -48,6 +49,7 @@ #include "net/spdy/platform/api/spdy_string.h" #include "net/spdy/platform/api/spdy_string_piece.h" #include "net/ssl/ssl_config_service.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "url/gurl.h" #include "url/scheme_host_port.h" @@ -85,7 +87,6 @@ const SpdyStreamId kLastStreamId = 0x7fffffff; struct LoadTimingInfo; class NetLog; -class ProxyDelegate; class SpdyStream; class SSLInfo; class TransportSecurityState; @@ -181,8 +182,10 @@ class NET_EXPORT_PRIVATE SpdyStreamRequest { const base::WeakPtr<SpdySession>& session, const GURL& url, RequestPriority priority, + const SocketTag& socket_tag, const NetLogWithSource& net_log, - const CompletionCallback& callback); + CompletionOnceCallback callback, + const NetworkTrafficAnnotationTag& traffic_annotation); // Cancels any pending stream creation request. May be called // repeatedly. @@ -197,6 +200,10 @@ class NET_EXPORT_PRIVATE SpdyStreamRequest { // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; + const NetworkTrafficAnnotationTag traffic_annotation() const { + return NetworkTrafficAnnotationTag(traffic_annotation_); + } + private: friend class SpdySession; @@ -222,8 +229,10 @@ class NET_EXPORT_PRIVATE SpdyStreamRequest { base::WeakPtr<SpdyStream> stream_; GURL url_; RequestPriority priority_; + SocketTag socket_tag_; NetLogWithSource net_log_; - CompletionCallback callback_; + CompletionOnceCallback callback_; + MutableNetworkTrafficAnnotationTag traffic_annotation_; base::WeakPtrFactory<SpdyStreamRequest> weak_ptr_factory_; @@ -257,11 +266,11 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, bool enable_sending_initial_data, bool enable_ping_based_connection_checking, bool support_ietf_format_quic_altsvc, + bool is_trusted_proxy, size_t session_max_recv_window_size, const SettingsMap& initial_settings, TimeFunc time_func, ServerPushDelegate* push_delegate, - ProxyDelegate* proxy_delegate, NetLog* net_log); ~SpdySession() override; @@ -451,11 +460,14 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, bool GetLoadTimingInfo(SpdyStreamId stream_id, LoadTimingInfo* load_timing_info) const; - // Returns true if session is not currently active + // Returns true if session is currently active. bool is_active() const { return !active_streams_.empty() || !created_streams_.empty(); } + // True if the server supports WebSocket protocol. + bool support_websocket() const { return support_websocket_; } + // Returns true if no stream in the session can send data due to // session flow control. bool IsSendStalled() const { return session_send_window_size_ == 0; } @@ -502,6 +514,9 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, size_t DumpMemoryStats(StreamSocket::SocketMemoryStats* stats, bool* is_session_active) const; + // Change this session's socket tag to |new_tag|. Returns true on success. + bool ChangeSocketTag(const SocketTag& new_tag); + private: friend class test::SpdyStreamTest; friend class base::RefCounted<SpdySession>; @@ -690,7 +705,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, void EnqueueWrite(RequestPriority priority, SpdyFrameType frame_type, std::unique_ptr<SpdyBufferProducer> producer, - const base::WeakPtr<SpdyStream>& stream); + const base::WeakPtr<SpdyStream>& stream, + const NetworkTrafficAnnotationTag& traffic_annotation); // Inserts a newly-created stream into |created_streams_|. void InsertCreatedStream(std::unique_ptr<SpdyStream> stream); @@ -766,7 +782,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, void OnStreamPadding(SpdyStreamId stream_id, size_t len) override; void OnSettings() override; void OnSettingsAck() override; - void OnSetting(SpdySettingsIds id, uint32_t value) override; + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override; void OnSettingsEnd() override {} void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override; void OnPushPromise(SpdyStreamId stream_id, @@ -864,7 +880,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, bool in_io_loop_; // The key used to identify this session. - const SpdySessionKey spdy_session_key_; + SpdySessionKey spdy_session_key_; // Set set of SpdySessionKeys for which this session has serviced // requests. @@ -945,6 +961,9 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // the socket completely. base::WeakPtr<SpdyStream> in_flight_write_stream_; + // Traffic annotation for the write in progress. + MutableNetworkTrafficAnnotationTag in_flight_write_traffic_annotation; + // Spdy Frame state. std::unique_ptr<BufferedSpdyFramer> buffered_spdy_framer_; @@ -1043,6 +1062,15 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // If true, alt-svc headers advertising QUIC in IETF format will be supported. bool support_ietf_format_quic_altsvc_; + // If true, this session is being made to a trusted SPDY/HTTP2 proxy that is + // allowed to push cross-origin resources. + const bool is_trusted_proxy_; + + // True if the server has advertised WebSocket support via + // SETTINGS_ENABLE_CONNECT_PROTOCOL, see + // https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-00. + bool support_websocket_; + // |connection_at_risk_of_loss_time_| is an optimization to avoid sending // wasteful preface pings (when we just got some data). // @@ -1065,11 +1093,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // get a PING response (http://crbug.com/127812). base::TimeDelta hung_interval_; - // The |proxy_delegate_| verifies that a given proxy is a trusted SPDY proxy, - // which is allowed to push resources from origins that are different from - // those of their associated streams. May be nullptr. - ProxyDelegate* proxy_delegate_; - TimeFunc time_func_; Http2PriorityDependencies priority_dependency_state_; diff --git a/chromium/net/spdy/chromium/spdy_session_fuzzer.cc b/chromium/net/spdy/chromium/spdy_session_fuzzer.cc index a1ac99dfaee..d7c076519d5 100644 --- a/chromium/net/spdy/chromium/spdy_session_fuzzer.cc +++ b/chromium/net/spdy/chromium/spdy_session_fuzzer.cc @@ -14,10 +14,12 @@ #include "net/log/test_net_log.h" #include "net/socket/client_socket_handle.h" #include "net/socket/fuzzed_socket_factory.h" +#include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" #include "net/socket/ssl_client_socket.h" #include "net/spdy/chromium/spdy_test_util_common.h" #include "net/ssl/ssl_config.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" namespace { @@ -117,7 +119,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { net::ProxyServer direct_connect(net::ProxyServer::Direct()); net::SpdySessionKey session_key(net::HostPortPair("127.0.0.1", 80), - direct_connect, net::PRIVACY_MODE_DISABLED); + direct_connect, net::PRIVACY_MODE_DISABLED, + net::SocketTag()); base::WeakPtr<net::SpdySession> spdy_session(net::CreateSpdySession( http_session.get(), session_key, bound_test_net_log.bound())); @@ -128,7 +131,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { int rv = stream_request.StartRequest( net::SPDY_REQUEST_RESPONSE_STREAM, spdy_session, GURL("http://www.example.invalid/"), net::DEFAULT_PRIORITY, - bound_test_net_log.bound(), wait_for_start.callback()); + net::SocketTag(), bound_test_net_log.bound(), wait_for_start.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS); if (rv == net::ERR_IO_PENDING) { rv = wait_for_start.WaitForResult(); diff --git a/chromium/net/spdy/chromium/spdy_session_key.cc b/chromium/net/spdy/chromium/spdy_session_key.cc index be206e5a9b3..4331c388a8c 100644 --- a/chromium/net/spdy/chromium/spdy_session_key.cc +++ b/chromium/net/spdy/chromium/spdy_session_key.cc @@ -16,9 +16,11 @@ SpdySessionKey::SpdySessionKey() = default; SpdySessionKey::SpdySessionKey(const HostPortPair& host_port_pair, const ProxyServer& proxy_server, - PrivacyMode privacy_mode) + PrivacyMode privacy_mode, + const SocketTag& socket_tag) : host_port_proxy_pair_(host_port_pair, proxy_server), - privacy_mode_(privacy_mode) { + privacy_mode_(privacy_mode), + socket_tag_(socket_tag) { DVLOG(1) << "SpdySessionKey(host=" << host_port_pair.ToString() << ", proxy=" << proxy_server.ToURI() << ", privacy=" << privacy_mode; @@ -30,15 +32,17 @@ SpdySessionKey::~SpdySessionKey() = default; bool SpdySessionKey::operator<(const SpdySessionKey& other) const { return std::tie(privacy_mode_, host_port_proxy_pair_.first, - host_port_proxy_pair_.second) < + host_port_proxy_pair_.second, socket_tag_) < std::tie(other.privacy_mode_, other.host_port_proxy_pair_.first, - other.host_port_proxy_pair_.second); + other.host_port_proxy_pair_.second, other.socket_tag_); } bool SpdySessionKey::operator==(const SpdySessionKey& other) const { return privacy_mode_ == other.privacy_mode_ && - host_port_proxy_pair_.first.Equals(other.host_port_proxy_pair_.first) && - host_port_proxy_pair_.second == other.host_port_proxy_pair_.second; + host_port_proxy_pair_.first.Equals( + other.host_port_proxy_pair_.first) && + host_port_proxy_pair_.second == other.host_port_proxy_pair_.second && + socket_tag_ == other.socket_tag_; } size_t SpdySessionKey::EstimateMemoryUsage() const { diff --git a/chromium/net/spdy/chromium/spdy_session_key.h b/chromium/net/spdy/chromium/spdy_session_key.h index ef5ac192fac..fe1e8741406 100644 --- a/chromium/net/spdy/chromium/spdy_session_key.h +++ b/chromium/net/spdy/chromium/spdy_session_key.h @@ -7,7 +7,8 @@ #include "net/base/net_export.h" #include "net/base/privacy_mode.h" -#include "net/proxy/proxy_server.h" +#include "net/base/proxy_server.h" +#include "net/socket/socket_tag.h" namespace net { @@ -17,7 +18,8 @@ class NET_EXPORT_PRIVATE SpdySessionKey { SpdySessionKey(); SpdySessionKey(const HostPortPair& host_port_pair, const ProxyServer& proxy_server, - PrivacyMode privacy_mode); + PrivacyMode privacy_mode, + const SocketTag& socket_tag); SpdySessionKey(const SpdySessionKey& other); @@ -45,6 +47,8 @@ class NET_EXPORT_PRIVATE SpdySessionKey { return privacy_mode_; } + const SocketTag& socket_tag() const { return socket_tag_; } + // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; @@ -52,6 +56,7 @@ class NET_EXPORT_PRIVATE SpdySessionKey { HostPortProxyPair host_port_proxy_pair_; // If enabled, then session cannot be tracked by the server. PrivacyMode privacy_mode_ = PRIVACY_MODE_DISABLED; + SocketTag socket_tag_; }; } // namespace net diff --git a/chromium/net/spdy/chromium/spdy_session_pool.cc b/chromium/net/spdy/chromium/spdy_session_pool.cc index 312e581ac3f..c1134e66364 100644 --- a/chromium/net/spdy/chromium/spdy_session_pool.cc +++ b/chromium/net/spdy/chromium/spdy_session_pool.cc @@ -55,8 +55,7 @@ SpdySessionPool::SpdySessionPool( bool support_ietf_format_quic_altsvc, size_t session_max_recv_window_size, const SettingsMap& initial_settings, - SpdySessionPool::TimeFunc time_func, - ProxyDelegate* proxy_delegate) + SpdySessionPool::TimeFunc time_func) : http_server_properties_(http_server_properties), transport_security_state_(transport_security_state), ssl_config_service_(ssl_config_service), @@ -69,8 +68,7 @@ SpdySessionPool::SpdySessionPool( session_max_recv_window_size_(session_max_recv_window_size), initial_settings_(initial_settings), time_func_(time_func), - push_delegate_(nullptr), - proxy_delegate_(proxy_delegate) { + push_delegate_(nullptr) { NetworkChangeNotifier::AddIPAddressObserver(this); if (ssl_config_service_.get()) ssl_config_service_->AddObserver(this); @@ -97,6 +95,7 @@ SpdySessionPool::~SpdySessionPool() { base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket( const SpdySessionKey& key, + bool is_trusted_proxy, std::unique_ptr<ClientSocketHandle> connection, const NetLogWithSource& net_log) { TRACE_EVENT0(kNetTracingCategory, @@ -109,8 +108,8 @@ base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket( key, http_server_properties_, transport_security_state_, quic_supported_versions_, enable_sending_initial_data_, enable_ping_based_connection_checking_, support_ietf_format_quic_altsvc_, - session_max_recv_window_size_, initial_settings_, time_func_, - push_delegate_, proxy_delegate_, net_log.net_log()); + is_trusted_proxy, session_max_recv_window_size_, initial_settings_, + time_func_, push_delegate_, net_log.net_log()); new_session->InitializeWithSocket(std::move(connection), this); @@ -130,7 +129,7 @@ base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket( if (key.proxy_server().is_direct()) { IPEndPoint address; if (available_session->GetPeerAddress(&address) == OK) - aliases_[address] = key; + aliases_.insert(AliasMap::value_type(address, key)); } return available_session; @@ -139,9 +138,11 @@ base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket( base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession( const SpdySessionKey& key, bool enable_ip_based_pooling, + bool is_websocket, const NetLogWithSource& net_log) { AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key); - if (it != available_sessions_.end()) { + if (it != available_sessions_.end() && + (!is_websocket || it->second->support_websocket())) { if (key == it->second->spdy_session_key()) { UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING, SPDY_SESSION_GET_MAX); @@ -185,48 +186,100 @@ base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession( for (AddressList::const_iterator address_it = addresses.begin(); address_it != addresses.end(); ++address_it) { - AliasMap::const_iterator alias_it = aliases_.find(*address_it); - if (alias_it == aliases_.end()) - continue; + auto range = aliases_.equal_range(*address_it); + for (auto alias_it = range.first; alias_it != range.second; ++alias_it) { + // We found an alias. + const SpdySessionKey& alias_key = alias_it->second; + + // We can reuse this session only if the proxy and privacy + // settings match. + if (!(alias_key.proxy_server() == key.proxy_server()) || + !(alias_key.privacy_mode() == key.privacy_mode())) { + continue; + } - // We found an alias. - const SpdySessionKey& alias_key = alias_it->second; + AvailableSessionMap::iterator available_session_it = + LookupAvailableSessionByKey(alias_key); + if (available_session_it == available_sessions_.end()) { + NOTREACHED(); // It shouldn't be in the aliases table if we can't get + // it! + continue; + } - // We can reuse this session only if the proxy and privacy - // settings match. - if (!(alias_key.proxy_server() == key.proxy_server()) || - !(alias_key.privacy_mode() == key.privacy_mode())) - continue; + // Make copy of WeakPtr as call to UnmapKey() will delete original. + const base::WeakPtr<SpdySession> available_session = + available_session_it->second; + DCHECK(base::ContainsKey(sessions_, available_session.get())); + + if (is_websocket && !available_session->support_websocket()) + continue; + + // If the session is a secure one, we need to verify that the + // server is authenticated to serve traffic for |host_port_proxy_pair| + // too. + if (!available_session->VerifyDomainAuthentication( + key.host_port_pair().host())) { + UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2); + continue; + } - AvailableSessionMap::iterator available_session_it = - LookupAvailableSessionByKey(alias_key); - if (available_session_it == available_sessions_.end()) { - NOTREACHED(); // It shouldn't be in the aliases table if we can't get it! - continue; - } + bool adding_pooled_alias = true; + + // If socket tags differ, see if session's socket tag can be changed. + if (alias_key.socket_tag() != key.socket_tag()) { + SpdySessionKey old_key = available_session->spdy_session_key(); + + if (!available_session->ChangeSocketTag(key.socket_tag())) + continue; + + const SpdySessionKey& new_key = available_session->spdy_session_key(); + + // This isn't a pooled alias, it's the actual session. + adding_pooled_alias = false; + + // Remap main session key. + UnmapKey(old_key); + MapKeyToAvailableSession(new_key, available_session); + + // Remap alias. + aliases_.insert(AliasMap::value_type(alias_it->first, new_key)); + aliases_.erase(alias_it); + + // Remap pooled session keys. + const auto& aliases = available_session->pooled_aliases(); + for (auto it = aliases.begin(); it != aliases.end();) { + // Ignore aliases this loop is inserting. + if (it->socket_tag() == key.socket_tag()) { + ++it; + continue; + } + UnmapKey(*it); + SpdySessionKey new_pool_alias_key = + SpdySessionKey(it->host_port_pair(), it->proxy_server(), + it->privacy_mode(), key.socket_tag()); + MapKeyToAvailableSession(new_pool_alias_key, available_session); + auto old_it = it; + ++it; + available_session->RemovePooledAlias(*old_it); + available_session->AddPooledAlias(new_pool_alias_key); + } + } - const base::WeakPtr<SpdySession>& available_session = - available_session_it->second; - DCHECK(base::ContainsKey(sessions_, available_session.get())); - // If the session is a secure one, we need to verify that the - // server is authenticated to serve traffic for |host_port_proxy_pair| too. - if (!available_session->VerifyDomainAuthentication( - key.host_port_pair().host())) { - UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2); - continue; + UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2); + UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", + FOUND_EXISTING_FROM_IP_POOL, + SPDY_SESSION_GET_MAX); + net_log.AddEvent( + NetLogEventType:: + HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, + available_session->net_log().source().ToEventParametersCallback()); + if (adding_pooled_alias) { + // Add this session to the map so that we can find it next time. + MapKeyToAvailableSession(key, available_session); + available_session->AddPooledAlias(key); + } + return available_session; } - - UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2); - UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", - FOUND_EXISTING_FROM_IP_POOL, - SPDY_SESSION_GET_MAX); - net_log.AddEvent( - NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, - available_session->net_log().source().ToEventParametersCallback()); - // Add this session to the map so that we can find it next time. - MapKeyToAvailableSession(key, available_session); - available_session->AddPooledAlias(key); - return available_session; } return base::WeakPtr<SpdySession>(); @@ -332,7 +385,6 @@ void SpdySessionPool::OnCertDBChanged() { void SpdySessionPool::OnNewSpdySessionReady( const base::WeakPtr<SpdySession>& spdy_session, - bool direct, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, bool was_alpn_negotiated, @@ -360,12 +412,9 @@ void SpdySessionPool::OnNewSpdySessionReady( std::make_unique<BidirectionalStreamSpdyImpl>(spdy_session, source_dependency)); } else { - bool use_relative_url = - direct || request->url().SchemeIs(url::kHttpsScheme); request->OnStreamReadyOnPooledConnection( used_ssl_config, used_proxy_info, std::make_unique<SpdyHttpStream>(spdy_session, kNoPushedStreamFound, - use_relative_url, source_dependency)); } } diff --git a/chromium/net/spdy/chromium/spdy_session_pool.h b/chromium/net/spdy/chromium/spdy_session_pool.h index 09f3a826912..8de7365a172 100644 --- a/chromium/net/spdy/chromium/spdy_session_pool.h +++ b/chromium/net/spdy/chromium/spdy_session_pool.h @@ -21,10 +21,10 @@ #include "net/base/net_errors.h" #include "net/base/net_export.h" #include "net/base/network_change_notifier.h" +#include "net/base/proxy_server.h" #include "net/cert/cert_database.h" #include "net/http/http_stream_factory_impl_request.h" -#include "net/proxy/proxy_config.h" -#include "net/proxy/proxy_server.h" +#include "net/proxy_resolution/proxy_config.h" #include "net/spdy/chromium/http2_push_promise_index.h" #include "net/spdy/chromium/server_push_delegate.h" #include "net/spdy/chromium/spdy_session_key.h" @@ -44,7 +44,6 @@ class ClientSocketHandle; class HostResolver; class HttpServerProperties; class NetLogWithSource; -class ProxyDelegate; class SpdySession; class TransportSecurityState; @@ -65,8 +64,7 @@ class NET_EXPORT SpdySessionPool bool support_ietf_format_quic_altsvc, size_t session_max_recv_window_size, const SettingsMap& initial_settings, - SpdySessionPool::TimeFunc time_func, - ProxyDelegate* proxy_delegate); + SpdySessionPool::TimeFunc time_func); ~SpdySessionPool() override; // In the functions below, a session is "available" if this pool has @@ -85,6 +83,7 @@ class NET_EXPORT SpdySessionPool // immediately afterwards if the first read of |connection| fails. base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket( const SpdySessionKey& key, + bool is_trusted_proxy, std::unique_ptr<ClientSocketHandle> connection, const NetLogWithSource& net_log); @@ -98,6 +97,7 @@ class NET_EXPORT SpdySessionPool base::WeakPtr<SpdySession> FindAvailableSession( const SpdySessionKey& key, bool enable_ip_based_pooling, + bool is_websocket, const NetLogWithSource& net_log); // Remove all mappings and aliases for the given session, which must @@ -165,10 +165,8 @@ class NET_EXPORT SpdySessionPool const SpdyString& parent_dump_absolute_name) const; // Called when a SpdySession is ready. It will find appropriate Requests and - // fulfill them. |direct| indicates whether or not |spdy_session| uses a - // proxy. + // fulfill them. void OnNewSpdySessionReady(const base::WeakPtr<SpdySession>& spdy_session, - bool direct, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, bool was_alpn_negotiated, @@ -205,7 +203,7 @@ class NET_EXPORT SpdySessionPool typedef std::vector<base::WeakPtr<SpdySession> > WeakSessionList; typedef std::map<SpdySessionKey, base::WeakPtr<SpdySession> > AvailableSessionMap; - typedef std::map<IPEndPoint, SpdySessionKey> AliasMap; + typedef std::multimap<IPEndPoint, SpdySessionKey> AliasMap; // Returns true iff |session| is in |available_sessions_|. bool IsSessionAvailable(const base::WeakPtr<SpdySession>& session) const; @@ -287,11 +285,6 @@ class NET_EXPORT SpdySessionPool TimeFunc time_func_; ServerPushDelegate* push_delegate_; - // Determines if a proxy is a trusted SPDY proxy, which is allowed to push - // resources from origins that are different from those of their associated - // streams. May be nullptr. - ProxyDelegate* proxy_delegate_; - DISALLOW_COPY_AND_ASSIGN(SpdySessionPool); }; diff --git a/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc b/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc index 74169d9afff..870052ba649 100644 --- a/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc @@ -20,6 +20,7 @@ #include "net/log/test_net_log.h" #include "net/log/test_net_log_entry.h" #include "net/socket/client_socket_handle.h" +#include "net/socket/socket_tag.h" #include "net/socket/transport_client_socket_pool.h" #include "net/spdy/chromium/spdy_session.h" #include "net/spdy/chromium/spdy_stream_test_util.h" @@ -118,9 +119,8 @@ TEST_F(SpdySessionPoolTest, CloseCurrentSessions) { HostPortPair test_host_port_pair(kTestHost, kTestPort); SpdySessionKey test_key = - SpdySessionKey( - test_host_port_pair, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + SpdySessionKey(test_host_port_pair, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); MockConnect connect_data(SYNCHRONOUS, OK); MockRead reads[] = { @@ -181,7 +181,7 @@ TEST_F(SpdySessionPoolTest, CloseCurrentIdleSessions) { const SpdyString kTestHost1("www.example.org"); HostPortPair test_host_port_pair1(kTestHost1, 80); SpdySessionKey key1(test_host_port_pair1, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> session1 = CreateSpdySession(http_session_.get(), key1, NetLogWithSource()); GURL url1(kTestHost1); @@ -196,7 +196,7 @@ TEST_F(SpdySessionPoolTest, CloseCurrentIdleSessions) { const SpdyString kTestHost2("mail.example.org"); HostPortPair test_host_port_pair2(kTestHost2, 80); SpdySessionKey key2(test_host_port_pair2, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> session2 = CreateSpdySession(http_session_.get(), key2, NetLogWithSource()); GURL url2(kTestHost2); @@ -211,7 +211,7 @@ TEST_F(SpdySessionPoolTest, CloseCurrentIdleSessions) { const SpdyString kTestHost3("mail.example.com"); HostPortPair test_host_port_pair3(kTestHost3, 80); SpdySessionKey key3(test_host_port_pair3, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> session3 = CreateSpdySession(http_session_.get(), key3, NetLogWithSource()); GURL url3(kTestHost3); @@ -290,9 +290,8 @@ TEST_F(SpdySessionPoolTest, CloseAllSessions) { HostPortPair test_host_port_pair(kTestHost, kTestPort); SpdySessionKey test_key = - SpdySessionKey( - test_host_port_pair, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + SpdySessionKey(test_host_port_pair, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); MockConnect connect_data(SYNCHRONOUS, OK); MockRead reads[] = { @@ -372,7 +371,7 @@ void SpdySessionPoolTest::RunIPPoolingTest( // Setup a SpdySessionKey. test_hosts[i].key = SpdySessionKey( HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); } MockConnect connect_data(SYNCHRONOUS, OK); @@ -406,13 +405,14 @@ void SpdySessionPoolTest::RunIPPoolingTest( base::WeakPtr<SpdySession> session1 = spdy_session_pool_->FindAvailableSession( test_hosts[1].key, /* enable_ip_based_pooling = */ false, - NetLogWithSource()); + /* is_websocket = */ false, NetLogWithSource()); EXPECT_FALSE(session1); // Verify that the second host, through a proxy, won't share the IP. - SpdySessionKey proxy_key(test_hosts[1].key.host_port_pair(), + SpdySessionKey proxy_key( + test_hosts[1].key.host_port_pair(), ProxyServer::FromPacString("HTTP http://proxy.foo.com/"), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); EXPECT_FALSE(HasSpdySession(spdy_session_pool_, proxy_key)); // Overlap between 2 and 3 does is not transitive to 1. @@ -437,7 +437,7 @@ void SpdySessionPoolTest::RunIPPoolingTest( // we got with host 0, and that is a different from host 2's session. session1 = spdy_session_pool_->FindAvailableSession( test_hosts[1].key, /* enable_ip_based_pooling = */ true, - NetLogWithSource()); + /* is_websocket = */ false, NetLogWithSource()); EXPECT_EQ(session.get(), session1.get()); EXPECT_NE(session2.get(), session1.get()); @@ -555,9 +555,9 @@ TEST_F(SpdySessionPoolTest, IPPoolingNetLog) { info, DEFAULT_PRIORITY, &test_hosts[i].addresses, CompletionCallback(), &test_hosts[i].request, NetLogWithSource()); - test_hosts[i].key = - SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + test_hosts[i].key = SpdySessionKey( + HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); } MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; @@ -580,7 +580,7 @@ TEST_F(SpdySessionPoolTest, IPPoolingNetLog) { base::WeakPtr<SpdySession> session1 = spdy_session_pool_->FindAvailableSession( test_hosts[1].key, /* enable_ip_based_pooling = */ true, - net_log.bound()); + /* is_websocket = */ false, net_log.bound()); EXPECT_EQ(session0.get(), session1.get()); ASSERT_EQ(1u, net_log.GetSize()); @@ -588,7 +588,8 @@ TEST_F(SpdySessionPoolTest, IPPoolingNetLog) { // A request to the second host should still pool to the existing connection. session1 = spdy_session_pool_->FindAvailableSession( - test_hosts[1].key, /* enable_ip_based_pooling = */ true, net_log.bound()); + test_hosts[1].key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, net_log.bound()); EXPECT_EQ(session0.get(), session1.get()); ASSERT_EQ(2u, net_log.GetSize()); @@ -634,9 +635,9 @@ TEST_F(SpdySessionPoolTest, IPPoolingDisabled) { info, DEFAULT_PRIORITY, &test_hosts[i].addresses, CompletionCallback(), &test_hosts[i].request, NetLogWithSource()); - test_hosts[i].key = - SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + test_hosts[i].key = SpdySessionKey( + HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); } MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; @@ -663,14 +664,14 @@ TEST_F(SpdySessionPoolTest, IPPoolingDisabled) { base::WeakPtr<SpdySession> session1 = spdy_session_pool_->FindAvailableSession( test_hosts[1].key, /* enable_ip_based_pooling = */ true, - NetLogWithSource()); + /* is_websocket = */ false, NetLogWithSource()); EXPECT_EQ(session0.get(), session1.get()); // A request to the second host should not pool to the existing connection if // IP based pooling is disabled. session1 = spdy_session_pool_->FindAvailableSession( test_hosts[1].key, /* enable_ip_based_pooling = */ false, - NetLogWithSource()); + /* is_websocket = */ false, NetLogWithSource()); EXPECT_FALSE(session1); // It should be possible to open a new SpdySession, even if a previous call to @@ -714,8 +715,8 @@ TEST_F(SpdySessionPoolTest, IPAddressChanged) { // Set up session A: Going away, but with an active stream. const SpdyString kTestHostA("www.example.org"); HostPortPair test_host_port_pairA(kTestHostA, 80); - SpdySessionKey keyA( - test_host_port_pairA, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + SpdySessionKey keyA(test_host_port_pairA, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> sessionA = CreateSpdySession(http_session_.get(), keyA, NetLogWithSource()); @@ -745,8 +746,8 @@ TEST_F(SpdySessionPoolTest, IPAddressChanged) { const SpdyString kTestHostB("mail.example.org"); HostPortPair test_host_port_pairB(kTestHostB, 80); - SpdySessionKey keyB( - test_host_port_pairB, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + SpdySessionKey keyB(test_host_port_pairB, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> sessionB = CreateSpdySession(http_session_.get(), keyB, NetLogWithSource()); EXPECT_TRUE(sessionB->IsAvailable()); @@ -767,8 +768,8 @@ TEST_F(SpdySessionPoolTest, IPAddressChanged) { const SpdyString kTestHostC("mail.example.com"); HostPortPair test_host_port_pairC(kTestHostC, 80); - SpdySessionKey keyC( - test_host_port_pairC, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + SpdySessionKey keyC(test_host_port_pairC, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> sessionC = CreateSpdySession(http_session_.get(), keyC, NetLogWithSource()); @@ -826,7 +827,7 @@ TEST_F(SpdySessionPoolTest, HandleIPAddressChangeThenShutdown) { const GURL url(kDefaultUrl); SpdySessionKey key(HostPortPair::FromURL(url), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> session = CreateSpdySession(http_session_.get(), key, NetLogWithSource()); @@ -881,7 +882,7 @@ TEST_F(SpdySessionPoolTest, HandleGracefulGoawayThenShutdown) { const GURL url(kDefaultUrl); SpdySessionKey key(HostPortPair::FromURL(url), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); base::WeakPtr<SpdySession> session = CreateSpdySession(http_session_.get(), key, NetLogWithSource()); @@ -928,7 +929,7 @@ INSTANTIATE_TEST_CASE_P( TEST_P(SpdySessionMemoryDumpTest, DumpMemoryStats) { SpdySessionKey key(HostPortPair("www.example.org", 443), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, SocketTag()); MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); @@ -974,4 +975,117 @@ TEST_P(SpdySessionMemoryDumpTest, DumpMemoryStats) { spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED); } +TEST_F(SpdySessionPoolTest, FindAvailableSessionForWebsocket) { + // Define two hosts with identical IP address. + const int kTestPort = 443; + struct TestHosts { + SpdyString name; + SpdyString iplist; + SpdySessionKey key; + AddressList addresses; + std::unique_ptr<HostResolver::Request> request; + } test_hosts[] = { + {"www.example.org", "192.168.0.1"}, {"mail.example.org", "192.168.0.1"}, + }; + + // Populate the HostResolver cache. + session_deps_.host_resolver->set_synchronous_mode(true); + for (size_t i = 0; i < arraysize(test_hosts); i++) { + session_deps_.host_resolver->rules()->AddIPLiteralRule( + test_hosts[i].name, test_hosts[i].iplist, SpdyString()); + + HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort)); + session_deps_.host_resolver->Resolve( + info, DEFAULT_PRIORITY, &test_hosts[i].addresses, CompletionCallback(), + &test_hosts[i].request, NetLogWithSource()); + + test_hosts[i].key = SpdySessionKey( + HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, SocketTag()); + } + + SpdyTestUtil spdy_util; + + SpdySerializedFrame req(spdy_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); + SpdySerializedFrame settings_ack(spdy_util.ConstructSpdySettingsAck()); + MockWrite writes[] = {CreateMockWrite(req, 0), + CreateMockWrite(settings_ack, 2)}; + + SettingsMap settings; + settings[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1; + SpdySerializedFrame settings_frame(spdy_util.ConstructSpdySettings(settings)); + SpdySerializedFrame resp(spdy_util.ConstructSpdyGetReply(nullptr, 0, 1)); + SpdySerializedFrame body(spdy_util.ConstructSpdyDataFrame(1, true)); + MockRead reads[] = {CreateMockRead(settings_frame, 1), + CreateMockRead(resp, 3), CreateMockRead(body, 4), + MockRead(ASYNC, ERR_IO_PENDING, 5), + MockRead(ASYNC, 0, 6)}; + + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + session_deps_.socket_factory->AddSocketDataProvider(&data); + AddSSLSocketData(); + CreateNetworkSession(); + + // Create a connection to the first host. + base::WeakPtr<SpdySession> session = CreateSpdySession( + http_session_.get(), test_hosts[0].key, NetLogWithSource()); + + // SpdySession does not support Websocket before SETTINGS frame is read. + EXPECT_FALSE(session->support_websocket()); + BoundTestNetLog net_log; + // FindAvailableSession should not find |session| for either SpdySessionKeys + // if |is_websocket| argument is set. + base::WeakPtr<SpdySession> result = spdy_session_pool_->FindAvailableSession( + test_hosts[0].key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ true, net_log.bound()); + EXPECT_FALSE(result.get()); + result = spdy_session_pool_->FindAvailableSession( + test_hosts[1].key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ true, net_log.bound()); + EXPECT_FALSE(result.get()); + + // Start request that triggers reading the SETTINGS frame. + const GURL url(kDefaultUrl); + base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( + SPDY_BIDIRECTIONAL_STREAM, session, url, LOWEST, NetLogWithSource()); + test::StreamDelegateDoNothing delegate(spdy_stream); + spdy_stream->SetDelegate(&delegate); + + SpdyHeaderBlock headers(spdy_util.ConstructGetHeaderBlock(url.spec())); + spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); + + base::RunLoop().RunUntilIdle(); + + // Now SpdySession has read the SETTINGS frame and thus supports Websocket. + EXPECT_TRUE(session->support_websocket()); + + // FindAvailableSession() should return |session| for either SpdySessionKeys + // when IP based pooling is enabled. + result = spdy_session_pool_->FindAvailableSession( + test_hosts[0].key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ true, net_log.bound()); + EXPECT_EQ(session.get(), result.get()); + result = spdy_session_pool_->FindAvailableSession( + test_hosts[1].key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ true, net_log.bound()); + EXPECT_EQ(session.get(), result.get()); + + // FindAvailableSession() should only return |session| for the first + // SpdySessionKey when IP based pooling is disabled. + result = spdy_session_pool_->FindAvailableSession( + test_hosts[0].key, /* enable_ip_based_pooling = */ false, + /* is_websocket = */ true, net_log.bound()); + EXPECT_EQ(session.get(), result.get()); + result = spdy_session_pool_->FindAvailableSession( + test_hosts[1].key, /* enable_ip_based_pooling = */ false, + /* is_websocket = */ true, net_log.bound()); + EXPECT_FALSE(result); + + // Read EOF. + data.Resume(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(data.AllReadDataConsumed()); + EXPECT_TRUE(data.AllWriteDataConsumed()); +} } // namespace net diff --git a/chromium/net/spdy/chromium/spdy_session_unittest.cc b/chromium/net/spdy/chromium/spdy_session_unittest.cc index 60e54bc8ff2..bc40c21675b 100644 --- a/chromium/net/spdy/chromium/spdy_session_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_session_unittest.cc @@ -11,16 +11,18 @@ #include "base/bind.h" #include "base/callback.h" #include "base/run_loop.h" +#include "base/strings/string_piece.h" #include "base/test/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_mock_time_task_runner.h" +#include "net/base/completion_callback.h" #include "net/base/host_port_pair.h" #include "net/base/io_buffer.h" #include "net/base/ip_endpoint.h" #include "net/base/proxy_delegate.h" +#include "net/base/proxy_server.h" #include "net/base/request_priority.h" #include "net/base/test_data_stream.h" -#include "net/base/test_proxy_delegate.h" #include "net/cert/ct_policy_status.h" #include "net/http/http_request_info.h" #include "net/log/net_log_event_type.h" @@ -28,7 +30,6 @@ #include "net/log/test_net_log.h" #include "net/log/test_net_log_entry.h" #include "net/log/test_net_log_util.h" -#include "net/proxy/proxy_server.h" #include "net/socket/client_socket_pool_manager.h" #include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" @@ -39,9 +40,12 @@ #include "net/spdy/chromium/spdy_stream_test_util.h" #include "net/spdy/chromium/spdy_test_util_common.h" #include "net/spdy/core/spdy_test_utils.h" +#include "net/spdy/platform/api/spdy_string.h" +#include "net/spdy/platform/api/spdy_string_piece.h" #include "net/test/cert_test_util.h" #include "net/test/gtest_util.h" #include "net/test/test_data_directory.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/platform_test.h" @@ -133,7 +137,8 @@ class SpdySessionTest : public PlatformTest { test_server_(test_url_), key_(HostPortPair::FromURL(test_url_), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED), + PRIVACY_MODE_DISABLED, + SocketTag()), ssl_(SYNCHRONOUS, OK) {} ~SpdySessionTest() override { @@ -176,6 +181,12 @@ class SpdySessionTest : public PlatformTest { ::net::CreateSpdySession(http_session_.get(), key_, log_.bound()); } + void CreateTrustedSpdySession() { + DCHECK(!session_); + session_ = ::net::CreateTrustedSpdySession(http_session_.get(), key_, + log_.bound()); + } + void StallSessionSend() { // Reduce the send window size to 0 to stall. while (session_send_window_size() > 0) { @@ -378,9 +389,9 @@ class StreamRequestDestroyingCallback : public TestCompletionCallbackBase { request_ = std::move(request); } - CompletionCallback MakeCallback() { - return base::Bind(&StreamRequestDestroyingCallback::OnComplete, - base::Unretained(this)); + CompletionOnceCallback MakeCallback() { + return base::BindOnce(&StreamRequestDestroyingCallback::OnComplete, + base::Unretained(this)); } private: @@ -425,15 +436,17 @@ TEST_F(SpdySessionTest, PendingStreamCancellingAnother) { StreamRequestDestroyingCallback callback1; ASSERT_EQ(ERR_IO_PENDING, request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, - test_url_, MEDIUM, NetLogWithSource(), - callback1.MakeCallback())); + test_url_, MEDIUM, SocketTag(), + NetLogWithSource(), callback1.MakeCallback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); // |callback2| is never called. TestCompletionCallback callback2; - ASSERT_EQ( - ERR_IO_PENDING, - request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_, - MEDIUM, NetLogWithSource(), callback2.callback())); + ASSERT_EQ(ERR_IO_PENDING, + request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, + test_url_, MEDIUM, SocketTag(), + NetLogWithSource(), callback2.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); callback1.SetRequestToDestroy(std::move(request2)); @@ -499,10 +512,8 @@ TEST_F(SpdySessionTest, GoAwayWithActiveStreams) { MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3), MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF }; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; @@ -571,8 +582,7 @@ TEST_F(SpdySessionTest, GoAwayWithActiveAndCreatedStream) { }; // No |req2|, because the second stream will never get activated. - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; @@ -630,10 +640,8 @@ TEST_F(SpdySessionTest, GoAwayTwice) { MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(goaway2, 5), MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7) // EOF }; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; @@ -699,10 +707,8 @@ TEST_F(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3), MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF }; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; @@ -764,8 +770,7 @@ TEST_F(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { TEST_F(SpdySessionTest, GoAwayWhileDraining) { session_deps_.host_resolver->set_synchronous_mode(true); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -830,8 +835,7 @@ TEST_F(SpdySessionTest, CreateStreamAfterGoAway) { MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2), MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, 0, 4) // EOF }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -866,9 +870,10 @@ TEST_F(SpdySessionTest, CreateStreamAfterGoAway) { EXPECT_TRUE(session_->IsStreamActive(1)); SpdyStreamRequest stream_request; - int rv = stream_request.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, - test_url_, MEDIUM, NetLogWithSource(), - CompletionCallback()); + int rv = stream_request.StartRequest( + SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, SocketTag(), + NetLogWithSource(), CompletionOnceCallback(), + TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(rv, IsError(ERR_FAILED)); EXPECT_TRUE(session_); @@ -890,8 +895,7 @@ TEST_F(SpdySessionTest, HeadersAfterGoAway) { MockRead(ASYNC, ERR_IO_PENDING, 3), CreateMockRead(push, 4), MockRead(ASYNC, 0, 6) // EOF }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 5)}; @@ -940,8 +944,7 @@ TEST_F(SpdySessionTest, NetworkChangeWithActiveStreams) { MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF }; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; @@ -1096,8 +1099,7 @@ TEST_F(SpdySessionTest, PingAndWriteLoop) { session_deps_.time_func = TheNearFuture; SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false)); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(write_ping, 1), }; @@ -1148,9 +1150,9 @@ TEST_F(SpdySessionTest, StreamIdSpaceExhausted) { // at which point the session closes. SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId - 2, MEDIUM, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId - 2, MEDIUM)); SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId, MEDIUM, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), @@ -1206,10 +1208,11 @@ TEST_F(SpdySessionTest, StreamIdSpaceExhausted) { SpdyStreamRequest request4; TestCompletionCallback callback4; - EXPECT_EQ( - ERR_IO_PENDING, - request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, - MEDIUM, NetLogWithSource(), callback4.callback())); + EXPECT_EQ(ERR_IO_PENDING, + request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, + test_url_, MEDIUM, SocketTag(), + NetLogWithSource(), callback4.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); // Streams 1-3 were created. 4th is stalled. No streams are active yet. EXPECT_EQ(0u, num_active_streams()); @@ -1277,8 +1280,7 @@ TEST_F(SpdySessionTest, MaxConcurrentStreamsZero) { SpdySerializedFrame settings_ack1(spdy_util_.ConstructSpdySettingsAck()); // Request and response. - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -1311,9 +1313,9 @@ TEST_F(SpdySessionTest, MaxConcurrentStreamsZero) { // Start request. SpdyStreamRequest request; TestCompletionCallback callback; - int rv = - request.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, - MEDIUM, NetLogWithSource(), callback.callback()); + int rv = request.StartRequest( + SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, SocketTag(), + NetLogWithSource(), callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Stream is stalled. @@ -1378,10 +1380,11 @@ TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) { SpdyStreamRequest request2; TestCompletionCallback callback2; - EXPECT_EQ( - ERR_IO_PENDING, - request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, - MEDIUM, NetLogWithSource(), callback2.callback())); + EXPECT_EQ(ERR_IO_PENDING, + request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, + test_url_, MEDIUM, SocketTag(), + NetLogWithSource(), callback2.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); EXPECT_EQ(1u, num_created_streams()); EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM)); @@ -1419,8 +1422,7 @@ TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) { TEST_F(SpdySessionTest, CancelPushAfterSessionGoesAway) { base::HistogramTester histogram_tester; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 2)}; @@ -1481,8 +1483,7 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) { base::HistogramTester histogram_tester; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame rst( @@ -1518,7 +1519,7 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) { auto ssl_params = base::MakeRefCounted<SSLSocketParams>( transport_params, nullptr, nullptr, key_.host_port_pair(), SSLConfig(), - key_.privacy_mode(), 0, false); + key_.privacy_mode(), 0); int rv = connection->Init( key_.host_port_pair().ToString(), ssl_params, MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), @@ -1535,7 +1536,8 @@ TEST_F(SpdySessionTest, CancelPushAfterExpired) { session_ = http_session_->spdy_session_pool()->CreateAvailableSessionFromSocket( - key_, std::move(connection), log_.bound()); + key_, /*is_trusted_proxy=*/false, std::move(connection), + log_.bound()); EXPECT_TRUE(session_); EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key_)); @@ -1594,8 +1596,7 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) { base::HistogramTester histogram_tester; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3)}; @@ -1626,7 +1627,7 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) { auto ssl_params = base::MakeRefCounted<SSLSocketParams>( transport_params, nullptr, nullptr, key_.host_port_pair(), SSLConfig(), - key_.privacy_mode(), 0, false); + key_.privacy_mode(), 0); int rv = connection->Init( key_.host_port_pair().ToString(), ssl_params, MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), @@ -1643,7 +1644,8 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) { session_ = http_session_->spdy_session_pool()->CreateAvailableSessionFromSocket( - key_, std::move(connection), log_.bound()); + key_, /*is_trusted_proxy=*/false, std::move(connection), + log_.bound()); EXPECT_TRUE(session_); EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key_)); @@ -1712,8 +1714,7 @@ TEST_F(SpdySessionTest, ClaimPushedStreamBeforeExpires) { TEST_F(SpdySessionTest, CancelPushBeforeClaimed) { base::HistogramTester histogram_tester; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame rst( @@ -1926,11 +1927,12 @@ TEST_F(SpdySessionTest, WaitingForWrongPing) { TEST_F(SpdySessionTest, OnSettings) { session_deps_.host_resolver->set_synchronous_mode(true); - const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS; + const SpdyKnownSettingsId kSpdyKnownSettingsId = + SETTINGS_MAX_CONCURRENT_STREAMS; SettingsMap new_settings; const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1; - new_settings[kSpdySettingsIds] = max_concurrent_streams; + new_settings[kSpdyKnownSettingsId] = max_concurrent_streams; SpdySerializedFrame settings_frame( spdy_util_.ConstructSpdySettings(new_settings)); MockRead reads[] = { @@ -1961,8 +1963,9 @@ TEST_F(SpdySessionTest, OnSettings) { SpdyStreamRequest request; ASSERT_EQ(ERR_IO_PENDING, request.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_, - MEDIUM, NetLogWithSource(), - stream_releaser.MakeCallback(&request))); + MEDIUM, SocketTag(), NetLogWithSource(), + stream_releaser.MakeCallback(&request), + TRAFFIC_ANNOTATION_FOR_TESTS)); base::RunLoop().RunUntilIdle(); @@ -2017,7 +2020,8 @@ TEST_F(SpdySessionTest, CancelPendingCreateStream) { SpdyStreamRequest request; ASSERT_THAT( request.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_, - MEDIUM, NetLogWithSource(), callback->callback()), + MEDIUM, SocketTag(), NetLogWithSource(), + callback->callback(), TRAFFIC_ANNOTATION_FOR_TESTS), IsError(ERR_IO_PENDING)); // Release the first one, this will allow the second to be created. @@ -2169,8 +2173,7 @@ TEST_F(SpdySessionTest, NetLogOnSessionEOF) { } TEST_F(SpdySessionTest, HeadersCompressionHistograms) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -2215,9 +2218,9 @@ TEST_F(SpdySessionTest, HeadersCompressionHistograms) { TEST_F(SpdySessionTest, OutOfOrderHeaders) { // Construct the request. SpdySerializedFrame req_highest( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST)); SpdySerializedFrame req_lowest( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); MockWrite writes[] = { CreateMockWrite(req_highest, 0), CreateMockWrite(req_lowest, 1), }; @@ -2283,8 +2286,7 @@ TEST_F(SpdySessionTest, OutOfOrderHeaders) { TEST_F(SpdySessionTest, CancelStream) { // Request 1, at HIGHEST priority, will be cancelled before it writes data. // Request 2, at LOWEST priority, will be a full request and will be id 1. - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(req2, 0), }; @@ -2469,10 +2471,8 @@ TEST_F(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; @@ -2542,10 +2542,8 @@ TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; @@ -2635,8 +2633,7 @@ class SessionClosingDelegate : public test::StreamDelegateDoNothing { TEST_F(SpdySessionTest, CloseActivatedStreamThatClosesSession) { session_deps_.host_resolver->set_synchronous_mode(true); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL)); SpdySerializedFrame goaway( @@ -2729,19 +2726,17 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) { // TODO(rtenneti): Define a helper class/methods and move the common code in // this file. SettingsMap new_settings; - const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; + const SpdyKnownSettingsId kSpdyKnownSettingsId1 = + SETTINGS_MAX_CONCURRENT_STREAMS; const uint32_t max_concurrent_streams = 1; - new_settings[kSpdySettingsIds1] = max_concurrent_streams; + new_settings[kSpdyKnownSettingsId1] = max_concurrent_streams; SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck()); - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); spdy_util_.UpdateWithStreamDestruction(1); - SpdySerializedFrame req2( - spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); + SpdySerializedFrame req2(spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST)); spdy_util_.UpdateWithStreamDestruction(3); - SpdySerializedFrame req3( - spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true)); + SpdySerializedFrame req3(spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST)); MockWrite writes[] = { CreateMockWrite(settings_ack, 1), CreateMockWrite(req1, 2), CreateMockWrite(req2, 5), CreateMockWrite(req3, 8), @@ -2794,17 +2789,19 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) { TestCompletionCallback callback2; SpdyStreamRequest request2; - ASSERT_EQ( - ERR_IO_PENDING, - request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, - LOWEST, NetLogWithSource(), callback2.callback())); + ASSERT_EQ(ERR_IO_PENDING, + request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, + test_url_, LOWEST, SocketTag(), + NetLogWithSource(), callback2.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); TestCompletionCallback callback3; SpdyStreamRequest request3; - ASSERT_EQ( - ERR_IO_PENDING, - request3.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, - LOWEST, NetLogWithSource(), callback3.callback())); + ASSERT_EQ(ERR_IO_PENDING, + request3.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_, + test_url_, LOWEST, SocketTag(), + NetLogWithSource(), callback3.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); EXPECT_EQ(0u, num_active_streams()); EXPECT_EQ(1u, num_created_streams()); @@ -2904,17 +2901,19 @@ TEST_F(SpdySessionTest, CancelTwoStalledCreateStream) { TestCompletionCallback callback2; SpdyStreamRequest request2; - ASSERT_EQ( - ERR_IO_PENDING, - request2.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_, - LOWEST, NetLogWithSource(), callback2.callback())); + ASSERT_EQ(ERR_IO_PENDING, + request2.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, + test_url_, LOWEST, SocketTag(), + NetLogWithSource(), callback2.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); TestCompletionCallback callback3; SpdyStreamRequest request3; - ASSERT_EQ( - ERR_IO_PENDING, - request3.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_, - LOWEST, NetLogWithSource(), callback3.callback())); + ASSERT_EQ(ERR_IO_PENDING, + request3.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, + test_url_, LOWEST, SocketTag(), + NetLogWithSource(), callback3.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS)); EXPECT_EQ(0u, num_active_streams()); EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams()); @@ -2957,8 +2956,7 @@ TEST_F(SpdySessionTest, ReadDataWithoutYielding) { session_deps_.host_resolver->set_synchronous_mode(true); session_deps_.time_func = InstantaneousReads; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; @@ -2973,9 +2971,9 @@ TEST_F(SpdySessionTest, ReadDataWithoutYielding) { test_stream.GetBytes(payload_data, kPayloadSize); SpdySerializedFrame partial_data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, payload_data, kPayloadSize, /*fin=*/false)); + 1, SpdyStringPiece(payload_data, kPayloadSize), /*fin=*/false)); SpdySerializedFrame finish_data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, payload_data, kPayloadSize - 1, /*fin=*/true)); + 1, SpdyStringPiece(payload_data, kPayloadSize - 1), /*fin=*/true)); SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -3041,8 +3039,7 @@ TEST_F(SpdySessionTest, TestYieldingSlowReads) { session_deps_.host_resolver->set_synchronous_mode(true); session_deps_.time_func = SlowReads; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; @@ -3100,16 +3097,15 @@ TEST_F(SpdySessionTest, TestYieldingSlowSynchronousReads) { session_deps_.host_resolver->set_synchronous_mode(true); session_deps_.time_func = SlowReads; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; SpdySerializedFrame partial_data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "foo ", 4, /*fin=*/false)); + spdy_util_.ConstructSpdyDataFrame(1, "foo ", /*fin=*/false)); SpdySerializedFrame finish_data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "bar", 3, /*fin=*/true)); + spdy_util_.ConstructSpdyDataFrame(1, "bar", /*fin=*/true)); SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -3167,8 +3163,7 @@ TEST_F(SpdySessionTest, TestYieldingDuringReadData) { session_deps_.host_resolver->set_synchronous_mode(true); session_deps_.time_func = InstantaneousReads; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; @@ -3183,9 +3178,9 @@ TEST_F(SpdySessionTest, TestYieldingDuringReadData) { test_stream.GetBytes(payload_data, kPayloadSize); SpdySerializedFrame partial_data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, payload_data, kPayloadSize, /*fin=*/false)); + 1, SpdyStringPiece(payload_data, kPayloadSize), /*fin=*/false)); SpdySerializedFrame finish_data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "h", 1, /*fin=*/true)); + spdy_util_.ConstructSpdyDataFrame(1, "h", /*fin=*/true)); SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -3258,8 +3253,7 @@ TEST_F(SpdySessionTest, TestYieldingDuringAsyncReadData) { session_deps_.host_resolver->set_synchronous_mode(true); session_deps_.time_func = InstantaneousReads; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; @@ -3281,11 +3275,13 @@ TEST_F(SpdySessionTest, TestYieldingDuringAsyncReadData) { test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); SpdySerializedFrame eightk_data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, eightk_payload_data, kEightKPayloadSize, /*fin=*/false)); + 1, SpdyStringPiece(eightk_payload_data, kEightKPayloadSize), + /*fin=*/false)); SpdySerializedFrame twok_data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, twok_payload_data, kTwoKPayloadSize, /*fin=*/false)); + 1, SpdyStringPiece(twok_payload_data, kTwoKPayloadSize), + /*fin=*/false)); SpdySerializedFrame finish_data_frame( - spdy_util_.ConstructSpdyDataFrame(1, "h", 1, /*fin=*/true)); + spdy_util_.ConstructSpdyDataFrame(1, "h", /*fin=*/true)); SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -3354,15 +3350,14 @@ TEST_F(SpdySessionTest, TestYieldingDuringAsyncReadData) { TEST_F(SpdySessionTest, GoAwayWhileInDoReadLoop) { session_deps_.host_resolver->set_synchronous_mode(true); - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req1, 0), }; SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true)); - SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway()); + SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(0)); MockRead reads[] = { CreateMockRead(resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -3508,14 +3503,16 @@ TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) { // Create an idle SPDY session. SpdySessionKey key1(HostPortPair("www.example.org", 80), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, + SocketTag()); base::WeakPtr<SpdySession> session1 = ::net::CreateSpdySession(http_session_.get(), key1, NetLogWithSource()); EXPECT_FALSE(pool->IsStalled()); // Set up an alias for the idle SPDY session, increasing its ref count to 2. SpdySessionKey key2(HostPortPair("mail.example.org", 80), - ProxyServer::Direct(), PRIVACY_MODE_DISABLED); + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, + SocketTag()); HostResolver::RequestInfo info(key2.host_port_pair()); AddressList addresses; std::unique_ptr<HostResolver::Request> request; @@ -3527,7 +3524,8 @@ TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) { // Get a session for |key2|, which should return the session created earlier. base::WeakPtr<SpdySession> session2 = spdy_session_pool_->FindAvailableSession( - key2, /* enable_ip_based_pooling = */ true, NetLogWithSource()); + key2, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, NetLogWithSource()); ASSERT_EQ(session1.get(), session2.get()); EXPECT_FALSE(pool->IsStalled()); @@ -3565,8 +3563,7 @@ TEST_F(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { MockRead reads[] = { MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. }; - SpdySerializedFrame req1( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame cancel1( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL)); MockWrite writes[] = { @@ -3649,9 +3646,9 @@ TEST_F(SpdySessionTest, SpdySessionKeyPrivacyMode) { HostPortPair host_port_pair("www.example.org", 443); SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(), - PRIVACY_MODE_ENABLED); + PRIVACY_MODE_ENABLED, SocketTag()); SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); @@ -3706,8 +3703,7 @@ class StreamCreatingDelegate : public test::StreamDelegateDoNothing { TEST_F(SpdySessionTest, CreateStreamOnStreamReset) { session_deps_.host_resolver->set_synchronous_mode(true); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -3942,8 +3938,8 @@ TEST_F(SpdySessionTest, SessionFlowControlPadding) { session_deps_.host_resolver->set_synchronous_mode(true); const int padding_length = 42; - SpdySerializedFrame resp(spdy_util_.ConstructSpdyDataFrame( - 1, kUploadData, kUploadDataSize, false, padding_length)); + SpdySerializedFrame resp( + spdy_util_.ConstructSpdyDataFrame(1, kUploadData, false, padding_length)); MockRead reads[] = { CreateMockRead(resp, 0), MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF @@ -3975,8 +3971,7 @@ TEST_F(SpdySessionTest, StreamFlowControlTooMuchData) { const int32_t stream_max_recv_window_size = 1024; const int32_t data_frame_size = 2 * stream_max_recv_window_size; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_FLOW_CONTROL_ERROR)); MockWrite writes[] = { @@ -3985,8 +3980,8 @@ TEST_F(SpdySessionTest, StreamFlowControlTooMuchData) { SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); const SpdyString payload(data_frame_size, 'a'); - SpdySerializedFrame data_frame(spdy_util_.ConstructSpdyDataFrame( - 1, payload.data(), data_frame_size, false)); + SpdySerializedFrame data_frame( + spdy_util_.ConstructSpdyDataFrame(1, payload, false)); MockRead reads[] = { CreateMockRead(resp, 1), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(data_frame, 3), MockRead(ASYNC, ERR_IO_PENDING, 5), @@ -4059,11 +4054,11 @@ TEST_F(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) { }; const SpdyString first_data_frame(first_data_frame_size, 'a'); - SpdySerializedFrame first(spdy_util_.ConstructSpdyDataFrame( - 1, first_data_frame.data(), first_data_frame_size, false)); + SpdySerializedFrame first( + spdy_util_.ConstructSpdyDataFrame(1, first_data_frame, false)); const SpdyString second_data_frame(second_data_frame_size, 'b'); - SpdySerializedFrame second(spdy_util_.ConstructSpdyDataFrame( - 1, second_data_frame.data(), second_data_frame_size, false)); + SpdySerializedFrame second( + spdy_util_.ConstructSpdyDataFrame(1, second_data_frame, false)); MockRead reads[] = { CreateMockRead(first, 0), MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(second, 2), MockRead(ASYNC, 0, 3), @@ -4108,8 +4103,7 @@ TEST_F(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) { ASSERT_LT(stream_max_recv_window_size, first_data_frame_size + second_data_frame_size); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_FLOW_CONTROL_ERROR)); MockWrite writes[] = { @@ -4118,11 +4112,11 @@ TEST_F(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) { SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); const SpdyString first_data_frame(first_data_frame_size, 'a'); - SpdySerializedFrame first(spdy_util_.ConstructSpdyDataFrame( - 1, first_data_frame.data(), first_data_frame_size, false)); + SpdySerializedFrame first( + spdy_util_.ConstructSpdyDataFrame(1, first_data_frame, false)); const SpdyString second_data_frame(second_data_frame_size, 'b'); - SpdySerializedFrame second(spdy_util_.ConstructSpdyDataFrame( - 1, second_data_frame.data(), second_data_frame_size, false)); + SpdySerializedFrame second( + spdy_util_.ConstructSpdyDataFrame(1, second_data_frame, false)); MockRead reads[] = { CreateMockRead(resp, 1), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(first, 3), MockRead(ASYNC, ERR_IO_PENDING, 4), @@ -4202,15 +4196,15 @@ TEST_F(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0)); - SpdySerializedFrame msg(spdy_util_.ConstructSpdyDataFrame( - 1, msg_data.data(), kMsgDataSize, false)); + SpdySerializedFrame msg( + spdy_util_.ConstructSpdyDataFrame(1, msg_data, false)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(msg, 2), }; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); - SpdySerializedFrame echo(spdy_util_.ConstructSpdyDataFrame( - 1, msg_data.data(), kMsgDataSize, false)); + SpdySerializedFrame echo( + spdy_util_.ConstructSpdyDataFrame(1, msg_data, false)); SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate( kSessionFlowControlStreamId, kMsgDataSize)); MockRead reads[] = { @@ -4344,15 +4338,15 @@ TEST_F(SpdySessionTest, SessionFlowControlEndToEnd) { SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0)); - SpdySerializedFrame msg(spdy_util_.ConstructSpdyDataFrame( - 1, msg_data.data(), kMsgDataSize, false)); + SpdySerializedFrame msg( + spdy_util_.ConstructSpdyDataFrame(1, msg_data, false)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(msg, 2), }; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); - SpdySerializedFrame echo(spdy_util_.ConstructSpdyDataFrame( - 1, msg_data.data(), kMsgDataSize, false)); + SpdySerializedFrame echo( + spdy_util_.ConstructSpdyDataFrame(1, msg_data, false)); SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate( kSessionFlowControlStreamId, kMsgDataSize)); MockRead reads[] = { @@ -4449,14 +4443,14 @@ void SpdySessionTest::RunResumeAfterUnstallTest( SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0)); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kBodyData, kBodyDataSize, true)); + spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true)); MockWrite writes[] = { CreateMockWrite(req, 0), CreateMockWrite(body, 1), }; SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); SpdySerializedFrame echo( - spdy_util_.ConstructSpdyDataFrame(1, kBodyData, kBodyDataSize, false)); + spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, false)); MockRead reads[] = { CreateMockRead(resp, 2), MockRead(ASYNC, 0, 3) // EOF }; @@ -4572,9 +4566,9 @@ TEST_F(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost( kDefaultUrl, 3, kBodyDataSize, MEDIUM, nullptr, 0)); SpdySerializedFrame body1( - spdy_util_.ConstructSpdyDataFrame(1, kBodyData, kBodyDataSize, true)); + spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true)); SpdySerializedFrame body2( - spdy_util_.ConstructSpdyDataFrame(3, kBodyData, kBodyDataSize, true)); + spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), CreateMockWrite(body2, 2), CreateMockWrite(body1, 3), @@ -4680,9 +4674,9 @@ TEST_F(SpdySessionTest, ResumeSessionWithStalledStream) { SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost( kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0)); SpdySerializedFrame body1( - spdy_util_.ConstructSpdyDataFrame(3, kBodyData, kBodyDataSize, true)); + spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true)); SpdySerializedFrame body2( - spdy_util_.ConstructSpdyDataFrame(1, kBodyData, kBodyDataSize, true)); + spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true)); MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), CreateMockWrite(body1, 2), CreateMockWrite(body2, 3)}; @@ -4822,7 +4816,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { SpdySerializedFrame req3(spdy_util_.ConstructSpdyPost( kDefaultUrl, 5, kBodyDataSize, LOWEST, nullptr, 0)); SpdySerializedFrame body2( - spdy_util_.ConstructSpdyDataFrame(3, kBodyData, kBodyDataSize, true)); + spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), CreateMockWrite(req3, 2), CreateMockWrite(body2, 3), @@ -4959,7 +4953,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost( kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0)); SpdySerializedFrame body1( - spdy_util_.ConstructSpdyDataFrame(1, kBodyData, kBodyDataSize, false)); + spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, false)); MockWrite writes[] = { CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), }; @@ -5044,8 +5038,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { } TEST_F(SpdySessionTest, GoAwayOnSessionFlowControlError) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( 0, ERROR_CODE_FLOW_CONTROL_ERROR, "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than " @@ -5112,8 +5105,7 @@ TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { }; SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck()); - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); MockWrite writes[] = { @@ -5194,8 +5186,7 @@ TEST_F(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { MockRead(ASYNC, ERR_IO_PENDING, 8), MockRead(ASYNC, 0, 9), }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority_a( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame priority_b( @@ -5287,8 +5278,7 @@ TEST_F(SpdySessionTest, TrustedSpdyProxy) { MockRead(ASYNC, 0, 8), }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority_http( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame rst_https( @@ -5301,16 +5291,10 @@ TEST_F(SpdySessionTest, TrustedSpdyProxy) { SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); session_deps_.socket_factory->AddSocketDataProvider(&data); - auto proxy_delegate = std::make_unique<TestProxyDelegate>(); - proxy_delegate->set_trusted_spdy_proxy( - net::ProxyServer(net::ProxyServer::SCHEME_HTTPS, - HostPortPair(GURL(kDefaultUrl).host(), 443))); - session_deps_.proxy_delegate = std::move(proxy_delegate); - AddSSLSocketData(); CreateNetworkSession(); - CreateSpdySession(); + CreateTrustedSpdySession(); base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_, @@ -5375,8 +5359,7 @@ TEST_F(SpdySessionTest, TrustedSpdyProxyNotSet) { MockRead(ASYNC, 0, 4), }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame rst( spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM)); MockWrite writes[] = { @@ -5440,8 +5423,7 @@ TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { MockRead(ASYNC, ERR_IO_PENDING, 10), MockRead(ASYNC, 0, 11), }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority_a( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame priority_b( @@ -5532,8 +5514,7 @@ TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8), }; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame rst( @@ -5638,8 +5619,7 @@ TEST_F(SpdySessionTest, GetPushedStream) { MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(headers_frame, 5), MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8)}; - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); SpdySerializedFrame priority( spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true)); SpdySerializedFrame rst( @@ -5775,6 +5755,121 @@ TEST_F(SpdySessionTest, RejectInvalidUnknownFrames) { EXPECT_FALSE(OnUnknownFrame(8, 0)); } +TEST_F(SpdySessionTest, EnableWebsocket) { + SettingsMap settings_map; + settings_map[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1; + SpdySerializedFrame settings(spdy_util_.ConstructSpdySettings(settings_map)); + MockRead reads[] = {CreateMockRead(settings, 0), + MockRead(ASYNC, ERR_IO_PENDING, 2), + MockRead(ASYNC, 0, 3)}; + + SpdySerializedFrame ack(spdy_util_.ConstructSpdySettingsAck()); + MockWrite writes[] = {CreateMockWrite(ack, 1)}; + + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + session_deps_.socket_factory->AddSocketDataProvider(&data); + + AddSSLSocketData(); + + CreateNetworkSession(); + CreateSpdySession(); + + EXPECT_FALSE(session_->support_websocket()); + + // Read SETTINGS frame. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(session_->support_websocket()); + + // Read EOF. + data.Resume(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(data.AllWriteDataConsumed()); + EXPECT_TRUE(data.AllReadDataConsumed()); + EXPECT_FALSE(session_); +} + +TEST_F(SpdySessionTest, DisableWebsocketDoesNothing) { + SettingsMap settings_map; + settings_map[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 0; + SpdySerializedFrame settings(spdy_util_.ConstructSpdySettings(settings_map)); + MockRead reads[] = {CreateMockRead(settings, 0), + MockRead(ASYNC, ERR_IO_PENDING, 2), + MockRead(ASYNC, 0, 3)}; + + SpdySerializedFrame ack(spdy_util_.ConstructSpdySettingsAck()); + MockWrite writes[] = {CreateMockWrite(ack, 1)}; + + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + session_deps_.socket_factory->AddSocketDataProvider(&data); + + AddSSLSocketData(); + + CreateNetworkSession(); + CreateSpdySession(); + + EXPECT_FALSE(session_->support_websocket()); + + // Read SETTINGS frame. + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(session_->support_websocket()); + + // Read EOF. + data.Resume(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(data.AllWriteDataConsumed()); + EXPECT_TRUE(data.AllReadDataConsumed()); + EXPECT_FALSE(session_); +} + +TEST_F(SpdySessionTest, EnableWebsocketThenDisableIsProtocolError) { + SettingsMap settings_map1; + settings_map1[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1; + SpdySerializedFrame settings1( + spdy_util_.ConstructSpdySettings(settings_map1)); + SettingsMap settings_map2; + settings_map2[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 0; + SpdySerializedFrame settings2( + spdy_util_.ConstructSpdySettings(settings_map2)); + MockRead reads[] = {CreateMockRead(settings1, 0), + MockRead(ASYNC, ERR_IO_PENDING, 2), + CreateMockRead(settings2, 3)}; + + SpdySerializedFrame ack1(spdy_util_.ConstructSpdySettingsAck()); + SpdySerializedFrame ack2(spdy_util_.ConstructSpdySettingsAck()); + SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway( + 0, ERROR_CODE_PROTOCOL_ERROR, + "Invalid value for SETTINGS_ENABLE_CONNECT_PROTOCOL.")); + MockWrite writes[] = {CreateMockWrite(ack1, 1), CreateMockWrite(ack2, 4), + CreateMockWrite(goaway, 5)}; + + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + session_deps_.socket_factory->AddSocketDataProvider(&data); + + AddSSLSocketData(); + + CreateNetworkSession(); + CreateSpdySession(); + + EXPECT_FALSE(session_->support_websocket()); + + // Read first SETTINGS frame. + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(session_->support_websocket()); + + // Read second SETTINGS frame. + data.Resume(); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(data.AllWriteDataConsumed()); + EXPECT_TRUE(data.AllReadDataConsumed()); + EXPECT_FALSE(session_); +} + enum ReadIfReadySupport { // ReadIfReady() field trial is enabled, and ReadIfReady() is implemented. READ_IF_READY_ENABLED_SUPPORTED, @@ -5810,8 +5905,7 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */, // Tests basic functionality of ReadIfReady() when it is enabled or disabled. TEST_P(SpdySessionReadIfReadyTest, ReadIfReady) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST)); MockWrite writes[] = { CreateMockWrite(req, 0), }; @@ -5930,15 +6024,15 @@ TEST_F(SendInitialSettingsOnNewSpdySessionTest, OverwriteValues) { // Unknown parameters should still be sent to the server. TEST_F(SendInitialSettingsOnNewSpdySessionTest, UnknownSettings) { // The following parameters are not defined in the HTTP/2 specification. - session_deps_.http2_settings[static_cast<SpdySettingsIds>(7)] = 1234; - session_deps_.http2_settings[static_cast<SpdySettingsIds>(25)] = 5678; + session_deps_.http2_settings[static_cast<SpdyKnownSettingsId>(7)] = 1234; + session_deps_.http2_settings[static_cast<SpdyKnownSettingsId>(25)] = 5678; SettingsMap expected_settings; expected_settings[SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize; expected_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = kSpdyMaxConcurrentPushedStreams; - expected_settings[static_cast<SpdySettingsIds>(7)] = 1234; - expected_settings[static_cast<SpdySettingsIds>(25)] = 5678; + expected_settings[static_cast<SpdyKnownSettingsId>(7)] = 1234; + expected_settings[static_cast<SpdyKnownSettingsId>(25)] = 5678; RunInitialSettingsTest(expected_settings); } @@ -6227,6 +6321,34 @@ TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnNonExistentStream) { .empty()); } +// Regression test for https://crbug.com/810404. +TEST_F(AltSvcFrameTest, InvalidOrigin) { + // This origin parses to an invalid GURL with https scheme. + const SpdyString origin("https:?"); + const GURL origin_gurl(origin); + EXPECT_FALSE(origin_gurl.is_valid()); + EXPECT_TRUE(origin_gurl.host().empty()); + EXPECT_TRUE(origin_gurl.SchemeIs(url::kHttpsScheme)); + + SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0); + altsvc_ir.add_altsvc(alternative_service_); + altsvc_ir.set_origin(origin); + AddSocketData(altsvc_ir); + AddSSLSocketData(); + + CreateNetworkSession(); + CreateSpdySession(); + + base::RunLoop().RunUntilIdle(); + + const url::SchemeHostPort session_origin("https", test_url_.host(), + test_url_.EffectiveIntPort()); + AlternativeServiceInfoVector altsvc_info_vector = + spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos( + session_origin); + EXPECT_TRUE(altsvc_info_vector.empty()); +} + TEST(MapFramerErrorToProtocolError, MapsValues) { CHECK_EQ(SPDY_ERROR_INVALID_CONTROL_FRAME, MapFramerErrorToProtocolError( diff --git a/chromium/net/spdy/chromium/spdy_stream.cc b/chromium/net/spdy/chromium/spdy_stream.cc index 41e08ed9154..5c38ee45f64 100644 --- a/chromium/net/spdy/chromium/spdy_stream.cc +++ b/chromium/net/spdy/chromium/spdy_stream.cc @@ -87,7 +87,8 @@ SpdyStream::SpdyStream(SpdyStreamType type, RequestPriority priority, int32_t initial_send_window_size, int32_t max_recv_window_size, - const NetLogWithSource& net_log) + const NetLogWithSource& net_log, + const NetworkTrafficAnnotationTag& traffic_annotation) : type_(type), stream_id_(0), url_(url), @@ -111,6 +112,7 @@ SpdyStream::SpdyStream(SpdyStreamType type, send_bytes_(0), recv_bytes_(0), write_handler_guard_(false), + traffic_annotation_(traffic_annotation), weak_ptr_factory_(this) { CHECK(type_ == SPDY_BIDIRECTIONAL_STREAM || type_ == SPDY_REQUEST_RESPONSE_STREAM || @@ -461,7 +463,8 @@ bool SpdyStream::ShouldRetryRSTPushStream() { return (response_headers_.empty() && type_ == SPDY_PUSH_STREAM && delegate_); } -void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers) { +void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers, + GURL url) { CHECK(!request_headers_valid_); CHECK_EQ(io_state_, STATE_IDLE); CHECK_EQ(type_, SPDY_PUSH_STREAM); @@ -470,7 +473,7 @@ void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers) { io_state_ = STATE_RESERVED_REMOTE; request_headers_ = std::move(headers); request_headers_valid_ = true; - url_from_header_block_ = GetUrlFromHeaderBlock(request_headers_); + url_from_header_block_ = std::move(url); } void SpdyStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { @@ -490,6 +493,13 @@ void SpdyStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { return; } + if (io_state_ == STATE_HALF_CLOSED_REMOTE) { + const SpdyString error("DATA received on half-closed (remove) stream."); + LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); + session_->ResetStream(stream_id_, ERROR_CODE_STREAM_CLOSED, error); + return; + } + // Track our bandwidth. recv_bytes_ += buffer ? buffer->GetRemainingSize() : 0; recv_last_byte_time_ = base::TimeTicks::Now(); diff --git a/chromium/net/spdy/chromium/spdy_stream.h b/chromium/net/spdy/chromium/spdy_stream.h index 06e6b1e8396..a47deebc30a 100644 --- a/chromium/net/spdy/chromium/spdy_stream.h +++ b/chromium/net/spdy/chromium/spdy_stream.h @@ -28,6 +28,7 @@ #include "net/spdy/core/spdy_protocol.h" #include "net/spdy/platform/api/spdy_string.h" #include "net/ssl/ssl_client_cert_type.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "url/gurl.h" namespace net { @@ -119,7 +120,8 @@ class NET_EXPORT_PRIVATE SpdyStream { RequestPriority priority, int32_t initial_send_window_size, int32_t max_recv_window_size, - const NetLogWithSource& net_log); + const NetLogWithSource& net_log, + const NetworkTrafficAnnotationTag& traffic_annotation); ~SpdyStream(); @@ -248,7 +250,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // Called by the SpdySession when a frame carrying request headers opening a // push stream is received. Stream transits to STATE_RESERVED_REMOTE state. - void OnPushPromiseHeadersReceived(SpdyHeaderBlock headers); + void OnPushPromiseHeadersReceived(SpdyHeaderBlock headers, GURL url); // Called by the SpdySession when response data has been received // for this stream. This callback may be called multiple times as @@ -321,6 +323,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // MORE_DATA_TO_SEND for bidirectional streams; for request/response // streams, it must be MORE_DATA_TO_SEND if there is more data to // upload, or NO_MORE_DATA_TO_SEND if not. + // Must not be called until Delegate::OnHeadersSent() is called. void SendData(IOBuffer* data, int length, SpdySendStatus send_status); // Fills SSL info in |ssl_info| and returns true when SSL is in use. @@ -383,6 +386,10 @@ class NET_EXPORT_PRIVATE SpdyStream { // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; + const NetworkTrafficAnnotationTag traffic_annotation() const { + return traffic_annotation_; + } + private: class HeadersBufferProducer; @@ -528,6 +535,8 @@ class NET_EXPORT_PRIVATE SpdyStream { // down. bool write_handler_guard_; + const NetworkTrafficAnnotationTag traffic_annotation_; + base::WeakPtrFactory<SpdyStream> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SpdyStream); diff --git a/chromium/net/spdy/chromium/spdy_stream_test_util.cc b/chromium/net/spdy/chromium/spdy_stream_test_util.cc index b891cd2ac22..24919ced517 100644 --- a/chromium/net/spdy/chromium/spdy_stream_test_util.cc +++ b/chromium/net/spdy/chromium/spdy_stream_test_util.cc @@ -8,7 +8,6 @@ #include <utility> #include "base/stl_util.h" -#include "net/base/completion_callback.h" #include "net/spdy/chromium/spdy_stream.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/net/spdy/chromium/spdy_stream_unittest.cc b/chromium/net/spdy/chromium/spdy_stream_unittest.cc index 12e40c0266c..dfdba6a9a1b 100644 --- a/chromium/net/spdy/chromium/spdy_stream_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_stream_unittest.cc @@ -15,13 +15,13 @@ #include "base/memory/ref_counted.h" #include "base/run_loop.h" -#include "net/base/completion_callback.h" #include "net/base/request_priority.h" #include "net/http/http_request_info.h" #include "net/log/net_log_event_type.h" #include "net/log/test_net_log.h" #include "net/log/test_net_log_entry.h" #include "net/log/test_net_log_util.h" +#include "net/socket/socket_tag.h" #include "net/socket/socket_test_util.h" #include "net/spdy/chromium/buffered_spdy_framer.h" #include "net/spdy/chromium/http2_push_promise_index.h" @@ -76,7 +76,7 @@ class SpdyStreamTest : public ::testing::Test { base::WeakPtr<SpdySession> CreateDefaultSpdySession() { SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); return CreateSpdySession(session_.get(), key, NetLogWithSource()); } @@ -170,11 +170,11 @@ TEST_F(SpdyStreamTest, SendDataAfterOpen) { AddRead(resp); SpdySerializedFrame msg( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddWrite(msg); SpdySerializedFrame echo( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(echo); AddReadEOF(); @@ -239,14 +239,14 @@ TEST_F(SpdyStreamTest, Trailers) { AddWrite(req); SpdySerializedFrame msg( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddWrite(msg); SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0)); AddRead(resp); SpdySerializedFrame echo( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(echo); SpdyHeaderBlock late_headers; @@ -295,8 +295,7 @@ TEST_F(SpdyStreamTest, Trailers) { } TEST_F(SpdyStreamTest, PushedStream) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -313,13 +312,12 @@ TEST_F(SpdyStreamTest, PushedStream) { AddReadPause(); SpdyStringPiece pushed_msg("foo"); - SpdySerializedFrame pushed_body(spdy_util_.ConstructSpdyDataFrame( - 2, pushed_msg.data(), pushed_msg.size(), true)); + SpdySerializedFrame pushed_body( + spdy_util_.ConstructSpdyDataFrame(2, pushed_msg, true)); AddRead(pushed_body); SpdyStringPiece msg("bar"); - SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, msg.data(), msg.size(), true)); + SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, msg, true)); AddRead(body); AddReadEOF(); @@ -356,7 +354,7 @@ TEST_F(SpdyStreamTest, PushedStream) { data.RunUntilPaused(); const SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(), - PRIVACY_MODE_DISABLED); + PRIVACY_MODE_DISABLED, SocketTag()); const GURL pushed_url(kPushUrl); HttpRequestInfo push_request; push_request.url = pushed_url; @@ -408,11 +406,11 @@ TEST_F(SpdyStreamTest, StreamError) { AddRead(resp); SpdySerializedFrame msg( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddWrite(msg); SpdySerializedFrame echo( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(echo); AddReadEOF(); @@ -476,13 +474,13 @@ TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) { AddWrite(req); SpdyString chunk_data(kMaxSpdyFrameChunkSize, 'x'); - SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame( - 1, chunk_data.data(), chunk_data.length(), false)); + SpdySerializedFrame chunk( + spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false)); AddWrite(chunk); AddWrite(chunk); - SpdySerializedFrame last_chunk(spdy_util_.ConstructSpdyDataFrame( - 1, chunk_data.data(), chunk_data.length(), true)); + SpdySerializedFrame last_chunk( + spdy_util_.ConstructSpdyDataFrame(1, chunk_data, true)); AddWrite(last_chunk); SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0)); @@ -535,8 +533,8 @@ TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { AddRead(resp); SpdyString chunk_data(kMaxSpdyFrameChunkSize, 'x'); - SpdySerializedFrame chunk(spdy_util_.ConstructSpdyDataFrame( - 1, chunk_data.data(), chunk_data.length(), false)); + SpdySerializedFrame chunk( + spdy_util_.ConstructSpdyDataFrame(1, chunk_data, false)); AddWrite(chunk); AddWrite(chunk); AddWrite(chunk); @@ -579,8 +577,7 @@ TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { // Receiving a header with uppercase ASCII should result in a protocol error. TEST_F(SpdyStreamTest, UpperCaseHeaders) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); const char* const kExtraHeaders[] = {"X-UpperCase", "yes"}; @@ -631,8 +628,7 @@ TEST_F(SpdyStreamTest, UpperCaseHeaders) { // Receiving a header with uppercase ASCII should result in a protocol error // even for a push stream. TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -693,8 +689,7 @@ TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) { } TEST_F(SpdyStreamTest, HeadersMustHaveStatus) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); // Response headers without ":status" header field: protocol error. @@ -747,8 +742,7 @@ TEST_F(SpdyStreamTest, HeadersMustHaveStatus) { } TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -777,7 +771,7 @@ TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) { AddWrite(rst); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddRead(body); AddReadEOF(); @@ -820,13 +814,12 @@ TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) { } TEST_F(SpdyStreamTest, HeadersMustPreceedData) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); // Response body not preceeded by headers: protocol error. SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddRead(body); SpdySerializedFrame rst( @@ -863,8 +856,7 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedData) { } TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -879,7 +871,7 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) { AddWrite(priority); SpdySerializedFrame pushed_body( - spdy_util_.ConstructSpdyDataFrame(2, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(2, kPostBodyStringPiece, true)); AddRead(pushed_body); SpdySerializedFrame rst( @@ -887,7 +879,7 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) { AddWrite(rst); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddRead(body); AddReadEOF(); @@ -930,15 +922,14 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) { } TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); AddRead(reply); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(body); SpdyHeaderBlock trailers_block; @@ -992,15 +983,14 @@ TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) { } TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdySerializedFrame reply(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); AddRead(reply); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(body); SpdyHeaderBlock trailers_block; @@ -1052,8 +1042,7 @@ TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) { } TEST_F(SpdyStreamTest, InformationalHeaders) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdyHeaderBlock informational_headers; @@ -1067,7 +1056,7 @@ TEST_F(SpdyStreamTest, InformationalHeaders) { AddRead(reply); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddRead(body); AddReadEOF(); @@ -1109,8 +1098,7 @@ TEST_F(SpdyStreamTest, InformationalHeaders) { } TEST_F(SpdyStreamTest, StatusMustBeNumber) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdyHeaderBlock incorrect_headers; @@ -1159,8 +1147,7 @@ TEST_F(SpdyStreamTest, StatusMustBeNumber) { } TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdyHeaderBlock headers_with_status_text; @@ -1171,7 +1158,7 @@ TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) { AddRead(reply); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddRead(body); SpdySerializedFrame rst( @@ -1214,8 +1201,7 @@ TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) { } TEST_F(SpdyStreamTest, StatusMustBePresent) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); SpdyHeaderBlock headers_without_status; @@ -1224,7 +1210,7 @@ TEST_F(SpdyStreamTest, StatusMustBePresent) { AddRead(reply); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddRead(body); SpdySerializedFrame rst( @@ -1362,7 +1348,7 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest( AddWrite(req); SpdySerializedFrame body( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, true)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); AddWrite(body); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); @@ -1438,11 +1424,11 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest( AddRead(resp); SpdySerializedFrame msg( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddWrite(msg); SpdySerializedFrame echo( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(echo); AddReadEOF(); @@ -1508,8 +1494,7 @@ TEST_F(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) { // Test calculation of amount of bytes received from network. TEST_F(SpdyStreamTest, ReceivedBytes) { - SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); + SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST)); AddWrite(req); AddReadPause(); @@ -1520,7 +1505,7 @@ TEST_F(SpdyStreamTest, ReceivedBytes) { AddReadPause(); SpdySerializedFrame msg( - spdy_util_.ConstructSpdyDataFrame(1, kPostBody, kPostBodyLength, false)); + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, false)); AddRead(msg); AddReadPause(); @@ -1578,6 +1563,61 @@ TEST_F(SpdyStreamTest, ReceivedBytes) { EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED)); } +// Regression test for https://crbug.com/810763. +TEST_F(SpdyStreamTest, DataOnHalfClosedRemoveStream) { + SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( + kDefaultUrl, 1, kPostBodyLength, LOWEST, nullptr, 0)); + AddWrite(req); + + SpdyHeaderBlock response_headers; + response_headers[kHttp2StatusHeader] = "200"; + SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders( + 1, std::move(response_headers), /* fin = */ true)); + AddRead(resp); + + SpdySerializedFrame data_frame( + spdy_util_.ConstructSpdyDataFrame(1, kPostBodyStringPiece, true)); + AddRead(data_frame); + + SpdySerializedFrame rst( + spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_STREAM_CLOSED)); + AddWrite(rst); + + AddReadEOF(); + + SequencedSocketData data(GetReads(), GetNumReads(), GetWrites(), + GetNumWrites()); + MockConnect connect_data(SYNCHRONOUS, OK); + data.set_connect_data(connect_data); + session_deps_.socket_factory->AddSocketDataProvider(&data); + + AddSSLSocketData(); + + base::WeakPtr<SpdySession> session(CreateDefaultSpdySession()); + + base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously( + SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource()); + ASSERT_TRUE(stream); + + StreamDelegateDoNothing delegate(stream); + stream->SetDelegate(&delegate); + + EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty()); + + SpdyHeaderBlock headers( + spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength)); + EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND), + IsError(ERR_IO_PENDING)); + EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec()); + + EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR)); + + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(data.AllReadDataConsumed()); + EXPECT_TRUE(data.AllWriteDataConsumed()); +} + } // namespace test } // namespace net diff --git a/chromium/net/spdy/chromium/spdy_test_util_common.cc b/chromium/net/spdy/chromium/spdy_test_util_common.cc index daa832c40bb..ff573aba4b5 100644 --- a/chromium/net/spdy/chromium/spdy_test_util_common.cc +++ b/chromium/net/spdy/chromium/spdy_test_util_common.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" +#include "net/base/completion_callback.h" #include "net/base/host_port_pair.h" #include "net/cert/ct_policy_enforcer.h" #include "net/cert/ct_policy_status.h" @@ -189,7 +190,7 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface { void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {} void OnSettings() override {} void OnSettingsAck() override {} - void OnSetting(SpdySettingsIds id, uint32_t value) override {} + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {} void OnSettingsEnd() override {} void OnPing(SpdyPingId unique_id, bool is_ack) override {} void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {} @@ -234,8 +235,9 @@ base::WeakPtr<SpdyStream> CreateStreamSynchronously( RequestPriority priority, const NetLogWithSource& net_log) { SpdyStreamRequest stream_request; - int rv = stream_request.StartRequest(type, session, url, priority, net_log, - CompletionCallback()); + int rv = stream_request.StartRequest( + type, session, url, priority, SocketTag(), net_log, + CompletionOnceCallback(), TRAFFIC_ANNOTATION_FOR_TESTS); return (rv == OK) ? stream_request.ReleaseStream() : base::WeakPtr<SpdyStream>(); } @@ -244,11 +246,10 @@ StreamReleaserCallback::StreamReleaserCallback() = default; StreamReleaserCallback::~StreamReleaserCallback() = default; -CompletionCallback StreamReleaserCallback::MakeCallback( +CompletionOnceCallback StreamReleaserCallback::MakeCallback( SpdyStreamRequest* request) { - return base::Bind(&StreamReleaserCallback::OnComplete, - base::Unretained(this), - request); + return base::BindOnce(&StreamReleaserCallback::OnComplete, + base::Unretained(this), request); } void StreamReleaserCallback::OnComplete( @@ -301,17 +302,17 @@ MockECSignatureCreatorFactory::Create(crypto::ECPrivateKey* key) { } SpdySessionDependencies::SpdySessionDependencies() - : SpdySessionDependencies(ProxyService::CreateDirect()) {} + : SpdySessionDependencies(ProxyResolutionService::CreateDirect()) {} SpdySessionDependencies::SpdySessionDependencies( - std::unique_ptr<ProxyService> proxy_service) + std::unique_ptr<ProxyResolutionService> proxy_resolution_service) : host_resolver(std::make_unique<MockCachingHostResolver>()), cert_verifier(std::make_unique<MockCertVerifier>()), channel_id_service(nullptr), transport_security_state(std::make_unique<TransportSecurityState>()), cert_transparency_verifier(std::make_unique<DoNothingCTVerifier>()), ct_policy_enforcer(std::make_unique<CTPolicyEnforcer>()), - proxy_service(std::move(proxy_service)), + proxy_resolution_service(std::move(proxy_resolution_service)), ssl_config_service(base::MakeRefCounted<SSLConfigServiceDefaults>()), socket_factory(std::make_unique<MockClientSocketFactory>()), http_auth_handler_factory( @@ -325,6 +326,7 @@ SpdySessionDependencies::SpdySessionDependencies( session_max_recv_window_size(kDefaultInitialWindowSize), time_func(&base::TimeTicks::Now), enable_http2_alternative_service(false), + enable_websocket_over_http2(false), net_log(nullptr), http_09_on_non_default_ports_enabled(false), disable_idle_sockets_close_on_memory_pressure(false) { @@ -379,6 +381,8 @@ HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams( params.time_func = session_deps->time_func; params.enable_http2_alternative_service = session_deps->enable_http2_alternative_service; + params.enable_websocket_over_http2 = + session_deps->enable_websocket_over_http2; params.http_09_on_non_default_ports_enabled = session_deps->http_09_on_non_default_ports_enabled; params.disable_idle_sockets_close_on_memory_pressure = @@ -398,7 +402,8 @@ HttpNetworkSession::Context SpdySessionDependencies::CreateSessionContext( context.cert_transparency_verifier = session_deps->cert_transparency_verifier.get(); context.ct_policy_enforcer = session_deps->ct_policy_enforcer.get(); - context.proxy_service = session_deps->proxy_service.get(); + context.proxy_resolution_service = + session_deps->proxy_resolution_service.get(); context.ssl_config_service = session_deps->ssl_config_service.get(); context.http_auth_handler_factory = session_deps->http_auth_handler_factory.get(); @@ -426,7 +431,7 @@ SpdyURLRequestContext::SpdyURLRequestContext() : storage_(this) { storage_.set_cert_verifier(std::make_unique<MockCertVerifier>()); storage_.set_transport_security_state( std::make_unique<TransportSecurityState>()); - storage_.set_proxy_service(ProxyService::CreateDirect()); + storage_.set_proxy_resolution_service(ProxyResolutionService::CreateDirect()); storage_.set_ct_policy_enforcer( std::make_unique<AllowAnyCertCTPolicyEnforcer>()); storage_.set_cert_transparency_verifier( @@ -445,7 +450,7 @@ SpdyURLRequestContext::SpdyURLRequestContext() : storage_(this) { session_context.host_resolver = host_resolver(); session_context.cert_verifier = cert_verifier(); session_context.transport_security_state = transport_security_state(); - session_context.proxy_service = proxy_service(); + session_context.proxy_resolution_service = proxy_resolution_service(); session_context.ct_policy_enforcer = ct_policy_enforcer(); session_context.cert_transparency_verifier = cert_transparency_verifier(); session_context.ssl_config_service = ssl_config_service(); @@ -467,7 +472,8 @@ SpdyURLRequestContext::~SpdyURLRequestContext() { bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key) { return static_cast<bool>(pool->FindAvailableSession( - key, /* enable_ip_based_pooling = */ true, NetLogWithSource())); + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, NetLogWithSource())); } namespace { @@ -476,9 +482,11 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper( HttpNetworkSession* http_session, const SpdySessionKey& key, const NetLogWithSource& net_log, - bool enable_ip_based_pooling) { + bool enable_ip_based_pooling, + bool is_trusted_proxy) { EXPECT_FALSE(http_session->spdy_session_pool()->FindAvailableSession( - key, enable_ip_based_pooling, NetLogWithSource())); + key, enable_ip_based_pooling, + /* is_websocket = */ false, NetLogWithSource())); auto transport_params = base::MakeRefCounted<TransportSocketParams>( key.host_port_pair(), /* disable_resolver_cache = */ false, @@ -491,9 +499,9 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper( SSLConfig ssl_config; auto ssl_params = base::MakeRefCounted<SSLSocketParams>( transport_params, nullptr, nullptr, key.host_port_pair(), ssl_config, - key.privacy_mode(), 0, /* expect_spdy = */ false); + key.privacy_mode(), 0); int rv = connection->Init( - key.host_port_pair().ToString(), ssl_params, MEDIUM, SocketTag(), + key.host_port_pair().ToString(), ssl_params, MEDIUM, key.socket_tag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), http_session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL), net_log); @@ -502,7 +510,7 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper( base::WeakPtr<SpdySession> spdy_session = http_session->spdy_session_pool()->CreateAvailableSessionFromSocket( - key, std::move(connection), net_log); + key, is_trusted_proxy, std::move(connection), net_log); // Failure is reported asynchronously. EXPECT_TRUE(spdy_session); EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key)); @@ -515,7 +523,17 @@ base::WeakPtr<SpdySession> CreateSpdySession(HttpNetworkSession* http_session, const SpdySessionKey& key, const NetLogWithSource& net_log) { return CreateSpdySessionHelper(http_session, key, net_log, - /* enable_ip_based_pooling = */ true); + /* enable_ip_based_pooling = */ true, + /* is_trusted_proxy = */ false); +} + +base::WeakPtr<SpdySession> CreateTrustedSpdySession( + HttpNetworkSession* http_session, + const SpdySessionKey& key, + const NetLogWithSource& net_log) { + return CreateSpdySessionHelper(http_session, key, net_log, + /* enable_ip_based_pooling = */ true, + /* is_trusted_proxy = */ true); } base::WeakPtr<SpdySession> CreateSpdySessionWithIpBasedPoolingDisabled( @@ -523,7 +541,8 @@ base::WeakPtr<SpdySession> CreateSpdySessionWithIpBasedPoolingDisabled( const SpdySessionKey& key, const NetLogWithSource& net_log) { return CreateSpdySessionHelper(http_session, key, net_log, - /* enable_ip_based_pooling = */ false); + /* enable_ip_based_pooling = */ false, + /* is_trusted_proxy = */ false); } namespace { @@ -593,8 +612,9 @@ base::WeakPtr<SpdySession> CreateFakeSpdySessionHelper( handle->SetSocket(std::make_unique<FakeSpdySessionClientSocket>( expected_status == OK ? ERR_IO_PENDING : expected_status)); base::WeakPtr<SpdySession> spdy_session = - pool->CreateAvailableSessionFromSocket(key, std::move(handle), - NetLogWithSource()); + pool->CreateAvailableSessionFromSocket( + key, + /*is_trusted_proxy=*/false, std::move(handle), NetLogWithSource()); // Failure is reported asynchronously. EXPECT_TRUE(spdy_session); EXPECT_TRUE(HasSpdySession(pool, key)); @@ -718,10 +738,6 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyPing(uint32_t ping_id, return SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(ping_ir)); } -SpdySerializedFrame SpdyTestUtil::ConstructSpdyGoAway() { - return ConstructSpdyGoAway(0); -} - SpdySerializedFrame SpdyTestUtil::ConstructSpdyGoAway( SpdyStreamId last_good_stream_id) { SpdyGoAwayIR go_ir(last_good_stream_id, ERROR_CODE_NO_ERROR, "go away"); @@ -779,8 +795,7 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyGet( const char* const extra_headers[], int extra_header_count, int stream_id, - RequestPriority request_priority, - bool direct) { + RequestPriority request_priority) { SpdyHeaderBlock block; block[kHttp2MethodHeader] = "GET"; AddUrlToHeaderBlock(default_url_.spec(), &block); @@ -980,26 +995,22 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyPostReply( SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id, bool fin) { - SpdyDataIR data_ir(stream_id, SpdyStringPiece(kUploadData, kUploadDataSize)); - data_ir.set_fin(fin); - return SpdySerializedFrame(headerless_spdy_framer_.SerializeData(data_ir)); + return ConstructSpdyDataFrame(stream_id, kUploadData, fin); } SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id, - const char* data, - uint32_t len, + base::StringPiece data, bool fin) { - SpdyDataIR data_ir(stream_id, SpdyStringPiece(data, len)); + SpdyDataIR data_ir(stream_id, data); data_ir.set_fin(fin); return SpdySerializedFrame(headerless_spdy_framer_.SerializeData(data_ir)); } SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id, - const char* data, - uint32_t len, + base::StringPiece data, bool fin, int padding_length) { - SpdyDataIR data_ir(stream_id, SpdyStringPiece(data, len)); + SpdyDataIR data_ir(stream_id, data); data_ir.set_fin(fin); data_ir.set_padding_len(padding_length); return SpdySerializedFrame(headerless_spdy_framer_.SerializeData(data_ir)); @@ -1008,7 +1019,8 @@ SpdySerializedFrame SpdyTestUtil::ConstructSpdyDataFrame(int stream_id, SpdySerializedFrame SpdyTestUtil::ConstructWrappedSpdyFrame( const SpdySerializedFrame& frame, int stream_id) { - return ConstructSpdyDataFrame(stream_id, frame.data(), frame.size(), false); + return ConstructSpdyDataFrame( + stream_id, base::StringPiece(frame.data(), frame.size()), false); } SpdySerializedFrame SpdyTestUtil::SerializeFrame(const SpdyFrameIR& frame_ir) { diff --git a/chromium/net/spdy/chromium/spdy_test_util_common.h b/chromium/net/spdy/chromium/spdy_test_util_common.h index 5aa3cd6a43b..c7187b38457 100644 --- a/chromium/net/spdy/chromium/spdy_test_util_common.h +++ b/chromium/net/spdy/chromium/spdy_test_util_common.h @@ -14,10 +14,12 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/strings/string_piece.h" #include "crypto/ec_private_key.h" #include "crypto/ec_signature_creator.h" -#include "net/base/completion_callback.h" +#include "net/base/completion_once_callback.h" #include "net/base/proxy_delegate.h" +#include "net/base/proxy_server.h" #include "net/base/request_priority.h" #include "net/base/test_completion_callback.h" #include "net/cert/cert_verifier.h" @@ -27,8 +29,7 @@ #include "net/http/http_response_info.h" #include "net/http/http_server_properties_impl.h" #include "net/http/transport_security_state.h" -#include "net/proxy/proxy_server.h" -#include "net/proxy/proxy_service.h" +#include "net/proxy_resolution/proxy_service.h" #include "net/socket/socket_test_util.h" #include "net/spdy/chromium/spdy_session.h" #include "net/spdy/core/spdy_protocol.h" @@ -120,26 +121,12 @@ class StreamReleaserCallback : public TestCompletionCallbackBase { ~StreamReleaserCallback() override; // Returns a callback that releases |request|'s stream. - CompletionCallback MakeCallback(SpdyStreamRequest* request); + CompletionOnceCallback MakeCallback(SpdyStreamRequest* request); private: void OnComplete(SpdyStreamRequest* request, int result); }; -// This struct holds information used to construct spdy control and data frames. -struct SpdyHeaderInfo { - SpdyFrameType kind; - SpdyStreamId id; - SpdyStreamId assoc_id; - SpdyPriority priority; - int weight; - SpdyControlFlags control_flags; - SpdyErrorCode error_code; - const char* data; - uint32_t data_length; - SpdyDataFlags data_flags; -}; - // An ECSignatureCreator that returns deterministic signatures. class MockECSignatureCreator : public crypto::ECSignatureCreator { public: @@ -179,7 +166,8 @@ struct SpdySessionDependencies { SpdySessionDependencies(); // Custom proxy service dependency. - explicit SpdySessionDependencies(std::unique_ptr<ProxyService> proxy_service); + explicit SpdySessionDependencies( + std::unique_ptr<ProxyResolutionService> proxy_resolution_service); ~SpdySessionDependencies(); @@ -203,7 +191,7 @@ struct SpdySessionDependencies { std::unique_ptr<TransportSecurityState> transport_security_state; std::unique_ptr<CTVerifier> cert_transparency_verifier; std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer; - std::unique_ptr<ProxyService> proxy_service; + std::unique_ptr<ProxyResolutionService> proxy_resolution_service; scoped_refptr<SSLConfigService> ssl_config_service; std::unique_ptr<MockClientSocketFactory> socket_factory; std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; @@ -218,6 +206,7 @@ struct SpdySessionDependencies { SpdySession::TimeFunc time_func; std::unique_ptr<ProxyDelegate> proxy_delegate; bool enable_http2_alternative_service; + bool enable_websocket_over_http2; NetLog* net_log; bool http_09_on_non_default_ports_enabled; bool disable_idle_sockets_close_on_memory_pressure; @@ -246,6 +235,13 @@ base::WeakPtr<SpdySession> CreateSpdySession(HttpNetworkSession* http_session, const SpdySessionKey& key, const NetLogWithSource& net_log); +// Like CreateSpdySession(), but the host is considered a trusted proxy and +// allowed to push cross-origin resources. +base::WeakPtr<SpdySession> CreateTrustedSpdySession( + HttpNetworkSession* http_session, + const SpdySessionKey& key, + const NetLogWithSource& net_log); + // Like CreateSpdySession(), but does not fail if there is already an IP // pooled session for |key|. base::WeakPtr<SpdySession> CreateSpdySessionWithIpBasedPoolingDisabled( @@ -304,43 +300,35 @@ class SpdyTestUtil { // Construct an expected SPDY SETTINGS frame. // |settings| are the settings to set. - // Returns the constructed frame. The caller takes ownership of the frame. + // Returns the constructed frame. SpdySerializedFrame ConstructSpdySettings(const SettingsMap& settings); // Constructs an expected SPDY SETTINGS acknowledgement frame. SpdySerializedFrame ConstructSpdySettingsAck(); - // Construct a SPDY PING frame. - // Returns the constructed frame. The caller takes ownership of the frame. + // Construct a SPDY PING frame. Returns the constructed frame. SpdySerializedFrame ConstructSpdyPing(uint32_t ping_id, bool is_ack); - // Construct a SPDY GOAWAY frame with last_good_stream_id = 0. - // Returns the constructed frame. The caller takes ownership of the frame. - SpdySerializedFrame ConstructSpdyGoAway(); - // Construct a SPDY GOAWAY frame with the specified last_good_stream_id. - // Returns the constructed frame. The caller takes ownership of the frame. + // Returns the constructed frame. SpdySerializedFrame ConstructSpdyGoAway(SpdyStreamId last_good_stream_id); // Construct a SPDY GOAWAY frame with the specified last_good_stream_id, - // status, and description. Returns the constructed frame. The caller takes - // ownership of the frame. + // status, and description. Returns the constructed frame. SpdySerializedFrame ConstructSpdyGoAway(SpdyStreamId last_good_stream_id, SpdyErrorCode error_code, const SpdyString& desc); - // Construct a SPDY WINDOW_UPDATE frame. - // Returns the constructed frame. The caller takes ownership of the frame. + // Construct a SPDY WINDOW_UPDATE frame. Returns the constructed frame. SpdySerializedFrame ConstructSpdyWindowUpdate(SpdyStreamId stream_id, uint32_t delta_window_size); - // Construct a SPDY RST_STREAM frame. - // Returns the constructed frame. The caller takes ownership of the frame. + // Construct a SPDY RST_STREAM frame. Returns the constructed frame. SpdySerializedFrame ConstructSpdyRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code); // Construct a PRIORITY frame. The weight is derived from |request_priority|. - // Returns the constructed frame. The caller takes ownership of the frame. + // Returns the constructed frame. SpdySerializedFrame ConstructSpdyPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id, RequestPriority request_priority, @@ -350,7 +338,6 @@ class SpdyTestUtil { // compression. // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyGet(const char* const url, SpdyStreamId stream_id, RequestPriority request_priority); @@ -359,12 +346,10 @@ class SpdyTestUtil { // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. If |direct| is false, the // the full url will be used instead of simply the path. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyGet(const char* const extra_headers[], int extra_header_count, int stream_id, - RequestPriority request_priority, - bool direct); + RequestPriority request_priority); // Constructs a SPDY HEADERS frame for a CONNECT request. SpdySerializedFrame ConstructSpdyConnect(const char* const extra_headers[], @@ -421,18 +406,15 @@ class SpdyTestUtil { // Constructs a standard SPDY HEADERS frame to match the SPDY GET. // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyGetReply(const char* const extra_headers[], int extra_header_count, int stream_id); // Constructs a standard SPDY HEADERS frame with an Internal Server // Error status code. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyReplyError(int stream_id); // Constructs a standard SPDY HEADERS frame with the specified status code. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyReplyError( const char* const status, const char* const* const extra_headers, @@ -442,7 +424,6 @@ class SpdyTestUtil { // Constructs a standard SPDY POST HEADERS frame. // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyPost(const char* url, SpdyStreamId stream_id, int64_t content_length, @@ -453,7 +434,6 @@ class SpdyTestUtil { // Constructs a chunked transfer SPDY POST HEADERS frame. // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructChunkedSpdyPost( const char* const extra_headers[], int extra_header_count); @@ -461,7 +441,6 @@ class SpdyTestUtil { // Constructs a standard SPDY HEADERS frame to match the SPDY POST. // |extra_headers| are the extra header-value pairs, which typically // will vary the most between calls. - // Returns a SpdySerializedFrame. SpdySerializedFrame ConstructSpdyPostReply(const char* const extra_headers[], int extra_header_count); @@ -470,14 +449,12 @@ class SpdyTestUtil { // Constructs a single SPDY data frame with the given content. SpdySerializedFrame ConstructSpdyDataFrame(int stream_id, - const char* data, - uint32_t len, + base::StringPiece data, bool fin); // Constructs a single SPDY data frame with the given content and padding. SpdySerializedFrame ConstructSpdyDataFrame(int stream_id, - const char* data, - uint32_t len, + base::StringPiece data, bool fin, int padding_length); diff --git a/chromium/net/spdy/chromium/spdy_write_queue.cc b/chromium/net/spdy/chromium/spdy_write_queue.cc index 2d874e44ae1..be0cf51b76b 100644 --- a/chromium/net/spdy/chromium/spdy_write_queue.cc +++ b/chromium/net/spdy/chromium/spdy_write_queue.cc @@ -22,10 +22,12 @@ SpdyWriteQueue::PendingWrite::PendingWrite() = default; SpdyWriteQueue::PendingWrite::PendingWrite( SpdyFrameType frame_type, std::unique_ptr<SpdyBufferProducer> frame_producer, - const base::WeakPtr<SpdyStream>& stream) + const base::WeakPtr<SpdyStream>& stream, + const MutableNetworkTrafficAnnotationTag& traffic_annotation) : frame_type(frame_type), frame_producer(std::move(frame_producer)), stream(stream), + traffic_annotation(traffic_annotation), has_stream(stream.get() != nullptr) {} SpdyWriteQueue::PendingWrite::~PendingWrite() = default; @@ -52,22 +54,27 @@ bool SpdyWriteQueue::IsEmpty() const { return true; } -void SpdyWriteQueue::Enqueue(RequestPriority priority, - SpdyFrameType frame_type, - std::unique_ptr<SpdyBufferProducer> frame_producer, - const base::WeakPtr<SpdyStream>& stream) { +void SpdyWriteQueue::Enqueue( + RequestPriority priority, + SpdyFrameType frame_type, + std::unique_ptr<SpdyBufferProducer> frame_producer, + const base::WeakPtr<SpdyStream>& stream, + const NetworkTrafficAnnotationTag& traffic_annotation) { CHECK(!removing_writes_); CHECK_GE(priority, MINIMUM_PRIORITY); CHECK_LE(priority, MAXIMUM_PRIORITY); if (stream.get()) DCHECK_EQ(stream->priority(), priority); - queue_[priority].push_back({frame_type, std::move(frame_producer), stream}); + queue_[priority].push_back( + {frame_type, std::move(frame_producer), stream, + MutableNetworkTrafficAnnotationTag(traffic_annotation)}); } bool SpdyWriteQueue::Dequeue( SpdyFrameType* frame_type, std::unique_ptr<SpdyBufferProducer>* frame_producer, - base::WeakPtr<SpdyStream>* stream) { + base::WeakPtr<SpdyStream>* stream, + MutableNetworkTrafficAnnotationTag* traffic_annotation) { CHECK(!removing_writes_); for (int i = MAXIMUM_PRIORITY; i >= MINIMUM_PRIORITY; --i) { if (!queue_[i].empty()) { @@ -76,6 +83,7 @@ bool SpdyWriteQueue::Dequeue( *frame_type = pending_write.frame_type; *frame_producer = std::move(pending_write.frame_producer); *stream = pending_write.stream; + *traffic_annotation = pending_write.traffic_annotation; if (pending_write.has_stream) DCHECK(stream->get()); return true; diff --git a/chromium/net/spdy/chromium/spdy_write_queue.h b/chromium/net/spdy/chromium/spdy_write_queue.h index 23377e1cf83..81a9ccd69fd 100644 --- a/chromium/net/spdy/chromium/spdy_write_queue.h +++ b/chromium/net/spdy/chromium/spdy_write_queue.h @@ -13,6 +13,7 @@ #include "net/base/net_export.h" #include "net/base/request_priority.h" #include "net/spdy/core/spdy_protocol.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace net { @@ -38,7 +39,8 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { void Enqueue(RequestPriority priority, SpdyFrameType frame_type, std::unique_ptr<SpdyBufferProducer> frame_producer, - const base::WeakPtr<SpdyStream>& stream); + const base::WeakPtr<SpdyStream>& stream, + const NetworkTrafficAnnotationTag& traffic_annotation); // Dequeues the frame producer with the highest priority that was // enqueued the earliest and its associated stream. Returns true and @@ -46,7 +48,8 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { // successful -- otherwise, just returns false. bool Dequeue(SpdyFrameType* frame_type, std::unique_ptr<SpdyBufferProducer>* frame_producer, - base::WeakPtr<SpdyStream>* stream); + base::WeakPtr<SpdyStream>* stream, + MutableNetworkTrafficAnnotationTag* traffic_annotation); // Removes all pending writes for the given stream, which must be // non-NULL. @@ -68,13 +71,15 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { SpdyFrameType frame_type; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; + MutableNetworkTrafficAnnotationTag traffic_annotation; // Whether |stream| was non-NULL when enqueued. bool has_stream; PendingWrite(); PendingWrite(SpdyFrameType frame_type, std::unique_ptr<SpdyBufferProducer> frame_producer, - const base::WeakPtr<SpdyStream>& stream); + const base::WeakPtr<SpdyStream>& stream, + const MutableNetworkTrafficAnnotationTag& traffic_annotation); ~PendingWrite(); PendingWrite(PendingWrite&& other); PendingWrite& operator=(PendingWrite&& other); diff --git a/chromium/net/spdy/chromium/spdy_write_queue_unittest.cc b/chromium/net/spdy/chromium/spdy_write_queue_unittest.cc index 8627e553134..fb5306dedb3 100644 --- a/chromium/net/spdy/chromium/spdy_write_queue_unittest.cc +++ b/chromium/net/spdy/chromium/spdy_write_queue_unittest.cc @@ -16,6 +16,7 @@ #include "net/spdy/chromium/spdy_buffer_producer.h" #include "net/spdy/chromium/spdy_stream.h" #include "net/spdy/platform/api/spdy_string.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -72,7 +73,8 @@ class RequeingBufferProducer : public SpdyBufferProducer { std::make_unique<SimpleBufferProducer>(std::move(buffer)); queue->Enqueue(MEDIUM, SpdyFrameType::RST_STREAM, - std::move(buffer_producer), base::WeakPtr<SpdyStream>()); + std::move(buffer_producer), base::WeakPtr<SpdyStream>(), + TRAFFIC_ANNOTATION_FOR_TESTS); } private: @@ -98,9 +100,9 @@ int ProducerToInt(std::unique_ptr<SpdyBufferProducer> producer) { // -- be careful to not call any functions that expect the session to // be there. std::unique_ptr<SpdyStream> MakeTestStream(RequestPriority priority) { - return std::make_unique<SpdyStream>(SPDY_BIDIRECTIONAL_STREAM, - base::WeakPtr<SpdySession>(), GURL(), - priority, 0, 0, NetLogWithSource()); + return std::make_unique<SpdyStream>( + SPDY_BIDIRECTIONAL_STREAM, base::WeakPtr<SpdySession>(), GURL(), priority, + 0, 0, NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS); } // Add some frame producers of different priority. The producers @@ -119,32 +121,39 @@ TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { // A NULL stream should still work. write_queue.Enqueue(LOW, SpdyFrameType::HEADERS, std::move(producer_low), - base::WeakPtr<SpdyStream>()); + base::WeakPtr<SpdyStream>(), + TRAFFIC_ANNOTATION_FOR_TESTS); write_queue.Enqueue(MEDIUM, SpdyFrameType::HEADERS, - std::move(producer_medium), stream_medium->GetWeakPtr()); + std::move(producer_medium), stream_medium->GetWeakPtr(), + TRAFFIC_ANNOTATION_FOR_TESTS); write_queue.Enqueue(HIGHEST, SpdyFrameType::RST_STREAM, - std::move(producer_highest), - stream_highest->GetWeakPtr()); + std::move(producer_highest), stream_highest->GetWeakPtr(), + TRAFFIC_ANNOTATION_FOR_TESTS); SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + MutableNetworkTrafficAnnotationTag traffic_annotation; + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::RST_STREAM, frame_type); EXPECT_EQ("HIGHEST", ProducerToString(std::move(frame_producer))); EXPECT_EQ(stream_highest.get(), stream.get()); - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::HEADERS, frame_type); EXPECT_EQ("MEDIUM", ProducerToString(std::move(frame_producer))); EXPECT_EQ(stream_medium.get(), stream.get()); - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::HEADERS, frame_type); EXPECT_EQ("LOW", ProducerToString(std::move(frame_producer))); EXPECT_EQ(nullptr, stream.get()); - EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); } // Add some frame producers with the same priority. The producers @@ -161,31 +170,39 @@ TEST_F(SpdyWriteQueueTest, DequeuesFIFO) { std::unique_ptr<SpdyStream> stream3 = MakeTestStream(DEFAULT_PRIORITY); write_queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, - std::move(producer1), stream1->GetWeakPtr()); + std::move(producer1), stream1->GetWeakPtr(), + TRAFFIC_ANNOTATION_FOR_TESTS); write_queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, - std::move(producer2), stream2->GetWeakPtr()); + std::move(producer2), stream2->GetWeakPtr(), + TRAFFIC_ANNOTATION_FOR_TESTS); write_queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::RST_STREAM, - std::move(producer3), stream3->GetWeakPtr()); + std::move(producer3), stream3->GetWeakPtr(), + TRAFFIC_ANNOTATION_FOR_TESTS); SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + MutableNetworkTrafficAnnotationTag traffic_annotation; + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::HEADERS, frame_type); EXPECT_EQ(1, ProducerToInt(std::move(frame_producer))); EXPECT_EQ(stream1.get(), stream.get()); - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::HEADERS, frame_type); EXPECT_EQ(2, ProducerToInt(std::move(frame_producer))); EXPECT_EQ(stream2.get(), stream.get()); - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::RST_STREAM, frame_type); EXPECT_EQ(3, ProducerToInt(std::move(frame_producer))); EXPECT_EQ(stream3.get(), stream.get()); - EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); } // Enqueue a bunch of writes and then call @@ -201,7 +218,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { base::WeakPtr<SpdyStream> stream = (((i % 3) == 0) ? stream1 : stream2)->GetWeakPtr(); write_queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, - IntToProducer(i), stream); + IntToProducer(i), stream, TRAFFIC_ANNOTATION_FOR_TESTS); } write_queue.RemovePendingWritesForStream(stream2->GetWeakPtr()); @@ -210,16 +227,22 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + MutableNetworkTrafficAnnotationTag traffic_annotation; + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); EXPECT_EQ(SpdyFrameType::HEADERS, frame_type); EXPECT_EQ(i, ProducerToInt(std::move(frame_producer))); EXPECT_EQ(stream1.get(), stream.get()); + EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), + traffic_annotation); } SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + MutableNetworkTrafficAnnotationTag traffic_annotation; + EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); } // Enqueue a bunch of writes and then call @@ -244,7 +267,8 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) { for (int i = 0; i < 100; ++i) { write_queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, - IntToProducer(i), streams[i % arraysize(streams)]); + IntToProducer(i), streams[i % arraysize(streams)], + TRAFFIC_ANNOTATION_FOR_TESTS); } write_queue.RemovePendingWritesForStreamsAfter(stream1->stream_id()); @@ -253,17 +277,23 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) { SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)) + MutableNetworkTrafficAnnotationTag traffic_annotation; + ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)) << "Unable to Dequeue i: " << i; EXPECT_EQ(SpdyFrameType::HEADERS, frame_type); EXPECT_EQ(i, ProducerToInt(std::move(frame_producer))); EXPECT_EQ(stream1.get(), stream.get()); + EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), + traffic_annotation); } SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + MutableNetworkTrafficAnnotationTag traffic_annotation; + EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); } // Enqueue a bunch of writes and then call Clear(). The write queue @@ -274,7 +304,8 @@ TEST_F(SpdyWriteQueueTest, Clear) { for (int i = 0; i < 100; ++i) { write_queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, - IntToProducer(i), base::WeakPtr<SpdyStream>()); + IntToProducer(i), base::WeakPtr<SpdyStream>(), + TRAFFIC_ANNOTATION_FOR_TESTS); } write_queue.Clear(); @@ -282,20 +313,24 @@ TEST_F(SpdyWriteQueueTest, Clear) { SpdyFrameType frame_type = SpdyFrameType::DATA; std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; - EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); + MutableNetworkTrafficAnnotationTag traffic_annotation; + EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream, + &traffic_annotation)); } TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) { SpdyWriteQueue queue; queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, std::make_unique<RequeingBufferProducer>(&queue), - base::WeakPtr<SpdyStream>()); + base::WeakPtr<SpdyStream>(), TRAFFIC_ANNOTATION_FOR_TESTS); { SpdyFrameType frame_type; std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; + MutableNetworkTrafficAnnotationTag traffic_annotation; - EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); + EXPECT_TRUE( + queue.Dequeue(&frame_type, &producer, &stream, &traffic_annotation)); EXPECT_TRUE(queue.IsEmpty()); EXPECT_EQ(SpdyString(kOriginal), producer->ProduceBuffer()->GetRemainingData()); @@ -306,8 +341,10 @@ TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) { SpdyFrameType frame_type; std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; + MutableNetworkTrafficAnnotationTag traffic_annotation; - EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); + EXPECT_TRUE( + queue.Dequeue(&frame_type, &producer, &stream, &traffic_annotation)); EXPECT_EQ(SpdyString(kRequeued), producer->ProduceBuffer()->GetRemainingData()); } @@ -316,7 +353,7 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnClear) { SpdyWriteQueue queue; queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, std::make_unique<RequeingBufferProducer>(&queue), - base::WeakPtr<SpdyStream>()); + base::WeakPtr<SpdyStream>(), TRAFFIC_ANNOTATION_FOR_TESTS); queue.Clear(); EXPECT_FALSE(queue.IsEmpty()); @@ -324,8 +361,10 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnClear) { SpdyFrameType frame_type; std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; + MutableNetworkTrafficAnnotationTag traffic_annotation; - EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); + EXPECT_TRUE( + queue.Dequeue(&frame_type, &producer, &stream, &traffic_annotation)); EXPECT_EQ(SpdyString(kRequeued), producer->ProduceBuffer()->GetRemainingData()); } @@ -337,7 +376,7 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) { SpdyWriteQueue queue; queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, std::make_unique<RequeingBufferProducer>(&queue), - stream->GetWeakPtr()); + stream->GetWeakPtr(), TRAFFIC_ANNOTATION_FOR_TESTS); queue.RemovePendingWritesForStreamsAfter(1); EXPECT_FALSE(queue.IsEmpty()); @@ -345,8 +384,10 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) { SpdyFrameType frame_type; std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> weak_stream; + MutableNetworkTrafficAnnotationTag traffic_annotation; - EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream)); + EXPECT_TRUE( + queue.Dequeue(&frame_type, &producer, &weak_stream, &traffic_annotation)); EXPECT_EQ(SpdyString(kRequeued), producer->ProduceBuffer()->GetRemainingData()); } @@ -358,7 +399,7 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesForStream) { SpdyWriteQueue queue; queue.Enqueue(DEFAULT_PRIORITY, SpdyFrameType::HEADERS, std::make_unique<RequeingBufferProducer>(&queue), - stream->GetWeakPtr()); + stream->GetWeakPtr(), TRAFFIC_ANNOTATION_FOR_TESTS); queue.RemovePendingWritesForStream(stream->GetWeakPtr()); EXPECT_FALSE(queue.IsEmpty()); @@ -366,8 +407,10 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesForStream) { SpdyFrameType frame_type; std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> weak_stream; + MutableNetworkTrafficAnnotationTag traffic_annotation; - EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream)); + EXPECT_TRUE( + queue.Dequeue(&frame_type, &producer, &weak_stream, &traffic_annotation)); EXPECT_EQ(SpdyString(kRequeued), producer->ProduceBuffer()->GetRemainingData()); } diff --git a/chromium/net/spdy/core/hpack/hpack_constants.h b/chromium/net/spdy/core/hpack/hpack_constants.h index 89790735ec1..401d8b97ee4 100644 --- a/chromium/net/spdy/core/hpack/hpack_constants.h +++ b/chromium/net/spdy/core/hpack/hpack_constants.h @@ -43,36 +43,37 @@ struct HpackStaticEntry { class HpackHuffmanTable; class HpackStaticTable; -// Defined in RFC 7540 section 6.5.2. +// Defined in RFC 7540, 6.5.2. const uint32_t kDefaultHeaderTableSizeSetting = 4096; -// 6.2: Flag for a string literal that is stored unmodified (i.e., +// RFC 7541, 5.2: Flag for a string literal that is stored unmodified (i.e., // without Huffman encoding). const HpackPrefix kStringLiteralIdentityEncoded = {0x0, 1}; -// 6.2: Flag for a Huffman-coded string literal. +// RFC 7541, 5.2: Flag for a Huffman-coded string literal. const HpackPrefix kStringLiteralHuffmanEncoded = {0x1, 1}; -// 7.1: Opcode for an indexed header field. -const HpackPrefix kIndexedOpcode = {0x1, 1}; +// RFC 7541, 6.1: Opcode for an indexed header field. +const HpackPrefix kIndexedOpcode = {0b1, 1}; -// 7.2.1: Opcode for a literal header field with incremental indexing. -const HpackPrefix kLiteralIncrementalIndexOpcode = {0x1, 2}; +// RFC 7541, 6.2.1: Opcode for a literal header field with incremental indexing. +const HpackPrefix kLiteralIncrementalIndexOpcode = {0b01, 2}; -// 7.2.2: Opcode for a literal header field without indexing. -const HpackPrefix kLiteralNoIndexOpcode = {0x0, 4}; +// RFC 7541, 6.2.2: Opcode for a literal header field without indexing. +const HpackPrefix kLiteralNoIndexOpcode = {0b0000, 4}; -// 7.2.3: Opcode for a literal header field which is never indexed. -const HpackPrefix kLiteralNeverIndexOpcode = {0x1, 4}; +// RFC 7541, 6.2.3: Opcode for a literal header field which is never indexed. +// Currently unused. +// const HpackPrefix kLiteralNeverIndexOpcode = {0b0001, 4}; -// 7.3: Opcode for maximum header table size update. Begins a varint-encoded -// table size with a 5-bit prefix. -const HpackPrefix kHeaderTableSizeUpdateOpcode = {0x1, 3}; +// RFC 7541, 6.3: Opcode for maximum header table size update. Begins a +// varint-encoded table size with a 5-bit prefix. +const HpackPrefix kHeaderTableSizeUpdateOpcode = {0b001, 3}; -// Returns symbol code table from "Appendix C. Huffman Code". +// Returns symbol code table from RFC 7541, "Appendix C. Huffman Code". SPDY_EXPORT_PRIVATE std::vector<HpackHuffmanSymbol> HpackHuffmanCode(); -// Returns static table from "Appendix B. Static Table Definition". +// Returns static table from RFC 7541, "Appendix B. Static Table Definition". SPDY_EXPORT_PRIVATE std::vector<HpackStaticEntry> HpackStaticTableVector(); // Returns a HpackHuffmanTable instance initialized with |kHpackHuffmanCode|. diff --git a/chromium/net/spdy/core/http2_frame_decoder_adapter.cc b/chromium/net/spdy/core/http2_frame_decoder_adapter.cc index 0655db68fe4..2922d8fa5e4 100644 --- a/chromium/net/spdy/core/http2_frame_decoder_adapter.cc +++ b/chromium/net/spdy/core/http2_frame_decoder_adapter.cc @@ -160,10 +160,7 @@ const char* Http2DecoderAdapter::SpdyFramerErrorToString( return "UNKNOWN_ERROR"; } -Http2DecoderAdapter::Http2DecoderAdapter() : Http2DecoderAdapter(false) {} - -Http2DecoderAdapter::Http2DecoderAdapter(bool h2_on_stream_pad_length) - : h2_on_stream_pad_length_(h2_on_stream_pad_length) { +Http2DecoderAdapter::Http2DecoderAdapter() { DVLOG(1) << "Http2DecoderAdapter ctor"; ResetInternal(); } @@ -441,11 +438,7 @@ void Http2DecoderAdapter::OnPadLength(size_t trailing_length) { opt_pad_length_ = trailing_length; DCHECK_LT(trailing_length, 256u); if (frame_header_.type == Http2FrameType::DATA) { - if (h2_on_stream_pad_length_) { - visitor()->OnStreamPadLength(stream_id(), trailing_length); - } else { - visitor()->OnStreamPadding(stream_id(), 1); - } + visitor()->OnStreamPadLength(stream_id(), trailing_length); } } @@ -480,8 +473,8 @@ void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) { void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) { DVLOG(1) << "OnSetting: " << setting_fields; - const uint16_t parameter = static_cast<uint16_t>(setting_fields.parameter); - SpdySettingsIds setting_id; + const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter); + SpdyKnownSettingsId setting_id; if (!ParseSettingsId(parameter, &setting_id)) { if (extension_ == nullptr) { DVLOG(1) << "Ignoring unknown setting id: " << setting_fields; @@ -804,7 +797,7 @@ void Http2DecoderAdapter::ResetInternal() { CorruptFrameHeader(&frame_header_); CorruptFrameHeader(&hpack_first_frame_header_); - frame_decoder_.reset(new Http2FrameDecoder(this)); + frame_decoder_ = SpdyMakeUnique<Http2FrameDecoder>(this); hpack_decoder_ = nullptr; } diff --git a/chromium/net/spdy/core/http2_frame_decoder_adapter.h b/chromium/net/spdy/core/http2_frame_decoder_adapter.h index 94be5d4c353..b8cf74101e3 100644 --- a/chromium/net/spdy/core/http2_frame_decoder_adapter.h +++ b/chromium/net/spdy/core/http2_frame_decoder_adapter.h @@ -77,7 +77,6 @@ class SPDY_EXPORT_PRIVATE Http2DecoderAdapter static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error); Http2DecoderAdapter(); - explicit Http2DecoderAdapter(bool h2_on_stream_pad_length); ~Http2DecoderAdapter() override; // Set callbacks to be called from the framer. A visitor must be set, or @@ -315,9 +314,6 @@ class SPDY_EXPORT_PRIVATE Http2DecoderAdapter bool handling_extension_payload_ = false; bool process_single_input_frame_ = false; - - // Flag value latched at construction. - const bool h2_on_stream_pad_length_ : 1; }; // Http2DecoderAdapter will use the given visitor implementing this @@ -400,7 +396,7 @@ class SPDY_EXPORT_PRIVATE SpdyFramerVisitorInterface { // Called when a complete setting within a SETTINGS frame has been parsed and // validated. - virtual void OnSetting(SpdySettingsIds id, uint32_t value) = 0; + virtual void OnSetting(SpdyKnownSettingsId id, uint32_t value) = 0; // Called when a SETTINGS frame is received with the ACK flag set. virtual void OnSettingsAck() {} @@ -490,7 +486,7 @@ class SPDY_EXPORT_PRIVATE ExtensionVisitorInterface { virtual ~ExtensionVisitorInterface() {} // Called when non-standard SETTINGS are received. - virtual void OnSetting(uint16_t id, uint32_t value) = 0; + virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0; // Called when non-standard frames are received. virtual bool OnFrameHeader(SpdyStreamId stream_id, diff --git a/chromium/net/spdy/core/mock_spdy_framer_visitor.h b/chromium/net/spdy/core/mock_spdy_framer_visitor.h index 696d508b9ff..4efbe538454 100644 --- a/chromium/net/spdy/core/mock_spdy_framer_visitor.h +++ b/chromium/net/spdy/core/mock_spdy_framer_visitor.h @@ -40,7 +40,7 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface { MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id, SpdyErrorCode error_code)); MOCK_METHOD0(OnSettings, void()); - MOCK_METHOD2(OnSetting, void(SpdySettingsIds id, uint32_t value)); + MOCK_METHOD2(OnSetting, void(SpdyKnownSettingsId id, uint32_t value)); MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack)); MOCK_METHOD0(OnSettingsEnd, void()); MOCK_METHOD2(OnGoAway, diff --git a/chromium/net/spdy/core/priority_write_scheduler.h b/chromium/net/spdy/core/priority_write_scheduler.h index fa14d4d9f46..c4c84cc7058 100644 --- a/chromium/net/spdy/core/priority_write_scheduler.h +++ b/chromium/net/spdy/core/priority_write_scheduler.h @@ -250,6 +250,17 @@ class PriorityWriteScheduler : public WriteScheduler<StreamIdType> { // Returns the number of ready streams. size_t NumReadyStreams() const override { return num_ready_streams_; } + // This function is used for debugging and test only. Returns true if a stream + // is ready. + bool IsStreamReady(StreamIdType stream_id) const { + auto it = stream_infos_.find(stream_id); + if (it == stream_infos_.end()) { + DLOG(INFO) << "Stream " << stream_id << " not registered"; + return false; + } + return it->second.ready; + } + private: friend class test::PriorityWriteSchedulerPeer<StreamIdType>; diff --git a/chromium/net/spdy/core/priority_write_scheduler_test.cc b/chromium/net/spdy/core/priority_write_scheduler_test.cc index 1dd7263eaa5..c99237c9b80 100644 --- a/chromium/net/spdy/core/priority_write_scheduler_test.cc +++ b/chromium/net/spdy/core/priority_write_scheduler_test.cc @@ -164,9 +164,13 @@ TEST_F(PriorityWriteSchedulerTest, UpdateStreamPrecedence) { // first by PopNextReadyStream() since it has higher priority. scheduler_.RegisterStream(4, SpdyStreamPrecedence(1)); scheduler_.MarkStreamReady(3, false); // priority 2 + EXPECT_TRUE(scheduler_.IsStreamReady(3)); scheduler_.MarkStreamReady(4, false); // priority 1 + EXPECT_TRUE(scheduler_.IsStreamReady(4)); EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); + EXPECT_FALSE(scheduler_.IsStreamReady(4)); EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); + EXPECT_FALSE(scheduler_.IsStreamReady(3)); // Verify that lowering priority of stream 4 causes it to be returned later // by PopNextReadyStream(). diff --git a/chromium/net/spdy/core/spdy_alt_svc_wire_format_test.cc b/chromium/net/spdy/core/spdy_alt_svc_wire_format_test.cc index 3b39d15daa5..94e26ab90fa 100644 --- a/chromium/net/spdy/core/spdy_alt_svc_wire_format_test.cc +++ b/chromium/net/spdy/core/spdy_alt_svc_wire_format_test.cc @@ -158,8 +158,6 @@ void FuzzAlternativeService(int i, } } -class SpdyAltSvcWireFormatTest : public ::testing::Test {}; - // Tests of public API. TEST(SpdyAltSvcWireFormatTest, DefaultValues) { diff --git a/chromium/net/spdy/core/spdy_bitmasks.h b/chromium/net/spdy/core/spdy_bitmasks.h index 1e9ddd10593..a0c4b1b352a 100644 --- a/chromium/net/spdy/core/spdy_bitmasks.h +++ b/chromium/net/spdy/core/spdy_bitmasks.h @@ -10,18 +10,9 @@ namespace net { // StreamId mask from the SpdyHeader const unsigned int kStreamIdMask = 0x7fffffff; -// Control flag mask from the SpdyHeader -const unsigned int kControlFlagMask = 0x8000; - // Mask the lower 24 bits. const unsigned int kLengthMask = 0xffffff; -// Legal flags on data packets. -const int kDataFlagsMask = 0x01; - -// Legal flags on control packets. -const int kControlFlagsMask = 0x03; - } // namespace net #endif // NET_SPDY_CORE_SPDY_BITMASKS_H_ diff --git a/chromium/net/spdy/core/spdy_deframer_visitor.cc b/chromium/net/spdy/core/spdy_deframer_visitor.cc index e7d1a46daaf..99ee8998662 100644 --- a/chromium/net/spdy/core/spdy_deframer_visitor.cc +++ b/chromium/net/spdy/core/spdy_deframer_visitor.cc @@ -164,7 +164,7 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer, SpdyStreamId promised_stream_id, bool end) override; void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override; - void OnSetting(SpdySettingsIds id, uint32_t value) override; + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override; void OnSettings() override; void OnSettingsAck() override; void OnSettingsEnd() override; @@ -604,7 +604,7 @@ void SpdyTestDeframerImpl::OnRstStream(SpdyStreamId stream_id, // Called for an individual setting. There is no negotiation, the sender is // stating the value that the sender is using. -void SpdyTestDeframerImpl::OnSetting(SpdySettingsIds id, uint32_t value) { +void SpdyTestDeframerImpl::OnSetting(SpdyKnownSettingsId id, uint32_t value) { DVLOG(1) << "OnSetting id: " << id << std::hex << " value: " << value; CHECK_EQ(frame_type_, SETTINGS) << " frame_type_=" << Http2FrameTypeToString(frame_type_); diff --git a/chromium/net/spdy/core/spdy_deframer_visitor.h b/chromium/net/spdy/core/spdy_deframer_visitor.h index a8174cd669a..fb6210303f5 100644 --- a/chromium/net/spdy/core/spdy_deframer_visitor.h +++ b/chromium/net/spdy/core/spdy_deframer_visitor.h @@ -86,7 +86,7 @@ namespace net { namespace test { // Non-lossy representation of a SETTINGS frame payload. -typedef std::vector<std::pair<SpdySettingsIds, uint32_t>> SettingVector; +typedef std::vector<std::pair<SpdyKnownSettingsId, uint32_t>> SettingVector; // StringPairVector is used to record information lost by SpdyHeaderBlock, in // particular the order of each header entry, though it doesn't expose the diff --git a/chromium/net/spdy/core/spdy_deframer_visitor_test.cc b/chromium/net/spdy/core/spdy_deframer_visitor_test.cc index e834325fb29..4e22a81855a 100644 --- a/chromium/net/spdy/core/spdy_deframer_visitor_test.cc +++ b/chromium/net/spdy/core/spdy_deframer_visitor_test.cc @@ -58,22 +58,6 @@ class SpdyDeframerVisitorTest : public ::testing::Test { decoder_.spdy_framer_error() == Http2DecoderAdapter::SPDY_NO_ERROR); } - SpdySerializedFrame SerializeFrame(const SpdyFrameIR& frame) { - return encoder_.SerializeFrame(frame); - } - - SpdyString SerializeFrames( - const std::vector<std::unique_ptr<SpdyFrameIR>>& frames) { - SpdyString result; - for (const auto& frame_ptr : frames) { - auto sf = SerializeFrame(*frame_ptr); - result.append(sf.data(), sf.size()); - } - return result; - } - - // bool - SpdyFramer encoder_; Http2DecoderAdapter decoder_; std::vector<CollectedFrame> collected_frames_; diff --git a/chromium/net/spdy/core/spdy_framer.cc b/chromium/net/spdy/core/spdy_framer.cc index eaefdde4918..1943fb4074e 100644 --- a/chromium/net/spdy/core/spdy_framer.cc +++ b/chromium/net/spdy/core/spdy_framer.cc @@ -426,7 +426,7 @@ std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator( } case SpdyFrameType::DATA: { DVLOG(1) << "Serialize a stream end DATA frame for VTL"; - // FALLTHROUGH_INTENDED + FALLTHROUGH; } default: { return SpdyMakeUnique<SpdyControlFrameIterator>(framer, @@ -508,7 +508,7 @@ SpdySerializedFrame SpdyFramer::SerializeSettings( ++it) { int setting_id = it->first; DCHECK_GE(setting_id, 0); - builder.WriteUInt16(static_cast<uint16_t>(setting_id)); + builder.WriteUInt16(static_cast<SpdySettingsId>(setting_id)); builder.WriteUInt32(it->second); } DCHECK_EQ(size, builder.length()); @@ -1004,7 +1004,7 @@ bool SpdyFramer::SerializeSettings(const SpdySettingsIR& settings, ++it) { int setting_id = it->first; DCHECK_GE(setting_id, 0); - ok = ok && builder.WriteUInt16(static_cast<uint16_t>(setting_id)) && + ok = ok && builder.WriteUInt16(static_cast<SpdySettingsId>(setting_id)) && builder.WriteUInt32(it->second); } DCHECK_EQ(size, builder.length()); diff --git a/chromium/net/spdy/core/spdy_framer_test.cc b/chromium/net/spdy/core/spdy_framer_test.cc index c5fad9ee027..4b7cf59c461 100644 --- a/chromium/net/spdy/core/spdy_framer_test.cc +++ b/chromium/net/spdy/core/spdy_framer_test.cc @@ -16,7 +16,6 @@ #include "base/macros.h" #include "base/strings/string_number_conversions.h" #include "net/quic/platform/api/quic_flags.h" -#include "net/spdy/chromium/spdy_flags.h" #include "net/spdy/core/array_output_buffer.h" #include "net/spdy/core/hpack/hpack_constants.h" #include "net/spdy/core/mock_spdy_framer_visitor.h" @@ -25,6 +24,7 @@ #include "net/spdy/core/spdy_frame_reader.h" #include "net/spdy/core/spdy_protocol.h" #include "net/spdy/core/spdy_test_utils.h" +#include "net/spdy/platform/api/spdy_flags.h" #include "net/spdy/platform/api/spdy_ptr_util.h" #include "net/spdy/platform/api/spdy_string.h" #include "net/spdy/platform/api/spdy_string_utils.h" @@ -62,139 +62,6 @@ class MockDebugVisitor : public SpdyFramerDebugVisitorInterface { size_t frame_len)); }; -class SpdyFramerTestUtil { - public: - // Decompress a single frame using the decompression context held by - // the SpdyFramer. The implemention is meant for use only in tests - // and will CHECK fail if the input is anything other than a single, - // well-formed compressed frame. - // - // Returns a new decompressed SpdySerializedFrame. - template <class SpdyFrameType> - static SpdySerializedFrame DecompressFrame(Http2DecoderAdapter* deframer, - const SpdyFrameType& frame) { - DecompressionVisitor visitor; - deframer->set_visitor(&visitor); - CHECK_EQ(frame.size(), deframer->ProcessInput(frame.data(), frame.size())); - CHECK_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer->state()); - deframer->set_visitor(nullptr); - SpdyFramer serializer(SpdyFramer::DISABLE_COMPRESSION); - return serializer.SerializeFrame(visitor.GetFrame()); - } - - class DecompressionVisitor : public SpdyFramerVisitorInterface { - public: - DecompressionVisitor() : finished_(false) {} - - const SpdyFrameIR& GetFrame() const { - CHECK(finished_); - return *frame_; - } - - SpdyHeadersHandlerInterface* OnHeaderFrameStart( - SpdyStreamId stream_id) override { - if (headers_handler_ == nullptr) { - headers_handler_ = SpdyMakeUnique<TestHeadersHandler>(); - } - return headers_handler_.get(); - } - - void OnHeaderFrameEnd(SpdyStreamId stream_id) override { - CHECK(!finished_); - frame_->set_header_block(headers_handler_->decoded_block().Clone()); - finished_ = true; - headers_handler_.reset(); - } - - void OnHeaders(SpdyStreamId stream_id, - bool has_priority, - int weight, - SpdyStreamId parent_stream_id, - bool exclusive, - bool fin, - bool end) override { - auto headers = SpdyMakeUnique<SpdyHeadersIR>(stream_id); - headers->set_has_priority(has_priority); - headers->set_weight(weight); - headers->set_parent_stream_id(parent_stream_id); - headers->set_exclusive(exclusive); - headers->set_fin(fin); - frame_ = std::move(headers); - } - - void OnPushPromise(SpdyStreamId stream_id, - SpdyStreamId promised_stream_id, - bool end) override { - frame_ = SpdyMakeUnique<SpdyPushPromiseIR>(stream_id, promised_stream_id); - } - - // TODO(birenroy): Add support for CONTINUATION. - void OnContinuation(SpdyStreamId stream_id, bool end) override { - LOG(FATAL); - } - - // All other methods just LOG(FATAL). - void OnError(Http2DecoderAdapter::SpdyFramerError error) override { - LOG(FATAL); - } - void OnDataFrameHeader(SpdyStreamId stream_id, - size_t length, - bool fin) override { - LOG(FATAL) << "Unexpected data frame header"; - } - void OnStreamFrameData(SpdyStreamId stream_id, - const char* data, - size_t len) override { - LOG(FATAL); - } - - void OnStreamEnd(SpdyStreamId stream_id) override { LOG(FATAL); } - - void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { - LOG(FATAL); - } - - void OnRstStream(SpdyStreamId stream_id, - SpdyErrorCode error_code) override { - LOG(FATAL); - } - void OnSetting(SpdySettingsIds id, uint32_t value) override { LOG(FATAL); } - void OnPing(SpdyPingId unique_id, bool is_ack) override { LOG(FATAL); } - void OnSettingsEnd() override { LOG(FATAL); } - void OnGoAway(SpdyStreamId last_accepted_stream_id, - SpdyErrorCode error_code) override { - LOG(FATAL); - } - - void OnWindowUpdate(SpdyStreamId stream_id, - int delta_window_size) override { - LOG(FATAL); - } - - void OnPriority(SpdyStreamId stream_id, - SpdyStreamId parent_stream_id, - int weight, - bool exclusive) override { - // Do nothing. - } - - bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override { - LOG(FATAL); - return false; - } - - private: - std::unique_ptr<TestHeadersHandler> headers_handler_; - std::unique_ptr<SpdyFrameWithHeaderBlockIR> frame_; - bool finished_; - - DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); - }; - - private: - DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); -}; - MATCHER_P(IsFrameUnionOf, frame_list, "") { size_t size_verified = 0; for (const auto& frame : *frame_list) { @@ -371,7 +238,6 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, explicit TestSpdyVisitor(SpdyFramer::CompressionOption option) : framer_(option), - deframer_(FLAGS_chromium_http2_flag_h2_on_stream_pad_length), error_count_(0), headers_frame_count_(0), push_promise_frame_count_(0), @@ -468,7 +334,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, ++fin_frame_count_; } - void OnSetting(SpdySettingsIds id, uint32_t value) override { + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override { VLOG(1) << "OnSetting(" << id << ", " << std::hex << value << ")"; ++setting_count_; } @@ -675,7 +541,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, class TestExtension : public ExtensionVisitorInterface { public: - void OnSetting(uint16_t id, uint32_t value) override { + void OnSetting(SpdySettingsId id, uint32_t value) override { settings_received_.push_back({id, value}); } @@ -697,7 +563,7 @@ class TestExtension : public ExtensionVisitorInterface { payload_.append(data, len); } - std::vector<std::pair<uint16_t, uint32_t>> settings_received_; + std::vector<std::pair<SpdySettingsId, uint32_t>> settings_received_; SpdyStreamId stream_id_ = 0; size_t length_ = 0; uint8_t type_ = 0; @@ -712,32 +578,13 @@ class TestSpdyUnknownIR : public SpdyUnknownIR { using SpdyUnknownIR::set_length; }; -// Retrieves serialized headers from a HEADERS frame. -SpdyStringPiece GetSerializedHeaders(const SpdySerializedFrame& frame, - const SpdyFramer& framer) { - SpdyFrameReader reader(frame.data(), frame.size()); - reader.Seek(3); // Seek past the frame length. - - uint8_t serialized_type; - reader.ReadUInt8(&serialized_type); - - SpdyFrameType type = ParseFrameType(serialized_type); - DCHECK_EQ(SpdyFrameType::HEADERS, type); - uint8_t flags; - reader.ReadUInt8(&flags); - - return SpdyStringPiece(frame.data() + kHeadersFrameMinimumSize, - frame.size() - kHeadersFrameMinimumSize); -} - enum Output { USE, NOT_USE }; class SpdyFramerTest : public ::testing::TestWithParam<Output> { public: SpdyFramerTest() : output_(output_buffer, kSize), - framer_(SpdyFramer::ENABLE_COMPRESSION), - deframer_(FLAGS_chromium_http2_flag_h2_on_stream_pad_length) {} + framer_(SpdyFramer::ENABLE_COMPRESSION) {} protected: void SetUp() override { @@ -763,17 +610,6 @@ class SpdyFramerTest : public ::testing::TestWithParam<Output> { expected, expected_len); } - void CompareFrames(const SpdyString& description, - const SpdySerializedFrame& expected_frame, - const SpdySerializedFrame& actual_frame) { - CompareCharArraysWithHexError( - description, - reinterpret_cast<const unsigned char*>(expected_frame.data()), - expected_frame.size(), - reinterpret_cast<const unsigned char*>(actual_frame.data()), - actual_frame.size()); - } - bool use_output_ = false; ArrayOutputBuffer output_; SpdyFramer framer_; @@ -959,11 +795,7 @@ TEST_P(SpdyFramerTest, CorrectlySizedDataPaddingNoError) { { testing::InSequence seq; EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, false)); - if (FLAGS_chromium_http2_flag_h2_on_stream_pad_length) { - EXPECT_CALL(visitor, OnStreamPadLength(1, 4)); - } else { - EXPECT_CALL(visitor, OnStreamPadding(1, 1)); - } + EXPECT_CALL(visitor, OnStreamPadLength(1, 4)); EXPECT_CALL(visitor, OnError(_)).Times(0); // Note that OnStreamFrameData(1, _, 1)) is never called // since there is no data, only padding @@ -1808,7 +1640,7 @@ TEST_P(SpdyFramerTest, CreateSettings) { uint32_t kValue = 0x0a0b0c0d; SpdySettingsIR settings_ir; - SpdySettingsIds kId = SETTINGS_INITIAL_WINDOW_SIZE; + SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE; settings_ir.AddSetting(kId, kValue); SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir)); @@ -2928,7 +2760,7 @@ TEST_F(SpdyControlFrameIteratorTest, RstStreamFrameWithIterator) { TEST_F(SpdyControlFrameIteratorTest, SettingsFrameWithIterator) { auto ir = SpdyMakeUnique<SpdySettingsIR>(); uint32_t kValue = 0x0a0b0c0d; - SpdySettingsIds kId = SETTINGS_INITIAL_WINDOW_SIZE; + SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE; ir->AddSetting(kId, kValue); RunTest(std::move(ir)); } @@ -3270,11 +3102,7 @@ TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) { bytes_consumed += kDataFrameMinimumSize; // Send the padding length field. - if (FLAGS_chromium_http2_flag_h2_on_stream_pad_length) { - EXPECT_CALL(visitor, OnStreamPadLength(1, kPaddingLen - 1)); - } else { - EXPECT_CALL(visitor, OnStreamPadding(1, 1)); - } + EXPECT_CALL(visitor, OnStreamPadLength(1, kPaddingLen - 1)); CHECK_EQ(1u, deframer_.ProcessInput(frame.data() + bytes_consumed, 1)); CHECK_EQ(deframer_.state(), Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME); CHECK_EQ(deframer_.spdy_framer_error(), Http2DecoderAdapter::SPDY_NO_ERROR); diff --git a/chromium/net/spdy/core/spdy_no_op_visitor.h b/chromium/net/spdy/core/spdy_no_op_visitor.h index 93e861d1f3e..6dabfcf1ef2 100644 --- a/chromium/net/spdy/core/spdy_no_op_visitor.h +++ b/chromium/net/spdy/core/spdy_no_op_visitor.h @@ -39,7 +39,7 @@ class SpdyNoOpVisitor : public SpdyFramerVisitorInterface, void OnStreamEnd(SpdyStreamId stream_id) override {} void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {} void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {} - void OnSetting(SpdySettingsIds id, uint32_t value) override {} + void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {} void OnPing(SpdyPingId unique_id, bool is_ack) override {} void OnSettingsEnd() override {} void OnSettingsAck() override {} diff --git a/chromium/net/spdy/core/spdy_pinnable_buffer_piece.h b/chromium/net/spdy/core/spdy_pinnable_buffer_piece.h index 5a692af45df..07e7facabfc 100644 --- a/chromium/net/spdy/core/spdy_pinnable_buffer_piece.h +++ b/chromium/net/spdy/core/spdy_pinnable_buffer_piece.h @@ -27,8 +27,6 @@ struct SPDY_EXPORT_PRIVATE SpdyPinnableBufferPiece { const char* buffer() const { return buffer_; } - size_t length() const { return length_; } - explicit operator SpdyStringPiece() const { return SpdyStringPiece(buffer_, length_); } diff --git a/chromium/net/spdy/core/spdy_protocol.cc b/chromium/net/spdy/core/spdy_protocol.cc index 3b57e367869..e67fbd4870c 100644 --- a/chromium/net/spdy/core/spdy_protocol.cc +++ b/chromium/net/spdy/core/spdy_protocol.cc @@ -7,14 +7,17 @@ #include <ostream> #include "net/spdy/core/spdy_bug_tracker.h" +#include "net/spdy/platform/api/spdy_flags.h" +#include "net/spdy/platform/api/spdy_ptr_util.h" +#include "net/spdy/platform/api/spdy_string_utils.h" namespace net { const char* const kHttp2ConnectionHeaderPrefix = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"; -std::ostream& operator<<(std::ostream& out, SpdySettingsIds id) { - return out << static_cast<uint16_t>(id); +std::ostream& operator<<(std::ostream& out, SpdyKnownSettingsId id) { + return out << static_cast<SpdySettingsId>(id); } std::ostream& operator<<(std::ostream& out, SpdyFrameType frame_type) { @@ -129,39 +132,64 @@ const char* FrameTypeToString(SpdyFrameType frame_type) { return "UNKNOWN_FRAME_TYPE"; } -bool ParseSettingsId(uint16_t wire_setting_id, SpdySettingsIds* setting_id) { - if (wire_setting_id < SETTINGS_MIN || wire_setting_id > SETTINGS_MAX) { +bool ParseSettingsId(SpdySettingsId wire_setting_id, + SpdyKnownSettingsId* setting_id) { + if (wire_setting_id != SETTINGS_EXPERIMENT_SCHEDULER && + (wire_setting_id < SETTINGS_MIN || wire_setting_id > SETTINGS_MAX)) { return false; } - *setting_id = static_cast<SpdySettingsIds>(wire_setting_id); - return true; + *setting_id = static_cast<SpdyKnownSettingsId>(wire_setting_id); + if (GetSpdyReloadableFlag(http2_check_settings_id_007)) { + // This switch ensures that the casted value is valid. The default case is + // explicitly omitted to have compile-time guarantees that new additions to + // |SpdyKnownSettingsId| must also be handled here. + switch (*setting_id) { + case SETTINGS_HEADER_TABLE_SIZE: + case SETTINGS_ENABLE_PUSH: + case SETTINGS_MAX_CONCURRENT_STREAMS: + case SETTINGS_INITIAL_WINDOW_SIZE: + case SETTINGS_MAX_FRAME_SIZE: + case SETTINGS_MAX_HEADER_LIST_SIZE: + case SETTINGS_ENABLE_CONNECT_PROTOCOL: + case SETTINGS_EXPERIMENT_SCHEDULER: + // FALLTHROUGH_INTENDED + return true; + } + return false; + } else { + return true; + } } -bool SettingsIdToString(SpdySettingsIds id, const char** settings_id_string) { - switch (id) { +SpdyString SettingsIdToString(SpdySettingsId id) { + SpdyKnownSettingsId known_id; + if (!ParseSettingsId(id, &known_id)) { + return SpdyStrCat("SETTINGS_UNKNOWN_", + SpdyHexEncodeUInt32AndTrim(uint32_t{id})); + } + + switch (known_id) { case SETTINGS_HEADER_TABLE_SIZE: - *settings_id_string = "SETTINGS_HEADER_TABLE_SIZE"; - return true; + return "SETTINGS_HEADER_TABLE_SIZE"; case SETTINGS_ENABLE_PUSH: - *settings_id_string = "SETTINGS_ENABLE_PUSH"; - return true; + return "SETTINGS_ENABLE_PUSH"; case SETTINGS_MAX_CONCURRENT_STREAMS: - *settings_id_string = "SETTINGS_MAX_CONCURRENT_STREAMS"; - return true; + return "SETTINGS_MAX_CONCURRENT_STREAMS"; case SETTINGS_INITIAL_WINDOW_SIZE: - *settings_id_string = "SETTINGS_INITIAL_WINDOW_SIZE"; - return true; + return "SETTINGS_INITIAL_WINDOW_SIZE"; case SETTINGS_MAX_FRAME_SIZE: - *settings_id_string = "SETTINGS_MAX_FRAME_SIZE"; - return true; + return "SETTINGS_MAX_FRAME_SIZE"; case SETTINGS_MAX_HEADER_LIST_SIZE: - *settings_id_string = "SETTINGS_MAX_HEADER_LIST_SIZE"; - return true; + return "SETTINGS_MAX_HEADER_LIST_SIZE"; + case SETTINGS_ENABLE_CONNECT_PROTOCOL: + return "SETTINGS_ENABLE_CONNECT_PROTOCOL"; + case SETTINGS_EXPERIMENT_SCHEDULER: + return "SETTINGS_EXPERIMENT_SCHEDULER"; } - *settings_id_string = "SETTINGS_UNKNOWN"; - return false; + return SpdyStrCat("SETTINGS_UNKNOWN_", + SpdyHexEncodeUInt32AndTrim(uint32_t{id})); } SpdyErrorCode ParseErrorCode(uint32_t wire_error_code) { @@ -221,6 +249,7 @@ const char* const kHttp2AuthorityHeader = ":authority"; const char* const kHttp2MethodHeader = ":method"; const char* const kHttp2PathHeader = ":path"; const char* const kHttp2SchemeHeader = ":scheme"; +const char* const kHttp2ProtocolHeader = ":protocol"; const char* const kHttp2StatusHeader = ":status"; diff --git a/chromium/net/spdy/core/spdy_protocol.h b/chromium/net/spdy/core/spdy_protocol.h index be15a0affc8..347090b8fb6 100644 --- a/chromium/net/spdy/core/spdy_protocol.h +++ b/chromium/net/spdy/core/spdy_protocol.h @@ -34,8 +34,11 @@ namespace net { -// A stream id is a 31 bit entity. -typedef uint32_t SpdyStreamId; +// A stream ID is a 31-bit entity. +using SpdyStreamId = uint32_t; + +// A SETTINGS ID is a 16-bit entity. +using SpdySettingsId = uint16_t; // Specifies the stream ID used to denote the current session (for // flow control). @@ -118,7 +121,6 @@ enum SpdyDataFlags { enum SpdyControlFlags { CONTROL_FLAG_NONE = 0x00, CONTROL_FLAG_FIN = 0x01, - CONTROL_FLAG_UNIDIRECTIONAL = 0x02, }; enum SpdyPingFlags { @@ -142,7 +144,7 @@ enum Http2SettingsControlFlags { }; // Wire values of HTTP/2 setting identifiers. -enum SpdySettingsIds : uint16_t { +enum SpdyKnownSettingsId : SpdySettingsId { // HPACK header table maximum size. SETTINGS_HEADER_TABLE_SIZE = 0x1, SETTINGS_MIN = SETTINGS_HEADER_TABLE_SIZE, @@ -156,20 +158,25 @@ enum SpdySettingsIds : uint16_t { SETTINGS_MAX_FRAME_SIZE = 0x5, // The maximum size of header list that the sender is prepared to accept. SETTINGS_MAX_HEADER_LIST_SIZE = 0x6, - SETTINGS_MAX = SETTINGS_MAX_HEADER_LIST_SIZE + // Enable Websockets over HTTP/2, see + // https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-00. + SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x8, + SETTINGS_MAX = SETTINGS_ENABLE_CONNECT_PROTOCOL, + // Experimental setting used to configure an alternative write scheduler. + SETTINGS_EXPERIMENT_SCHEDULER = 0xFF45, }; // This explicit operator is needed, otherwise compiler finds // overloaded operator to be ambiguous. SPDY_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, - SpdySettingsIds id); + SpdyKnownSettingsId id); // This operator is needed, because SpdyFrameType is an enum class, // therefore implicit conversion to underlying integer type is not allowed. SPDY_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out, SpdyFrameType frame_type); -using SettingsMap = std::map<SpdySettingsIds, uint32_t>; +using SettingsMap = std::map<SpdyKnownSettingsId, uint32_t>; // HTTP/2 error codes, RFC 7540 Section 7. enum SpdyErrorCode : uint32_t { @@ -252,13 +259,13 @@ const char* FrameTypeToString(SpdyFrameType frame_type); // If |wire_setting_id| is the on-the-wire representation of a defined SETTINGS // parameter, parse it to |*setting_id| and return true. -SPDY_EXPORT_PRIVATE bool ParseSettingsId(uint16_t wire_setting_id, - SpdySettingsIds* setting_id); +SPDY_EXPORT_PRIVATE bool ParseSettingsId(SpdySettingsId wire_setting_id, + SpdyKnownSettingsId* setting_id); -// Return if |id| corresponds to a defined setting; -// stringify |id| to |*settings_id_string| regardless. -SPDY_EXPORT_PRIVATE bool SettingsIdToString(SpdySettingsIds id, - const char** settings_id_string); +// Returns a string representation of the |id| for logging/debugging. Returns +// the |id| prefixed with "SETTINGS_UNKNOWN_" for unknown SETTINGS IDs. To parse +// the |id| into a SpdyKnownSettingsId (if applicable), use ParseSettingsId(). +SPDY_EXPORT_PRIVATE SpdyString SettingsIdToString(SpdySettingsId id); // Parse |wire_error_code| to a SpdyErrorCode. // Treat unrecognized error codes as INTERNAL_ERROR @@ -283,7 +290,7 @@ const size_t kPriorityFrameSize = kFrameHeaderSize + 5; const size_t kRstStreamFrameSize = kFrameHeaderSize + 4; const size_t kSettingsFrameMinimumSize = kFrameHeaderSize; const size_t kSettingsOneSettingSize = - sizeof(uint32_t) + sizeof(SpdySettingsIds); + sizeof(uint32_t) + sizeof(SpdySettingsId); // PUSH_PROMISE frame has promised_stream_id (4 octet) field. const size_t kPushPromiseFrameMinimumSize = kFrameHeaderSize + 4; // PING frame has opaque_bytes (8 octet) field. @@ -318,6 +325,7 @@ SPDY_EXPORT_PRIVATE extern const char* const kHttp2AuthorityHeader; SPDY_EXPORT_PRIVATE extern const char* const kHttp2MethodHeader; SPDY_EXPORT_PRIVATE extern const char* const kHttp2PathHeader; SPDY_EXPORT_PRIVATE extern const char* const kHttp2SchemeHeader; +SPDY_EXPORT_PRIVATE extern const char* const kHttp2ProtocolHeader; // Name of pseudo-header defined for HTTP/2 responses. SPDY_EXPORT_PRIVATE extern const char* const kHttp2StatusHeader; @@ -595,7 +603,9 @@ class SPDY_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR { // Overwrites as appropriate. const SettingsMap& values() const { return values_; } - void AddSetting(SpdySettingsIds id, int32_t value) { values_[id] = value; } + void AddSetting(SpdyKnownSettingsId id, int32_t value) { + values_[id] = value; + } bool is_ack() const { return is_ack_; } void set_is_ack(bool is_ack) { is_ack_ = is_ack; } diff --git a/chromium/net/spdy/core/spdy_protocol_test.cc b/chromium/net/spdy/core/spdy_protocol_test.cc index a3463063b50..af4b1b9c5ee 100644 --- a/chromium/net/spdy/core/spdy_protocol_test.cc +++ b/chromium/net/spdy/core/spdy_protocol_test.cc @@ -10,6 +10,7 @@ #include "net/spdy/core/spdy_bitmasks.h" #include "net/spdy/core/spdy_test_utils.h" +#include "net/spdy/platform/api/spdy_flags.h" #include "net/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -104,7 +105,7 @@ TEST(SpdyProtocolTest, IsValidHTTP2FrameStreamId) { } TEST(SpdyProtocolTest, ParseSettingsId) { - SpdySettingsIds setting_id; + SpdyKnownSettingsId setting_id; EXPECT_FALSE(ParseSettingsId(0, &setting_id)); EXPECT_TRUE(ParseSettingsId(1, &setting_id)); EXPECT_EQ(SETTINGS_HEADER_TABLE_SIZE, setting_id); @@ -118,29 +119,42 @@ TEST(SpdyProtocolTest, ParseSettingsId) { EXPECT_EQ(SETTINGS_MAX_FRAME_SIZE, setting_id); EXPECT_TRUE(ParseSettingsId(6, &setting_id)); EXPECT_EQ(SETTINGS_MAX_HEADER_LIST_SIZE, setting_id); - EXPECT_FALSE(ParseSettingsId(7, &setting_id)); + if (GetSpdyReloadableFlag(http2_check_settings_id_007)) { + EXPECT_FALSE(ParseSettingsId(7, &setting_id)); + } else { + EXPECT_TRUE(ParseSettingsId(7, &setting_id)); + EXPECT_EQ(0x07, setting_id); + } + EXPECT_TRUE(ParseSettingsId(8, &setting_id)); + EXPECT_EQ(SETTINGS_ENABLE_CONNECT_PROTOCOL, setting_id); + EXPECT_FALSE(ParseSettingsId(9, &setting_id)); + EXPECT_FALSE(ParseSettingsId(0xFF44, &setting_id)); + EXPECT_TRUE(ParseSettingsId(0xFF45, &setting_id)); + EXPECT_EQ(SETTINGS_EXPERIMENT_SCHEDULER, setting_id); + EXPECT_FALSE(ParseSettingsId(0xFF46, &setting_id)); } TEST(SpdyProtocolTest, SettingsIdToString) { struct { - SpdySettingsIds setting_id; - bool expected_bool; + SpdySettingsId setting_id; const SpdyString expected_string; } test_cases[] = { - {static_cast<SpdySettingsIds>(0), false, "SETTINGS_UNKNOWN"}, - {SETTINGS_HEADER_TABLE_SIZE, true, "SETTINGS_HEADER_TABLE_SIZE"}, - {SETTINGS_ENABLE_PUSH, true, "SETTINGS_ENABLE_PUSH"}, - {SETTINGS_MAX_CONCURRENT_STREAMS, true, - "SETTINGS_MAX_CONCURRENT_STREAMS"}, - {SETTINGS_INITIAL_WINDOW_SIZE, true, "SETTINGS_INITIAL_WINDOW_SIZE"}, - {SETTINGS_MAX_FRAME_SIZE, true, "SETTINGS_MAX_FRAME_SIZE"}, - {SETTINGS_MAX_HEADER_LIST_SIZE, true, "SETTINGS_MAX_HEADER_LIST_SIZE"}, - {static_cast<SpdySettingsIds>(7), false, "SETTINGS_UNKNOWN"}}; + {0, "SETTINGS_UNKNOWN_0"}, + {SETTINGS_HEADER_TABLE_SIZE, "SETTINGS_HEADER_TABLE_SIZE"}, + {SETTINGS_ENABLE_PUSH, "SETTINGS_ENABLE_PUSH"}, + {SETTINGS_MAX_CONCURRENT_STREAMS, "SETTINGS_MAX_CONCURRENT_STREAMS"}, + {SETTINGS_INITIAL_WINDOW_SIZE, "SETTINGS_INITIAL_WINDOW_SIZE"}, + {SETTINGS_MAX_FRAME_SIZE, "SETTINGS_MAX_FRAME_SIZE"}, + {SETTINGS_MAX_HEADER_LIST_SIZE, "SETTINGS_MAX_HEADER_LIST_SIZE"}, + {7, "SETTINGS_UNKNOWN_7"}, + {SETTINGS_ENABLE_CONNECT_PROTOCOL, "SETTINGS_ENABLE_CONNECT_PROTOCOL"}, + {9, "SETTINGS_UNKNOWN_9"}, + {0xFF44, "SETTINGS_UNKNOWN_ff44"}, + {0xFF45, "SETTINGS_EXPERIMENT_SCHEDULER"}, + {0xFF46, "SETTINGS_UNKNOWN_ff46"}}; for (auto test_case : test_cases) { - const char* settings_id_string; - EXPECT_EQ(test_case.expected_bool, - SettingsIdToString(test_case.setting_id, &settings_id_string)); - EXPECT_EQ(test_case.expected_string, settings_id_string); + EXPECT_EQ(test_case.expected_string, + SettingsIdToString(test_case.setting_id)); } } diff --git a/chromium/net/spdy/platform/api/spdy_flags.h b/chromium/net/spdy/platform/api/spdy_flags.h new file mode 100644 index 00000000000..2a81172d479 --- /dev/null +++ b/chromium/net/spdy/platform/api/spdy_flags.h @@ -0,0 +1,12 @@ +// Copyright 2018 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_SPDY_PLATFORM_API_SPDY_FLAGS_H_ +#define NET_SPDY_PLATFORM_API_SPDY_FLAGS_H_ + +#include "net/spdy/platform/impl/spdy_flags_impl.h" + +#define GetSpdyReloadableFlag(flag) GetSpdyReloadableFlagImpl(flag) + +#endif // NET_SPDY_PLATFORM_API_SPDY_FLAGS_H_ diff --git a/chromium/net/spdy/platform/impl/spdy_flags_impl.cc b/chromium/net/spdy/platform/impl/spdy_flags_impl.cc new file mode 100644 index 00000000000..bcec96c5d25 --- /dev/null +++ b/chromium/net/spdy/platform/impl/spdy_flags_impl.cc @@ -0,0 +1,12 @@ +// Copyright 2018 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/spdy/platform/impl/spdy_flags_impl.h" + +namespace net { + +// Consider SETTINGS identifier 0x07 as invalid. +bool http2_check_settings_id_007 = true; + +} // namespace net diff --git a/chromium/net/spdy/platform/impl/spdy_flags_impl.h b/chromium/net/spdy/platform/impl/spdy_flags_impl.h new file mode 100644 index 00000000000..95e26b72da0 --- /dev/null +++ b/chromium/net/spdy/platform/impl/spdy_flags_impl.h @@ -0,0 +1,20 @@ +// Copyright 2018 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_SPDY_PLATFORM_IMPL_SPDY_FLAGS_IMPL_H_ +#define NET_SPDY_PLATFORM_IMPL_SPDY_FLAGS_IMPL_H_ + +#include "net/base/net_export.h" + +namespace net { + +NET_EXPORT_PRIVATE extern bool http2_check_settings_id_007; + +inline bool GetSpdyReloadableFlagImpl(bool flag) { + return flag; +} + +} // namespace net + +#endif // NET_SPDY_PLATFORM_IMPL_SPDY_FLAGS_IMPL_H_ |