| 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,
|
|
|