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

Unified Diff: net/spdy/spdy_session.cc

Issue 2596703002: http2: Update priorities of pushed streams (Closed)
Patch Set: actually rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_session.cc
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 9ad1cb3e076ef15c9cb646d0af361341038d901f..fe16bf02af011f95f6b1b8ee5322f73d30e73937 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -107,7 +107,7 @@ std::unique_ptr<base::Value> NetLogSpdyHeadersSentCallback(
SpdyStreamId parent_stream_id,
bool exclusive,
NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
dict->SetBoolean("fin", fin);
dict->SetInteger("stream_id", stream_id);
@@ -125,7 +125,7 @@ std::unique_ptr<base::Value> NetLogSpdyHeadersReceivedCallback(
bool fin,
SpdyStreamId stream_id,
NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
dict->SetBoolean("fin", fin);
dict->SetInteger("stream_id", stream_id);
@@ -136,7 +136,7 @@ std::unique_ptr<base::Value> NetLogSpdySessionCloseCallback(
int net_error,
const std::string* description,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("net_error", net_error);
dict->SetString("description", *description);
return std::move(dict);
@@ -145,7 +145,7 @@ std::unique_ptr<base::Value> NetLogSpdySessionCloseCallback(
std::unique_ptr<base::Value> NetLogSpdySessionCallback(
const HostPortProxyPair* host_pair,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetString("host", host_pair->first.ToString());
dict->SetString("proxy", host_pair->second.ToPacString());
return std::move(dict);
@@ -154,7 +154,7 @@ std::unique_ptr<base::Value> NetLogSpdySessionCallback(
std::unique_ptr<base::Value> NetLogSpdyInitializedCallback(
NetLogSource source,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
if (source.IsValid()) {
source.AddToEventParameters(dict.get());
}
@@ -165,7 +165,7 @@ std::unique_ptr<base::Value> NetLogSpdyInitializedCallback(
std::unique_ptr<base::Value> NetLogSpdySettingsCallback(
const HostPortPair& host_port_pair,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetString("host", host_port_pair.ToString());
return std::move(dict);
}
@@ -174,7 +174,7 @@ std::unique_ptr<base::Value> NetLogSpdySettingCallback(
SpdySettingsIds id,
uint32_t value,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("id", id);
dict->SetInteger("value", value);
return std::move(dict);
@@ -183,8 +183,8 @@ std::unique_ptr<base::Value> NetLogSpdySettingCallback(
std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback(
const SettingsMap* settings,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
- std::unique_ptr<base::ListValue> settings_list(new base::ListValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
+ auto settings_list = base::MakeUnique<base::ListValue>();
for (SettingsMap::const_iterator it = settings->begin();
it != settings->end(); ++it) {
const SpdySettingsIds id = it->first;
@@ -200,7 +200,7 @@ std::unique_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback(
SpdyStreamId stream_id,
uint32_t delta,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("delta", delta);
return std::move(dict);
@@ -210,7 +210,7 @@ std::unique_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback(
int32_t delta,
int32_t window_size,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("delta", delta);
dict->SetInteger("window_size", window_size);
return std::move(dict);
@@ -221,7 +221,7 @@ std::unique_ptr<base::Value> NetLogSpdyDataCallback(
int size,
bool fin,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("size", size);
dict->SetBoolean("fin", fin);
@@ -233,7 +233,7 @@ std::unique_ptr<base::Value> NetLogSpdyRstCallback(
int status,
const std::string* description,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("stream_id", static_cast<int>(stream_id));
dict->SetInteger("status", status);
dict->SetString("description", *description);
@@ -245,7 +245,7 @@ std::unique_ptr<base::Value> NetLogSpdyPingCallback(
bool is_ack,
const char* type,
NetLogCaptureMode /* capture_mode */) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("unique_id", static_cast<int>(unique_id));
dict->SetString("type", type);
dict->SetBoolean("is_ack", is_ack);
@@ -259,7 +259,7 @@ std::unique_ptr<base::Value> NetLogSpdyGoAwayCallback(
SpdyGoAwayStatus status,
base::StringPiece debug_data,
NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("last_accepted_stream_id",
static_cast<int>(last_stream_id));
dict->SetInteger("active_streams", active_streams);
@@ -275,7 +275,7 @@ std::unique_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback(
SpdyStreamId stream_id,
SpdyStreamId promised_stream_id,
NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
dict->SetInteger("id", stream_id);
dict->SetInteger("promised_stream_id", promised_stream_id);
@@ -286,7 +286,7 @@ std::unique_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback(
SpdyStreamId stream_id,
const GURL* url,
NetLogCaptureMode capture_mode) {
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ auto dict = base::MakeUnique<base::DictionaryValue>();
dict->SetInteger("stream_id", stream_id);
dict->SetString("url", url->spec());
return std::move(dict);
@@ -308,6 +308,20 @@ std::unique_ptr<base::Value> NetLogSpdySessionStalledCallback(
return std::move(dict);
}
+std::unique_ptr<base::Value> NetLogSpdyPriorityCallback(
+ SpdyStreamId stream_id,
+ SpdyStreamId parent_stream_id,
+ int weight,
+ bool exclusive,
+ NetLogCaptureMode capture_mode) {
+ auto dict = base::MakeUnique<base::DictionaryValue>();
+ dict->SetInteger("stream_id", stream_id);
+ dict->SetInteger("parent_stream_id", parent_stream_id);
+ dict->SetInteger("weight", weight);
+ dict->SetBoolean("exclusive", exclusive);
+ return std::move(dict);
+}
+
// Helper function to return the total size of an array of objects
// with .size() member functions.
template <typename T, size_t N> size_t GetTotalSize(const T (&arr)[N]) {
@@ -825,6 +839,7 @@ bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
}
int SpdySession::GetPushStream(const GURL& url,
+ RequestPriority priority,
base::WeakPtr<SpdyStream>* stream,
const NetLogWithSource& stream_net_log) {
CHECK(!in_io_loop_);
@@ -838,7 +853,26 @@ int SpdySession::GetPushStream(const GURL& url,
if (*stream) {
DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_);
streams_pushed_and_claimed_count_++;
+
+ // If the stream is still open, update its priority to match
+ // the priority of the matching request.
+ if (!(*stream)->IsClosed() && (*stream)->priority() != priority) {
+ (*stream)->set_priority(priority);
+
+ // Send PRIORITY updates.
+ auto updates = priority_dependency_state_.OnStreamUpdate(
+ (*stream)->stream_id(),
+ ConvertRequestPriorityToSpdyPriority(priority));
+ 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);
+ }
+ }
}
+
return OK;
}
@@ -1070,8 +1104,8 @@ std::unique_ptr<SpdySerializedFrame> SpdySession::CreateHeaders(
SpdyStreamId dependent_stream_id = 0;
bool exclusive = false;
- priority_dependency_state_.OnStreamSynSent(stream_id, spdy_priority,
- &dependent_stream_id, &exclusive);
+ priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority,
+ &dependent_stream_id, &exclusive);
if (net_log().IsCapturing()) {
net_log().AddEvent(
@@ -1329,6 +1363,28 @@ void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id,
RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status));
}
+void SpdySession::EnqueuePriorityFrame(SpdyStreamId stream_id,
+ SpdyStreamId dependency_id,
+ int weight,
+ bool exclusive) {
+ net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY,
+ base::Bind(&NetLogSpdyPriorityCallback, stream_id,
+ dependency_id, weight, exclusive));
+
+ DCHECK(buffered_spdy_framer_.get());
+ std::unique_ptr<SpdySerializedFrame> frame(
+ buffered_spdy_framer_->CreatePriority(stream_id, dependency_id, weight,
+ exclusive));
+
+ // PRIORITY frames describe sequenced updates to the tree, so they must
+ // be serialized. We do this by queueing all PRIORITY frames at HIGHEST
+ // priority.
+ EnqueueWrite(HIGHEST, PRIORITY,
+ base::MakeUnique<SimpleBufferProducer>(
+ base::MakeUnique<SpdyBuffer>(std::move(frame))),
+ base::WeakPtr<SpdyStream>());
+}
+
void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) {
CHECK(!in_io_loop_);
if (availability_state_ == STATE_DRAINING) {
@@ -2466,7 +2522,6 @@ void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
SpdyStreamId associated_stream_id,
- SpdyPriority priority,
SpdyHeaderBlock headers) {
// Server-initiated streams should have even sequence numbers.
if ((stream_id & 0x1) != 0) {
@@ -2501,8 +2556,8 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
last_accepted_push_stream_id_ = stream_id;
- RequestPriority request_priority =
- ConvertSpdyPriorityToRequestPriority(priority);
+ // Pushed streams are speculative, so they start at an IDLE priority.
+ const RequestPriority request_priority = IDLE;
if (availability_state_ == STATE_GOING_AWAY) {
// TODO(akalin): This behavior isn't in the SPDY spec, although it
@@ -2619,6 +2674,16 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
stream_max_recv_window_size_, net_log_));
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;
+ bool exclusive = false;
+ priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority,
+ &dependency_id, &exclusive);
+ EnqueuePriorityFrame(stream_id, dependency_id,
+ Spdy3PriorityToHttp2Weight(spdy_priority), exclusive);
+
// PUSH_PROMISE arrives on associated stream.
associated_it->second->AddRawReceivedBytes(last_compressed_frame_len_);
last_compressed_frame_len_ = 0;
@@ -2660,8 +2725,7 @@ void SpdySession::OnPushPromise(SpdyStreamId stream_id,
&headers, stream_id, promised_stream_id));
}
- // Any priority will do. TODO(baranovich): Pass parent stream id priority?
- TryCreatePushStream(promised_stream_id, stream_id, 0, std::move(headers));
+ TryCreatePushStream(promised_stream_id, stream_id, std::move(headers));
}
void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id,
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698