Update from https://crrev.com/305340
Added a few #includes of base/compiler_specific.h for upstream cleanup.
Changed callers for cc::BeginFrameArgs and cc::RendererSettings API
changes.
Review URL: https://codereview.chromium.org/754433003
diff --git a/net/BUILD.gn b/net/BUILD.gn
index be0ac53..a9d20aa 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -406,8 +406,8 @@
"websockets/websocket_frame_parser.h",
"websockets/websocket_handshake_constants.cc",
"websockets/websocket_handshake_constants.h",
- "websockets/websocket_handshake_handler.cc",
- "websockets/websocket_handshake_handler.h",
+ "websockets/websocket_handshake_challenge.cc",
+ "websockets/websocket_handshake_challenge.h",
"websockets/websocket_handshake_request_info.cc",
"websockets/websocket_handshake_request_info.h",
"websockets/websocket_handshake_response_info.cc",
@@ -609,8 +609,12 @@
source_set("test_support") {
testonly = true
sources = [
+ "base/captured_net_log_entry.cc",
+ "base/captured_net_log_entry.h",
"base/capturing_net_log.cc",
"base/capturing_net_log.h",
+ "base/capturing_net_log_observer.cc",
+ "base/capturing_net_log_observer.h",
"base/load_timing_info_test_util.cc",
"base/load_timing_info_test_util.h",
"base/mock_file_stream.cc",
@@ -1238,8 +1242,7 @@
"websockets/websocket_extension_parser_test.cc",
"websockets/websocket_frame_parser_test.cc",
"websockets/websocket_frame_test.cc",
- "websockets/websocket_handshake_handler_spdy_test.cc",
- "websockets/websocket_handshake_handler_test.cc",
+ "websockets/websocket_handshake_challenge_test.cc",
"websockets/websocket_handshake_stream_create_helper_test.cc",
"websockets/websocket_inflater_test.cc",
"websockets/websocket_stream_test.cc",
diff --git a/net/android/java/src/org/chromium/net/DefaultAndroidKeyStore.java b/net/android/java/src/org/chromium/net/DefaultAndroidKeyStore.java
index 60f910c..2a6c2f2 100644
--- a/net/android/java/src/org/chromium/net/DefaultAndroidKeyStore.java
+++ b/net/android/java/src/org/chromium/net/DefaultAndroidKeyStore.java
@@ -123,8 +123,8 @@
signature.update(message);
return signature.sign();
} catch (Exception e) {
- Log.e(TAG, "Exception while signing message with " + javaKey.getAlgorithm() +
- " private key: " + e);
+ Log.e(TAG, "Exception while signing message with " + javaKey.getAlgorithm()
+ + " private key: " + e);
return null;
}
}
@@ -170,8 +170,8 @@
// This may happen if the PrivateKey was not created by the "AndroidOpenSSL"
// provider, which should be the default. That could happen if an OEM decided
// to implement a different default provider. Also highly unlikely.
- Log.e(TAG, "Private key is not an OpenSSLRSAPrivateKey instance, its class name is:" +
- javaKey.getClass().getCanonicalName());
+ Log.e(TAG, "Private key is not an OpenSSLRSAPrivateKey instance, its class name is:"
+ + javaKey.getClass().getCanonicalName());
return null;
}
@@ -284,8 +284,8 @@
}
// Sanity-check the returned engine.
if (!engineClass.isInstance(engine)) {
- Log.e(TAG, "Engine is not an OpenSSLEngine instance, its class name is:" +
- engine.getClass().getCanonicalName());
+ Log.e(TAG, "Engine is not an OpenSSLEngine instance, its class name is:"
+ + engine.getClass().getCanonicalName());
return null;
}
return engine;
diff --git a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
index 1e72da9..9db46e2 100644
--- a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
+++ b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
@@ -161,8 +161,8 @@
public int getCurrentConnectionType() {
// Track exactly what type of connection we have.
- if (!mConnectivityManagerDelegate.activeNetworkExists() ||
- !mConnectivityManagerDelegate.isConnected()) {
+ if (!mConnectivityManagerDelegate.activeNetworkExists()
+ || !mConnectivityManagerDelegate.isConnected()) {
return NetworkChangeNotifier.CONNECTION_NONE;
}
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java
index 3f6c70d..08ead31 100644
--- a/net/android/java/src/org/chromium/net/X509Util.java
+++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -372,8 +372,8 @@
// If the subject and public key match, this is a system root.
X509Certificate anchorX509 = (X509Certificate) anchor;
- if (root.getSubjectX500Principal().equals(anchorX509.getSubjectX500Principal()) &&
- root.getPublicKey().equals(anchorX509.getPublicKey())) {
+ if (root.getSubjectX500Principal().equals(anchorX509.getSubjectX500Principal())
+ && root.getPublicKey().equals(anchorX509.getPublicKey())) {
sSystemTrustAnchorCache.add(key);
return true;
}
@@ -405,10 +405,10 @@
if (ekuOids == null) return true;
for (String ekuOid : ekuOids) {
- if (ekuOid.equals(OID_TLS_SERVER_AUTH) ||
- ekuOid.equals(OID_ANY_EKU) ||
- ekuOid.equals(OID_SERVER_GATED_NETSCAPE) ||
- ekuOid.equals(OID_SERVER_GATED_MICROSOFT)) {
+ if (ekuOid.equals(OID_TLS_SERVER_AUTH)
+ || ekuOid.equals(OID_ANY_EKU)
+ || ekuOid.equals(OID_SERVER_GATED_NETSCAPE)
+ || ekuOid.equals(OID_SERVER_GATED_MICROSOFT)) {
return true;
}
}
@@ -421,8 +421,8 @@
String host)
throws KeyStoreException, NoSuchAlgorithmException {
if (certChain == null || certChain.length == 0 || certChain[0] == null) {
- throw new IllegalArgumentException("Expected non-null and non-empty certificate " +
- "chain passed as |certChain|. |certChain|=" + Arrays.deepToString(certChain));
+ throw new IllegalArgumentException("Expected non-null and non-empty certificate "
+ + "chain passed as |certChain|. |certChain|=" + Arrays.deepToString(certChain));
}
@@ -475,8 +475,8 @@
} catch (CertificateException eTestManager) {
// Neither of the trust managers confirms the validity of the certificate chain,
// log the error message returned by the system trust manager.
- Log.i(TAG, "Failed to validate the certificate chain, error: " +
- eDefaultManager.getMessage());
+ Log.i(TAG, "Failed to validate the certificate chain, error: "
+ + eDefaultManager.getMessage());
return new AndroidCertVerifyResult(
CertVerifyStatusAndroid.NO_TRUSTED_ROOT);
}
diff --git a/net/base/captured_net_log_entry.cc b/net/base/captured_net_log_entry.cc
new file mode 100644
index 0000000..9c57271
--- /dev/null
+++ b/net/base/captured_net_log_entry.cc
@@ -0,0 +1,77 @@
+// Copyright 2014 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/base/captured_net_log_entry.h"
+
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/values.h"
+
+namespace net {
+
+CapturedNetLogEntry::CapturedNetLogEntry(
+ NetLog::EventType type,
+ const base::TimeTicks& time,
+ NetLog::Source source,
+ NetLog::EventPhase phase,
+ scoped_ptr<base::DictionaryValue> params)
+ : type(type),
+ time(time),
+ source(source),
+ phase(phase),
+ params(params.Pass()) {
+ // Only entries without a NetLog should have an invalid source.
+ CHECK(source.IsValid());
+}
+
+CapturedNetLogEntry::CapturedNetLogEntry(const CapturedNetLogEntry& entry) {
+ *this = entry;
+}
+
+CapturedNetLogEntry::~CapturedNetLogEntry() {}
+
+CapturedNetLogEntry& CapturedNetLogEntry::operator=(
+ const CapturedNetLogEntry& entry) {
+ type = entry.type;
+ time = entry.time;
+ source = entry.source;
+ phase = entry.phase;
+ params.reset(entry.params ? entry.params->DeepCopy() : NULL);
+ return *this;
+}
+
+bool CapturedNetLogEntry::GetStringValue(const std::string& name,
+ std::string* value) const {
+ if (!params)
+ return false;
+ return params->GetString(name, value);
+}
+
+bool CapturedNetLogEntry::GetIntegerValue(const std::string& name,
+ int* value) const {
+ if (!params)
+ return false;
+ return params->GetInteger(name, value);
+}
+
+bool CapturedNetLogEntry::GetListValue(const std::string& name,
+ base::ListValue** value) const {
+ if (!params)
+ return false;
+ return params->GetList(name, value);
+}
+
+bool CapturedNetLogEntry::GetNetErrorCode(int* value) const {
+ return GetIntegerValue("net_error", value);
+}
+
+std::string CapturedNetLogEntry::GetParamsJson() const {
+ if (!params)
+ return std::string();
+ std::string json;
+ base::JSONWriter::Write(params.get(), &json);
+ return json;
+}
+
+} // namespace net
diff --git a/net/base/captured_net_log_entry.h b/net/base/captured_net_log_entry.h
new file mode 100644
index 0000000..97245e3
--- /dev/null
+++ b/net/base/captured_net_log_entry.h
@@ -0,0 +1,69 @@
+// Copyright 2014 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_BASE_CAPTURED_NET_LOG_ENTRY_H_
+#define NET_BASE_CAPTURED_NET_LOG_ENTRY_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "net/base/net_log.h"
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+namespace net {
+
+// CapturedNetLogEntry is much like NetLog::Entry, except it has its own copy of
+// all log data, so a list of entries can be gathered over the course of a test,
+// and then inspected at the end. It is intended for testing only, and is part
+// of the net_test_support project.
+struct CapturedNetLogEntry {
+ // Ordered set of logged entries.
+ typedef std::vector<CapturedNetLogEntry> List;
+
+ CapturedNetLogEntry(NetLog::EventType type,
+ const base::TimeTicks& time,
+ NetLog::Source source,
+ NetLog::EventPhase phase,
+ scoped_ptr<base::DictionaryValue> params);
+ // Copy constructor needed to store in a std::vector because of the
+ // scoped_ptr.
+ CapturedNetLogEntry(const CapturedNetLogEntry& entry);
+
+ ~CapturedNetLogEntry();
+
+ // Equality operator needed to store in a std::vector because of the
+ // scoped_ptr.
+ CapturedNetLogEntry& operator=(const CapturedNetLogEntry& entry);
+
+ // Attempt to retrieve an value of the specified type with the given name
+ // from |params|. Returns true on success, false on failure. Does not
+ // modify |value| on failure.
+ bool GetStringValue(const std::string& name, std::string* value) const;
+ bool GetIntegerValue(const std::string& name, int* value) const;
+ bool GetListValue(const std::string& name, base::ListValue** value) const;
+
+ // Same as GetIntegerValue, but returns the error code associated with a
+ // log entry.
+ bool GetNetErrorCode(int* value) const;
+
+ // Returns the parameters as a JSON string, or empty string if there are no
+ // parameters.
+ std::string GetParamsJson() const;
+
+ NetLog::EventType type;
+ base::TimeTicks time;
+ NetLog::Source source;
+ NetLog::EventPhase phase;
+ scoped_ptr<base::DictionaryValue> params;
+};
+
+} // namespace net
+
+#endif // NET_BASE_CAPTURED_NET_LOG_ENTRY_H_
diff --git a/net/base/capturing_net_log.cc b/net/base/capturing_net_log.cc
index 3837fe6..f2e2c04 100644
--- a/net/base/capturing_net_log.cc
+++ b/net/base/capturing_net_log.cc
@@ -4,130 +4,8 @@
#include "net/base/capturing_net_log.h"
-#include "base/json/json_writer.h"
-#include "base/logging.h"
-#include "base/values.h"
-
namespace net {
-CapturingNetLog::CapturedEntry::CapturedEntry(
- EventType type,
- const base::TimeTicks& time,
- Source source,
- EventPhase phase,
- scoped_ptr<base::DictionaryValue> params)
- : type(type),
- time(time),
- source(source),
- phase(phase),
- params(params.Pass()) {
-}
-
-CapturingNetLog::CapturedEntry::CapturedEntry(const CapturedEntry& entry) {
- *this = entry;
-}
-
-CapturingNetLog::CapturedEntry::~CapturedEntry() {}
-
-CapturingNetLog::CapturedEntry&
-CapturingNetLog::CapturedEntry::operator=(const CapturedEntry& entry) {
- type = entry.type;
- time = entry.time;
- source = entry.source;
- phase = entry.phase;
- params.reset(entry.params ? entry.params->DeepCopy() : NULL);
- return *this;
-}
-
-bool CapturingNetLog::CapturedEntry::GetStringValue(
- const std::string& name,
- std::string* value) const {
- if (!params)
- return false;
- return params->GetString(name, value);
-}
-
-bool CapturingNetLog::CapturedEntry::GetIntegerValue(
- const std::string& name,
- int* value) const {
- if (!params)
- return false;
- return params->GetInteger(name, value);
-}
-
-bool CapturingNetLog::CapturedEntry::GetListValue(
- const std::string& name,
- base::ListValue** value) const {
- if (!params)
- return false;
- return params->GetList(name, value);
-}
-
-bool CapturingNetLog::CapturedEntry::GetNetErrorCode(int* value) const {
- return GetIntegerValue("net_error", value);
-}
-
-std::string CapturingNetLog::CapturedEntry::GetParamsJson() const {
- if (!params)
- return std::string();
- std::string json;
- base::JSONWriter::Write(params.get(), &json);
- return json;
-}
-
-CapturingNetLog::Observer::Observer() {}
-
-CapturingNetLog::Observer::~Observer() {}
-
-void CapturingNetLog::Observer::GetEntries(
- CapturedEntryList* entry_list) const {
- base::AutoLock lock(lock_);
- *entry_list = captured_entries_;
-}
-
-void CapturingNetLog::Observer::GetEntriesForSource(
- NetLog::Source source,
- CapturedEntryList* entry_list) const {
- base::AutoLock lock(lock_);
- entry_list->clear();
- for (CapturedEntryList::const_iterator entry = captured_entries_.begin();
- entry != captured_entries_.end(); ++entry) {
- if (entry->source.id == source.id)
- entry_list->push_back(*entry);
- }
-}
-
-size_t CapturingNetLog::Observer::GetSize() const {
- base::AutoLock lock(lock_);
- return captured_entries_.size();
-}
-
-void CapturingNetLog::Observer::Clear() {
- base::AutoLock lock(lock_);
- captured_entries_.clear();
-}
-
-void CapturingNetLog::Observer::OnAddEntry(const net::NetLog::Entry& entry) {
- // Only BoundNetLogs without a NetLog should have an invalid source.
- CHECK(entry.source().IsValid());
-
- // Using Dictionaries instead of Values makes checking values a little
- // simpler.
- base::DictionaryValue* param_dict = NULL;
- base::Value* param_value = entry.ParametersToValue();
- if (param_value && !param_value->GetAsDictionary(¶m_dict))
- delete param_value;
-
- // Only need to acquire the lock when accessing class variables.
- base::AutoLock lock(lock_);
- captured_entries_.push_back(
- CapturedEntry(entry.type(),
- base::TimeTicks::Now(),
- entry.source(),
- entry.phase(),
- scoped_ptr<base::DictionaryValue>(param_dict)));
-}
-
CapturingNetLog::CapturingNetLog() {
AddThreadSafeObserver(&capturing_net_log_observer_, LOG_ALL_BUT_BYTES);
}
diff --git a/net/base/capturing_net_log.h b/net/base/capturing_net_log.h
index 5977533..452c9a0 100644
--- a/net/base/capturing_net_log.h
+++ b/net/base/capturing_net_log.h
@@ -8,68 +8,22 @@
#include <string>
#include <vector>
-#include "base/atomicops.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
+#include "net/base/captured_net_log_entry.h"
+#include "net/base/capturing_net_log_observer.h"
#include "net/base/net_log.h"
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
namespace net {
-// CapturingNetLog is a NetLog which instantiates Observer that saves messages
-// to a bounded buffer. It is intended for testing only, and is part of the
-// net_test_support project. This is provided for convinience and compatilbility
-// with the old unittests.
+// CapturingNetLog is convenience class which combines a NetLog and a
+// CapturingNetLogObserver. It is intended for testing only, and is part of the
+// net_test_support project.
class CapturingNetLog : public NetLog {
public:
- struct CapturedEntry {
- CapturedEntry(EventType type,
- const base::TimeTicks& time,
- Source source,
- EventPhase phase,
- scoped_ptr<base::DictionaryValue> params);
- // Copy constructor needed to store in a std::vector because of the
- // scoped_ptr.
- CapturedEntry(const CapturedEntry& entry);
-
- ~CapturedEntry();
-
- // Equality operator needed to store in a std::vector because of the
- // scoped_ptr.
- CapturedEntry& operator=(const CapturedEntry& entry);
-
- // Attempt to retrieve an value of the specified type with the given name
- // from |params|. Returns true on success, false on failure. Does not
- // modify |value| on failure.
- bool GetStringValue(const std::string& name, std::string* value) const;
- bool GetIntegerValue(const std::string& name, int* value) const;
- bool GetListValue(const std::string& name, base::ListValue** value) const;
-
- // Same as GetIntegerValue, but returns the error code associated with a
- // log entry.
- bool GetNetErrorCode(int* value) const;
-
- // Returns the parameters as a JSON string, or empty string if there are no
- // parameters.
- std::string GetParamsJson() const;
-
- EventType type;
- base::TimeTicks time;
- Source source;
- EventPhase phase;
- scoped_ptr<base::DictionaryValue> params;
- };
-
- // Ordered set of entries that were logged.
- typedef std::vector<CapturedEntry> CapturedEntryList;
+ // TODO(mmenke): Get rid of these.
+ typedef CapturedNetLogEntry CapturedEntry;
+ typedef CapturedNetLogEntry::List CapturedEntryList;
CapturingNetLog();
~CapturingNetLog() override;
@@ -83,39 +37,7 @@
void Clear();
private:
- // Observer is an implementation of NetLog::ThreadSafeObserver
- // that saves messages to a bounded buffer. It is intended for testing only,
- // and is part of the net_test_support project.
- class Observer : public NetLog::ThreadSafeObserver {
- public:
- Observer();
- ~Observer() override;
-
- // Returns the list of all entries in the log.
- void GetEntries(CapturedEntryList* entry_list) const;
-
- // Fills |entry_list| with all entries in the log from the specified Source.
- void GetEntriesForSource(Source source,
- CapturedEntryList* entry_list) const;
-
- // Returns number of entries in the log.
- size_t GetSize() const;
-
- void Clear();
-
- private:
- // ThreadSafeObserver implementation:
- void OnAddEntry(const Entry& entry) override;
-
- // Needs to be "mutable" so can use it in GetEntries().
- mutable base::Lock lock_;
-
- CapturedEntryList captured_entries_;
-
- DISALLOW_COPY_AND_ASSIGN(Observer);
- };
-
- Observer capturing_net_log_observer_;
+ CapturingNetLogObserver capturing_net_log_observer_;
DISALLOW_COPY_AND_ASSIGN(CapturingNetLog);
};
@@ -123,7 +45,7 @@
// Helper class that exposes a similar API as BoundNetLog, but uses a
// CapturingNetLog rather than the more generic NetLog.
//
-// CapturingBoundNetLog can easily be converted to a BoundNetLog using the
+// A CapturingBoundNetLog can easily be converted to a BoundNetLog using the
// bound() method.
class CapturingBoundNetLog {
public:
diff --git a/net/base/capturing_net_log_observer.cc b/net/base/capturing_net_log_observer.cc
new file mode 100644
index 0000000..da99852
--- /dev/null
+++ b/net/base/capturing_net_log_observer.cc
@@ -0,0 +1,62 @@
+// Copyright 2014 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/base/capturing_net_log_observer.h"
+
+#include "base/values.h"
+
+namespace net {
+
+CapturingNetLogObserver::CapturingNetLogObserver() {}
+
+CapturingNetLogObserver::~CapturingNetLogObserver() {}
+
+void CapturingNetLogObserver::GetEntries(
+ CapturedNetLogEntry::List* entry_list) const {
+ base::AutoLock lock(lock_);
+ *entry_list = captured_entries_;
+}
+
+void CapturingNetLogObserver::GetEntriesForSource(
+ NetLog::Source source,
+ CapturedNetLogEntry::List* entry_list) const {
+ base::AutoLock lock(lock_);
+ entry_list->clear();
+ for (CapturedNetLogEntry::List::const_iterator entry =
+ captured_entries_.begin();
+ entry != captured_entries_.end(); ++entry) {
+ if (entry->source.id == source.id)
+ entry_list->push_back(*entry);
+ }
+}
+
+size_t CapturingNetLogObserver::GetSize() const {
+ base::AutoLock lock(lock_);
+ return captured_entries_.size();
+}
+
+void CapturingNetLogObserver::Clear() {
+ base::AutoLock lock(lock_);
+ captured_entries_.clear();
+}
+
+void CapturingNetLogObserver::OnAddEntry(const net::NetLog::Entry& entry) {
+ // Using Dictionaries instead of Values makes checking values a little
+ // simpler.
+ base::DictionaryValue* param_dict = nullptr;
+ base::Value* param_value = entry.ParametersToValue();
+ if (param_value && !param_value->GetAsDictionary(¶m_dict))
+ delete param_value;
+
+ // Only need to acquire the lock when accessing class variables.
+ base::AutoLock lock(lock_);
+ captured_entries_.push_back(
+ CapturedNetLogEntry(entry.type(),
+ base::TimeTicks::Now(),
+ entry.source(),
+ entry.phase(),
+ scoped_ptr<base::DictionaryValue>(param_dict)));
+}
+
+} // namespace net
diff --git a/net/base/capturing_net_log_observer.h b/net/base/capturing_net_log_observer.h
new file mode 100644
index 0000000..267352a
--- /dev/null
+++ b/net/base/capturing_net_log_observer.h
@@ -0,0 +1,58 @@
+// Copyright 2014 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_BASE_CAPTURING_NET_LOG_OBSERVER_H_
+#define NET_BASE_CAPTURING_NET_LOG_OBSERVER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/synchronization/lock.h"
+#include "net/base/captured_net_log_entry.h"
+#include "net/base/net_log.h"
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+namespace net {
+
+// CapturingNetLogObserver is an implementation of NetLog::ThreadSafeObserver
+// that saves messages to a bounded buffer. It is intended for testing only,
+// and is part of the net_test_support project.
+class CapturingNetLogObserver : public NetLog::ThreadSafeObserver {
+ public:
+ CapturingNetLogObserver();
+ ~CapturingNetLogObserver() override;
+
+ // Returns the list of all entries in the log.
+ void GetEntries(CapturedNetLogEntry::List* entry_list) const;
+
+ // Fills |entry_list| with all entries in the log from the specified Source.
+ void GetEntriesForSource(NetLog::Source source,
+ CapturedNetLogEntry::List* entry_list) const;
+
+ // Returns number of entries in the log.
+ size_t GetSize() const;
+
+ void Clear();
+
+ private:
+ // ThreadSafeObserver implementation:
+ void OnAddEntry(const NetLog::Entry& entry) override;
+
+ // Needs to be "mutable" so can use it in GetEntries().
+ mutable base::Lock lock_;
+
+ CapturedNetLogEntry::List captured_entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(CapturingNetLogObserver);
+};
+
+} // namespace net
+
+#endif // NET_BASE_CAPTURING_NET_LOG_OBSERVER_H_
diff --git a/net/base/file_stream_context_win.cc b/net/base/file_stream_context_win.cc
index 3b942d3..369dfc1 100644
--- a/net/base/file_stream_context_win.cc
+++ b/net/base/file_stream_context_win.cc
@@ -68,14 +68,13 @@
if (!ReadFile(file_.GetPlatformFile(), buf->data(), buf_len,
&bytes_read, &io_context_.overlapped)) {
IOResult error = IOResult::FromOSError(GetLastError());
- if (error.os_error == ERROR_IO_PENDING) {
- IOCompletionIsPending(callback, buf);
- } else if (error.os_error == ERROR_HANDLE_EOF) {
+ if (error.os_error == ERROR_HANDLE_EOF)
return 0; // Report EOF by returning 0 bytes read.
- } else {
+ if (error.os_error == ERROR_IO_PENDING)
+ IOCompletionIsPending(callback, buf);
+ else
LOG(WARNING) << "ReadFile failed: " << error.os_error;
- }
- return error.result;
+ return static_cast<int>(error.result);
}
IOCompletionIsPending(callback, buf);
@@ -89,12 +88,11 @@
if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len,
&bytes_written, &io_context_.overlapped)) {
IOResult error = IOResult::FromOSError(GetLastError());
- if (error.os_error == ERROR_IO_PENDING) {
+ if (error.os_error == ERROR_IO_PENDING)
IOCompletionIsPending(callback, buf);
- } else {
+ else
LOG(WARNING) << "WriteFile failed: " << error.os_error;
- }
- return error.result;
+ return static_cast<int>(error.result);
}
IOCompletionIsPending(callback, buf);
@@ -149,7 +147,7 @@
result = 0;
} else if (error) {
IOResult error_result = IOResult::FromOSError(error);
- result = error_result.result;
+ result = static_cast<int>(error_result.result);
} else {
result = bytes_read;
IncrementOffset(&io_context_.overlapped, bytes_read);
diff --git a/net/base/host_mapping_rules.cc b/net/base/host_mapping_rules.cc
index f91f3fd..01b98b7 100644
--- a/net/base/host_mapping_rules.cc
+++ b/net/base/host_mapping_rules.cc
@@ -58,7 +58,7 @@
host_port->set_host(rule.replacement_hostname);
if (rule.replacement_port != -1)
- host_port->set_port(rule.replacement_port);
+ host_port->set_port(static_cast<uint16>(rule.replacement_port));
return true;
}
diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc
index 18cf9f5..1570bbb 100644
--- a/net/base/host_port_pair.cc
+++ b/net/base/host_port_pair.cc
@@ -21,7 +21,8 @@
// static
HostPortPair HostPortPair::FromURL(const GURL& url) {
- return HostPortPair(url.HostNoBrackets(), url.EffectiveIntPort());
+ return HostPortPair(url.HostNoBrackets(),
+ static_cast<uint16>(url.EffectiveIntPort()));
}
// static
@@ -41,7 +42,7 @@
return HostPortPair();
HostPortPair host_port_pair;
host_port_pair.set_host(key_port[0]);
- host_port_pair.set_port(port);
+ host_port_pair.set_port(static_cast<uint16>(port));
return host_port_pair;
}
diff --git a/net/base/ip_endpoint.cc b/net/base/ip_endpoint.cc
index a0d378e..65c5d50 100644
--- a/net/base/ip_endpoint.cc
+++ b/net/base/ip_endpoint.cc
@@ -25,7 +25,7 @@
IPEndPoint::~IPEndPoint() {}
-IPEndPoint::IPEndPoint(const IPAddressNumber& address, int port)
+IPEndPoint::IPEndPoint(const IPAddressNumber& address, uint16 port)
: address_(address),
port_(port) {}
diff --git a/net/base/ip_endpoint.h b/net/base/ip_endpoint.h
index 5e5d9c1..c2639b1 100644
--- a/net/base/ip_endpoint.h
+++ b/net/base/ip_endpoint.h
@@ -24,11 +24,11 @@
public:
IPEndPoint();
~IPEndPoint();
- IPEndPoint(const IPAddressNumber& address, int port);
+ IPEndPoint(const IPAddressNumber& address, uint16 port);
IPEndPoint(const IPEndPoint& endpoint);
const IPAddressNumber& address() const { return address_; }
- int port() const { return port_; }
+ uint16 port() const { return port_; }
// Returns AddressFamily of the address.
AddressFamily GetFamily() const;
@@ -66,7 +66,7 @@
private:
IPAddressNumber address_;
- int port_;
+ uint16 port_;
};
} // namespace net
diff --git a/net/base/ip_endpoint_unittest.cc b/net/base/ip_endpoint_unittest.cc
index 5d70911..17b325c 100644
--- a/net/base/ip_endpoint_unittest.cc
+++ b/net/base/ip_endpoint_unittest.cc
@@ -29,7 +29,7 @@
{ "::1", "[::1]", true },
{ "2001:db8:0::42", "[2001:db8::42]", true },
};
-int test_count = arraysize(tests);
+uint16 test_count = static_cast<uint16>(arraysize(tests));
class IPEndPointTest : public PlatformTest {
public:
@@ -46,7 +46,7 @@
IPEndPoint endpoint;
EXPECT_EQ(0, endpoint.port());
- for (int index = 0; index < test_count; ++index) {
+ for (uint16 index = 0; index < test_count; ++index) {
IPEndPoint endpoint(tests[index].ip_address, 80);
EXPECT_EQ(80, endpoint.port());
EXPECT_EQ(tests[index].ip_address, endpoint.address());
@@ -54,7 +54,7 @@
}
TEST_F(IPEndPointTest, Assignment) {
- for (int index = 0; index < test_count; ++index) {
+ for (uint16 index = 0; index < test_count; ++index) {
IPEndPoint src(tests[index].ip_address, index);
IPEndPoint dest = src;
@@ -64,7 +64,7 @@
}
TEST_F(IPEndPointTest, Copy) {
- for (int index = 0; index < test_count; ++index) {
+ for (uint16 index = 0; index < test_count; ++index) {
IPEndPoint src(tests[index].ip_address, index);
IPEndPoint dest(src);
@@ -74,7 +74,7 @@
}
TEST_F(IPEndPointTest, ToFromSockAddr) {
- for (int index = 0; index < test_count; ++index) {
+ for (uint16 index = 0; index < test_count; ++index) {
IPEndPoint ip_endpoint(tests[index].ip_address, index);
// Convert to a sockaddr.
@@ -97,7 +97,7 @@
}
TEST_F(IPEndPointTest, ToSockAddrBufTooSmall) {
- for (int index = 0; index < test_count; ++index) {
+ for (uint16 index = 0; index < test_count; ++index) {
IPEndPoint ip_endpoint(tests[index].ip_address, index);
SockaddrStorage storage;
@@ -116,7 +116,7 @@
}
TEST_F(IPEndPointTest, Equality) {
- for (int index = 0; index < test_count; ++index) {
+ for (uint16 index = 0; index < test_count; ++index) {
IPEndPoint src(tests[index].ip_address, index);
IPEndPoint dest(src);
EXPECT_TRUE(src == dest);
@@ -159,8 +159,8 @@
IPEndPoint endpoint;
EXPECT_EQ(0, endpoint.port());
- for (int index = 0; index < test_count; ++index) {
- int port = 100 + index;
+ for (uint16 index = 0; index < test_count; ++index) {
+ uint16 port = 100 + index;
IPEndPoint endpoint(tests[index].ip_address, port);
const std::string result = endpoint.ToString();
EXPECT_EQ(tests[index].host_normalized + ":" + base::IntToString(port),
diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h
index 494b762..d6e6187 100644
--- a/net/base/net_log_event_type_list.h
+++ b/net/base/net_log_event_type_list.h
@@ -1325,6 +1325,10 @@
EVENT_TYPE(SPDY_STREAM)
// A stream is attached to a pushed stream.
+// {
+// "stream_id": <The stream id>,
+// "url": <The url of the pushed resource>,
+// }
EVENT_TYPE(SPDY_STREAM_ADOPTED_PUSH_STREAM)
// A stream is unstalled by flow control.
diff --git a/net/base/net_log_util.cc b/net/base/net_log_util.cc
index a15e899..3b437aa 100644
--- a/net/base/net_log_util.cc
+++ b/net/base/net_log_util.cc
@@ -4,12 +4,17 @@
#include "net/base/net_log_util.h"
+#include <algorithm>
#include <string>
+#include <vector>
+#include "base/bind.h"
+#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "net/base/address_family.h"
#include "net/base/load_states.h"
@@ -28,6 +33,7 @@
#include "net/proxy/proxy_service.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_utils.h"
+#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
namespace net {
@@ -101,6 +107,25 @@
return http_cache->GetCurrentBackend();
}
+// Returns true if |request1| was created before |request2|.
+bool RequestCreatedBefore(const net::URLRequest* request1,
+ const net::URLRequest* request2) {
+ if (request1->creation_time() < request2->creation_time())
+ return true;
+ if (request1->creation_time() > request2->creation_time())
+ return false;
+ // If requests were created at the same time, sort by ID. Mostly matters for
+ // testing purposes.
+ return request1->identifier() < request2->identifier();
+}
+
+// Returns a Value representing the state of a pre-existing URLRequest when
+// net-internals was opened.
+base::Value* GetRequestStateAsValue(const net::URLRequest* request,
+ net::NetLog::LogLevel log_level) {
+ return request->GetStateAsValue();
+}
+
} // namespace
scoped_ptr<base::DictionaryValue> GetNetConstants() {
@@ -298,6 +323,9 @@
NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
URLRequestContext* context, int info_sources) {
+ // May only be called on the context's thread.
+ DCHECK(context->CalledOnValidThread());
+
scoped_ptr<base::DictionaryValue> net_info_dict(new base::DictionaryValue());
// TODO(mmenke): The code for most of these sources should probably be moved
@@ -489,4 +517,41 @@
return net_info_dict.Pass();
}
+NET_EXPORT void CreateNetLogEntriesForActiveObjects(
+ const std::set<URLRequestContext*>& contexts,
+ NetLog::ThreadSafeObserver* observer) {
+ // Not safe to call this when the observer is watching a NetLog.
+ DCHECK(!observer->net_log());
+
+ // Put together the list of all requests.
+ std::vector<const URLRequest*> requests;
+ for (const auto& context : contexts) {
+ // May only be called on the context's thread.
+ DCHECK(context->CalledOnValidThread());
+ // Contexts should all be using the same NetLog.
+ DCHECK_EQ((*contexts.begin())->net_log(), context->net_log());
+ for (const auto& request : *context->url_requests()) {
+ requests.push_back(request);
+ }
+ }
+
+ // Sort by creation time.
+ std::sort(requests.begin(), requests.end(), RequestCreatedBefore);
+
+ // Create fake events.
+ ScopedVector<NetLog::Entry> entries;
+ for (const auto& request : requests) {
+ net::NetLog::ParametersCallback callback =
+ base::Bind(&GetRequestStateAsValue, base::Unretained(request));
+
+ net::NetLog::EntryData entry_data(net::NetLog::TYPE_REQUEST_ALIVE,
+ request->net_log().source(),
+ net::NetLog::PHASE_BEGIN,
+ request->creation_time(),
+ &callback);
+ NetLog::Entry entry(&entry_data, request->net_log().GetLogLevel());
+ observer->OnAddEntry(entry);
+ }
+}
+
} // namespace net
diff --git a/net/base/net_log_util.h b/net/base/net_log_util.h
index d9627da..d6d6857 100644
--- a/net/base/net_log_util.h
+++ b/net/base/net_log_util.h
@@ -5,8 +5,11 @@
#ifndef NET_BASE_NET_LOG_UTIL_H_
#define NET_BASE_NET_LOG_UTIL_H_
+#include <set>
+
#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
+#include "net/base/net_log.h"
namespace base {
class DictionaryValue;
@@ -28,16 +31,38 @@
// Utility methods for creating NetLog dumps.
-// Create a dictionary containing legend for net/ constants.
+// Create a dictionary containing a legend for net/ constants.
NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetConstants();
// Retrieves a dictionary containing information about the current state of
// |context|. |info_sources| is a set of NetInfoSources OR'd together,
// indicating just what information is being requested. Each NetInfoSource adds
// one top-level entry to the returned dictionary.
+//
+// May only be called on |context|'s thread.
NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo(
URLRequestContext* context, int info_sources);
+// Takes in a set of contexts and a NetLog::Observer, and passes in
+// NetLog::Entries to the observer for certain NetLog::Sources with pending
+// events. This allows requests that were ongoing when logging was started to
+// have an initial event that has some information. This is particularly useful
+// for hung requests. Note that these calls are not protected by the NetLog's
+// lock, so this should generally be invoked before the observer starts watching
+// the NetLog.
+//
+// All members of |contexts| must be using the same NetLog, and live on the
+// current thread.
+//
+// Currently only creates events for URLRequests.
+//
+// The reason for not returning a list of NetLog::Entries is that entries don't
+// own most of their data, so it's simplest just to pass them in to the observer
+// directly while their data is on the stack.
+NET_EXPORT void CreateNetLogEntriesForActiveObjects(
+ const std::set<URLRequestContext*>& contexts,
+ NetLog::ThreadSafeObserver* observer);
+
} // namespace net
#endif // NET_BASE_NET_LOG_UTIL_H_
diff --git a/net/base/net_log_util_unittest.cc b/net/base/net_log_util_unittest.cc
index e5cc3a3..e052980 100644
--- a/net/base/net_log_util_unittest.cc
+++ b/net/base/net_log_util_unittest.cc
@@ -4,12 +4,17 @@
#include "net/base/net_log_util.h"
+#include <set>
+
+#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
+#include "net/base/capturing_net_log_observer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_cache.h"
#include "net/http/http_transaction.h"
+#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -49,6 +54,65 @@
EXPECT_EQ(net_info_without_cache->size(), net_info_with_cache->size());
}
+// Make sure CreateNetLogEntriesForActiveObjects works for requests from a
+// single URLRequestContext.
+TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsOneContext) {
+ // Using same context for each iteration makes sure deleted requests don't
+ // appear in the list, or result in crashes.
+ TestURLRequestContext context(true);
+ NetLog net_log;
+ context.set_net_log(&net_log);
+ context.Init();
+ TestDelegate delegate;
+ for (size_t num_requests = 0; num_requests < 5; ++num_requests) {
+ ScopedVector<URLRequest> requests;
+ for (size_t i = 0; i < num_requests; ++i) {
+ requests.push_back(context.CreateRequest(
+ GURL("about:life"), DEFAULT_PRIORITY, &delegate, nullptr).release());
+ }
+ std::set<URLRequestContext*> contexts;
+ contexts.insert(&context);
+ CapturingNetLogObserver capturing_observer;
+ CreateNetLogEntriesForActiveObjects(contexts, &capturing_observer);
+ CapturedNetLogEntry::List entry_list;
+ capturing_observer.GetEntries(&entry_list);
+ ASSERT_EQ(num_requests, entry_list.size());
+
+ for (size_t i = 0; i < num_requests; ++i) {
+ EXPECT_EQ(entry_list[i].source.id, requests[i]->net_log().source().id);
+ }
+ }
+}
+
+// Make sure CreateNetLogEntriesForActiveObjects works with multiple
+// URLRequestContexts.
+TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsMultipleContexts) {
+ TestDelegate delegate;
+ for (size_t num_requests = 0; num_requests < 5; ++num_requests) {
+ ScopedVector<TestURLRequestContext> contexts;
+ ScopedVector<URLRequest> requests;
+ NetLog net_log;
+ std::set<URLRequestContext*> context_set;
+ for (size_t i = 0; i < num_requests; ++i) {
+ contexts.push_back(new TestURLRequestContext(true));
+ contexts[i]->set_net_log(&net_log);
+ contexts[i]->Init();
+ context_set.insert(contexts[i]);
+ requests.push_back(contexts[i]->CreateRequest(
+ GURL("about:hats"), DEFAULT_PRIORITY, &delegate, nullptr).release());
+ }
+ CapturingNetLogObserver capturing_observer;
+ CreateNetLogEntriesForActiveObjects(context_set, &capturing_observer);
+ CapturedNetLogEntry::List entry_list;
+ capturing_observer.GetEntries(&entry_list);
+ ASSERT_EQ(num_requests, entry_list.size());
+
+ for (size_t i = 0; i < num_requests; ++i) {
+ EXPECT_EQ(entry_list[i].source.id, requests[i]->net_log().source().id);
+ }
+ }
+}
+
} // namespace
} // namespace net
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 9dcf9df..3b49dff 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -306,7 +306,7 @@
return false;
}
}
- return true;
+ return IsPortValid(port);
}
bool IsPortAllowedByFtp(int port) {
@@ -573,7 +573,7 @@
*address = reinterpret_cast<const uint8*>(&addr->btAddr);
*address_len = kBluetoothAddressSize;
if (port)
- *port = addr->port;
+ *port = static_cast<uint16>(addr->port);
return true;
}
#endif
@@ -1015,8 +1015,7 @@
}
NetworkInterface::NetworkInterface()
- : type(NetworkChangeNotifier::CONNECTION_UNKNOWN),
- network_prefix(0) {
+ : type(NetworkChangeNotifier::CONNECTION_UNKNOWN), prefix_length(0) {
}
NetworkInterface::NetworkInterface(const std::string& name,
@@ -1024,14 +1023,14 @@
uint32 interface_index,
NetworkChangeNotifier::ConnectionType type,
const IPAddressNumber& address,
- uint32 network_prefix,
+ uint32 prefix_length,
int ip_address_attributes)
: name(name),
friendly_name(friendly_name),
interface_index(interface_index),
type(type),
address(address),
- network_prefix(network_prefix),
+ prefix_length(prefix_length),
ip_address_attributes(ip_address_attributes) {
}
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 44b913a..9e9dbad 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -468,7 +468,7 @@
uint32 interface_index,
NetworkChangeNotifier::ConnectionType type,
const IPAddressNumber& address,
- uint32 network_prefix,
+ uint32 prefix_length,
int ip_address_attributes);
~NetworkInterface();
@@ -477,7 +477,7 @@
uint32 interface_index; // Always 0 on Android.
NetworkChangeNotifier::ConnectionType type;
IPAddressNumber address;
- uint32 network_prefix;
+ uint32 prefix_length;
int ip_address_attributes; // Combination of |IPAddressAttributes|.
};
@@ -487,9 +487,6 @@
enum HostAddressSelectionPolicy {
INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES = 0x0,
EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES = 0x1,
- // Include temp address only when interface has both permanent and
- // temp addresses.
- INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE = 0x2,
};
// Returns list of network interfaces except loopback interface. If an
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index a25903a..cb9ec1f 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -36,21 +36,22 @@
#include <iphlpapi.h>
#include <objbase.h>
#include "base/win/windows_version.h"
-#include "net/base/net_util_win.h"
#endif // OS_WIN
#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_WIN)
#include "net/base/address_tracker_linux.h"
#endif // !OS_MACOSX && !OS_NACL && !OS_WIN
-#if !defined(OS_WIN)
+#if defined(OS_WIN)
+#include "net/base/net_util_win.h"
+#else // OS_WIN
#include "net/base/net_util_posix.h"
#if defined(OS_MACOSX)
#include "net/base/net_util_mac.h"
#else // OS_MACOSX
#include "net/base/net_util_linux.h"
-#endif
-#endif // !OS_WIN
+#endif // OS_MACOSX
+#endif // OS_WIN
using base::ASCIIToUTF16;
using base::WideToUTF16;
@@ -830,8 +831,8 @@
}
}
EXPECT_FALSE(all_zeroes);
- EXPECT_GT(it->network_prefix, 1u);
- EXPECT_LE(it->network_prefix, it->address.size() * 8);
+ EXPECT_GT(it->prefix_length, 1u);
+ EXPECT_LE(it->prefix_length, it->address.size() * 8);
#if defined(OS_WIN)
// On Windows |name| is NET_LUID.
@@ -877,16 +878,32 @@
}
static const char ifname_em1[] = "em1";
+#if defined(OS_WIN)
+static const char ifname_vm[] = "VMnet";
+#else
static const char ifname_vm[] = "vmnet";
+#endif // OS_WIN
static const unsigned char kIPv6LocalAddr[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
+// The following 3 addresses need to be changed together. IPv6Addr is the IPv6
+// address. IPv6Netmask is the mask address with as many leading bits set to 1
+// as the prefix length. IPv6AddrPrefix needs to match IPv6Addr with the same
+// number of bits as the prefix length.
static const unsigned char kIPv6Addr[] =
{0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
0xfe, 0xe5, 0x00, 0xc3};
+#if defined(OS_WIN)
+static const unsigned char kIPv6AddrPrefix[] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+#endif // OS_WIN
+#if defined(OS_MACOSX)
static const unsigned char kIPv6Netmask[] =
{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
+#endif // OS_MACOSX
#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_NACL)
@@ -908,8 +925,6 @@
IPAddressNumber ipv6_local_address(
kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
- IPAddressNumber ipv6_netmask(kIPv6Netmask,
- kIPv6Netmask + arraysize(kIPv6Netmask));
NetworkInterfaceList results;
::base::hash_set<int> online_links;
@@ -960,7 +975,7 @@
GetInterfaceNameVM));
EXPECT_EQ(results.size(), 1ul);
EXPECT_EQ(results[0].name, ifname_vm);
- EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
EXPECT_EQ(results[0].address, ipv6_address);
results.clear();
@@ -1002,7 +1017,7 @@
GetInterfaceName));
EXPECT_EQ(results.size(), 1ul);
EXPECT_EQ(results[0].name, ifname_em1);
- EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
EXPECT_EQ(results[0].address, ipv6_address);
EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
results.clear();
@@ -1020,7 +1035,7 @@
GetInterfaceName));
EXPECT_EQ(results.size(), 1ul);
EXPECT_EQ(results[0].name, ifname_em1);
- EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
EXPECT_EQ(results[0].address, ipv6_address);
EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
results.clear();
@@ -1064,7 +1079,7 @@
&ip_attributes_getter));
EXPECT_EQ(results.size(), 1ul);
EXPECT_EQ(results[0].name, ifname_vm);
- EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
EXPECT_EQ(results[0].address, ipv6_address);
results.clear();
@@ -1098,7 +1113,7 @@
&ip_attributes_getter));
EXPECT_EQ(results.size(), 1ul);
EXPECT_EQ(results[0].name, ifname_em1);
- EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
EXPECT_EQ(results[0].address, ipv6_address);
EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
results.clear();
@@ -1113,12 +1128,181 @@
&ip_attributes_getter));
EXPECT_EQ(results.size(), 1ul);
EXPECT_EQ(results[0].name, ifname_em1);
- EXPECT_EQ(results[0].network_prefix, 1ul);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
EXPECT_EQ(results[0].address, ipv6_address);
EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
results.clear();
#endif // !OS_IOS
}
+#elif defined(OS_WIN) // !OS_MACOSX && !OS_WIN && !OS_NACL
+
+// Helper function to create a valid IP_ADAPTER_ADDRESSES with reasonable
+// default value. The output is the |adapter_address|. All the rests are input
+// to fill the |adapter_address|. |sock_addrs| are temporary storage used by
+// |adapter_address| once the function is returned.
+bool FillAdapterAddress(IP_ADAPTER_ADDRESSES* adapter_address,
+ const char* ifname,
+ const IPAddressNumber& ip_address,
+ const IPAddressNumber& ip_netmask,
+ sockaddr_storage sock_addrs[2]) {
+ adapter_address->AdapterName = const_cast<char*>(ifname);
+ adapter_address->FriendlyName = const_cast<PWCHAR>(L"interface");
+ adapter_address->IfType = IF_TYPE_ETHERNET_CSMACD;
+ adapter_address->OperStatus = IfOperStatusUp;
+ adapter_address->FirstUnicastAddress->DadState = IpDadStatePreferred;
+ adapter_address->FirstUnicastAddress->PrefixOrigin = IpPrefixOriginOther;
+ adapter_address->FirstUnicastAddress->SuffixOrigin = IpSuffixOriginOther;
+ adapter_address->FirstUnicastAddress->PreferredLifetime = 100;
+ adapter_address->FirstUnicastAddress->ValidLifetime = 1000;
+
+ socklen_t sock_len = sizeof(sockaddr_storage);
+
+ // Convert to sockaddr for next check.
+ if (!IPEndPoint(ip_address, 0)
+ .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[0]),
+ &sock_len)) {
+ return false;
+ }
+ adapter_address->FirstUnicastAddress->Address.lpSockaddr =
+ reinterpret_cast<sockaddr*>(&sock_addrs[0]);
+ adapter_address->FirstUnicastAddress->Address.iSockaddrLength = sock_len;
+ adapter_address->FirstUnicastAddress->OnLinkPrefixLength = 1;
+
+ sock_len = sizeof(sockaddr_storage);
+ if (!IPEndPoint(ip_netmask, 0)
+ .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[1]),
+ &sock_len)) {
+ return false;
+ }
+ adapter_address->FirstPrefix->Address.lpSockaddr =
+ reinterpret_cast<sockaddr*>(&sock_addrs[1]);
+ adapter_address->FirstPrefix->Address.iSockaddrLength = sock_len;
+ adapter_address->FirstPrefix->PrefixLength = 1;
+
+ DCHECK_EQ(sock_addrs[0].ss_family, sock_addrs[1].ss_family);
+ if (sock_addrs[0].ss_family == AF_INET6) {
+ adapter_address->Ipv6IfIndex = 0;
+ } else {
+ DCHECK_EQ(sock_addrs[0].ss_family, AF_INET);
+ adapter_address->IfIndex = 0;
+ }
+
+ return true;
+}
+
+TEST(NetUtilTest, GetNetworkListTrimming) {
+ IPAddressNumber ipv6_local_address(
+ kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
+ IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
+ IPAddressNumber ipv6_prefix(kIPv6AddrPrefix,
+ kIPv6AddrPrefix + arraysize(kIPv6AddrPrefix));
+
+ NetworkInterfaceList results;
+ sockaddr_storage addresses[2];
+ IP_ADAPTER_ADDRESSES adapter_address = {0};
+ IP_ADAPTER_UNICAST_ADDRESS address = {0};
+ IP_ADAPTER_PREFIX adapter_prefix = {0};
+ adapter_address.FirstUnicastAddress = &address;
+ adapter_address.FirstPrefix = &adapter_prefix;
+
+ // Address of offline links should be ignored.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
+ ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ adapter_address.OperStatus = IfOperStatusDown;
+
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+
+ EXPECT_EQ(results.size(), 0ul);
+
+ // Address on loopback interface should be trimmed out.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
+ ipv6_local_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ adapter_address.IfType = IF_TYPE_SOFTWARE_LOOPBACK;
+
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+ EXPECT_EQ(results.size(), 0ul);
+
+ // vmware address should return by default.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_vm /* ifname */,
+ ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+ EXPECT_EQ(results.size(), 1ul);
+ EXPECT_EQ(results[0].name, ifname_vm);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
+ EXPECT_EQ(results[0].address, ipv6_address);
+ EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_NONE);
+ results.clear();
+
+ // vmware address should be trimmed out if policy specified so.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_vm /* ifname */,
+ ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+ EXPECT_EQ(results.size(), 0ul);
+ results.clear();
+
+ // Addresses with incompleted DAD should be ignored.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
+ ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ adapter_address.FirstUnicastAddress->DadState = IpDadStateTentative;
+
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+ EXPECT_EQ(results.size(), 0ul);
+ results.clear();
+
+ // Addresses with allowed attribute IpSuffixOriginRandom should be returned
+ // and attributes should be translated correctly to
+ // IP_ADDRESS_ATTRIBUTE_TEMPORARY.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
+ ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ adapter_address.FirstUnicastAddress->PrefixOrigin =
+ IpPrefixOriginRouterAdvertisement;
+ adapter_address.FirstUnicastAddress->SuffixOrigin = IpSuffixOriginRandom;
+
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+ EXPECT_EQ(results.size(), 1ul);
+ EXPECT_EQ(results[0].name, ifname_em1);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
+ EXPECT_EQ(results[0].address, ipv6_address);
+ EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
+ results.clear();
+
+ // Addresses with preferred lifetime 0 should be returned and
+ // attributes should be translated correctly to
+ // IP_ADDRESS_ATTRIBUTE_DEPRECATED.
+ ASSERT_TRUE(FillAdapterAddress(
+ &adapter_address /* adapter_address */, ifname_em1 /* ifname */,
+ ipv6_address /* ip_address */, ipv6_prefix /* ip_netmask */,
+ addresses /* sock_addrs */));
+ adapter_address.FirstUnicastAddress->PreferredLifetime = 0;
+ adapter_address.FriendlyName = const_cast<PWCHAR>(L"FriendlyInterfaceName");
+ EXPECT_TRUE(net::internal::GetNetworkListImpl(
+ &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, true, &adapter_address));
+ EXPECT_EQ(results.size(), 1ul);
+ EXPECT_EQ(results[0].friendly_name, "FriendlyInterfaceName");
+ EXPECT_EQ(results[0].name, ifname_em1);
+ EXPECT_EQ(results[0].prefix_length, 1ul);
+ EXPECT_EQ(results[0].address, ipv6_address);
+ EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
+ results.clear();
+}
#endif // !OS_MACOSX && !OS_WIN && !OS_NACL
diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc
index 7d146b9..ec40233 100644
--- a/net/base/net_util_win.cc
+++ b/net/base/net_util_win.cc
@@ -85,35 +85,11 @@
free_memory_func && close_handle_func;
}
-} // namespace internal
-
-bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
- // GetAdaptersAddresses() may require IO operations.
- base::ThreadRestrictions::AssertIOAllowed();
- bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA;
- ULONG len = 0;
- ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0;
- // First get number of networks.
- ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len);
- if (result != ERROR_BUFFER_OVERFLOW) {
- // There are 0 networks.
- return true;
- }
- scoped_ptr<char[]> buf(new char[len]);
- IP_ADAPTER_ADDRESSES *adapters =
- reinterpret_cast<IP_ADAPTER_ADDRESSES *>(buf.get());
- result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len);
- if (result != NO_ERROR) {
- LOG(ERROR) << "GetAdaptersAddresses failed: " << result;
- return false;
- }
-
- // These two variables are used below when this method is asked to pick a
- // IPv6 address which has the shortest lifetime.
- ULONG ipv6_valid_lifetime = 0;
- scoped_ptr<NetworkInterface> ipv6_address;
-
- for (IP_ADAPTER_ADDRESSES *adapter = adapters; adapter != NULL;
+bool GetNetworkListImpl(NetworkInterfaceList* networks,
+ int policy,
+ bool is_xp,
+ const IP_ADAPTER_ADDRESSES* adapters) {
+ for (const IP_ADAPTER_ADDRESSES* adapter = adapters; adapter != NULL;
adapter = adapter->Next) {
// Ignore the loopback device.
if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
@@ -128,7 +104,7 @@
// VMware Virtual Ethernet Adapter for VMnet1
// but don't ignore any GUEST side adapters with a description like:
// VMware Accelerated AMD PCNet Adapter #2
- if (policy == EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES &&
+ if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) &&
strstr(adapter->AdapterName, "VMnet") != NULL) {
continue;
}
@@ -141,7 +117,7 @@
if (endpoint.FromSockAddr(address->Address.lpSockaddr,
address->Address.iSockaddrLength)) {
// XP has no OnLinkPrefixLength field.
- size_t net_prefix = is_xp ? 0 : address->OnLinkPrefixLength;
+ size_t prefix_length = is_xp ? 0 : address->OnLinkPrefixLength;
if (is_xp) {
// Prior to Windows Vista the FirstPrefix pointed to the list with
// single prefix for each IP address assigned to the adapter.
@@ -157,52 +133,72 @@
IPNumberMatchesPrefix(endpoint.address(),
network_endpoint.address(),
prefix->PrefixLength)) {
- net_prefix = std::max<size_t>(net_prefix, prefix->PrefixLength);
+ prefix_length =
+ std::max<size_t>(prefix_length, prefix->PrefixLength);
}
}
}
+
+ // If the duplicate address detection (DAD) state is not changed to
+ // Preferred, skip this address.
+ if (address->DadState != IpDadStatePreferred) {
+ continue;
+ }
+
uint32 index =
(family == AF_INET) ? adapter->IfIndex : adapter->Ipv6IfIndex;
- // Pick one IPv6 address with least valid lifetime.
- // The reason we are checking |ValidLifeftime| as there is no other
- // way identifying the interface type. Usually (and most likely) temp
- // IPv6 will have a shorter ValidLifetime value then the permanent
- // interface.
- if (family == AF_INET6 &&
- (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE)) {
- if (ipv6_valid_lifetime == 0 ||
- ipv6_valid_lifetime > address->ValidLifetime) {
- ipv6_valid_lifetime = address->ValidLifetime;
- ipv6_address.reset(new NetworkInterface(
- adapter->AdapterName,
- base::SysWideToNativeMB(adapter->FriendlyName),
- index,
- GetNetworkInterfaceType(adapter->IfType),
- endpoint.address(),
- net_prefix,
- IP_ADDRESS_ATTRIBUTE_NONE));
- continue;
+
+ // From http://technet.microsoft.com/en-us/ff568768(v=vs.60).aspx, the
+ // way to identify a temporary IPv6 Address is to check if
+ // PrefixOrigin is equal to IpPrefixOriginRouterAdvertisement and
+ // SuffixOrigin equal to IpSuffixOriginRandom.
+ int ip_address_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
+ if (family == AF_INET6) {
+ if (address->PrefixOrigin == IpPrefixOriginRouterAdvertisement &&
+ address->SuffixOrigin == IpSuffixOriginRandom) {
+ ip_address_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
+ }
+ if (address->PreferredLifetime == 0) {
+ ip_address_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
}
}
- networks->push_back(
- NetworkInterface(adapter->AdapterName,
- base::SysWideToNativeMB(adapter->FriendlyName),
- index,
- GetNetworkInterfaceType(adapter->IfType),
- endpoint.address(),
- net_prefix,
- IP_ADDRESS_ATTRIBUTE_NONE));
+ networks->push_back(NetworkInterface(
+ adapter->AdapterName,
+ base::SysWideToNativeMB(adapter->FriendlyName), index,
+ GetNetworkInterfaceType(adapter->IfType), endpoint.address(),
+ prefix_length, ip_address_attributes));
}
}
}
}
-
- if (ipv6_address.get()) {
- networks->push_back(*(ipv6_address.get()));
- }
return true;
}
+} // namespace internal
+
+bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
+ bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA;
+ ULONG len = 0;
+ ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0;
+ // GetAdaptersAddresses() may require IO operations.
+ base::ThreadRestrictions::AssertIOAllowed();
+ ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len);
+ if (result != ERROR_BUFFER_OVERFLOW) {
+ // There are 0 networks.
+ return true;
+ }
+ scoped_ptr<char[]> buf(new char[len]);
+ IP_ADAPTER_ADDRESSES* adapters =
+ reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buf.get());
+ result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len);
+ if (result != NO_ERROR) {
+ LOG(ERROR) << "GetAdaptersAddresses failed: " << result;
+ return false;
+ }
+
+ return internal::GetNetworkListImpl(networks, policy, is_xp, adapters);
+}
+
WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
if (!wlanapi.initialized)
diff --git a/net/base/net_util_win.h b/net/base/net_util_win.h
index afa888b..b0c2dd6 100644
--- a/net/base/net_util_win.h
+++ b/net/base/net_util_win.h
@@ -8,10 +8,12 @@
// This file is only used to expose some of the internals
// of net_util_win.cc to tests.
+#include <iphlpapi.h>
#include <wlanapi.h>
#include "base/win/scoped_handle.h"
#include "net/base/net_export.h"
+#include "net/base/net_util.h"
namespace net {
namespace internal {
@@ -78,6 +80,12 @@
}
};
+NET_EXPORT bool GetNetworkListImpl(
+ NetworkInterfaceList* networks,
+ int policy,
+ bool is_xp,
+ const IP_ADAPTER_ADDRESSES* ip_adapter_addresses);
+
} // namespace internal
} // namespace net
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index 5b69cfb..d4aa19e 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -339,12 +339,6 @@
return false;
}
-int NetworkDelegate::OnBeforeSocketStreamConnect(
- SocketStream* socket,
- const CompletionCallback& callback) {
- return OK;
-}
-
bool NetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
const GURL& target_url,
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h
index 03dee0b..a169fc6 100644
--- a/net/base/network_delegate.h
+++ b/net/base/network_delegate.h
@@ -38,7 +38,6 @@
class ProxyInfo;
class ProxyServer;
class ProxyService;
-class SocketStream;
class URLRequest;
class NET_EXPORT NetworkDelegate : public base::NonThreadSafe {
@@ -268,11 +267,6 @@
const GURL& url,
const GURL& first_party_for_cookies) const;
- // Called before a SocketStream tries to connect.
- // See OnBeforeURLRequest for return value description. Returns OK by default.
- virtual int OnBeforeSocketStreamConnect(
- SocketStream* socket, const CompletionCallback& callback);
-
// Called when the |referrer_url| for requesting |target_url| during handling
// of the |request| is does not comply with the referrer policy (e.g. a
// secure referrer for an insecure initial target).
diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc
index af5e6ee..1aa9627 100644
--- a/net/base/sdch_manager.cc
+++ b/net/base/sdch_manager.cc
@@ -9,6 +9,7 @@
#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "base/time/default_clock.h"
#include "base/values.h"
#include "crypto/sha2.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -38,9 +39,6 @@
namespace net {
-//------------------------------------------------------------------------------
-// static
-
// Adjust SDCH limits downwards for mobile.
#if defined(OS_ANDROID) || defined(OS_IOS)
// static
@@ -58,7 +56,6 @@
// static
bool SdchManager::g_secure_scheme_supported_ = true;
-//------------------------------------------------------------------------------
SdchManager::Dictionary::Dictionary(const std::string& dictionary_text,
size_t offset,
const std::string& client_hash,
@@ -73,45 +70,22 @@
domain_(domain),
path_(path),
expiration_(expiration),
- ports_(ports) {
+ ports_(ports),
+ clock_(new base::DefaultClock) {
}
-SdchManager::Dictionary::~Dictionary() {
-}
+SdchManager::Dictionary::Dictionary(const SdchManager::Dictionary& rhs)
+ : text_(rhs.text_),
+ client_hash_(rhs.client_hash_),
+ url_(rhs.url_),
+ domain_(rhs.domain_),
+ path_(rhs.path_),
+ expiration_(rhs.expiration_),
+ ports_(rhs.ports_),
+ clock_(new base::DefaultClock) {}
-SdchProblemCode SdchManager::Dictionary::CanAdvertise(
- const GURL& target_url) const {
- /* The specific rules of when a dictionary should be advertised in an
- Avail-Dictionary header are modeled after the rules for cookie scoping. The
- terms "domain-match" and "pathmatch" are defined in RFC 2965 [6]. A
- dictionary may be advertised in the Avail-Dictionaries header exactly when
- all of the following are true:
- 1. The server's effective host name domain-matches the Domain attribute of
- the dictionary.
- 2. If the dictionary has a Port attribute, the request port is one of the
- ports listed in the Port attribute.
- 3. The request URI path-matches the path header of the dictionary.
- 4. The request is not an HTTPS request.
- We can override (ignore) item (4) only when we have explicitly enabled
- HTTPS support AND the dictionary acquisition scheme matches the target
- url scheme.
- */
- if (!DomainMatch(target_url, domain_))
- return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
- if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
- return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
- if (path_.size() && !PathMatch(target_url.path(), path_))
- return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
- if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
- return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
- if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
- return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
- if (base::Time::Now() > expiration_)
- return SDCH_DICTIONARY_FOUND_EXPIRED;
- return SDCH_OK;
-}
+SdchManager::Dictionary::~Dictionary() {}
-//------------------------------------------------------------------------------
// Security functions restricting loads and use of dictionaries.
// static
@@ -168,7 +142,7 @@
}
SdchProblemCode SdchManager::Dictionary::CanUse(
- const GURL& referring_url) const {
+ const GURL& target_url) const {
/*
1. The request URL's host name domain-matches the Domain attribute of the
dictionary.
@@ -180,24 +154,24 @@
HTTPS support AND the dictionary acquisition scheme matches the target
url scheme.
*/
- if (!DomainMatch(referring_url, domain_))
+ if (!DomainMatch(target_url, domain_))
return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
- if (!ports_.empty() && 0 == ports_.count(referring_url.EffectiveIntPort()))
+ if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
- if (path_.size() && !PathMatch(referring_url.path(), path_))
+ if (path_.size() && !PathMatch(target_url.path(), path_))
return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
- if (!SdchManager::secure_scheme_supported() && referring_url.SchemeIsSecure())
+ if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
- if (referring_url.SchemeIsSecure() != url_.SchemeIsSecure())
+ if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
// TODO(jar): Remove overly restrictive failsafe test (added per security
// review) when we have a need to be more general.
- if (!referring_url.SchemeIsHTTPOrHTTPS())
+ if (!target_url.SchemeIsHTTPOrHTTPS())
return SDCH_ATTEMPT_TO_DECODE_NON_HTTP_DATA;
return SDCH_OK;
@@ -228,7 +202,54 @@
return gurl.DomainIs(restriction.data(), restriction.size());
}
-//------------------------------------------------------------------------------
+bool SdchManager::Dictionary::Expired() const {
+ return clock_->Now() > expiration_;
+}
+
+void SdchManager::Dictionary::SetClockForTesting(
+ scoped_ptr<base::Clock> clock) {
+ clock_ = clock.Pass();
+}
+
+SdchManager::DictionarySet::DictionarySet() {}
+
+SdchManager::DictionarySet::~DictionarySet() {}
+
+std::string SdchManager::DictionarySet::GetDictionaryClientHashList() const {
+ std::string result;
+ bool first = true;
+ for (const auto& entry: dictionaries_) {
+ if (!first)
+ result.append(",");
+
+ result.append(entry.second->data.client_hash());
+ first = false;
+ }
+ return result;
+}
+
+const SdchManager::Dictionary* SdchManager::DictionarySet::GetDictionary(
+ const std::string& hash) const {
+ auto it = dictionaries_.find(hash);
+ if (it == dictionaries_.end())
+ return NULL;
+
+ return &it->second->data;
+}
+
+bool SdchManager::DictionarySet::Empty() const {
+ return dictionaries_.empty();
+}
+
+void SdchManager::DictionarySet::AddDictionary(
+ const std::string& server_hash,
+ const scoped_refptr<base::RefCountedData<SdchManager::Dictionary>>&
+ dictionary) {
+ DCHECK(dictionaries_.end() == dictionaries_.find(server_hash));
+
+ dictionaries_[server_hash] = dictionary;
+}
+
SdchManager::SdchManager() {
DCHECK(thread_checker_.CalledOnValidThread());
}
@@ -236,7 +257,7 @@
SdchManager::~SdchManager() {
DCHECK(thread_checker_.CalledOnValidThread());
while (!dictionaries_.empty()) {
- DictionaryMap::iterator it = dictionaries_.begin();
+ auto it = dictionaries_.begin();
dictionaries_.erase(it->first);
}
}
@@ -246,7 +267,7 @@
allow_latency_experiment_.clear();
// Note that this may result in not having dictionaries we've advertised
- // for incoming responses. The window is relatively small (as ClearData()
+ // for incoming responses. The window is relatively small (as ClearData()
// is not expected to be called frequently), so we rely on meta-refresh
// to handle this case.
dictionaries_.clear();
@@ -386,7 +407,7 @@
3 The parent domain of the referrer URL host name is not a top level
domain
*/
- // Item (1) above implies item (2). Spec should be updated.
+ // Item (1) above implies item (2). Spec should be updated.
// I take "host name match" to be "is identical to"
if (referring_url.host() != dictionary_url.host() ||
referring_url.scheme() != dictionary_url.scheme())
@@ -403,51 +424,49 @@
return SDCH_OK;
}
-SdchProblemCode SdchManager::GetVcdiffDictionary(
- const std::string& server_hash,
- const GURL& referring_url,
- scoped_refptr<Dictionary>* dictionary) {
- DCHECK(thread_checker_.CalledOnValidThread());
- *dictionary = NULL;
- DictionaryMap::iterator it = dictionaries_.find(server_hash);
- if (it == dictionaries_.end())
- return SDCH_DICTIONARY_HASH_NOT_FOUND;
+scoped_ptr<SdchManager::DictionarySet>
+SdchManager::GetDictionarySet(const GURL& target_url) {
+ if (IsInSupportedDomain(target_url) != SDCH_OK)
+ return NULL;
- scoped_refptr<Dictionary> matching_dictionary = it->second;
-
- SdchProblemCode rv = IsInSupportedDomain(referring_url);
- if (rv != SDCH_OK)
- return rv;
-
- rv = matching_dictionary->CanUse(referring_url);
- if (rv == SDCH_OK)
- *dictionary = matching_dictionary;
- return rv;
-}
-
-// TODO(jar): If we have evictions from the dictionaries_, then we need to
-// change this interface to return a list of reference counted Dictionary
-// instances that can be used if/when a server specifies one.
-void SdchManager::GetAvailDictionaryList(const GURL& target_url,
- std::string* list) {
- DCHECK(thread_checker_.CalledOnValidThread());
int count = 0;
- for (DictionaryMap::iterator it = dictionaries_.begin();
- it != dictionaries_.end(); ++it) {
- SdchProblemCode rv = IsInSupportedDomain(target_url);
- if (rv != SDCH_OK)
+ scoped_ptr<SdchManager::DictionarySet> result(new DictionarySet);
+ for (const auto& entry: dictionaries_) {
+ if (entry.second->data.CanUse(target_url) != SDCH_OK)
continue;
-
- if (it->second->CanAdvertise(target_url) != SDCH_OK)
+ if (entry.second->data.Expired())
continue;
++count;
- if (!list->empty())
- list->append(",");
- list->append(it->second->client_hash());
+ result->AddDictionary(entry.first, entry.second);
}
- // Watch to see if we have corrupt or numerous dictionaries.
- if (count > 0)
- UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
+
+ if (count == 0)
+ return NULL;
+
+ UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
+
+ return result.Pass();
+}
+
+scoped_ptr<SdchManager::DictionarySet>
+SdchManager::GetDictionarySetByHash(
+ const GURL& target_url,
+ const std::string& server_hash,
+ SdchProblemCode* problem_code) {
+ scoped_ptr<SdchManager::DictionarySet> result;
+
+ *problem_code = SDCH_DICTIONARY_HASH_NOT_FOUND;
+ const auto& it = dictionaries_.find(server_hash);
+ if (it == dictionaries_.end())
+ return result;
+
+ *problem_code = it->second->data.CanUse(target_url);
+ if (*problem_code != SDCH_OK)
+ return result;
+
+ result.reset(new DictionarySet);
+ result->AddDictionary(it->first, it->second);
+ return result;
}
// static
@@ -465,7 +484,6 @@
DCHECK_EQ(client_hash->length(), 8u);
}
-//------------------------------------------------------------------------------
// Methods for supporting latency experiments.
bool SdchManager::AllowLatencyExperiment(const GURL& url) const {
@@ -575,8 +593,8 @@
return rv;
// TODO(jar): Remove these hacks to preclude a DOS attack involving piles of
- // useless dictionaries. We should probably have a cache eviction plan,
- // instead of just blocking additions. For now, with the spec in flux, it
+ // useless dictionaries. We should probably have a cache eviction plan,
+ // instead of just blocking additions. For now, with the spec in flux, it
// is probably not worth doing eviction handling.
if (kMaxDictionarySize < dictionary_text.size())
return SDCH_DICTIONARY_IS_TOO_LARGE;
@@ -587,15 +605,22 @@
UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size());
DVLOG(1) << "Loaded dictionary with client hash " << client_hash
<< " and server hash " << server_hash;
- Dictionary* dictionary =
- new Dictionary(dictionary_text, header_end + 2, client_hash,
- dictionary_url_normalized, domain,
- path, expiration, ports);
- dictionaries_[server_hash] = dictionary;
+ Dictionary dictionary(dictionary_text, header_end + 2, client_hash,
+ dictionary_url_normalized, domain, path, expiration,
+ ports);
+ dictionaries_[server_hash] =
+ new base::RefCountedData<Dictionary>(dictionary);
+
return SDCH_OK;
}
// static
+scoped_ptr<SdchManager::DictionarySet>
+SdchManager::CreateEmptyDictionarySetForTesting() {
+ return scoped_ptr<DictionarySet>(new DictionarySet).Pass();
+}
+
+// static
void SdchManager::UrlSafeBase64Encode(const std::string& input,
std::string* output) {
// Since this is only done during a dictionary load, and hashes are only 8
@@ -612,20 +637,20 @@
value->SetBoolean("secure_scheme_support", secure_scheme_supported());
base::ListValue* entry_list = new base::ListValue();
- for (DictionaryMap::const_iterator it = dictionaries_.begin();
- it != dictionaries_.end(); ++it) {
+ for (const auto& entry: dictionaries_) {
base::DictionaryValue* entry_dict = new base::DictionaryValue();
- entry_dict->SetString("url", it->second->url().spec());
- entry_dict->SetString("client_hash", it->second->client_hash());
- entry_dict->SetString("domain", it->second->domain());
- entry_dict->SetString("path", it->second->path());
+ entry_dict->SetString("url", entry.second->data.url().spec());
+ entry_dict->SetString("client_hash", entry.second->data.client_hash());
+ entry_dict->SetString("domain", entry.second->data.domain());
+ entry_dict->SetString("path", entry.second->data.path());
base::ListValue* port_list = new base::ListValue();
- for (std::set<int>::const_iterator port_it = it->second->ports().begin();
- port_it != it->second->ports().end(); ++port_it) {
+ for (std::set<int>::const_iterator port_it =
+ entry.second->data.ports().begin();
+ port_it != entry.second->data.ports().end(); ++port_it) {
port_list->AppendInteger(*port_it);
}
entry_dict->Set("ports", port_list);
- entry_dict->SetString("server_hash", it->first);
+ entry_dict->SetString("server_hash", entry.first);
entry_list->Append(entry_dict);
}
value->Set("dictionaries", entry_list);
diff --git a/net/base/sdch_manager.h b/net/base/sdch_manager.h
index 016978a..0948b4c 100644
--- a/net/base/sdch_manager.h
+++ b/net/base/sdch_manager.h
@@ -2,12 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file contains the SdchManager class and two nested classes
+// (Dictionary, DictionarySet). SdchManager::Dictionary contains all
+// of the information about an SDCH dictionary. The manager is
+// responsible for storing those dictionaries, and provides access to
+// them through DictionarySet objects. A DictionarySet is an object
+// whose lifetime is under the control of the consumer. It is a
+// reference to a set of dictionaries, and guarantees that none of
+// those dictionaries will be destroyed while the DictionarySet
+// reference is alive.
+
#ifndef NET_BASE_SDCH_MANAGER_H_
#define NET_BASE_SDCH_MANAGER_H_
#include <map>
#include <set>
#include <string>
+#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
@@ -20,6 +31,7 @@
#include "url/gurl.h"
namespace base {
+class Clock;
class Value;
}
@@ -38,25 +50,22 @@
// These dictionaries are acquired over the net, and include a header
// (containing metadata) as well as a VCDIFF dictionary (for use by a VCDIFF
// module) to decompress data.
+//
+// A dictionary held by the manager may nonetheless outlive the manager if
+// a DictionarySet object refers to it; see below.
class NET_EXPORT SdchManager {
public:
+ class Dictionary;
+ typedef std::map<std::string, scoped_refptr<base::RefCountedData<Dictionary>>>
+ DictionaryMap;
+
// Use the following static limits to block DOS attacks until we implement
// a cached dictionary evicition strategy.
static const size_t kMaxDictionarySize;
static const size_t kMaxDictionaryCount;
- // There is one instance of |Dictionary| for each memory-cached SDCH
- // dictionary.
- class NET_EXPORT_PRIVATE Dictionary : public base::RefCounted<Dictionary> {
+ class NET_EXPORT_PRIVATE Dictionary {
public:
- // Sdch filters can get our text to use in decoding compressed data.
- const std::string& text() const { return text_; }
-
- private:
- friend class base::RefCounted<Dictionary>;
- friend class SdchManager; // Only manager can construct an instance.
- FRIEND_TEST_ALL_PREFIXES(SdchManagerTest, PathMatch);
-
// Construct a vc-diff usable dictionary from the dictionary_text starting
// at the given offset. The supplied client_hash should be used to
// advertise the dictionary's availability relative to the suppplied URL.
@@ -68,7 +77,11 @@
const std::string& path,
const base::Time& expiration,
const std::set<int>& ports);
- virtual ~Dictionary();
+
+ ~Dictionary();
+
+ // Sdch filters can get our text to use in decoding compressed data.
+ const std::string& text() const { return text_; }
const GURL& url() const { return url_; }
const std::string& client_hash() const { return client_hash_; }
@@ -77,10 +90,6 @@
const base::Time& expiration() const { return expiration_; }
const std::set<int>& ports() const { return ports_; }
- // Security method to check if we can advertise this dictionary for use
- // if the |target_url| returns SDCH compressed data.
- SdchProblemCode CanAdvertise(const GURL& target_url) const;
-
// Security methods to check if we can establish a new dictionary with the
// given data, that arrived in response to get of dictionary_url.
static SdchProblemCode CanSet(const std::string& domain,
@@ -99,6 +108,19 @@
// Compare domains to see if the "match" for dictionary use.
static bool DomainMatch(const GURL& url, const std::string& restriction);
+ // Is this dictionary expired?
+ bool Expired() const;
+
+ void SetClockForTesting(scoped_ptr<base::Clock> clock);
+
+ private:
+ friend class base::RefCountedData<Dictionary>;
+
+ // Private copy-constructor to support RefCountedData<>, which requires
+ // that an object stored in it be either DefaultConstructible or
+ // CopyConstructible
+ Dictionary(const Dictionary& rhs);
+
// The actual text of the dictionary.
std::string text_;
@@ -118,7 +140,40 @@
const base::Time expiration_; // Implied by max-age.
const std::set<int> ports_;
- DISALLOW_COPY_AND_ASSIGN(Dictionary);
+ scoped_ptr<base::Clock> clock_;
+
+ void operator=(const Dictionary&) = delete;
+ };
+
+ // A handle for one or more dictionaries which will keep the dictionaries
+ // alive and accessible for the handle's lifetime.
+ class NET_EXPORT_PRIVATE DictionarySet {
+ public:
+ ~DictionarySet();
+
+ // Return a comma separated list of client hashes.
+ std::string GetDictionaryClientHashList() const;
+
+ // Lookup a given dictionary based on server hash. Returned pointer
+ // is guaranteed to be valid for the lifetime of the DictionarySet.
+ // Returns NULL if hash is not a valid server hash for a dictionary
+ // named by DictionarySet.
+ const SdchManager::Dictionary* GetDictionary(const std::string& hash) const;
+
+ bool Empty() const;
+
+ private:
+ // A DictionarySet may only be constructed by the SdchManager.
+ friend class SdchManager;
+
+ DictionarySet();
+ void AddDictionary(const std::string& server_hash,
+ const scoped_refptr<base::RefCountedData<
+ SdchManager::Dictionary>>& dictionary);
+
+ DictionaryMap dictionaries_;
+
+ DISALLOW_COPY_AND_ASSIGN(DictionarySet);
};
SdchManager();
@@ -178,23 +233,22 @@
SdchProblemCode OnGetDictionary(const GURL& request_url,
const GURL& dictionary_url);
- // Find the vcdiff dictionary (the body of the sdch dictionary that appears
- // after the meta-data headers like Domain:...) with the given |server_hash|
- // to use to decompreses data that arrived as SDCH encoded content. Check to
- // be sure the returned |dictionary| can be used for decoding content supplied
- // in response to a request for |referring_url|.
- // Return null in |dictionary| if there is no matching legal dictionary.
- // Returns SDCH_OK if dictionary is not found, SDCH(-over-https) is disabled,
- // or if matching legal dictionary exists. Otherwise returns the
- // corresponding problem code.
- SdchProblemCode GetVcdiffDictionary(const std::string& server_hash,
- const GURL& referring_url,
- scoped_refptr<Dictionary>* dictionary);
+ // Get a handle to the available dictionaries that might be used
+ // for encoding responses for the given URL. The return set will not
+ // include expired dictionaries. If no dictionaries
+ // are appropriate to use with the target_url, NULL is returned.
+ scoped_ptr<DictionarySet> GetDictionarySet(const GURL& target_url);
- // Get list of available (pre-cached) dictionaries that we have already loaded
- // into memory. The list is a comma separated list of (client) hashes per
- // the SDCH spec.
- void GetAvailDictionaryList(const GURL& target_url, std::string* list);
+ // Get a handle to a specific dictionary, by its server hash, confirming
+ // that that specific dictionary is appropriate to use with |target_url|.
+ // Expired dictionaries will be returned. If no dictionary with that
+ // hash exists that is usable with |target_url|, NULL is returned.
+ // If there is a usability problem, |*error_code| is set to the
+ // appropriate problem code.
+ scoped_ptr<DictionarySet> GetDictionarySetByHash(
+ const GURL& target_url,
+ const std::string& server_hash,
+ SdchProblemCode* problem_code);
// Construct the pair of hashes for client and server to identify an SDCH
// dictionary. This is only made public to facilitate unit testing, but is
@@ -225,6 +279,8 @@
void AddObserver(SdchObserver* observer);
void RemoveObserver(SdchObserver* observer);
+ static scoped_ptr<DictionarySet> CreateEmptyDictionarySetForTesting();
+
private:
struct BlacklistInfo {
BlacklistInfo() : count(0), exponential_count(0), reason(SDCH_OK) {}
@@ -233,18 +289,16 @@
int exponential_count; // Current exponential backoff ratchet.
SdchProblemCode reason; // Why domain was blacklisted.
};
+
typedef std::map<std::string, BlacklistInfo> DomainBlacklistInfo;
typedef std::set<std::string> ExperimentSet;
// Determines whether a "Get-Dictionary" header is legal (dictionary
// url has appropriate relationship to referrer url) in the SDCH
- // protocol. Return SDCH_OK if fetch is legal.
+ // protocol. Return SDCH_OK if fetch is legal.
SdchProblemCode CanFetchDictionary(const GURL& referring_url,
const GURL& dictionary_url) const;
- // A map of dictionaries info indexed by the hash that the server provides.
- typedef std::map<std::string, scoped_refptr<Dictionary> > DictionaryMap;
-
// Support SDCH compression, by advertising in headers.
static bool g_sdch_enabled_;
diff --git a/net/base/sdch_manager_unittest.cc b/net/base/sdch_manager_unittest.cc
index c20be58..2b78394 100644
--- a/net/base/sdch_manager_unittest.cc
+++ b/net/base/sdch_manager_unittest.cc
@@ -8,6 +8,8 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/simple_test_clock.h"
#include "net/base/net_log.h"
#include "net/base/sdch_manager.h"
#include "net/base/sdch_observer.h"
@@ -199,12 +201,9 @@
EXPECT_TRUE(AddSdchDictionary(dictionary_text,
GURL("http://" + dictionary_domain)));
- std::string dictionary_list;
// HTTP target URL can advertise dictionary.
- sdch_manager()->GetAvailDictionaryList(
- GURL("http://" + dictionary_domain + "/test"),
- &dictionary_list);
- EXPECT_FALSE(dictionary_list.empty());
+ EXPECT_TRUE(sdch_manager()->GetDictionarySet(
+ GURL("http://" + dictionary_domain + "/test")));
}
TEST_F(SdchManagerTest, CanNotAdvertiseDictionaryOverHTTPS) {
@@ -214,12 +213,9 @@
EXPECT_TRUE(AddSdchDictionary(dictionary_text,
GURL("http://" + dictionary_domain)));
- std::string dictionary_list;
// HTTPS target URL should NOT advertise dictionary.
- sdch_manager()->GetAvailDictionaryList(
- GURL("https://" + dictionary_domain + "/test"),
- &dictionary_list);
- EXPECT_TRUE(dictionary_list.empty());
+ EXPECT_FALSE(sdch_manager()->GetDictionarySet(
+ GURL("https://" + dictionary_domain + "/test")));
}
TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) {
@@ -234,20 +230,21 @@
GURL("https://" + dictionary_domain)));
GURL target_url("https://" + dictionary_domain + "/test");
- std::string dictionary_list;
// HTTPS target URL should advertise dictionary if secure scheme support is
// enabled.
- sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
- EXPECT_FALSE(dictionary_list.empty());
+ EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_url));
// Dictionary should be available.
- scoped_refptr<SdchManager::Dictionary> dictionary;
std::string client_hash;
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
- EXPECT_EQ(SDCH_OK, sdch_manager()->GetVcdiffDictionary(
- server_hash, target_url, &dictionary));
- EXPECT_TRUE(dictionary.get() != NULL);
+ SdchProblemCode problem_code;
+ scoped_ptr<SdchManager::DictionarySet> dict_set(
+ sdch_manager()->GetDictionarySetByHash(
+ target_url, server_hash, &problem_code));
+ EXPECT_EQ(SDCH_OK, problem_code);
+ EXPECT_TRUE(dict_set.get());
+ EXPECT_TRUE(dict_set->GetDictionary(server_hash));
}
TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) {
@@ -258,21 +255,20 @@
GURL("http://" + dictionary_domain)));
GURL target_url("https://" + dictionary_domain + "/test");
- std::string dictionary_list;
// HTTPS target URL should not advertise dictionary acquired over HTTP even if
// secure scheme support is enabled.
SdchManager::EnableSecureSchemeSupport(true);
- sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
- EXPECT_TRUE(dictionary_list.empty());
+ EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url));
- scoped_refptr<SdchManager::Dictionary> dictionary;
std::string client_hash;
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
- EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME,
- sdch_manager()->GetVcdiffDictionary(server_hash, target_url,
- &dictionary));
- EXPECT_TRUE(dictionary.get() == NULL);
+ SdchProblemCode problem_code;
+ scoped_ptr<SdchManager::DictionarySet> dict_set(
+ sdch_manager()->GetDictionarySetByHash(
+ target_url, server_hash, &problem_code));
+ EXPECT_FALSE(dict_set.get());
+ EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME, problem_code);
}
TEST_F(SdchManagerTest, CanNotUseHTTPSDictionaryOverHTTP) {
@@ -284,20 +280,19 @@
GURL("https://" + dictionary_domain)));
GURL target_url("http://" + dictionary_domain + "/test");
- std::string dictionary_list;
// HTTP target URL should not advertise dictionary acquired over HTTPS even if
// secure scheme support is enabled.
- sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
- EXPECT_TRUE(dictionary_list.empty());
+ EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url));
- scoped_refptr<SdchManager::Dictionary> dictionary;
std::string client_hash;
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
- EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME,
- sdch_manager()->GetVcdiffDictionary(server_hash, target_url,
- &dictionary));
- EXPECT_TRUE(dictionary.get() == NULL);
+ SdchProblemCode problem_code;
+ scoped_ptr<SdchManager::DictionarySet> dict_set(
+ sdch_manager()->GetDictionarySetByHash(
+ target_url, server_hash, &problem_code));
+ EXPECT_FALSE(dict_set.get());
+ EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME, problem_code);
}
TEST_F(SdchManagerTest, FailToSetDomainMismatchDictionary) {
@@ -438,7 +433,7 @@
EXPECT_TRUE(PathMatch("/search/", "/search/"));
// Prefix only works if last character of restriction is a slash, or first
- // character in path after a match is a slash. Validate each case separately.
+ // character in path after a match is a slash. Validate each case separately.
// Rely on the slash in the path (not at the end of the restriction).
EXPECT_TRUE(PathMatch("/search/something", "/search"));
@@ -519,34 +514,36 @@
// can't get them from the other.
EXPECT_TRUE(AddSdchDictionary(dictionary_text_1,
GURL("http://" + dictionary_domain_1)));
- scoped_refptr<SdchManager::Dictionary> dictionary;
- EXPECT_EQ(SDCH_OK, sdch_manager()->GetVcdiffDictionary(
- server_hash_1,
- GURL("http://" + dictionary_domain_1 + "/random_url"),
- &dictionary));
- EXPECT_TRUE(dictionary.get());
+ scoped_ptr<SdchManager::DictionarySet> dict_set;
+
+ SdchProblemCode problem_code;
+ dict_set = sdch_manager()->GetDictionarySetByHash(
+ GURL("http://" + dictionary_domain_1 + "/random_url"),
+ server_hash_1, &problem_code);
+ EXPECT_TRUE(dict_set);
+ EXPECT_TRUE(dict_set->GetDictionary(server_hash_1));
+ EXPECT_EQ(SDCH_OK, problem_code);
second_manager.AddSdchDictionary(
dictionary_text_2, GURL("http://" + dictionary_domain_2));
- second_manager.GetVcdiffDictionary(
- server_hash_2,
+ dict_set = second_manager.GetDictionarySetByHash(
GURL("http://" + dictionary_domain_2 + "/random_url"),
- &dictionary);
- EXPECT_TRUE(dictionary.get());
+ server_hash_2, &problem_code);
+ EXPECT_TRUE(dict_set);
+ EXPECT_TRUE(dict_set->GetDictionary(server_hash_2));
+ EXPECT_EQ(SDCH_OK, problem_code);
- EXPECT_EQ(
- SDCH_DICTIONARY_HASH_NOT_FOUND,
- sdch_manager()->GetVcdiffDictionary(
- server_hash_2, GURL("http://" + dictionary_domain_2 + "/random_url"),
- &dictionary));
- EXPECT_FALSE(dictionary.get());
+ dict_set = sdch_manager()->GetDictionarySetByHash(
+ GURL("http://" + dictionary_domain_2 + "/random_url"),
+ server_hash_2, &problem_code);
+ EXPECT_FALSE(dict_set);
+ EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code);
- EXPECT_EQ(
- SDCH_DICTIONARY_HASH_NOT_FOUND,
- second_manager.GetVcdiffDictionary(
- server_hash_1, GURL("http://" + dictionary_domain_1 + "/random_url"),
- &dictionary));
- EXPECT_FALSE(dictionary.get());
+ dict_set = second_manager.GetDictionarySetByHash(
+ GURL("http://" + dictionary_domain_1 + "/random_url"),
+ server_hash_1, &problem_code);
+ EXPECT_FALSE(dict_set);
+ EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code);
}
TEST_F(SdchManagerTest, HttpsCorrectlySupported) {
@@ -578,12 +575,16 @@
EXPECT_TRUE(AddSdchDictionary(dictionary_text,
GURL("http://" + dictionary_domain)));
- scoped_refptr<SdchManager::Dictionary> dictionary;
- EXPECT_EQ(SDCH_OK, sdch_manager()->GetVcdiffDictionary(
- server_hash,
- GURL("http://" + dictionary_domain + "/random_url"),
- &dictionary));
- EXPECT_TRUE(dictionary.get());
+
+ scoped_ptr<SdchManager::DictionarySet> dict_set;
+
+ SdchProblemCode problem_code;
+ dict_set = sdch_manager()->GetDictionarySetByHash(
+ GURL("http://" + dictionary_domain + "/random_url"),
+ server_hash, &problem_code);
+ EXPECT_TRUE(dict_set);
+ EXPECT_TRUE(dict_set->GetDictionary(server_hash));
+ EXPECT_EQ(SDCH_OK, problem_code);
sdch_manager()->BlacklistDomain(GURL(blacklist_url), SDCH_OK);
EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
@@ -591,13 +592,11 @@
sdch_manager()->ClearData();
- dictionary = NULL;
- EXPECT_EQ(
- SDCH_DICTIONARY_HASH_NOT_FOUND,
- sdch_manager()->GetVcdiffDictionary(
- server_hash, GURL("http://" + dictionary_domain + "/random_url"),
- &dictionary));
- EXPECT_FALSE(dictionary.get());
+ dict_set = sdch_manager()->GetDictionarySetByHash(
+ GURL("http://" + dictionary_domain + "/random_url"),
+ server_hash, &problem_code);
+ EXPECT_FALSE(dict_set);
+ EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code);
EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(blacklist_url));
}
@@ -620,4 +619,39 @@
EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url());
}
+TEST_F(SdchManagerTest, ExpirationCheckedProperly) {
+ // Create an SDCH dictionary with an expiration time in the past.
+ std::string dictionary_domain("x.y.z.google.com");
+ std::string dictionary_text(base::StringPrintf(
+ "Domain: %s\nMax-age: 0\n\n", dictionary_domain.c_str()));
+ dictionary_text.append(
+ kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1);
+ std::string client_hash;
+ std::string server_hash;
+ SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash);
+ GURL target_gurl("http://" + dictionary_domain);
+ AddSdchDictionary(dictionary_text, target_gurl);
+
+ // It should be visible if looked up by hash whether expired or not.
+ scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
+ clock->SetNow(base::Time::Now());
+ clock->Advance(base::TimeDelta::FromMinutes(5));
+ SdchProblemCode problem_code;
+ scoped_ptr<SdchManager::DictionarySet> hash_set(
+ sdch_manager()->GetDictionarySetByHash(
+ target_gurl, server_hash, &problem_code).Pass());
+ ASSERT_TRUE(hash_set);
+ ASSERT_EQ(SDCH_OK, problem_code);
+ const_cast<SdchManager::Dictionary*>(
+ hash_set->GetDictionary(server_hash))->SetClockForTesting(
+ clock.Pass());
+
+ // Make sure it's not visible for advertisement, but is visible
+ // if looked up by hash.
+ EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_gurl));
+ EXPECT_TRUE(sdch_manager()->GetDictionarySetByHash(
+ target_gurl, server_hash, &problem_code));
+ EXPECT_EQ(SDCH_OK, problem_code);
+}
+
} // namespace net
diff --git a/net/base/sdch_problem_code_list.h b/net/base/sdch_problem_code_list.h
index a0d5196..0eef912 100644
--- a/net/base/sdch_problem_code_list.h
+++ b/net/base/sdch_problem_code_list.h
@@ -65,6 +65,10 @@
SDCH_PROBLEM_CODE(MULTIENCODING_FOR_NON_SDCH_REQUEST, 50)
SDCH_PROBLEM_CODE(SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST, 51)
+// A dictionary that wasn't advertised is being used for decoding.
+SDCH_PROBLEM_CODE(UNADVERTISED_DICTIONARY_USED, 52)
+SDCH_PROBLEM_CODE(UNADVERTISED_DICTIONARY_USED_CACHED, 53)
+
// Dictionary manager issues.
SDCH_PROBLEM_CODE(DOMAIN_BLACKLIST_INCLUDES_TARGET, 61)
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index c3f118d..cd9c9b8 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -1319,16 +1319,12 @@
if (!HasCookieableScheme(url))
return std::string();
- TimeTicks start_time(TimeTicks::Now());
-
std::vector<CanonicalCookie*> cookies;
FindCookiesForHostAndDomain(url, options, true, &cookies);
std::sort(cookies.begin(), cookies.end(), CookieSorter);
std::string cookie_line = BuildCookieLine(cookies);
- histogram_time_get_->AddTime(TimeTicks::Now() - start_time);
-
VLOG(kVlogGetCookies) << "GetCookies() result: " << cookie_line;
return cookie_line;
@@ -2245,9 +2241,6 @@
base::Histogram::kUmaTargetedHistogramFlag);
// From UMA_HISTOGRAM_{CUSTOM_,}TIMES
- histogram_time_get_ = base::Histogram::FactoryTimeGet("Cookie.TimeGet",
- base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
- 50, base::Histogram::kUmaTargetedHistogramFlag);
histogram_time_blocked_on_load_ = base::Histogram::FactoryTimeGet(
"Cookie.TimeBlockedOnLoad",
base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 18d1b8a..0f00490 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -635,7 +635,6 @@
base::HistogramBase* histogram_domain_per_etldp1_count_;
base::HistogramBase* histogram_number_duplicate_db_cookies_;
base::HistogramBase* histogram_cookie_deletion_cause_;
- base::HistogramBase* histogram_time_get_;
base::HistogramBase* histogram_time_mac_;
base::HistogramBase* histogram_time_blocked_on_load_;
diff --git a/net/disk_cache/blockfile/in_flight_backend_io.cc b/net/disk_cache/blockfile/in_flight_backend_io.cc
index 2cb3ff0..5b3b904 100644
--- a/net/disk_cache/blockfile/in_flight_backend_io.cc
+++ b/net/disk_cache/blockfile/in_flight_backend_io.cc
@@ -341,35 +341,57 @@
}
void InFlightBackendIO::Init(const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ // TODO(vadimt): Remove wrapping the callback with
+ // ScopedTracker::TrackCallback() once crbug.com/422516 is fixed.
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_,
+ tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("422516 InFlightBackendIO::Init"),
+ callback)));
operation->Init();
PostOperation(operation.get());
}
void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::OpenEntry"),
+ callback)));
operation->OpenEntry(key, entry);
PostOperation(operation.get());
}
void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::CreateEntry"),
+ callback)));
operation->CreateEntry(key, entry);
PostOperation(operation.get());
}
void InFlightBackendIO::DoomEntry(const std::string& key,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::DoomEntry"),
+ callback)));
operation->DoomEntry(key);
PostOperation(operation.get());
}
void InFlightBackendIO::DoomAllEntries(
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::DoomAllEntries"),
+ callback)));
operation->DoomAllEntries();
PostOperation(operation.get());
}
@@ -377,14 +399,22 @@
void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time,
const base::Time end_time,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::DoomEntriesBetween"),
+ callback)));
operation->DoomEntriesBetween(initial_time, end_time);
PostOperation(operation.get());
}
void InFlightBackendIO::DoomEntriesSince(
const base::Time initial_time, const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::DoomEntriesSince"),
+ callback)));
operation->DoomEntriesSince(initial_time);
PostOperation(operation.get());
}
@@ -392,7 +422,11 @@
void InFlightBackendIO::OpenNextEntry(Rankings::Iterator* iterator,
Entry** next_entry,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::OpenNextEntry"),
+ callback)));
operation->OpenNextEntry(iterator, next_entry);
PostOperation(operation.get());
}
@@ -427,14 +461,22 @@
}
void InFlightBackendIO::FlushQueue(const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::FlushQueue"),
+ callback)));
operation->FlushQueue();
PostOperation(operation.get());
}
void InFlightBackendIO::RunTask(
const base::Closure& task, const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_,
+ tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION("422516 InFlightBackendIO::RunTask"),
+ callback)));
operation->RunTask(task);
PostOperation(operation.get());
}
@@ -442,7 +484,11 @@
void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset,
net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::ReadData"),
+ callback)));
operation->ReadData(entry, index, offset, buf, buf_len);
PostOperation(operation.get());
}
@@ -451,7 +497,11 @@
net::IOBuffer* buf, int buf_len,
bool truncate,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::WriteData"),
+ callback)));
operation->WriteData(entry, index, offset, buf, buf_len, truncate);
PostOperation(operation.get());
}
@@ -459,7 +509,11 @@
void InFlightBackendIO::ReadSparseData(
EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::ReadSparseData"),
+ callback)));
operation->ReadSparseData(entry, offset, buf, buf_len);
PostOperation(operation.get());
}
@@ -467,7 +521,11 @@
void InFlightBackendIO::WriteSparseData(
EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::WriteSparseData"),
+ callback)));
operation->WriteSparseData(entry, offset, buf, buf_len);
PostOperation(operation.get());
}
@@ -475,7 +533,11 @@
void InFlightBackendIO::GetAvailableRange(
EntryImpl* entry, int64 offset, int len, int64* start,
const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::GetAvailableRange"),
+ callback)));
operation->GetAvailableRange(entry, offset, len, start);
PostOperation(operation.get());
}
@@ -489,7 +551,11 @@
void InFlightBackendIO::ReadyForSparseIO(
EntryImpl* entry, const net::CompletionCallback& callback) {
- scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback));
+ scoped_refptr<BackendIO> operation(new BackendIO(
+ this, backend_, tracked_objects::ScopedTracker::TrackCallback(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 InFlightBackendIO::CancelSparseIO"),
+ callback)));
operation->ReadyForSparseIO(entry);
PostOperation(operation.get());
}
diff --git a/net/disk_cache/simple/simple_util_win.cc b/net/disk_cache/simple/simple_util_win.cc
index d0d191d..f2adcd0 100644
--- a/net/disk_cache/simple/simple_util_win.cc
+++ b/net/disk_cache/simple/simple_util_win.cc
@@ -24,7 +24,7 @@
// Why a random name? Because if the name was derived from our original name,
// then churn on a particular cache entry could cause flakey behaviour.
- // TODO(gaivnp): Ensure these "todelete_" files are cleaned up on periodic
+ // TODO(gavinp): Ensure these "todelete_" files are cleaned up on periodic
// directory sweeps.
const base::FilePath rename_target =
path.DirName().AppendASCII(base::StringPrintf("todelete_%016" PRIx64,
diff --git a/net/dns/dns_config_service_win_unittest.cc b/net/dns/dns_config_service_win_unittest.cc
index 7ac01d1..54a6411 100644
--- a/net/dns/dns_config_service_win_unittest.cc
+++ b/net/dns/dns_config_service_win_unittest.cc
@@ -55,7 +55,7 @@
IF_OPER_STATUS oper_status;
const WCHAR* dns_suffix;
std::string dns_server_addresses[4]; // Empty string indicates end.
- int ports[4];
+ uint16 ports[4];
};
scoped_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> CreateAdapterAddresses(
@@ -102,7 +102,7 @@
}
IPAddressNumber ip;
CHECK(ParseIPLiteralToNumber(info.dns_server_addresses[j], &ip));
- IPEndPoint ipe(ip, info.ports[j]);
+ IPEndPoint ipe = IPEndPoint(ip, info.ports[j]);
address->Address.lpSockaddr =
reinterpret_cast<LPSOCKADDR>(storage + num_addresses);
socklen_t length = sizeof(struct sockaddr_storage);
@@ -120,7 +120,7 @@
AdapterInfo input_adapters[4]; // |if_type| == 0 indicates end.
std::string expected_nameservers[4]; // Empty string indicates end.
std::string expected_suffix;
- int expected_ports[4];
+ uint16 expected_ports[4];
} cases[] = {
{ // Ignore loopback and inactive adapters.
{
@@ -181,7 +181,7 @@
for (size_t j = 0; !t.expected_nameservers[j].empty(); ++j) {
IPAddressNumber ip;
ASSERT_TRUE(ParseIPLiteralToNumber(t.expected_nameservers[j], &ip));
- int port = t.expected_ports[j];
+ uint16 port = t.expected_ports[j];
if (!port)
port = dns_protocol::kDefaultPort;
expected_nameservers.push_back(IPEndPoint(ip, port));
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h
index 2823c4b..0203dc9 100644
--- a/net/dns/host_resolver.h
+++ b/net/dns/host_resolver.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_family.h"
#include "net/base/completion_callback.h"
@@ -67,7 +68,7 @@
host_port_pair_ = host_port_pair;
}
- int port() const { return host_port_pair_.port(); }
+ uint16 port() const { return host_port_pair_.port(); }
const std::string& hostname() const { return host_port_pair_.host(); }
AddressFamily address_family() const { return address_family_; }
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
index fe63820..9426da5 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_impl.cc
@@ -300,14 +300,13 @@
#elif defined(OS_WIN)
// Map the error code to a human-readable string.
LPWSTR error_string = NULL;
- int size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- 0, // Use the internal message table.
- os_error,
- 0, // Use default language.
- (LPWSTR)&error_string,
- 0, // Buffer size.
- 0); // Arguments (unused).
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, // Use the internal message table.
+ os_error,
+ 0, // Use default language.
+ (LPWSTR)&error_string,
+ 0, // Buffer size.
+ 0); // Arguments (unused).
dict->SetString("os_error_string", base::WideToUTF8(error_string));
LocalFree(error_string);
#endif
diff --git a/net/dns/host_resolver_impl_unittest.cc b/net/dns/host_resolver_impl_unittest.cc
index 7b6a391..7a46a1c 100644
--- a/net/dns/host_resolver_impl_unittest.cc
+++ b/net/dns/host_resolver_impl_unittest.cc
@@ -181,7 +181,7 @@
};
bool AddressListContains(const AddressList& list, const std::string& address,
- int port) {
+ uint16 port) {
IPAddressNumber ip;
bool rv = ParseIPLiteralToNumber(address, &ip);
DCHECK(rv);
@@ -249,7 +249,7 @@
bool completed() const { return result_ != ERR_IO_PENDING; }
bool pending() const { return handle_ != NULL; }
- bool HasAddress(const std::string& address, int port) const {
+ bool HasAddress(const std::string& address, uint16 port) const {
return AddressListContains(list_, address, port);
}
@@ -258,7 +258,7 @@
return list_.size();
}
- bool HasOneAddress(const std::string& address, int port) const {
+ bool HasOneAddress(const std::string& address, uint16 port) const {
return HasAddress(address, port) && (NumberOfAddresses() == 1u);
}
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc
index 48e004e..6d8cba3 100644
--- a/net/dns/mock_host_resolver.cc
+++ b/net/dns/mock_host_resolver.cc
@@ -48,7 +48,7 @@
LOG(WARNING) << "Not a supported IP literal: " << addresses[index];
return ERR_UNEXPECTED;
}
- addrlist->push_back(IPEndPoint(ip_number, -1));
+ addrlist->push_back(IPEndPoint(ip_number, 0));
}
return OK;
}
diff --git a/net/filter/filter.cc b/net/filter/filter.cc
index 53d6583..b3f98cb 100644
--- a/net/filter/filter.cc
+++ b/net/filter/filter.cc
@@ -3,20 +3,20 @@
// found in the LICENSE file.
// The basic usage of the Filter interface is described in the comment at
-// the beginning of filter.h. If Filter::Factory is passed a vector of
+// the beginning of filter.h. If Filter::Factory is passed a vector of
// size greater than 1, that interface is implemented by a series of filters
-// connected in a chain. In such a case the first filter
+// connected in a chain. In such a case the first filter
// in the chain proxies calls to ReadData() so that its return values
// apply to the entire chain.
//
// In a filter chain, the data flows from first filter (held by the
-// caller) down the chain. When ReadData() is called on any filter
+// caller) down the chain. When ReadData() is called on any filter
// except for the last filter, it proxies the call down the chain,
// filling in the input buffers of subsequent filters if needed (==
// that filter's last_status() value is FILTER_NEED_MORE_DATA) and
-// available (== the current filter has data it can output). The last
+// available (== the current filter has data it can output). The last
// Filter will then output data if possible, and return
-// FILTER_NEED_MORE_DATA if not. Because the indirection pushes
+// FILTER_NEED_MORE_DATA if not. Because the indirection pushes
// data along the filter chain at each level if it's available and the
// next filter needs it, a return value of FILTER_NEED_MORE_DATA from the
// final filter will apply to the entire chain.
@@ -43,8 +43,8 @@
const char kGZip[] = "gzip";
const char kXGZip[] = "x-gzip";
const char kSdch[] = "sdch";
-// compress and x-compress are currently not supported. If we decide to support
-// them, we'll need the same mime type compatibility hack we have for gzip. For
+// compress and x-compress are currently not supported. If we decide to support
+// them, we'll need the same mime type compatibility hack we have for gzip. For
// more information, see Firefox's nsHttpChannel::ProcessNormal.
// Mime types:
@@ -153,9 +153,9 @@
// In the case where this filter has data internally, and is indicating such
// with a last_status_ of FILTER_OK, but at the same time the next filter in
// the chain indicated it FILTER_NEED_MORE_DATA, we have to be cautious
- // about confusing the caller. The API confusion can appear if we return
+ // about confusing the caller. The API confusion can appear if we return
// FILTER_OK (suggesting we have more data in aggregate), but yet we don't
- // populate our output buffer. When that is the case, we need to
+ // populate our output buffer. When that is the case, we need to
// alternately call our filter element, and the next_filter element until we
// get out of this state (by pumping data into the next filter until it
// outputs data, or it runs out of data and reports that it NEED_MORE_DATA.)
@@ -217,8 +217,8 @@
LowerCaseEqualsASCII(mime_type, kApplicationGzip) ||
LowerCaseEqualsASCII(mime_type, kApplicationXGunzip))
// The server has told us that it sent us gziped content with a gzip
- // content encoding. Sadly, Apache mistakenly sets these headers for all
- // .gz files. We match Firefox's nsHttpChannel::ProcessNormal and ignore
+ // content encoding. Sadly, Apache mistakenly sets these headers for all
+ // .gz files. We match Firefox's nsHttpChannel::ProcessNormal and ignore
// the Content-Encoding here.
encoding_types->clear();
@@ -256,7 +256,7 @@
}
// If the request was for SDCH content, then we might need additional fixups.
- if (!filter_context.SdchResponseExpected()) {
+ if (!filter_context.SdchDictionariesAdvertised()) {
// It was not an SDCH request, so we'll just record stats.
if (1 < encoding_types->size()) {
// Multiple filters were intended to only be used for SDCH (thus far!)
@@ -271,7 +271,7 @@
}
// The request was tagged as an SDCH request, which means the server supplied
- // a dictionary, and we advertised it in the request. Some proxies will do
+ // a dictionary, and we advertised it in the request. Some proxies will do
// very strange things to the request, or the response, so we have to handle
// them gracefully.
@@ -280,7 +280,7 @@
(FILTER_TYPE_SDCH == encoding_types->front())) {
// Some proxies (found currently in Argentina) strip the Content-Encoding
// text from "sdch,gzip" to a mere "sdch" without modifying the compressed
- // payload. To handle this gracefully, we simulate the "probably" deleted
+ // payload. To handle this gracefully, we simulate the "probably" deleted
// ",gzip" by appending a tentative gzip decode, which will default to a
// no-op pass through filter if it doesn't get gzip headers where expected.
if (1 == encoding_types->size()) {
@@ -290,20 +290,20 @@
return;
}
- // There are now several cases to handle for an SDCH request. Foremost, if
+ // There are now several cases to handle for an SDCH request. Foremost, if
// the outbound request was stripped so as not to advertise support for
// encodings, we might get back content with no encoding, or (for example)
- // just gzip. We have to be sure that any changes we make allow for such
- // minimal coding to work. That issue is why we use TENTATIVE filters if we
+ // just gzip. We have to be sure that any changes we make allow for such
+ // minimal coding to work. That issue is why we use TENTATIVE filters if we
// add any, as those filters sniff the content, and act as pass-through
// filters if headers are not found.
// If the outbound GET is not modified, then the server will generally try to
- // send us SDCH encoded content. As that content returns, there are several
+ // send us SDCH encoded content. As that content returns, there are several
// corruptions of the header "content-encoding" that proxies may perform (and
- // have been detected in the wild). We already dealt with the a honest
+ // have been detected in the wild). We already dealt with the a honest
// content encoding of "sdch,gzip" being corrupted into "sdch" with on change
- // of the actual content. Another common corruption is to either disscard
+ // of the actual content. Another common corruption is to either disscard
// the accurate content encoding, or to replace it with gzip only (again, with
// no change in actual content). The last observed corruption it to actually
// change the content, such as by re-gzipping it, and that may happen along
@@ -328,7 +328,7 @@
} else {
// Remarkable case!?! We advertised an SDCH dictionary, content-encoding
// was not marked for SDCH processing: Why did the server suggest an SDCH
- // dictionary in the first place??. Also, the content isn't
+ // dictionary in the first place??. Also, the content isn't
// tagged as HTML, despite the fact that SDCH encoding is mostly likely for
// HTML: Did some anti-virus system strip this tag (sometimes they strip
// accept-encoding headers on the request)?? Does the content encoding not
@@ -344,9 +344,9 @@
}
// Leave the existing encoding type to be processed first, and add our
- // tentative decodings to be done afterwards. Vodaphone UK reportedyl will
+ // tentative decodings to be done afterwards. Vodaphone UK reportedyl will
// perform a second layer of gzip encoding atop the server's sdch,gzip
- // encoding, and then claim that the content encoding is a mere gzip. As a
+ // encoding, and then claim that the content encoding is a mere gzip. As a
// result we'll need (in that case) to do the gunzip, plus our tentative
// gunzip and tentative SDCH decoding.
// This approach nicely handles the empty() list as well, and should work with
diff --git a/net/filter/filter.h b/net/filter/filter.h
index cec8398..428dc8c 100644
--- a/net/filter/filter.h
+++ b/net/filter/filter.h
@@ -20,22 +20,22 @@
// through its accessor and fills in stream_buffer_ with pre-filter data, next
// calls FlushStreamBuffer to notify Filter, then calls ReadFilteredData
// repeatedly to get all the filtered data. After all data have been filtered
-// and read out, the caller may fill in stream_buffer_ again. This
+// and read out, the caller may fill in stream_buffer_ again. This
// WriteBuffer-Flush-Read cycle is repeated until reaching the end of data
// stream.
//
// A return of FILTER_OK from ReadData() means that more data is
// available to a future ReadData() call and data may not be written
-// into stream_buffer(). A return of FILTER_NEED_MORE_DATA from ReadData()
+// into stream_buffer(). A return of FILTER_NEED_MORE_DATA from ReadData()
// indicates that no data will be forthcoming from the filter until
// it receives more input data, and that the buffer at
// stream_buffer() may be written to.
//
// The filter being complete (no more data to provide) may be indicated
// by either returning FILTER_DONE or by returning FILTER_OK and indicating
-// zero bytes output; consumers understand both those signals. Consumers
+// zero bytes output; consumers understand both those signals. Consumers
// are responsible for not calling ReadData() on a filter after one of these
-// signals have been returned. Note that some filters may never signal that
+// signals have been returned. Note that some filters may never signal that
// they are done (e.g. a pass-through filter will always
// say FILTER_NEED_MORE_DATA), so the consumer will also need to
// recognize the state of |no_more_input_data_available &&
@@ -55,6 +55,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
+#include "net/base/sdch_manager.h"
class GURL;
@@ -66,11 +67,19 @@
//------------------------------------------------------------------------------
// Define an interface class that allows access to contextual information
-// supplied by the owner of this filter. In the case where there are a chain of
+// supplied by the owner of this filter. In the case where there are a chain of
// filters, there is only one owner of all the chained filters, and that context
-// is passed to the constructor of all those filters. To be clear, the context
+// is passed to the constructor of all those filters. To be clear, the context
// does NOT reflect the position in a chain, or the fact that there are prior
// or later filters in a chain.
+//
+// TODO(rdsmith): FilterContext is a grab-bag of methods which may or may
+// not be relevant for any particular filter, and it's getting worse over
+// time. In addition, it only supports two filters, SDCH and gzip.
+// It would make more sense to implement FilterContext as a
+// base::SupportsUserData structure to which filter-specific information
+// could be added by whatever the ultimate consumer of the filter chain is,
+// and a particular filter (if included) could access that information.
class NET_EXPORT_PRIVATE FilterContext {
public:
// Enum to control what histograms are emitted near end-of-life of this
@@ -107,14 +116,14 @@
virtual bool IsDownload() const = 0;
// Was this data flagged as a response to a request with an SDCH dictionary?
- virtual bool SdchResponseExpected() const = 0;
+ virtual SdchManager::DictionarySet* SdchDictionariesAdvertised() const = 0;
// How many bytes were read from the net or cache so far (and potentially
// pushed into a filter for processing)?
virtual int64 GetByteReadCount() const = 0;
// What response code was received with the associated network transaction?
- // For example: 200 is ok. 4xx are error codes. etc.
+ // For example: 200 is ok. 4xx are error codes. etc.
virtual int GetResponseCode() const = 0;
// The URLRequestContext associated with the request.
@@ -137,7 +146,7 @@
FILTER_OK,
// Read filtered data successfully, and the data in the buffer has been
// consumed by the filter, but more data is needed in order to continue
- // filtering. At this point, the caller is free to reuse the filter
+ // filtering. At this point, the caller is free to reuse the filter
// buffer to provide more data.
FILTER_NEED_MORE_DATA,
// Read filtered data successfully, and filter reaches the end of the data
@@ -169,7 +178,7 @@
//
// Note: filter_types is an array of filter types (content encoding types as
// provided in an HTTP header), which will be chained together serially to do
- // successive filtering of data. The types in the vector are ordered based on
+ // successive filtering of data. The types in the vector are ordered based on
// encoding order, and the filters are chained to operate in the reverse
// (decoding) order. For example, types[0] = FILTER_TYPE_SDCH,
// types[1] = FILTER_TYPE_GZIP will cause data to first be gunzip filtered,
@@ -182,7 +191,7 @@
// initialized.
static Filter* GZipFactory();
- // External call to obtain data from this filter chain. If ther is no
+ // External call to obtain data from this filter chain. If ther is no
// next_filter_, then it obtains data from this specific filter.
FilterStatus ReadData(char* dest_buffer, int* dest_len);
@@ -216,10 +225,10 @@
static FilterType ConvertEncodingToType(const std::string& filter_type);
// Given a array of encoding_types, try to do some error recovery adjustment
- // to the list. This includes handling known bugs in the Apache server (where
+ // to the list. This includes handling known bugs in the Apache server (where
// redundant gzip encoding is specified), as well as issues regarding SDCH
// encoding, where various proxies and anti-virus products modify or strip the
- // encodings. These fixups require context, which includes whether this
+ // encodings. These fixups require context, which includes whether this
// response was made to an SDCH request (i.e., an available dictionary was
// advertised in the GET), as well as the mime type of the content.
static void FixupEncodingTypes(const FilterContext& filter_context,
@@ -270,8 +279,8 @@
void InitBuffer(int size);
// A factory helper for creating filters for within a chain of potentially
- // multiple encodings. If a chain of filters is created, then this may be
- // called multiple times during the filter creation process. In most simple
+ // multiple encodings. If a chain of filters is created, then this may be
+ // called multiple times during the filter creation process. In most simple
// cases, this is only called once. Returns NULL and cleans up (deleting
// filter_list) if a new filter can't be constructed.
static Filter* PrependNewFilter(FilterType type_id,
diff --git a/net/filter/filter_unittest.cc b/net/filter/filter_unittest.cc
index 5b2446c..fcedeaf 100644
--- a/net/filter/filter_unittest.cc
+++ b/net/filter/filter_unittest.cc
@@ -24,9 +24,6 @@
} // namespace
-class FilterTest : public testing::Test {
-};
-
TEST(FilterTest, ContentTypeId) {
// Check for basic translation of Content-Encoding, including case variations.
EXPECT_EQ(Filter::FILTER_TYPE_DEFLATE,
@@ -54,7 +51,7 @@
// Check various fixups that modify content encoding lists.
TEST(FilterTest, ApacheGzip) {
MockFilterContext filter_context;
- filter_context.SetSdchResponse(false);
+ filter_context.SetSdchResponse(NULL);
// Check that redundant gzip mime type removes only solo gzip encoding.
const std::string kGzipMime1("application/x-gzip");
@@ -100,7 +97,7 @@
TEST(FilterTest, GzipContentDispositionFilename) {
MockFilterContext filter_context;
- filter_context.SetSdchResponse(false);
+ filter_context.SetSdchResponse(NULL);
const std::string kGzipMime("application/x-tar");
const std::string kContentDisposition("attachment; filename=\"foo.tgz\"");
@@ -119,7 +116,9 @@
// Handle content encodings including SDCH.
const std::string kTextHtmlMime("text/html");
MockFilterContext filter_context;
- filter_context.SetSdchResponse(true);
+ // Empty handle indicates to filter that SDCH is active.
+ filter_context.SetSdchResponse(
+ SdchManager::CreateEmptyDictionarySetForTesting().Pass());
std::vector<Filter::FilterType> encoding_types;
@@ -156,7 +155,8 @@
// Handle interesting case where entire SDCH encoding assertion "got lost."
const std::string kTextHtmlMime("text/html");
MockFilterContext filter_context;
- filter_context.SetSdchResponse(true);
+ filter_context.SetSdchResponse(
+ SdchManager::CreateEmptyDictionarySetForTesting().Pass());
std::vector<Filter::FilterType> encoding_types;
@@ -169,7 +169,7 @@
EXPECT_EQ(Filter::FILTER_TYPE_GZIP_HELPING_SDCH, encoding_types[1]);
// Loss of encoding, but it was an SDCH response with a prefix that says it
- // was an html type. Note that it *should* be the case that a precise match
+ // was an html type. Note that it *should* be the case that a precise match
// with "text/html" we be collected by GetMimeType() and passed in, but we
// coded the fixup defensively (scanning for a prefix of "text/html", so this
// is an example which could survive such confusion in the caller).
diff --git a/net/filter/mock_filter_context.cc b/net/filter/mock_filter_context.cc
index 35ab9ee..67012de 100644
--- a/net/filter/mock_filter_context.cc
+++ b/net/filter/mock_filter_context.cc
@@ -11,7 +11,6 @@
MockFilterContext::MockFilterContext()
: is_cached_content_(false),
is_download_(false),
- is_sdch_response_(false),
ok_to_call_get_url_(true),
response_code_(-1),
context_(new URLRequestContext()) {
@@ -54,8 +53,9 @@
bool MockFilterContext::IsDownload() const { return is_download_; }
-bool MockFilterContext::SdchResponseExpected() const {
- return is_sdch_response_;
+SdchManager::DictionarySet*
+MockFilterContext::SdchDictionariesAdvertised() const {
+ return dictionaries_handle_.get();
}
int64 MockFilterContext::GetByteReadCount() const { return 0; }
diff --git a/net/filter/mock_filter_context.h b/net/filter/mock_filter_context.h
index 41c9e9e..776a237 100644
--- a/net/filter/mock_filter_context.h
+++ b/net/filter/mock_filter_context.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "net/base/net_log.h"
+#include "net/base/sdch_manager.h"
#include "net/filter/filter.h"
#include "url/gurl.h"
@@ -30,15 +31,15 @@
void SetCached(bool is_cached) { is_cached_content_ = is_cached; }
void SetDownload(bool is_download) { is_download_ = is_download; }
void SetResponseCode(int response_code) { response_code_ = response_code; }
- void SetSdchResponse(bool is_sdch_response) {
- is_sdch_response_ = is_sdch_response;
+ void SetSdchResponse(scoped_ptr<SdchManager::DictionarySet> handle) {
+ dictionaries_handle_ = handle.Pass();
}
URLRequestContext* GetModifiableURLRequestContext() const {
return context_.get();
}
// After a URLRequest's destructor is called, some interfaces may become
- // unstable. This method is used to signal that state, so we can tag use
+ // unstable. This method is used to signal that state, so we can tag use
// of those interfaces as coding errors.
void NukeUnstableInterfaces();
@@ -61,8 +62,8 @@
// Is this a download?
bool IsDownload() const override;
- // Was this data flagged as a response to a request with an SDCH dictionary?
- bool SdchResponseExpected() const override;
+ // Handle to dictionaries advertised.
+ SdchManager::DictionarySet* SdchDictionariesAdvertised() const override;
// How many bytes were fed to filter(s) so far?
int64 GetByteReadCount() const override;
@@ -84,7 +85,7 @@
base::Time request_time_;
bool is_cached_content_;
bool is_download_;
- bool is_sdch_response_;
+ scoped_ptr<SdchManager::DictionarySet> dictionaries_handle_;
bool ok_to_call_get_url_;
int response_code_;
scoped_ptr<URLRequestContext> context_;
diff --git a/net/filter/sdch_filter.cc b/net/filter/sdch_filter.cc
index d1eb7f4..30392cd 100644
--- a/net/filter/sdch_filter.cc
+++ b/net/filter/sdch_filter.cc
@@ -14,6 +14,7 @@
#include "base/values.h"
#include "net/base/sdch_manager.h"
#include "net/base/sdch_net_log_params.h"
+#include "net/base/sdch_problem_codes.h"
#include "net/url_request/url_request_context.h"
#include "sdch/open-vcdiff/src/google/vcdecoder.h"
@@ -251,12 +252,12 @@
// advertisement (so that we are sure we're not hurting anything).
//
// Watch out for an error page inserted by the proxy as part of a 40x
- // error response. When we see such content molestation, we certainly
+ // error response. When we see such content molestation, we certainly
// need to fall into the meta-refresh case.
ResponseCorruptionDetectionCause cause = RESPONSE_NONE;
if (filter_context_.GetResponseCode() == 404) {
// We could be more generous, but for now, only a "NOT FOUND" code will
- // cause a pass through. All other bad codes will fall into a
+ // cause a pass through. All other bad codes will fall into a
// meta-refresh.
LogSdchProblem(SDCH_PASS_THROUGH_404_CODE);
cause = RESPONSE_404;
@@ -276,13 +277,13 @@
// error. We were just overly cautious when we added a TENTATIVE_SDCH.
// We added the sdch coding tag, and it should not have been added.
// This can happen in server experiments, where the server decides
- // not to use sdch, even though there is a dictionary. To be
+ // not to use sdch, even though there is a dictionary. To be
// conservative, we locally added the tentative sdch (fearing that a
// proxy stripped it!) and we must now recant (pass through).
//
// However.... just to be sure we don't get burned by proxies that
// re-compress with gzip or other system, we can sniff to see if this
- // is compressed data etc. For now, we do nothing, which gets us into
+ // is compressed data etc. For now, we do nothing, which gets us into
// the meta-refresh result.
// TODO(jar): Improve robustness by sniffing for valid text that we can
// actual use re: decoding_status_ = PASS_THROUGH;
@@ -292,8 +293,8 @@
// The common cause is a restart of the browser, where we try to render
// cached content that was saved when we had a dictionary.
cause = RESPONSE_NO_DICTIONARY;
- } else if (filter_context_.SdchResponseExpected()) {
- // This is a very corrupt SDCH request response. We can't decode it.
+ } else if (filter_context_.SdchDictionariesAdvertised()) {
+ // This is a very corrupt SDCH request response. We can't decode it.
// We'll use a meta-refresh, and get content without asking for SDCH.
// This will also progressively disable SDCH for this domain.
cause = RESPONSE_CORRUPT_SDCH;
@@ -377,7 +378,7 @@
if (decoding_status_ != DECODING_IN_PROGRESS) {
if (META_REFRESH_RECOVERY == decoding_status_) {
- // Absorb all input data. We've already output page reload HTML.
+ // Absorb all input data. We've already output page reload HTML.
next_stream_data_ = NULL;
stream_data_len_ = 0;
return FILTER_NEED_MORE_DATA;
@@ -441,25 +442,52 @@
else
next_stream_data_ = NULL;
- DCHECK(!dictionary_.get());
+ DCHECK(!dictionary_);
dictionary_hash_is_plausible_ = true; // Assume plausible, but check.
SdchProblemCode rv = SDCH_OK;
if ('\0' == dictionary_hash_[kServerIdLength - 1]) {
- SdchManager* manager(url_request_context_->sdch_manager());
- rv = manager->GetVcdiffDictionary(
- std::string(dictionary_hash_, 0, kServerIdLength - 1), url_,
- &dictionary_);
- if (rv == SDCH_DICTIONARY_HASH_NOT_FOUND) {
- DCHECK(dictionary_hash_.size() == kServerIdLength);
- // Since dictionary was not found, check to see if hash was even
- // plausible.
- for (size_t i = 0; i < kServerIdLength - 1; ++i) {
- char base64_char = dictionary_hash_[i];
- if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) {
- rv = SDCH_DICTIONARY_HASH_MALFORMED;
- dictionary_hash_is_plausible_ = false;
- break;
+ std::string server_hash(dictionary_hash_, 0, kServerIdLength - 1);
+ SdchManager::DictionarySet* handle =
+ filter_context_.SdchDictionariesAdvertised();
+ if (handle)
+ dictionary_ = handle->GetDictionary(server_hash);
+ if (!dictionary_) {
+ // This is a hack. Naively, the dictionaries available for
+ // decoding should be only the ones advertised. However, there are
+ // cases, specifically resources encoded with old dictionaries living
+ // in the cache, that mean the full set of dictionaries should be made
+ // available for decoding. It's not known how often this happens;
+ // if it happens rarely enough, this code can be removed.
+ //
+ // TODO(rdsmith): Long-term, a better solution is necessary, since
+ // an entry in the cache being encoded with the dictionary doesn't
+ // guarantee that the dictionary is present. That solution probably
+ // involves storing unencoded resources in the cache, but might
+ // involve evicting encoded resources on dictionary removal.
+ // See http://crbug.com/383405.
+ unexpected_dictionary_handle_ =
+ url_request_context_->sdch_manager()->GetDictionarySetByHash(
+ url_, server_hash, &rv);
+ if (unexpected_dictionary_handle_) {
+ dictionary_ = unexpected_dictionary_handle_->GetDictionary(server_hash);
+ // Override SDCH_OK rv; this is still worth logging.
+ rv = (filter_context_.IsCachedContent() ?
+ SDCH_UNADVERTISED_DICTIONARY_USED_CACHED :
+ SDCH_UNADVERTISED_DICTIONARY_USED);
+ } else {
+ // Since dictionary was not found, check to see if hash was
+ // even plausible.
+ DCHECK(dictionary_hash_.size() == kServerIdLength);
+ rv = SDCH_DICTIONARY_HASH_NOT_FOUND;
+ for (size_t i = 0; i < kServerIdLength - 1; ++i) {
+ char base64_char = dictionary_hash_[i];
+ if (!isalnum(base64_char) &&
+ '-' != base64_char && '_' != base64_char) {
+ dictionary_hash_is_plausible_ = false;
+ rv = SDCH_DICTIONARY_HASH_MALFORMED;
+ break;
+ }
}
}
}
@@ -467,12 +495,15 @@
dictionary_hash_is_plausible_ = false;
rv = SDCH_DICTIONARY_HASH_MALFORMED;
}
- if (rv != SDCH_OK) {
+
+ if (rv != SDCH_OK)
LogSdchProblem(rv);
+
+ if (!dictionary_) {
decoding_status_ = DECODING_ERROR;
return FILTER_ERROR;
}
- DCHECK(dictionary_.get());
+
vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
vcdiff_streaming_decoder_->SetAllowVcdTarget(false);
vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(),
diff --git a/net/filter/sdch_filter.h b/net/filter/sdch_filter.h
index bc7788c..9541742 100644
--- a/net/filter/sdch_filter.h
+++ b/net/filter/sdch_filter.h
@@ -43,7 +43,7 @@
FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override;
private:
- // Internal status. Once we enter an error state, we stop processing data.
+ // Internal status. Once we enter an error state, we stop processing data.
enum DecodingStatus {
DECODING_UNINITIALIZED,
WAITING_FOR_DICTIONARY_SELECTION,
@@ -87,19 +87,19 @@
// After assembling an entire dictionary hash (the first 9 bytes of the
// sdch payload, we check to see if it is plausible, meaning it has a null
// termination, and has 8 characters that are possible in a net-safe base64
- // encoding. If the hash is not plausible, then the payload is probably not
+ // encoding. If the hash is not plausible, then the payload is probably not
// an SDCH encoded bundle, and various error recovery strategies can be
// attempted.
bool dictionary_hash_is_plausible_;
- // We hold an in-memory copy of the dictionary during the entire decoding, as
- // it is used directly by the VC-DIFF decoding system.
- // That char* data is part of the dictionary_ we hold a reference to.
- scoped_refptr<SdchManager::Dictionary> dictionary_;
+ // Validity of this pointer is guaranteed by either the FilterContext holding
+ // a containing SdchManager::DictionarySet, or this object holding a
+ // container in |unexpected_dictionary_handle_| below.
+ const SdchManager::Dictionary *dictionary_;
// We keep a copy of the URLRequestContext for use in the destructor, (at
// which point GetURLRequestContext() will likely return null because of
- // the disassociation of the URLRequest from the URLRequestJob). This is
+ // the disassociation of the URLRequest from the URLRequestJob). This is
// safe because the URLRequestJob (and any filters) are guaranteed to be
// deleted before the URLRequestContext is destroyed.
const URLRequestContext* const url_request_context_;
@@ -129,6 +129,11 @@
// by checking within this mime type (we may do a meta-refresh via html).
std::string mime_type_;
+ // If the response was encoded with a dictionary different than those
+ // advertised (e.g. a cached response using an old dictionary), this
+ // variable preserves that dictionary from deletion during decoding.
+ scoped_ptr<SdchManager::DictionarySet> unexpected_dictionary_handle_;
+
DISALLOW_COPY_AND_ASSIGN(SdchFilter);
};
diff --git a/net/filter/sdch_filter_unittest.cc b/net/filter/sdch_filter_unittest.cc
index 79b5673..be9790d 100644
--- a/net/filter/sdch_filter_unittest.cc
+++ b/net/filter/sdch_filter_unittest.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/test/simple_test_clock.h"
#include "net/base/io_buffer.h"
#include "net/filter/mock_filter_context.h"
#include "net/filter/sdch_filter.h"
@@ -25,12 +26,12 @@
// Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary.
static const char kTestVcdiffDictionary[] = "DictionaryFor"
"SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";
-// Pre-compression test data. Note that we pad with a lot of highly gzip
-// compressible content to help to exercise the chaining pipeline. That is why
+// Pre-compression test data. Note that we pad with a lot of highly gzip
+// compressible content to help to exercise the chaining pipeline. That is why
// there are a PILE of zeros at the start and end.
// This will ensure that gzip compressed data can be fed to the chain in one
// gulp, but (with careful selection of intermediate buffers) that it takes
-// several sdch buffers worth of data to satisfy the sdch filter. See detailed
+// several sdch buffers worth of data to satisfy the sdch filter. See detailed
// CHECK() calls in FilterChaining test for specifics.
static const char kTestData[] = "0000000000000000000000000000000000000000000000"
"0000000000000000000000000000TestData "
@@ -63,8 +64,8 @@
url_request_context->set_sdch_manager(sdch_manager_.get());
}
- // Attempt to add a dictionary to the manager; returns whether or not
- // the attempt succeeded.
+ // Attempt to add a dictionary to the manager and probe for success or
+ // failure.
bool AddSdchDictionary(const std::string& dictionary_text,
const GURL& gurl) {
return sdch_manager_->AddSdchDictionary(dictionary_text, gurl) == SDCH_OK;
@@ -72,6 +73,13 @@
MockFilterContext* filter_context() { return filter_context_.get(); }
+ // Sets both the GURL and the SDCH response for a filter context.
+ void SetupFilterContextWithGURL(GURL url) {
+ filter_context_->SetURL(url);
+ filter_context_->SetSdchResponse(
+ sdch_manager_->GetDictionarySet(url).Pass());
+ }
+
std::string NewSdchCompressedData(const std::string dictionary) {
std::string client_hash;
std::string server_hash;
@@ -108,11 +116,11 @@
//------------------------------------------------------------------------------
// Provide a generic helper function for trying to filter data.
// This function repeatedly calls the filter to process data, until the entire
-// source is consumed. The return value from the filter is appended to output.
+// source is consumed. The return value from the filter is appended to output.
// This allows us to vary input and output block sizes in order to test for edge
// effects (boundary effects?) during the filtering process.
// This function provides data to the filter in blocks of no-more-than the
-// specified input_block_length. It allows the filter to fill no more than
+// specified input_block_length. It allows the filter to fill no more than
// output_buffer_length in any one call to proccess (a.k.a., Read) data, and
// concatenates all these little output blocks into the singular output string.
static bool FilterTestData(const std::string& source,
@@ -159,6 +167,19 @@
return dictionary;
}
+static std::string NewSdchExpiredDictionary(const std::string& domain) {
+ std::string dictionary;
+ if (!domain.empty()) {
+ dictionary.append("Domain: ");
+ dictionary.append(domain);
+ dictionary.append("\n");
+ }
+ dictionary.append("Max-Age: 0\n");
+ dictionary.append("\n");
+ dictionary.append(kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1);
+ return dictionary;
+}
+
//------------------------------------------------------------------------------
TEST_F(SdchFilterTest, EmptyInputOk) {
@@ -197,10 +218,10 @@
EXPECT_EQ(0, output_bytes_or_buffer_size);
EXPECT_EQ(Filter::FILTER_NEED_MORE_DATA, status);
- // Partially tear down context. Anything that goes through request()
+ // Partially tear down context. Anything that goes through request()
// without checking it for null in the URLRequestJob::HttpFilterContext
- // implementation is suspect. Everything that does check it for null should
- // return null. This is to test for incorrectly relying on filter_context()
+ // implementation is suspect. Everything that does check it for null should
+ // return null. This is to test for incorrectly relying on filter_context()
// from the SdchFilter destructor.
filter_context()->NukeUnstableInterfaces();
}
@@ -451,7 +472,7 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(url);
+ SetupFilterContextWithGURL(url);
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
@@ -488,7 +509,8 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(GURL("https://" + kSampleDomain));
+ GURL filter_context_gurl("https://" + kSampleDomain);
+ SetupFilterContextWithGURL(GURL("https://" + kSampleDomain));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
const size_t feed_block_size(100);
@@ -501,7 +523,7 @@
// Current failsafe TODO/hack refuses to decode any content that doesn't use
// http as the scheme (see use of DICTIONARY_SELECTED_FOR_NON_HTTP).
-// The following tests this blockage. Note that blacklisting results, so we
+// The following tests this blockage. Note that blacklisting results, so we
// we need separate tests for each of these.
TEST_F(SdchFilterTest, NoDecodeFtp) {
// Construct a valid SDCH dictionary from a VCDIFF dictionary.
@@ -518,7 +540,7 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(GURL("ftp://" + kSampleDomain));
+ SetupFilterContextWithGURL(GURL("ftp://" + kSampleDomain));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
const size_t feed_block_size(100);
@@ -544,7 +566,7 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(GURL("file://" + kSampleDomain));
+ SetupFilterContextWithGURL(GURL("file://" + kSampleDomain));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
const size_t feed_block_size(100);
@@ -570,7 +592,7 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(GURL("about://" + kSampleDomain));
+ SetupFilterContextWithGURL(GURL("about://" + kSampleDomain));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
const size_t feed_block_size(100);
@@ -596,7 +618,7 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(GURL("javascript://" + kSampleDomain));
+ SetupFilterContextWithGURL(GURL("javascript://" + kSampleDomain));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
const size_t feed_block_size(100);
@@ -622,7 +644,7 @@
std::vector<Filter::FilterType> filter_types;
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
- filter_context()->SetURL(GURL("http://" + kSampleDomain));
+ SetupFilterContextWithGURL(GURL("http://" + kSampleDomain));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
const size_t feed_block_size(100);
@@ -651,7 +673,7 @@
// Decode with content arriving from the "wrong" domain.
// This tests SdchManager::CanSet().
GURL wrong_domain_url("http://www.wrongdomain.com");
- filter_context()->SetURL(wrong_domain_url);
+ SetupFilterContextWithGURL(wrong_domain_url);
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
size_t feed_block_size = 100;
@@ -696,7 +718,7 @@
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
// Test decode the path data, arriving from a valid path.
- filter_context()->SetURL(GURL(url_string + path));
+ SetupFilterContextWithGURL(GURL(url_string + path));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
size_t feed_block_size = 100;
@@ -708,7 +730,7 @@
EXPECT_EQ(output, expanded_);
// Test decode the path data, arriving from a invalid path.
- filter_context()->SetURL(GURL(url_string));
+ SetupFilterContextWithGURL(GURL(url_string));
filter.reset(Filter::Factory(filter_types, *filter_context()));
feed_block_size = 100;
@@ -753,7 +775,7 @@
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
// Test decode the port data, arriving from a valid port.
- filter_context()->SetURL(GURL(url_string + ":" + port));
+ SetupFilterContextWithGURL(GURL(url_string + ":" + port));
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
size_t feed_block_size = 100;
@@ -764,7 +786,7 @@
EXPECT_EQ(output, expanded_);
// Test decode the port data, arriving from a valid (default) port.
- filter_context()->SetURL(GURL(url_string)); // Default port.
+ SetupFilterContextWithGURL(GURL(url_string)); // Default port.
filter.reset(Filter::Factory(filter_types, *filter_context()));
feed_block_size = 100;
@@ -775,7 +797,7 @@
EXPECT_EQ(output, expanded_);
// Test decode the port data, arriving from a invalid port.
- filter_context()->SetURL(GURL(url_string + ":" + port + "1"));
+ SetupFilterContextWithGURL(GURL(url_string + ":" + port + "1"));
filter.reset(Filter::Factory(filter_types, *filter_context()));
feed_block_size = 100;
@@ -856,8 +878,8 @@
};
// Test that filters can be cascaded (chained) so that the output of one filter
-// is processed by the next one. This is most critical for SDCH, which is
-// routinely followed by gzip (during encoding). The filter we'll test for will
+// is processed by the next one. This is most critical for SDCH, which is
+// routinely followed by gzip (during encoding). The filter we'll test for will
// do the gzip decoding first, and then decode the SDCH content.
TEST_F(SdchFilterTest, FilterChaining) {
// Construct a valid SDCH dictionary from a VCDIFF dictionary.
@@ -884,7 +906,7 @@
CHECK_GT(kLargeInputBufferSize, gzip_compressed_sdch.size());
CHECK_GT(kLargeInputBufferSize, sdch_compressed.size());
CHECK_GT(kLargeInputBufferSize, expanded_.size());
- filter_context()->SetURL(url);
+ SetupFilterContextWithGURL(url);
scoped_ptr<Filter> filter(
SdchFilterChainingTest::Factory(filter_types, *filter_context(),
kLargeInputBufferSize));
@@ -962,16 +984,15 @@
filter_types.push_back(Filter::FILTER_TYPE_SDCH);
filter_context()->SetMimeType("anything/mime");
- filter_context()->SetSdchResponse(true);
+ SetupFilterContextWithGURL(url);
+
Filter::FixupEncodingTypes(*filter_context(), &filter_types);
ASSERT_EQ(filter_types.size(), 2u);
EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH);
EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH);
// First try with a large buffer (larger than test input, or compressed data).
- filter_context()->SetURL(url);
- scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
-
+ scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
// Verify that chained filter is waiting for data.
char tiny_output_buffer[10];
@@ -1020,7 +1041,7 @@
filter_types.push_back(Filter::FILTER_TYPE_GZIP);
filter_context()->SetMimeType("anything/mime");
- filter_context()->SetSdchResponse(true);
+ SetupFilterContextWithGURL(url);
Filter::FixupEncodingTypes(*filter_context(), &filter_types);
ASSERT_EQ(filter_types.size(), 3u);
EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE);
@@ -1028,10 +1049,8 @@
EXPECT_EQ(filter_types[2], Filter::FILTER_TYPE_GZIP);
// First try with a large buffer (larger than test input, or compressed data).
- filter_context()->SetURL(url);
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
-
// Verify that chained filter is waiting for data.
char tiny_output_buffer[10];
int tiny_output_size = sizeof(tiny_output_buffer);
@@ -1077,17 +1096,15 @@
std::vector<Filter::FilterType> filter_types;
filter_context()->SetMimeType("anything/mime");
- filter_context()->SetSdchResponse(true);
+ SetupFilterContextWithGURL(url);
Filter::FixupEncodingTypes(*filter_context(), &filter_types);
ASSERT_EQ(filter_types.size(), 2u);
EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE);
EXPECT_EQ(filter_types[1], Filter::FILTER_TYPE_GZIP_HELPING_SDCH);
// First try with a large buffer (larger than test input, or compressed data).
- filter_context()->SetURL(url);
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
-
// Verify that chained filter is waiting for data.
char tiny_output_buffer[10];
int tiny_output_size = sizeof(tiny_output_buffer);
@@ -1138,7 +1155,7 @@
filter_types.push_back(Filter::FILTER_TYPE_GZIP);
filter_context()->SetMimeType("anything/mime");
- filter_context()->SetSdchResponse(true);
+ SetupFilterContextWithGURL(url);
Filter::FixupEncodingTypes(*filter_context(), &filter_types);
ASSERT_EQ(filter_types.size(), 3u);
EXPECT_EQ(filter_types[0], Filter::FILTER_TYPE_SDCH_POSSIBLE);
@@ -1146,7 +1163,6 @@
EXPECT_EQ(filter_types[2], Filter::FILTER_TYPE_GZIP);
// First try with a large buffer (larger than test input, or compressed data).
- filter_context()->SetURL(url);
scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
// Verify that chained filter is waiting for data.
@@ -1173,4 +1189,58 @@
EXPECT_EQ(output, expanded_);
}
+// Test to make sure we decode properly with an unexpected dictionary.
+TEST_F(SdchFilterTest, UnexpectedDictionary) {
+ // Setup a dictionary, add it to the filter context, and create a filter
+ // based on that dictionary.
+ const std::string kSampleDomain = "sdchtest.com";
+ std::string dictionary(NewSdchDictionary(kSampleDomain));
+ std::string url_string = "http://" + kSampleDomain;
+ GURL url(url_string);
+ EXPECT_TRUE(AddSdchDictionary(dictionary, url));
+
+ SetupFilterContextWithGURL(url);
+
+ std::vector<Filter::FilterType> filter_types;
+ filter_types.push_back(Filter::FILTER_TYPE_SDCH);
+ scoped_ptr<Filter> filter(Filter::Factory(filter_types, *filter_context()));
+
+ // Setup another dictionary, expired. Don't add it to the filter context.
+ // Delete stored dictionaries first to handle platforms which only
+ // have room for a single dictionary.
+ sdch_manager_->ClearData();
+ std::string expired_dictionary(NewSdchExpiredDictionary(kSampleDomain));
+
+ // Don't use the Helper function since its insertion check is indeterminate
+ // for a Max-Age: 0 dictionary.
+ sdch_manager_->AddSdchDictionary(expired_dictionary, url);
+
+ std::string client_hash;
+ std::string server_hash;
+ SdchManager::GenerateHash(expired_dictionary, &client_hash, &server_hash);
+
+ // Make sure Max-Age: 0 shows up as expired.
+ scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
+ clock->SetNow(base::Time::Now());
+ clock->Advance(base::TimeDelta::FromMinutes(5));
+ SdchProblemCode problem_code;
+ scoped_ptr<SdchManager::DictionarySet> hash_set(
+ sdch_manager_->GetDictionarySetByHash(
+ url, server_hash, &problem_code).Pass());
+ ASSERT_TRUE(hash_set);
+ ASSERT_EQ(SDCH_OK, problem_code);
+
+ const_cast<SdchManager::Dictionary*>(
+ hash_set->GetDictionary(server_hash))->SetClockForTesting(
+ clock.Pass());
+
+ // Encode output with the second dictionary.
+ std::string sdch_compressed(NewSdchCompressedData(expired_dictionary));
+
+ // See if the filter decodes it.
+ std::string output;
+ EXPECT_TRUE(FilterTestData(sdch_compressed, 100, 100, filter.get(), &output));
+ EXPECT_EQ(expanded_, output);
+}
+
} // namespace net
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index 4cbde27..74bd6bf 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -965,14 +965,16 @@
switch (GetErrorClass(response.status_code)) {
case ERROR_CLASS_INITIATED:
return Stop(ERR_INVALID_RESPONSE);
- case ERROR_CLASS_OK:
- if (!ExtractPortFromEPSVResponse( response, &data_connection_port_))
+ case ERROR_CLASS_OK: {
+ int port;
+ if (!ExtractPortFromEPSVResponse(response, &port))
return Stop(ERR_INVALID_RESPONSE);
- if (data_connection_port_ < 1024 ||
- !IsPortAllowedByFtp(data_connection_port_))
+ if (port < 1024 || !IsPortAllowedByFtp(port))
return Stop(ERR_UNSAFE_PORT);
+ data_connection_port_ = static_cast<uint16>(port);
next_state_ = STATE_DATA_CONNECT;
break;
+ }
case ERROR_CLASS_INFO_NEEDED:
return Stop(ERR_INVALID_RESPONSE);
case ERROR_CLASS_TRANSIENT_ERROR:
@@ -999,14 +1001,16 @@
switch (GetErrorClass(response.status_code)) {
case ERROR_CLASS_INITIATED:
return Stop(ERR_INVALID_RESPONSE);
- case ERROR_CLASS_OK:
- if (!ExtractPortFromPASVResponse(response, &data_connection_port_))
+ case ERROR_CLASS_OK: {
+ int port;
+ if (!ExtractPortFromPASVResponse(response, &port))
return Stop(ERR_INVALID_RESPONSE);
- if (data_connection_port_ < 1024 ||
- !IsPortAllowedByFtp(data_connection_port_))
+ if (port < 1024 || !IsPortAllowedByFtp(port))
return Stop(ERR_UNSAFE_PORT);
+ data_connection_port_ = static_cast<uint16>(port);
next_state_ = STATE_DATA_CONNECT;
break;
+ }
case ERROR_CLASS_INFO_NEEDED:
return Stop(ERR_INVALID_RESPONSE);
case ERROR_CLASS_TRANSIENT_ERROR:
diff --git a/net/ftp/ftp_network_transaction.h b/net/ftp/ftp_network_transaction.h
index c8ed550..e350e16 100644
--- a/net/ftp/ftp_network_transaction.h
+++ b/net/ftp/ftp_network_transaction.h
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -245,7 +246,7 @@
// with any trailing slash removed.
std::string current_remote_directory_;
- int data_connection_port_;
+ uint16 data_connection_port_;
ClientSocketFactory* socket_factory_;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 20ffdd1..8cddaf5 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1027,11 +1027,8 @@
return OK;
}
- HostPortPair endpoint = HostPortPair(request_->url.HostNoBrackets(),
- request_->url.EffectiveIntPort());
- ProcessAlternateProtocol(session_,
- *response_.headers.get(),
- endpoint);
+ ProcessAlternateProtocol(session_, *response_.headers.get(),
+ HostPortPair::FromURL(request_->url));
int rv = HandleAuthChallenge();
if (rv != OK)
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index d08d162..878406e 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -268,12 +268,15 @@
base::MessageLoop::current()->RunUntilIdle();
}
+ const char* GetAlternateProtocolFromParam() {
+ return
+ AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
+ }
+
// This is the expected return from a current server advertising SPDY.
std::string GetAlternateProtocolHttpHeader() {
- return
- std::string("Alternate-Protocol: 443:") +
- AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
- "\r\n\r\n";
+ return std::string("Alternate-Protocol: 443:") +
+ GetAlternateProtocolFromParam() + "\r\n\r\n";
}
// Either |write_failure| specifies a write failure or |read_failure|
@@ -407,8 +410,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
HttpNetworkTransactionTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
namespace {
@@ -10107,10 +10109,12 @@
};
MockRead data_reads_1[] = {
MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead("HTTP/1.1 200 OK\r\n"
- "Alternate-Protocol: 443:npn-spdy/2\r\n"
- "Proxy-Connection: close\r\n"
- "\r\n"),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alternate-Protocol: 443:"),
+ MockRead(GetAlternateProtocolFromParam()),
+ MockRead("\r\n"),
+ MockRead("Proxy-Connection: close\r\n"),
+ MockRead("\r\n"),
};
StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
data_writes_1, arraysize(data_writes_1));
@@ -11402,8 +11406,7 @@
// SPDY GET for HTTP URL (through the proxy, but not the tunnel).
SpdyHeaderBlock req2_block;
req2_block[spdy_util_.GetMethodKey()] = "GET";
- req2_block[spdy_util_.GetPathKey()] =
- spdy_util_.is_spdy2() ? http_url.c_str() : "/";
+ req2_block[spdy_util_.GetPathKey()] = "/";
req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
req2_block[spdy_util_.GetSchemeKey()] = "http";
spdy_util_.MaybeAddVersionHeader(&req2_block);
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index 694d394..bdaf57f 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -42,7 +42,7 @@
struct HttpProxyClientSocketPoolTestParams {
HttpProxyClientSocketPoolTestParams()
: proxy_type(HTTP),
- protocol(kProtoSPDY3) {}
+ protocol(kProtoSPDY31) {}
HttpProxyClientSocketPoolTestParams(
HttpProxyType proxy_type,
@@ -342,12 +342,6 @@
HttpProxyClientSocketPoolTests,
HttpProxyClientSocketPoolTest,
::testing::Values(
- HttpProxyClientSocketPoolTestParams(HTTP, kProtoDeprecatedSPDY2),
- HttpProxyClientSocketPoolTestParams(HTTPS, kProtoDeprecatedSPDY2),
- HttpProxyClientSocketPoolTestParams(SPDY, kProtoDeprecatedSPDY2),
- HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY3),
- HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY3),
- HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY3),
HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY31),
HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY31),
HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31),
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index 65ecd11..1bf541b 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -67,7 +67,7 @@
}
// Attempt to find canonical servers.
- int canonical_ports[] = { 80, 443 };
+ uint16 canonical_ports[] = { 80, 443 };
for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
std::string canonical_suffix = canonical_suffixes_[i];
for (size_t j = 0; j < arraysize(canonical_ports); ++j) {
@@ -301,8 +301,14 @@
const HostPortPair& server) {
AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server);
if (it == alternate_protocol_map_.end()) {
- LOG(DFATAL) << "Trying to mark unknown alternate protocol broken.";
- return;
+ if (!HasAlternateProtocol(server)) {
+ LOG(DFATAL) << "Trying to mark unknown alternate protocol broken.";
+ return;
+ }
+ // This server's alternate protocol information is coming from a canonical
+ // server. Add an entry in the map for this server explicitly so that
+ // it can be marked as broken.
+ it = alternate_protocol_map_.Put(server, GetAlternateProtocol(server));
}
it->second.is_broken = true;
int count = ++broken_alternate_protocol_map_[server];
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc
index 1c016b7..3d1bacb 100644
--- a/net/http/http_server_properties_impl_unittest.cc
+++ b/net/http/http_server_properties_impl_unittest.cc
@@ -475,6 +475,23 @@
EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair));
}
+TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken2) {
+ HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
+ HostPortPair canonical_port_pair("bar.c.youtube.com", 80);
+
+ AlternateProtocolInfo canonical_protocol(1234, QUIC, 1);
+
+ impl_.SetAlternateProtocol(canonical_port_pair,
+ canonical_protocol.port,
+ canonical_protocol.protocol,
+ canonical_protocol.probability);
+
+ impl_.SetBrokenAlternateProtocol(test_host_port_pair);
+ AlternateProtocolInfo alternate =
+ impl_.GetAlternateProtocol(test_host_port_pair);
+ EXPECT_TRUE(alternate.is_broken);
+}
+
TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
HostPortPair canonical_port_pair("bar.c.youtube.com", 80);
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index 41b70b1..5773129 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -449,9 +449,8 @@
continue;
}
- net::AlternateProtocolInfo port_alternate_protocol(port,
- protocol,
- probability);
+ net::AlternateProtocolInfo port_alternate_protocol(
+ static_cast<uint16>(port), protocol, probability);
alternate_protocol_map->Put(server, port_alternate_protocol);
++count;
} while (false);
diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc
index 29d9b26..f84b80c 100644
--- a/net/http/http_stream_factory.cc
+++ b/net/http/http_stream_factory.cc
@@ -60,7 +60,7 @@
}
if (!base::StringToInt(port_protocol_vector[0], &port) ||
- port <= 0 || port >= 1 << 16) {
+ port == 0 || !IsPortValid(port)) {
DVLOG(1) << kAlternateProtocolHeader
<< " header has unrecognizable port: "
<< port_protocol_vector[0];
@@ -94,8 +94,8 @@
return;
}
- http_server_properties->SetAlternateProtocol(host_port, port, protocol,
- probability);
+ http_server_properties->SetAlternateProtocol(
+ host_port, static_cast<uint16>(port), protocol, probability);
}
GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index 8304694..8b12dba 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -184,8 +184,7 @@
if (original_url.SchemeIs("ftp"))
return kNoAlternateProtocol;
- HostPortPair origin = HostPortPair(original_url.HostNoBrackets(),
- original_url.EffectiveIntPort());
+ HostPortPair origin = HostPortPair::FromURL(original_url);
HttpServerProperties& http_server_properties =
*session_->http_server_properties();
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index a11dd2e..8369443 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -132,13 +132,10 @@
int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) {
DCHECK_GT(num_streams, 0);
- HostPortPair origin_server =
- HostPortPair(request_info_.url.HostNoBrackets(),
- request_info_.url.EffectiveIntPort());
base::WeakPtr<HttpServerProperties> http_server_properties =
session_->http_server_properties();
- if (http_server_properties &&
- http_server_properties->SupportsSpdy(origin_server)) {
+ if (http_server_properties && http_server_properties->SupportsSpdy(
+ HostPortPair::FromURL(request_info_.url))) {
num_streams_ = 1;
} else {
num_streams_ = num_streams;
@@ -617,8 +614,7 @@
}
int HttpStreamFactoryImpl::Job::DoStart() {
- int port = request_info_.url.EffectiveIntPort();
- origin_ = HostPortPair(request_info_.url.HostNoBrackets(), port);
+ origin_ = HostPortPair::FromURL(request_info_.url);
origin_url_ = stream_factory_->ApplyHostMappingRules(
request_info_.url, &origin_);
@@ -628,14 +624,14 @@
priority_));
// Don't connect to restricted ports.
- bool is_port_allowed = IsPortAllowedByDefault(port);
+ bool is_port_allowed = IsPortAllowedByDefault(origin_.port());
if (request_info_.url.SchemeIs("ftp")) {
// Never share connection with other jobs for FTP requests.
DCHECK(!waiting_job_);
- is_port_allowed = IsPortAllowedByFtp(port);
+ is_port_allowed = IsPortAllowedByFtp(origin_.port());
}
- if (!is_port_allowed && !IsPortAllowedByOverride(port)) {
+ if (!is_port_allowed && !IsPortAllowedByOverride(origin_.port())) {
if (waiting_job_) {
waiting_job_->Resume(this);
waiting_job_ = NULL;
diff --git a/net/http/http_stream_factory_impl_request_unittest.cc b/net/http/http_stream_factory_impl_request_unittest.cc
index 587358d..32900f9 100644
--- a/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/net/http/http_stream_factory_impl_request_unittest.cc
@@ -19,8 +19,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
HttpStreamFactoryImplRequestTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
namespace {
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index 68e9114..4ac5467 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -424,8 +424,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
HttpStreamFactoryTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
diff --git a/net/net.gyp b/net/net.gyp
index 3c9a520..da91a92 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -876,8 +876,12 @@
'../testing/gmock.gyp:gmock',
],
'sources': [
+ 'base/captured_net_log_entry.cc',
+ 'base/captured_net_log_entry.h',
'base/capturing_net_log.cc',
'base/capturing_net_log.h',
+ 'base/capturing_net_log_observer.cc',
+ 'base/capturing_net_log_observer.h',
'base/load_timing_info_test_util.cc',
'base/load_timing_info_test_util.h',
'base/mock_file_stream.cc',
diff --git a/net/net.gypi b/net/net.gypi
index 337f016..cc9ff35 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -1236,8 +1236,8 @@
'websockets/websocket_frame_parser.h',
'websockets/websocket_handshake_constants.cc',
'websockets/websocket_handshake_constants.h',
- 'websockets/websocket_handshake_handler.cc',
- 'websockets/websocket_handshake_handler.h',
+ 'websockets/websocket_handshake_challenge.cc',
+ 'websockets/websocket_handshake_challenge.h',
'websockets/websocket_handshake_request_info.cc',
'websockets/websocket_handshake_request_info.h',
'websockets/websocket_handshake_response_info.cc',
@@ -1709,7 +1709,7 @@
'websockets/websocket_extension_parser_test.cc',
'websockets/websocket_frame_parser_test.cc',
'websockets/websocket_frame_test.cc',
- 'websockets/websocket_handshake_handler_test.cc',
+ 'websockets/websocket_handshake_challenge_test.cc',
'websockets/websocket_handshake_stream_create_helper_test.cc',
'websockets/websocket_inflater_test.cc',
'websockets/websocket_stream_test.cc',
diff --git a/net/proxy/network_delegate_error_observer_unittest.cc b/net/proxy/network_delegate_error_observer_unittest.cc
index 5d2c501..da87f8d 100644
--- a/net/proxy/network_delegate_error_observer_unittest.cc
+++ b/net/proxy/network_delegate_error_observer_unittest.cc
@@ -77,10 +77,6 @@
bool OnCanThrottleRequest(const URLRequest& request) const override {
return false;
}
- int OnBeforeSocketStreamConnect(SocketStream* stream,
- const CompletionCallback& callback) override {
- return OK;
- }
bool got_pac_error_;
};
diff --git a/net/proxy/proxy_config_service_android.cc b/net/proxy/proxy_config_service_android.cc
index f1a0b6c..50407fe 100644
--- a/net/proxy/proxy_config_service_android.cc
+++ b/net/proxy/proxy_config_service_android.cc
@@ -197,7 +197,8 @@
: jni_delegate_(this),
network_task_runner_(network_task_runner),
jni_task_runner_(jni_task_runner),
- get_property_callback_(get_property_callback) {
+ get_property_callback_(get_property_callback),
+ exclude_pac_url_(false) {
}
void SetupJNI() {
@@ -271,13 +272,22 @@
const std::vector<std::string>& exclusion_list) {
DCHECK(OnJNIThread());
ProxyConfig proxy_config;
- CreateStaticProxyConfig(host, port, pac_url, exclusion_list, &proxy_config);
+ if (exclude_pac_url_) {
+ CreateStaticProxyConfig(host, port, "", exclusion_list, &proxy_config);
+ } else {
+ CreateStaticProxyConfig(host, port, pac_url, exclusion_list,
+ &proxy_config);
+ }
network_task_runner_->PostTask(
FROM_HERE,
base::Bind(
&Delegate::SetNewConfigOnNetworkThread, this, proxy_config));
}
+ void set_exclude_pac_url(bool enabled) {
+ exclude_pac_url_ = enabled;
+ }
+
private:
friend class base::RefCountedThreadSafe<Delegate>;
@@ -344,6 +354,7 @@
scoped_refptr<base::SequencedTaskRunner> jni_task_runner_;
GetPropertyCallback get_property_callback_;
ProxyConfig proxy_config_;
+ bool exclude_pac_url_;
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
@@ -366,6 +377,10 @@
return RegisterNativesImpl(env);
}
+void ProxyConfigServiceAndroid::set_exclude_pac_url(bool enabled) {
+ delegate_->set_exclude_pac_url(enabled);
+}
+
void ProxyConfigServiceAndroid::AddObserver(Observer* observer) {
delegate_->AddObserver(observer);
}
diff --git a/net/proxy/proxy_config_service_android.h b/net/proxy/proxy_config_service_android.h
index d642d37..cb15bc5 100644
--- a/net/proxy/proxy_config_service_android.h
+++ b/net/proxy/proxy_config_service_android.h
@@ -64,6 +64,11 @@
// Register JNI bindings.
static bool Register(JNIEnv* env);
+ // Android provides a local HTTP proxy that does PAC resolution. When this
+ // setting is enabled, the proxy config service ignores the PAC URL and uses
+ // the local proxy for all proxy resolution.
+ void set_exclude_pac_url(bool enabled);
+
// ProxyConfigService:
// Called only on the network thread.
virtual void AddObserver(Observer* observer) override;
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 24fbe9e..963153d 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -196,7 +196,7 @@
return false;
v8::HandleScope scope(isolate);
- v8::Local<v8::String> str_object = object->ToString();
+ v8::Local<v8::String> str_object = object->ToString(isolate);
if (str_object.IsEmpty())
return false;
*utf16_result = V8StringToUTF16(str_object);
@@ -211,7 +211,8 @@
if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
return false;
- const base::string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString());
+ const base::string16 hostname_utf16 =
+ V8StringToUTF16(v8::Local<v8::String>::Cast(args[0]));
// If the hostname is already in ASCII, simply return it as is.
if (base::IsStringASCII(hostname_utf16)) {
@@ -393,7 +394,7 @@
return ERR_PAC_SCRIPT_FAILED;
}
- base::string16 ret_str = V8StringToUTF16(ret->ToString());
+ base::string16 ret_str = V8StringToUTF16(v8::Local<v8::String>::Cast(ret));
if (!base::IsStringASCII(ret_str)) {
// TODO(eroman): Rather than failing when a wide string is returned, we
@@ -656,7 +657,8 @@
return;
}
- std::string ip_address_list = V8StringToUTF8(args[0]->ToString());
+ std::string ip_address_list =
+ V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
if (!base::IsStringASCII(ip_address_list)) {
args.GetReturnValue().SetNull();
return;
@@ -681,12 +683,14 @@
return;
}
- std::string ip_address = V8StringToUTF8(args[0]->ToString());
+ std::string ip_address =
+ V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
if (!base::IsStringASCII(ip_address)) {
args.GetReturnValue().Set(false);
return;
}
- std::string ip_prefix = V8StringToUTF8(args[1]->ToString());
+ std::string ip_prefix =
+ V8StringToUTF8(v8::Local<v8::String>::Cast(args[1]));
if (!base::IsStringASCII(ip_prefix)) {
args.GetReturnValue().Set(false);
return;
diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc
index 2073d00..4c5bd4c 100644
--- a/net/proxy/proxy_script_fetcher_impl_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -179,11 +179,6 @@
return false;
}
- int OnBeforeSocketStreamConnect(SocketStream* stream,
- const CompletionCallback& callback) override {
- return OK;
- }
-
DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
};
diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc
index 0b9ba67..78d5c3e 100644
--- a/net/proxy/proxy_server.cc
+++ b/net/proxy/proxy_server.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "net/base/net_util.h"
#include "net/http/http_util.h"
@@ -238,7 +239,7 @@
if (port == -1)
port = GetDefaultPortForScheme(scheme);
- host_port_pair = HostPortPair(host, port);
+ host_port_pair = HostPortPair(host, static_cast<uint16>(port));
}
return ProxyServer(scheme, host_port_pair);
diff --git a/net/quic/congestion_control/pacing_sender.cc b/net/quic/congestion_control/pacing_sender.cc
index 8073c5b..7e9f81a 100644
--- a/net/quic/congestion_control/pacing_sender.cc
+++ b/net/quic/congestion_control/pacing_sender.cc
@@ -27,6 +27,11 @@
sender_->SetFromConfig(config, is_server, using_pacing);
}
+void PacingSender::ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) {
+ sender_->ResumeConnectionState(cached_network_params);
+}
+
void PacingSender::SetNumEmulatedConnections(int num_connections) {
sender_->SetNumEmulatedConnections(num_connections);
}
diff --git a/net/quic/congestion_control/pacing_sender.h b/net/quic/congestion_control/pacing_sender.h
index 4eb3dab..d7d3b2d 100644
--- a/net/quic/congestion_control/pacing_sender.h
+++ b/net/quic/congestion_control/pacing_sender.h
@@ -16,6 +16,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
+#include "net/quic/crypto/cached_network_parameters.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_protocol.h"
@@ -38,6 +39,8 @@
void SetFromConfig(const QuicConfig& config,
bool is_server,
bool using_pacing) override;
+ void ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) override;
void SetNumEmulatedConnections(int num_connections) override;
void OnCongestionEvent(bool rtt_updated,
QuicByteCount bytes_in_flight,
@@ -63,6 +66,7 @@
bool InRecovery() const override;
QuicByteCount GetSlowStartThreshold() const override;
CongestionControlType GetCongestionControlType() const override;
+ // End implementation of SendAlgorithmInterface.
private:
scoped_ptr<SendAlgorithmInterface> sender_; // Underlying sender.
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h
index 7195f81..322ff1d 100644
--- a/net/quic/congestion_control/send_algorithm_interface.h
+++ b/net/quic/congestion_control/send_algorithm_interface.h
@@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "net/base/net_export.h"
+#include "net/quic/crypto/cached_network_parameters.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_clock.h"
#include "net/quic/quic_config.h"
@@ -113,6 +114,10 @@
virtual QuicByteCount GetSlowStartThreshold() const = 0;
virtual CongestionControlType GetCongestionControlType() const = 0;
+
+ // Called by the Session when we get a bandwidth estimate from the client.
+ virtual void ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) = 0;
};
} // namespace net
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc
index 2d0efd7..5fa1559 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc
@@ -27,13 +27,12 @@
const uint32 kDefaultNumConnections = 2; // N-connection emulation.
} // namespace
-TcpCubicSender::TcpCubicSender(
- const QuicClock* clock,
- const RttStats* rtt_stats,
- bool reno,
- QuicPacketCount initial_tcp_congestion_window,
- QuicPacketCount max_tcp_congestion_window,
- QuicConnectionStats* stats)
+TcpCubicSender::TcpCubicSender(const QuicClock* clock,
+ const RttStats* rtt_stats,
+ bool reno,
+ QuicPacketCount initial_tcp_congestion_window,
+ QuicPacketCount max_tcp_congestion_window,
+ QuicConnectionStats* stats)
: hybrid_slow_start_(clock),
cubic_(clock, stats),
rtt_stats_(rtt_stats),
@@ -49,8 +48,8 @@
slowstart_threshold_(max_tcp_congestion_window),
previous_slowstart_threshold_(0),
last_cutback_exited_slowstart_(false),
- max_tcp_congestion_window_(max_tcp_congestion_window) {
-}
+ max_tcp_congestion_window_(max_tcp_congestion_window),
+ clock_(clock) {}
TcpCubicSender::~TcpCubicSender() {
UMA_HISTOGRAM_COUNTS("Net.QuicSession.FinalTcpCwnd", congestion_window_);
@@ -73,6 +72,26 @@
}
}
+void TcpCubicSender::ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) {
+ // If the previous bandwidth estimate is less than an hour old, store in
+ // preparation for doing bandwidth resumption.
+ int64 seconds_since_estimate =
+ clock_->WallNow().ToUNIXSeconds() - cached_network_params.timestamp();
+ if (seconds_since_estimate > kNumSecondsPerHour) {
+ return;
+ }
+
+ QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(
+ cached_network_params.bandwidth_estimate_bytes_per_second());
+ QuicTime::Delta rtt_ms =
+ QuicTime::Delta::FromMilliseconds(cached_network_params.min_rtt_ms());
+ congestion_window_ = bandwidth.ToBytesPerPeriod(rtt_ms) / kMaxPacketSize;
+
+ // TODO(rjshade): Set appropriate CWND when previous connection was in slow
+ // start at time of estimate.
+}
+
void TcpCubicSender::SetNumEmulatedConnections(int num_connections) {
num_connections_ = max(1, num_connections);
cubic_.SetNumConnections(num_connections_);
diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h
index a7507a2..eeb9331 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.h
+++ b/net/quic/congestion_control/tcp_cubic_sender.h
@@ -15,6 +15,7 @@
#include "net/quic/congestion_control/hybrid_slow_start.h"
#include "net/quic/congestion_control/prr_sender.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
+#include "net/quic/crypto/cached_network_parameters.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_connection_stats.h"
#include "net/quic/quic_protocol.h"
@@ -43,6 +44,8 @@
void SetFromConfig(const QuicConfig& config,
bool is_server,
bool using_pacing) override;
+ void ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) override;
void SetNumEmulatedConnections(int num_connections) override;
void OnCongestionEvent(bool rtt_updated,
QuicByteCount bytes_in_flight,
@@ -130,6 +133,8 @@
// Maximum number of outstanding packets for tcp.
QuicPacketCount max_tcp_congestion_window_;
+ const QuicClock* clock_;
+
DISALLOW_COPY_AND_ASSIGN(TcpCubicSender);
};
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc
index 427dd8c..e4737eb 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -701,5 +701,32 @@
EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
}
+TEST_F(TcpCubicSenderTest, BandwidthResumption) {
+ // Test that when provided with CachedNetworkParameters and opted in to the
+ // bandwidth resumption experiment, that the TcpCubicSender sets initial CWND
+ // appropriately.
+
+ // Set some common values.
+ CachedNetworkParameters cached_network_params;
+ const QuicPacketCount kNumberOfPackets = 123;
+ const int kBandwidthEstimateBytesPerSecond =
+ kNumberOfPackets * kMaxPacketSize;
+ cached_network_params.set_bandwidth_estimate_bytes_per_second(
+ kBandwidthEstimateBytesPerSecond);
+ cached_network_params.set_min_rtt_ms(1000);
+
+ // Ensure that an old estimate is not used for bandwidth resumption.
+ cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
+ (kNumSecondsPerHour + 1));
+ sender_->ResumeConnectionState(cached_network_params);
+ EXPECT_EQ(10u, sender_->congestion_window());
+
+ // If the estimate is new enough, make sure it is used.
+ cached_network_params.set_timestamp(clock_.WallNow().ToUNIXSeconds() -
+ (kNumSecondsPerHour - 1));
+ sender_->ResumeConnectionState(cached_network_params);
+ EXPECT_EQ(kNumberOfPackets, sender_->congestion_window());
+}
+
} // namespace test
} // namespace net
diff --git a/net/quic/congestion_control/tcp_loss_algorithm.cc b/net/quic/congestion_control/tcp_loss_algorithm.cc
index 6cf56d8..9366105 100644
--- a/net/quic/congestion_control/tcp_loss_algorithm.cc
+++ b/net/quic/congestion_control/tcp_loss_algorithm.cc
@@ -40,7 +40,7 @@
continue;
}
- LOG_IF(DFATAL, it->nack_count == 0)
+ LOG_IF(DFATAL, it->nack_count == 0 && it->sent_time.IsInitialized())
<< "All packets less than largest observed should have been nacked."
<< "sequence_number:" << sequence_number
<< " largest_observed:" << largest_observed;
diff --git a/net/quic/congestion_control/tcp_loss_algorithm_test.cc b/net/quic/congestion_control/tcp_loss_algorithm_test.cc
index 5819fb1..fe6a6ea 100644
--- a/net/quic/congestion_control/tcp_loss_algorithm_test.cc
+++ b/net/quic/congestion_control/tcp_loss_algorithm_test.cc
@@ -12,8 +12,14 @@
#include "net/quic/test_tools/mock_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using std::vector;
+
namespace net {
namespace test {
+namespace {
+
+// Default packet length.
+const uint32 kDefaultLength = 1000;
class TcpLossAlgorithmTest : public ::testing::Test {
protected:
@@ -24,9 +30,16 @@
clock_.Now());
}
+ ~TcpLossAlgorithmTest() override {
+ STLDeleteElements(&packets_);
+ }
+
void SendDataPacket(QuicPacketSequenceNumber sequence_number) {
+ packets_.push_back(QuicPacket::NewDataPacket(
+ nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false,
+ PACKET_1BYTE_SEQUENCE_NUMBER));
SerializedPacket packet(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER,
- nullptr, 0, new RetransmittableFrames());
+ packets_.back(), 0, new RetransmittableFrames());
unacked_packets_.AddSentPacket(packet, 0, NOT_RETRANSMISSION, clock_.Now(),
1000, true);
}
@@ -43,6 +56,7 @@
}
}
+ vector<QuicPacket*> packets_;
QuicUnackedPacketMap unacked_packets_;
TCPLossAlgorithm loss_algorithm_;
RttStats rtt_stats_;
@@ -179,5 +193,6 @@
EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
}
+} // namespace
} // namespace test
} // namespace net
diff --git a/net/quic/congestion_control/time_loss_algorithm.cc b/net/quic/congestion_control/time_loss_algorithm.cc
index 9dd9ae9..b5f90b7 100644
--- a/net/quic/congestion_control/time_loss_algorithm.cc
+++ b/net/quic/congestion_control/time_loss_algorithm.cc
@@ -46,8 +46,10 @@
if (!it->in_flight) {
continue;
}
- LOG_IF(DFATAL, it->nack_count == 0)
- << "All packets less than largest observed should have been nacked.";
+ LOG_IF(DFATAL, it->nack_count == 0 && it->sent_time.IsInitialized())
+ << "All packets less than largest observed should have been nacked."
+ << "sequence_number:" << sequence_number
+ << " largest_observed:" << largest_observed;
// Packets are sent in order, so break when we haven't waited long enough
// to lose any more packets and leave the loss_time_ set for the timeout.
diff --git a/net/quic/congestion_control/time_loss_algorithm_test.cc b/net/quic/congestion_control/time_loss_algorithm_test.cc
index b964d28..1e9b7e5 100644
--- a/net/quic/congestion_control/time_loss_algorithm_test.cc
+++ b/net/quic/congestion_control/time_loss_algorithm_test.cc
@@ -12,8 +12,14 @@
#include "net/quic/test_tools/mock_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using std::vector;
+
namespace net {
namespace test {
+namespace {
+
+// Default packet length.
+const uint32 kDefaultLength = 1000;
class TimeLossAlgorithmTest : public ::testing::Test {
protected:
@@ -24,9 +30,16 @@
clock_.Now());
}
+ ~TimeLossAlgorithmTest() override {
+ STLDeleteElements(&packets_);
+ }
+
void SendDataPacket(QuicPacketSequenceNumber sequence_number) {
+ packets_.push_back(QuicPacket::NewDataPacket(
+ nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false,
+ PACKET_1BYTE_SEQUENCE_NUMBER));
SerializedPacket packet(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER,
- nullptr, 0, new RetransmittableFrames());
+ packets_.back(), 0, new RetransmittableFrames());
unacked_packets_.AddSentPacket(packet, 0, NOT_RETRANSMISSION, clock_.Now(),
1000, true);
}
@@ -43,6 +56,7 @@
}
}
+ vector<QuicPacket*> packets_;
QuicUnackedPacketMap unacked_packets_;
TimeLossAlgorithm loss_algorithm_;
RttStats rtt_stats_;
@@ -134,5 +148,6 @@
EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
}
+} // namespace
} // namespace test
} // namespace net
diff --git a/net/quic/crypto/common_cert_set.cc b/net/quic/crypto/common_cert_set.cc
index 09379f3..b2ea3a7 100644
--- a/net/quic/crypto/common_cert_set.cc
+++ b/net/quic/crypto/common_cert_set.cc
@@ -153,7 +153,7 @@
private:
CommonCertSetsQUIC() {}
- virtual ~CommonCertSetsQUIC() {}
+ ~CommonCertSetsQUIC() override {}
friend struct DefaultSingletonTraits<CommonCertSetsQUIC>;
DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC);
diff --git a/net/quic/crypto/crypto_handshake_message.cc b/net/quic/crypto/crypto_handshake_message.cc
index 9125968..23e8ea2 100644
--- a/net/quic/crypto/crypto_handshake_message.cc
+++ b/net/quic/crypto/crypto_handshake_message.cc
@@ -302,8 +302,9 @@
static_cast<int>(it->second.size()));
done = true;
break;
+ case kSNI:
case kUAID:
- ret += it->second;
+ ret += "\"" + it->second + "\"";
done = true;
break;
}
diff --git a/net/quic/crypto/crypto_protocol.h b/net/quic/crypto/crypto_protocol.h
index d010776..57a5508 100644
--- a/net/quic/crypto/crypto_protocol.h
+++ b/net/quic/crypto/crypto_protocol.h
@@ -71,6 +71,9 @@
// FEC options
const QuicTag kFHDR = TAG('F', 'H', 'D', 'R'); // FEC protect headers
+// Enable bandwidth resumption experiment.
+const QuicTag kBWRE = TAG('B', 'W', 'R', 'E'); // Bandwidth resumption.
+
// Proof types (i.e. certificate types)
// NOTE: although it would be silly to do so, specifying both kX509 and kX59R
// is allowed and is equivalent to specifying only kX509.
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index 274099c..97d6c3b 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -13,6 +13,7 @@
#include "base/values.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
+#include "net/base/network_activity_monitor.h"
#include "net/http/transport_security_state.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/crypto/quic_server_info.h"
@@ -633,6 +634,18 @@
"Net.QuicSession.TimedOutWithOpenStreams.ConsecutiveTLPCount",
connection()->sent_packet_manager().consecutive_tlp_count());
}
+ if (connection()->sent_packet_manager().HasUnackedPackets()) {
+ UMA_HISTOGRAM_TIMES(
+ "Net.QuicSession.LocallyTimedOutWithOpenStreams."
+ "TimeSinceLastReceived.UnackedPackets",
+ NetworkActivityMonitor::GetInstance()->GetTimeSinceLastReceived());
+ } else {
+ UMA_HISTOGRAM_TIMES(
+ "Net.QuicSession.LocallyTimedOutWithOpenStreams."
+ "TimeSinceLastReceived.NoUnackedPackets",
+ NetworkActivityMonitor::GetInstance()->GetTimeSinceLastReceived());
+ }
+
} else {
UMA_HISTOGRAM_COUNTS(
"Net.QuicSession.ConnectionClose.NumOpenStreams.HandshakeTimedOut",
diff --git a/net/quic/quic_client_session_test.cc b/net/quic/quic_client_session_test.cc
index 66583b8..88beca7 100644
--- a/net/quic/quic_client_session_test.cc
+++ b/net/quic/quic_client_session_test.cc
@@ -52,6 +52,8 @@
/*is_secure=*/false,
PRIVACY_MODE_DISABLED),
&crypto_config_, nullptr);
+ // Advance the time, because timers do not like uninitialized times.
+ connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
void TearDown() override { session_.CloseSessionOnError(ERR_ABORTED); }
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index fd9ec5f..62cbc64 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -282,6 +282,11 @@
max_undecryptable_packets_ = config.max_undecryptable_packets();
}
+void QuicConnection::ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) {
+ sent_packet_manager_.ResumeConnectionState(cached_network_params);
+}
+
void QuicConnection::SetNumOpenStreams(size_t num_streams) {
sent_packet_manager_.SetNumOpenStreams(num_streams);
}
@@ -911,10 +916,6 @@
} else {
// Send an ack much more quickly for crypto handshake packets.
QuicTime::Delta delayed_ack_time = sent_packet_manager_.DelayedAckTime();
- if (last_stream_frames_.size() == 1 &&
- last_stream_frames_[0].stream_id == kCryptoStreamId) {
- delayed_ack_time = QuicTime::Delta::Zero();
- }
ack_alarm_->Set(clock_->ApproximateNow().Add(delayed_ack_time));
DVLOG(1) << "Ack timer set; next packet or timer will trigger ACK.";
}
@@ -1449,6 +1450,13 @@
<< QuicUtils::StringToHexASCIIDump(
packet->serialized_packet.packet->AsStringPiece());
+ QuicTime packet_send_time = QuicTime::Zero();
+ if (FLAGS_quic_record_send_time_before_write) {
+ // Measure the RTT from before the write begins to avoid underestimating the
+ // min_rtt_, especially in cases where the thread blocks or gets swapped out
+ // during the WritePacket below.
+ packet_send_time = clock_->Now();
+ }
WriteResult result = writer_->WritePacket(encrypted->data(),
encrypted->length(),
self_address().address(),
@@ -1467,7 +1475,16 @@
return false;
}
}
- QuicTime now = clock_->Now();
+ if (!FLAGS_quic_record_send_time_before_write) {
+ packet_send_time = clock_->Now();
+ }
+ if (!packet_send_time.IsInitialized()) {
+ // TODO(jokulik): This is only needed because of the two code paths for
+ // initializing packet_send_time. Once "quic_record_send_time_before_write"
+ // is deprecated, this check can be removed.
+ LOG(DFATAL) << "The packet send time should never be zero. "
+ << "This is a programming bug, please report it.";
+ }
if (result.status != WRITE_STATUS_ERROR && debug_visitor_.get() != nullptr) {
// Pass the write result to the visitor.
debug_visitor_->OnPacketSent(packet->serialized_packet,
@@ -1475,14 +1492,17 @@
packet->encryption_level,
packet->transmission_type,
*encrypted,
- now);
+ packet_send_time);
}
if (packet->transmission_type == NOT_RETRANSMISSION) {
- time_of_last_sent_new_packet_ = now;
+ time_of_last_sent_new_packet_ = packet_send_time;
}
SetPingAlarm();
- DVLOG(1) << ENDPOINT << "time of last sent packet: "
- << now.ToDebuggingValue();
+ DVLOG(1) << ENDPOINT << "time "
+ << (FLAGS_quic_record_send_time_before_write ?
+ "we began writing " : "we finished writing ")
+ << "last sent packet: "
+ << packet_send_time.ToDebuggingValue();
// TODO(ianswett): Change the sequence number length and other packet creator
// options by a more explicit API than setting a struct value directly,
@@ -1494,7 +1514,7 @@
bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent(
&packet->serialized_packet,
packet->original_sequence_number,
- now,
+ packet_send_time,
encrypted->length(),
packet->transmission_type,
IsRetransmittable(*packet));
@@ -1585,6 +1605,12 @@
void QuicConnection::OnHandshakeComplete() {
sent_packet_manager_.SetHandshakeConfirmed();
+ // The client should immediately ack the SHLO to confirm the handshake is
+ // complete with the server.
+ if (!is_server_ && !ack_queued_) {
+ ack_alarm_->Cancel();
+ ack_alarm_->Set(clock_->ApproximateNow());
+ }
}
void QuicConnection::SendOrQueuePacket(QueuedPacket packet) {
@@ -1598,8 +1624,6 @@
sent_entropy_manager_.RecordPacketEntropyHash(
packet.serialized_packet.sequence_number,
packet.serialized_packet.entropy_hash);
- LOG_IF(DFATAL, !queued_packets_.empty() && !writer_->IsWriteBlocked())
- << "Packets should only be left queued if we're write blocked.";
if (!WritePacket(&packet)) {
queued_packets_.push_back(packet);
}
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 96f5cbc..abab048 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include "base/basictypes.h"
#include "base/logging.h"
#include "net/base/iovec.h"
#include "net/base/ip_endpoint.h"
@@ -258,6 +259,11 @@
// Sets connection parameters from the supplied |config|.
void SetFromConfig(const QuicConfig& config);
+ // Called by the Session when the client has provided CachedNetworkParameters.
+ // Virtual for tests.
+ virtual void ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params);
+
// Sets the number of active streams on the connection for congestion control.
void SetNumOpenStreams(size_t num_streams);
@@ -689,7 +695,7 @@
IPEndPoint self_address_;
IPEndPoint peer_address_;
// Used to store latest peer port to possibly migrate to later.
- int migrating_peer_port_;
+ uint16 migrating_peer_port_;
// True if the last packet has gotten far enough in the framer to be
// decrypted.
@@ -783,8 +789,8 @@
// This is used for timeouts, and does not indicate the packet was processed.
QuicTime time_of_last_received_packet_;
- // The last time a new (non-retransmitted) packet was sent for this
- // connection.
+ // The last time this connection began sending a new (non-retransmitted)
+ // packet.
QuicTime time_of_last_sent_new_packet_;
// Sequence number of the last sent packet. Packets are guaranteed to be sent
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 4e58dfd..ede61c8 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -67,7 +67,7 @@
}
bool GenerateCongestionFeedback(
- QuicCongestionFeedbackFrame* congestion_feedback) {
+ QuicCongestionFeedbackFrame* congestion_feedback) override {
if (feedback_ == nullptr) {
return false;
}
@@ -95,6 +95,7 @@
// QuicEncrypter interface.
bool SetKey(StringPiece key) override { return true; }
+
bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
bool Encrypt(StringPiece nonce,
@@ -149,6 +150,7 @@
// QuicDecrypter interface
bool SetKey(StringPiece key) override { return true; }
+
bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
bool Decrypt(StringPiece nonce,
@@ -258,7 +260,7 @@
class TestPacketWriter : public QuicPacketWriter {
public:
- explicit TestPacketWriter(QuicVersion version)
+ TestPacketWriter(QuicVersion version, MockClock *clock)
: version_(version),
framer_(SupportedVersions(version_)),
last_packet_size_(0),
@@ -268,7 +270,9 @@
final_bytes_of_last_packet_(0),
final_bytes_of_previous_packet_(0),
use_tagging_decrypter_(false),
- packets_write_attempts_(0) {
+ packets_write_attempts_(0),
+ clock_(clock),
+ write_pause_time_delta_(QuicTime::Delta::Zero()) {
}
// QuicPacketWriter interface
@@ -297,6 +301,10 @@
return WriteResult(WRITE_STATUS_BLOCKED, -1);
}
last_packet_size_ = packet.length();
+
+ if (!write_pause_time_delta_.IsZero()) {
+ clock_->AdvanceTime(write_pause_time_delta_);
+ }
return WriteResult(WRITE_STATUS_OK, last_packet_size_);
}
@@ -310,6 +318,11 @@
void BlockOnNextWrite() { block_on_next_write_ = true; }
+ // Sets the amount of time that the writer should before the actual write.
+ void SetWritePauseTimeDelta(QuicTime::Delta delta) {
+ write_pause_time_delta_ = delta;
+ }
+
const QuicPacketHeader& header() { return framer_.header(); }
size_t frame_count() const { return framer_.num_frames(); }
@@ -390,6 +403,10 @@
uint32 final_bytes_of_previous_packet_;
bool use_tagging_decrypter_;
uint32 packets_write_attempts_;
+ MockClock *clock_;
+ // If non-zero, the clock will pause during WritePacket for this amount of
+ // time.
+ QuicTime::Delta write_pause_time_delta_;
DISALLOW_COPY_AND_ASSIGN(TestPacketWriter);
};
@@ -597,7 +614,7 @@
MockPacketWriterFactory(QuicPacketWriter* writer) {
ON_CALL(*this, Create(_)).WillByDefault(Return(writer));
}
- virtual ~MockPacketWriterFactory() {}
+ ~MockPacketWriterFactory() override {}
MOCK_CONST_METHOD1(Create, QuicPacketWriter*(QuicConnection* connection));
};
@@ -611,7 +628,7 @@
send_algorithm_(new StrictMock<MockSendAlgorithm>),
loss_algorithm_(new MockLossAlgorithm()),
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
- writer_(new TestPacketWriter(version())),
+ writer_(new TestPacketWriter(version(), &clock_)),
factory_(writer_.get()),
connection_(connection_id_, IPEndPoint(), helper_.get(),
factory_, false, version()),
@@ -974,6 +991,10 @@
EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
}
+ void SetWritePauseTimeDelta(QuicTime::Delta delta) {
+ writer_->SetWritePauseTimeDelta(delta);
+ }
+
void CongestionBlockWrites() {
EXPECT_CALL(*send_algorithm_,
TimeUntilSend(_, _, _)).WillRepeatedly(
@@ -1548,6 +1569,74 @@
EXPECT_EQ(7u, least_unacked());
}
+// If FLAGS_quic_record_send_time_before_write is disabled, QuicConnection
+// should record the packet sen-tdime after the packet is sent.
+TEST_P(QuicConnectionTest, RecordSentTimeAfterPacketSent) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_record_send_time_before_write, false);
+ // We're using a MockClock for the tests, so we have complete control over the
+ // time.
+ // Our recorded timestamp for the last packet sent time will be passed in to
+ // the send_algorithm. Make sure that it is set to the correct value.
+ QuicTime actual_recorded_send_time = QuicTime::Zero();
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
+
+ // First send without any pause and check the result.
+ QuicTime expected_recorded_send_time = clock_.Now();
+ connection_.SendStreamDataWithString(1, "foo", 0, !kFin, nullptr);
+ EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+ << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+ << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+
+ // Now pause during the write, and check the results.
+ actual_recorded_send_time = QuicTime::Zero();
+ const QuicTime::Delta kWritePauseTimeDelta =
+ QuicTime::Delta::FromMilliseconds(5000);
+ SetWritePauseTimeDelta(kWritePauseTimeDelta);
+ expected_recorded_send_time = clock_.Now().Add(kWritePauseTimeDelta);
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
+ connection_.SendStreamDataWithString(2, "baz", 0, !kFin, nullptr);
+ EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+ << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+ << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+}
+
+// If FLAGS_quic_record_send_time_before_write is enabled, QuicConnection should
+// record the the packet sent-time prior to sending the packet.
+TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
+ ValueRestore<bool> old_flag(&FLAGS_quic_record_send_time_before_write, true);
+ // We're using a MockClock for the tests, so we have complete control over the
+ // time.
+ // Our recorded timestamp for the last packet sent time will be passed in to
+ // the send_algorithm. Make sure that it is set to the correct value.
+ QuicTime actual_recorded_send_time = QuicTime::Zero();
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
+
+ // First send without any pause and check the result.
+ QuicTime expected_recorded_send_time = clock_.Now();
+ connection_.SendStreamDataWithString(1, "foo", 0, !kFin, nullptr);
+ EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+ << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+ << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+
+ // Now pause during the write, and check the results.
+ actual_recorded_send_time = QuicTime::Zero();
+ const QuicTime::Delta kWritePauseTimeDelta =
+ QuicTime::Delta::FromMilliseconds(5000);
+ SetWritePauseTimeDelta(kWritePauseTimeDelta);
+ expected_recorded_send_time = clock_.Now();
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+ .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
+ connection_.SendStreamDataWithString(2, "baz", 0, !kFin, nullptr);
+ EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
+ << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
+ << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
+}
+
TEST_P(QuicConnectionTest, FECSending) {
// All packets carry version info till version is negotiated.
QuicPacketCreator* creator =
@@ -1565,7 +1654,8 @@
creator->set_max_packet_length(length);
// Send 4 protected data packets, which should also trigger 1 FEC packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(5);
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(5);
// The first stream frame will have 2 fewer overhead bytes than the other 3.
const string payload(payload_length * 4 + 2, 'a');
connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
@@ -1601,7 +1691,8 @@
&connection_)->IsFecEnabled());
// 1 Data and 1 FEC packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(2);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
const QuicTime::Delta retransmission_time =
@@ -1620,8 +1711,9 @@
EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
&connection_)->IsFecEnabled());
- // 1 Data and 1 FEC packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
+ // 3 Data and 3 FEC packets.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(6);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
// Send some more data afterwards to ensure early retransmit doesn't trigger.
connection_.SendStreamDataWithStringWithFec(3, "foo", 3, !kFin, nullptr);
@@ -1648,8 +1740,9 @@
EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
&connection_)->IsFecEnabled());
- // 1 Data and 1 FEC packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
+ // 3 Data and 3 FEC packet.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(6);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
// Send some more data afterwards to ensure early retransmit doesn't trigger.
connection_.SendStreamDataWithStringWithFec(3, "foo", 3, !kFin, nullptr);
@@ -3070,22 +3163,25 @@
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
}
-TEST_P(QuicConnectionTest, SendEarlyDelayedAckForCrypto) {
- QuicTime ack_time = clock_.ApproximateNow();
+TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
- // Process a packet from the crypto stream, which is frame1_'s default.
ProcessPacket(1);
- // Check if delayed ack timer is running for the expected interval.
+ // Check that ack is sent and that delayed ack alarm is set.
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ QuicTime ack_time = clock_.ApproximateNow().Add(DefaultDelayedAckTime());
+ EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
+
+ // Completing the handshake as the server does nothing.
+ QuicConnectionPeer::SetIsServer(&connection_, true);
+ connection_.OnHandshakeComplete();
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
- // Simulate delayed ack alarm firing.
- connection_.GetAckAlarm()->Fire();
- // Check that ack is sent and that delayed ack alarm is reset.
- EXPECT_EQ(2u, writer_->frame_count());
- EXPECT_FALSE(writer_->stop_waiting_frames().empty());
- EXPECT_FALSE(writer_->ack_frames().empty());
- EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+
+ // Complete the handshake as the client decreases the delayed ack time to 0ms.
+ QuicConnectionPeer::SetIsServer(&connection_, false);
+ connection_.OnHandshakeComplete();
+ EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+ EXPECT_EQ(clock_.ApproximateNow(), connection_.GetAckAlarm()->deadline());
}
TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
diff --git a/net/quic/quic_crypto_client_stream_test.cc b/net/quic/quic_crypto_client_stream_test.cc
index 1df2313..8e14d77 100644
--- a/net/quic/quic_crypto_client_stream_test.cc
+++ b/net/quic/quic_crypto_client_stream_test.cc
@@ -34,6 +34,8 @@
stream_(new QuicCryptoClientStream(server_id_, session_.get(), nullptr,
&crypto_config_)) {
session_->SetCryptoStream(stream_.get());
+ // Advance the time, because timers do not like uninitialized times.
+ connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
void CompleteCryptoHandshake() {
@@ -128,8 +130,8 @@
// Advance time 5 years to ensure that we pass the expiry time of the cached
// server config.
- reinterpret_cast<MockClock*>(const_cast<QuicClock*>(connection_->clock()))
- ->AdvanceTime(QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
+ connection_->AdvanceTime(
+ QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
// Check that a client hello was sent and that CryptoConnect doesn't fail
// with an error.
diff --git a/net/quic/quic_crypto_server_stream.cc b/net/quic/quic_crypto_server_stream.cc
index 1d62376..c4b5893 100644
--- a/net/quic/quic_crypto_server_stream.cc
+++ b/net/quic/quic_crypto_server_stream.cc
@@ -245,8 +245,8 @@
void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {
}
-CachedNetworkParameters*
-QuicCryptoServerStream::get_previous_cached_network_params() {
+const CachedNetworkParameters*
+QuicCryptoServerStream::previous_cached_network_params() const {
return previous_cached_network_params_.get();
}
diff --git a/net/quic/quic_crypto_server_stream.h b/net/quic/quic_crypto_server_stream.h
index 09d9bd8..f88affe 100644
--- a/net/quic/quic_crypto_server_stream.h
+++ b/net/quic/quic_crypto_server_stream.h
@@ -82,6 +82,8 @@
void set_previous_cached_network_params(
CachedNetworkParameters cached_network_params);
+ const CachedNetworkParameters* previous_cached_network_params() const;
+
protected:
virtual QuicErrorCode ProcessClientHello(
const CryptoHandshakeMessage& message,
@@ -93,8 +95,6 @@
// before going through the parameter negotiation step.
virtual void OverrideQuicConfigDefaults(QuicConfig* config);
- CachedNetworkParameters* get_previous_cached_network_params();
-
private:
friend class test::CryptoTestUtils;
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 47d58ce..e737933 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -54,3 +54,14 @@
// If true, QUIC connections will delay moving to forward security until the
// client starts sending foward secure encrypted packets.
bool FLAGS_enable_quic_delay_forward_security = true;
+
+// Do not flip this flag. jokulik plans more testing and additional monitoring
+// before the flag can go the auto-flip process.
+//
+// If true, record the timestamp for the last sent new packet before the call to
+// WritePacket, rather than after in QUIC.
+bool FLAGS_quic_record_send_time_before_write = false;
+
+// If true, enables the QUIC bandwidth resumption experiment (triggered by
+// Chrome/Finch).
+bool FLAGS_quic_enable_bandwidth_resumption_experiment = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index a75f79b..2ffe618 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -20,5 +20,8 @@
NET_EXPORT_PRIVATE extern bool FLAGS_allow_truncated_connection_ids_for_quic;
NET_EXPORT_PRIVATE extern bool FLAGS_quic_too_many_outstanding_packets;
NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_delay_forward_security;
+NET_EXPORT_PRIVATE extern bool FLAGS_quic_record_send_time_before_write;
+NET_EXPORT_PRIVATE
+extern bool FLAGS_quic_enable_bandwidth_resumption_experiment;
#endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/quic_packet_creator_test.cc b/net/quic/quic_packet_creator_test.cc
index 4e03e3a..578acea 100644
--- a/net/quic/quic_packet_creator_test.cc
+++ b/net/quic/quic_packet_creator_test.cc
@@ -87,8 +87,7 @@
server_framer_.set_visitor(&framer_visitor_);
}
- virtual ~QuicPacketCreatorTest() override {
- }
+ ~QuicPacketCreatorTest() override {}
void ProcessPacket(QuicPacket* packet) {
scoped_ptr<QuicEncryptedPacket> encrypted(
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc
index 3f2472c..ac99144 100644
--- a/net/quic/quic_packet_generator_test.cc
+++ b/net/quic/quic_packet_generator_test.cc
@@ -33,7 +33,7 @@
class MockDelegate : public QuicPacketGenerator::DelegateInterface {
public:
MockDelegate() {}
- virtual ~MockDelegate() override {}
+ ~MockDelegate() override {}
MOCK_METHOD3(ShouldGeneratePacket,
bool(TransmissionType transmission_type,
@@ -116,7 +116,7 @@
packet6_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr),
packet7_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr) {}
- virtual ~QuicPacketGeneratorTest() override {
+ ~QuicPacketGeneratorTest() override {
delete packet_.packet;
delete packet_.retransmittable_frames;
delete packet2_.packet;
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index 5aa831e..b631b07 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -704,7 +704,8 @@
transmission_type(NOT_RETRANSMISSION),
all_transmissions(nullptr),
in_flight(false),
- is_unackable(false) {}
+ is_unackable(false),
+ is_fec_packet(false) {}
TransmissionInfo::TransmissionInfo(
RetransmittableFrames* retransmittable_frames,
@@ -719,6 +720,7 @@
transmission_type(transmission_type),
all_transmissions(nullptr),
in_flight(false),
- is_unackable(false) {}
+ is_unackable(false),
+ is_fec_packet(false) {}
} // namespace net
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index 00064ff..4cd53a9 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -1099,6 +1099,8 @@
bool in_flight;
// True if the packet can never be acked, so it can be removed.
bool is_unackable;
+ // True if the packet is an FEC packet.
+ bool is_fec_packet;
};
} // namespace net
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index 7978fed..142871e 100644
--- a/net/quic/quic_sent_packet_manager.cc
+++ b/net/quic/quic_sent_packet_manager.cc
@@ -163,6 +163,11 @@
}
}
+void QuicSentPacketManager::ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params) {
+ send_algorithm_->ResumeConnectionState(cached_network_params);
+}
+
void QuicSentPacketManager::SetNumOpenStreams(size_t num_streams) {
if (n_connection_simulation_) {
// Ensure the number of connections is between 1 and 5.
@@ -323,6 +328,9 @@
(retransmission_type == ALL_UNACKED_RETRANSMISSION ||
frames->encryption_level() == ENCRYPTION_INITIAL)) {
MarkForRetransmission(sequence_number, retransmission_type);
+ } else if (it->is_fec_packet) {
+ // Remove FEC packets from the packet map, since we can't retransmit them.
+ unacked_packets_.RemoveFromInFlight(sequence_number);
}
}
}
@@ -549,12 +557,18 @@
}
// Only track packets as in flight that the send algorithm wants us to track.
+ // Since FEC packets should also be counted towards the congestion window,
+ // consider them as retransmittable for the purposes of congestion control.
+ HasRetransmittableData has_congestion_controlled_data =
+ serialized_packet->packet->is_fec_packet() ?
+ HAS_RETRANSMITTABLE_DATA : has_retransmittable_data;
const bool in_flight =
send_algorithm_->OnPacketSent(sent_time,
unacked_packets_.bytes_in_flight(),
sequence_number,
bytes,
- has_retransmittable_data);
+ has_congestion_controlled_data);
+
unacked_packets_.AddSentPacket(*serialized_packet,
original_sequence_number,
transmission_type,
diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h
index 2a3ea64..2a94e09 100644
--- a/net/quic/quic_sent_packet_manager.h
+++ b/net/quic/quic_sent_packet_manager.h
@@ -16,6 +16,7 @@
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/congestion_control/rtt_stats.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
+#include "net/quic/crypto/cached_network_parameters.h"
#include "net/quic/quic_ack_notifier_manager.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_sustained_bandwidth_recorder.h"
@@ -99,6 +100,10 @@
virtual void SetFromConfig(const QuicConfig& config);
+ // Pass the CachedNetworkParameters to the send algorithm.
+ void ResumeConnectionState(
+ const CachedNetworkParameters& cached_network_params);
+
void SetNumOpenStreams(size_t num_streams);
void SetHandshakeConfirmed() { handshake_confirmed_ = true; }
@@ -111,6 +116,13 @@
bool IsUnacked(QuicPacketSequenceNumber sequence_number) const;
// Requests retransmission of all unacked packets of |retransmission_type|.
+ // The behavior of this method depends on the value of |retransmission_type|:
+ // ALL_UNACKED_RETRANSMISSION - All unacked packets will be retransmitted.
+ // This can happen, for example, after a version negotiation packet has been
+ // received and all packets needs to be retransmitted with the new version.
+ // ALL_INITIAL_RETRANSMISSION - Only initially encrypted packets will be
+ // retransmitted. This can happen, for example, when a CHLO has been rejected
+ // and the previously encrypted data needs to be encrypted with a new key.
void RetransmitUnackedPackets(TransmissionType retransmission_type);
// Retransmits the oldest pending packet there is still a tail loss probe
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index d710120..c1e6f20 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -64,9 +64,7 @@
EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
}
- virtual ~QuicSentPacketManagerTest() override {
- STLDeleteElements(&packets_);
- }
+ ~QuicSentPacketManagerTest() override { STLDeleteElements(&packets_); }
QuicByteCount BytesInFlight() {
return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_);
@@ -216,7 +214,7 @@
void SendFecPacket(QuicPacketSequenceNumber sequence_number) {
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, BytesInFlight(), sequence_number,
- kDefaultLength, NO_RETRANSMITTABLE_DATA))
+ kDefaultLength, HAS_RETRANSMITTABLE_DATA))
.Times(1).WillOnce(Return(true));
SerializedPacket packet(CreateFecPacket(sequence_number));
manager_.OnPacketSent(&packet, 0, clock_.Now(),
diff --git a/net/quic/quic_server_session.cc b/net/quic/quic_server_session.cc
index 1d48182..e0defd6 100644
--- a/net/quic/quic_server_session.cc
+++ b/net/quic/quic_server_session.cc
@@ -37,14 +37,29 @@
void QuicServerSession::OnConfigNegotiated() {
QuicSession::OnConfigNegotiated();
- if (!FLAGS_enable_quic_fec ||
- !config()->HasReceivedConnectionOptions() ||
- !ContainsQuicTag(config()->ReceivedConnectionOptions(), kFHDR)) {
+
+ if (!config()->HasReceivedConnectionOptions()) {
return;
}
- // kFHDR config maps to FEC protection always for headers stream.
- // TODO(jri): Add crypto stream in addition to headers for kHDR.
- headers_stream_->set_fec_policy(FEC_PROTECT_ALWAYS);
+
+ // If the client has provided a bandwidth estimate from the same serving
+ // region, then pass it to the sent packet manager in preparation for possible
+ // bandwidth resumption.
+ const CachedNetworkParameters* cached_network_params =
+ crypto_stream_->previous_cached_network_params();
+ if (FLAGS_quic_enable_bandwidth_resumption_experiment &&
+ cached_network_params != nullptr &&
+ ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE) &&
+ cached_network_params->serving_region() == serving_region_) {
+ connection()->ResumeConnectionState(*cached_network_params);
+ }
+
+ if (FLAGS_enable_quic_fec &&
+ ContainsQuicTag(config()->ReceivedConnectionOptions(), kFHDR)) {
+ // kFHDR config maps to FEC protection always for headers stream.
+ // TODO(jri): Add crypto stream in addition to headers for kHDR.
+ headers_stream_->set_fec_policy(FEC_PROTECT_ALWAYS);
+ }
}
void QuicServerSession::OnConnectionClosed(QuicErrorCode error,
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index 2318ab4..e4b163f 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -48,8 +48,8 @@
session_->PostProcessAfterData();
}
- void OnWindowUpdateFrames(const vector<QuicWindowUpdateFrame>& frames)
- override {
+ void OnWindowUpdateFrames(
+ const vector<QuicWindowUpdateFrame>& frames) override {
session_->OnWindowUpdateFrames(frames);
session_->PostProcessAfterData();
}
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index d14d875..d953678 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -54,8 +54,7 @@
: QuicCryptoStream(session) {
}
- virtual void OnHandshakeMessage(
- const CryptoHandshakeMessage& message) override {
+ void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
encryption_established_ = true;
handshake_confirmed_ = true;
CryptoHandshakeMessage msg;
@@ -94,7 +93,7 @@
using ReliableQuicStream::CloseWriteSide;
- virtual uint32 ProcessData(const char* data, uint32 data_len) override {
+ uint32 ProcessData(const char* data, uint32 data_len) override {
return data_len;
}
@@ -131,17 +130,15 @@
InitializeSession();
}
- virtual TestCryptoStream* GetCryptoStream() override {
- return &crypto_stream_;
- }
+ TestCryptoStream* GetCryptoStream() override { return &crypto_stream_; }
- virtual TestStream* CreateOutgoingDataStream() override {
+ TestStream* CreateOutgoingDataStream() override {
TestStream* stream = new TestStream(GetNextStreamId(), this);
ActivateStream(stream);
return stream;
}
- virtual TestStream* CreateIncomingDataStream(QuicStreamId id) override {
+ TestStream* CreateIncomingDataStream(QuicStreamId id) override {
return new TestStream(id, this);
}
@@ -153,7 +150,7 @@
return QuicSession::GetIncomingDataStream(stream_id);
}
- virtual QuicConsumedData WritevData(
+ QuicConsumedData WritevData(
QuicStreamId id,
const IOVector& data,
QuicStreamOffset offset,
@@ -223,6 +220,7 @@
"Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
"EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
"JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
+ connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
void CheckClosedStreams() {
diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc
index 8c90c9f..43a105b 100644
--- a/net/quic/quic_stream_sequencer_test.cc
+++ b/net/quic/quic_stream_sequencer_test.cc
@@ -44,7 +44,7 @@
const string& details));
MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error));
MOCK_METHOD0(OnCanWrite, void());
- virtual QuicPriority EffectivePriority() const override {
+ QuicPriority EffectivePriority() const override {
return QuicUtils::HighestPriority();
}
virtual bool IsFlowControlEnabled() const {
diff --git a/net/quic/quic_time.h b/net/quic/quic_time.h
index 53e5ebe..62bf582 100644
--- a/net/quic/quic_time.h
+++ b/net/quic/quic_time.h
@@ -17,6 +17,8 @@
namespace net {
+static const int kNumSecondsPerMinute = 60;
+static const int kNumSecondsPerHour = kNumSecondsPerMinute * 60;
static const uint64 kNumMicrosPerSecond = base::Time::kMicrosecondsPerSecond;
static const uint64 kNumMicrosPerMilli =
base::Time::kMicrosecondsPerMillisecond;
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc
index 04eb1b8..bbff3c9 100644
--- a/net/quic/quic_unacked_packet_map.cc
+++ b/net/quic/quic_unacked_packet_map.cc
@@ -53,6 +53,9 @@
packet.sequence_number_length,
transmission_type,
sent_time);
+ DCHECK(packet.packet != nullptr);
+ info.is_fec_packet = packet.packet->is_fec_packet();
+
if (old_sequence_number == 0) {
if (packet.retransmittable_frames != nullptr &&
packet.retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) {
diff --git a/net/quic/quic_unacked_packet_map_test.cc b/net/quic/quic_unacked_packet_map_test.cc
index d31ce44..7840495 100644
--- a/net/quic/quic_unacked_packet_map_test.cc
+++ b/net/quic/quic_unacked_packet_map_test.cc
@@ -8,6 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using std::min;
+using std::vector;
namespace net {
namespace test {
@@ -23,16 +24,26 @@
: now_(QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1000))) {
}
+ ~QuicUnackedPacketMapTest() override {
+ STLDeleteElements(&packets_);
+ }
+
SerializedPacket CreateRetransmittablePacket(
QuicPacketSequenceNumber sequence_number) {
+ packets_.push_back(QuicPacket::NewDataPacket(
+ nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false,
+ PACKET_1BYTE_SEQUENCE_NUMBER));
return SerializedPacket(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER,
- nullptr, 0, new RetransmittableFrames());
+ packets_.back(), 0, new RetransmittableFrames());
}
SerializedPacket CreateNonRetransmittablePacket(
QuicPacketSequenceNumber sequence_number) {
+ packets_.push_back(QuicPacket::NewDataPacket(
+ nullptr, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false,
+ PACKET_1BYTE_SEQUENCE_NUMBER));
return SerializedPacket(sequence_number, PACKET_1BYTE_SEQUENCE_NUMBER,
- nullptr, 0, nullptr);
+ packets_.back(), 0, nullptr);
}
void VerifyInFlightPackets(QuicPacketSequenceNumber* packets,
@@ -94,7 +105,7 @@
<< " packets[" << i << "]:" << packets[i];
}
}
-
+ vector<QuicPacket*> packets_;
QuicUnackedPacketMap unacked_packets_;
QuicTime now_;
};
@@ -185,8 +196,8 @@
unacked_packets_.RemoveFromInFlight(2);
QuicPacketSequenceNumber unacked2[] = { 1 };
- VerifyUnackedPackets(unacked, arraysize(unacked2));
- VerifyInFlightPackets(unacked, arraysize(unacked2));
+ VerifyUnackedPackets(unacked2, arraysize(unacked2));
+ VerifyInFlightPackets(unacked2, arraysize(unacked2));
VerifyRetransmittablePackets(nullptr, 0);
unacked_packets_.RemoveFromInFlight(1);
diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc
index 814be7b..b24316f 100644
--- a/net/quic/test_tools/crypto_test_utils.cc
+++ b/net/quic/test_tools/crypto_test_utils.cc
@@ -214,6 +214,8 @@
QuicCryptoServerStream* server,
const FakeClientOptions& options) {
PacketSavingConnection* client_conn = new PacketSavingConnection(false);
+ // Advance the time, because timers do not like uninitialized times.
+ client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(1));
TestClientSession client_session(client_conn, DefaultQuicConfig());
QuicCryptoClientConfig crypto_config;
diff --git a/net/quic/test_tools/mock_quic_dispatcher.h b/net/quic/test_tools/mock_quic_dispatcher.h
index f923790..4945724 100644
--- a/net/quic/test_tools/mock_quic_dispatcher.h
+++ b/net/quic/test_tools/mock_quic_dispatcher.h
@@ -22,7 +22,7 @@
PacketWriterFactory* packet_writer_factory,
QuicConnectionHelperInterface* helper);
- virtual ~MockQuicDispatcher();
+ ~MockQuicDispatcher() override;
MOCK_METHOD3(ProcessPacket, void(const IPEndPoint& server_address,
const IPEndPoint& client_address,
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index fa987de..9df03eb 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
@@ -31,7 +32,7 @@
namespace test {
static const QuicConnectionId kTestConnectionId = 42;
-static const int kTestPort = 123;
+static const uint16 kTestPort = 123;
static const uint32 kInitialStreamFlowControlWindowForTest =
32 * 1024; // 32 KB
static const uint32 kInitialSessionFlowControlWindowForTest =
@@ -150,7 +151,7 @@
class MockFramerVisitor : public QuicFramerVisitorInterface {
public:
MockFramerVisitor();
- virtual ~MockFramerVisitor();
+ ~MockFramerVisitor() override;
MOCK_METHOD1(OnError, void(QuicFramer* framer));
// The constructor sets this up to return false by default.
@@ -225,7 +226,7 @@
class MockConnectionVisitor : public QuicConnectionVisitorInterface {
public:
MockConnectionVisitor();
- virtual ~MockConnectionVisitor();
+ ~MockConnectionVisitor() override;
MOCK_METHOD1(OnStreamFrames, void(const std::vector<QuicStreamFrame>& frame));
MOCK_METHOD1(OnWindowUpdateFrames,
@@ -293,7 +294,7 @@
// Uses a Mock helper, ConnectionId of 42, and 127.0.0.1:123.
MockConnection(bool is_server, const QuicVersionVector& supported_versions);
- virtual ~MockConnection();
+ ~MockConnection() override;
// If the constructor that uses a MockHelper has been used then this method
// will advance the time of the MockClock.
@@ -324,7 +325,7 @@
QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
}
- virtual bool OnProtocolVersionMismatch(QuicVersion version) override {
+ bool OnProtocolVersionMismatch(QuicVersion version) override {
return false;
}
@@ -355,7 +356,7 @@
class MockSession : public QuicSession {
public:
explicit MockSession(QuicConnection* connection);
- virtual ~MockSession();
+ ~MockSession() override;
MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
MOCK_METHOD0(GetCryptoStream, QuicCryptoStream*());
@@ -388,14 +389,14 @@
class TestSession : public QuicSession {
public:
TestSession(QuicConnection* connection, const QuicConfig& config);
- virtual ~TestSession();
+ ~TestSession() override;
MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
void SetCryptoStream(QuicCryptoStream* stream);
- virtual QuicCryptoStream* GetCryptoStream() override;
+ QuicCryptoStream* GetCryptoStream() override;
private:
QuicCryptoStream* crypto_stream_;
@@ -406,7 +407,7 @@
class TestClientSession : public QuicClientSessionBase {
public:
TestClientSession(QuicConnection* connection, const QuicConfig& config);
- virtual ~TestClientSession();
+ ~TestClientSession() override;
// QuicClientSessionBase
MOCK_METHOD1(OnProofValid,
@@ -420,7 +421,7 @@
void SetCryptoStream(QuicCryptoStream* stream);
- virtual QuicCryptoStream* GetCryptoStream() override;
+ QuicCryptoStream* GetCryptoStream() override;
private:
QuicCryptoStream* crypto_stream_;
@@ -431,7 +432,7 @@
class MockPacketWriter : public QuicPacketWriter {
public:
MockPacketWriter();
- virtual ~MockPacketWriter();
+ ~MockPacketWriter() override;
MOCK_METHOD4(WritePacket,
WriteResult(const char* buffer,
@@ -449,7 +450,7 @@
class MockSendAlgorithm : public SendAlgorithmInterface {
public:
MockSendAlgorithm();
- virtual ~MockSendAlgorithm();
+ ~MockSendAlgorithm() override;
MOCK_METHOD3(SetFromConfig, void(const QuicConfig& config,
bool is_server,
@@ -482,6 +483,7 @@
MOCK_CONST_METHOD0(InRecovery, bool());
MOCK_CONST_METHOD0(GetSlowStartThreshold, QuicByteCount());
MOCK_CONST_METHOD0(GetCongestionControlType, CongestionControlType());
+ MOCK_METHOD1(ResumeConnectionState, void(const CachedNetworkParameters&));
private:
DISALLOW_COPY_AND_ASSIGN(MockSendAlgorithm);
@@ -490,7 +492,7 @@
class MockLossAlgorithm : public LossDetectionInterface {
public:
MockLossAlgorithm();
- virtual ~MockLossAlgorithm();
+ ~MockLossAlgorithm() override;
MOCK_CONST_METHOD0(GetLossDetectionType, LossDetectionType());
MOCK_METHOD4(DetectLostPackets,
@@ -520,7 +522,7 @@
class MockEntropyCalculator : public TestEntropyCalculator {
public:
MockEntropyCalculator();
- virtual ~MockEntropyCalculator();
+ ~MockEntropyCalculator() override;
MOCK_CONST_METHOD1(
EntropyHash,
@@ -542,7 +544,7 @@
protected:
// Object is ref counted.
- virtual ~MockAckNotifierDelegate();
+ ~MockAckNotifierDelegate() override;
private:
DISALLOW_COPY_AND_ASSIGN(MockAckNotifierDelegate);
@@ -552,7 +554,7 @@
public QuicSentPacketManager::NetworkChangeVisitor {
public:
MockNetworkChangeVisitor();
- virtual ~MockNetworkChangeVisitor();
+ ~MockNetworkChangeVisitor() override;
MOCK_METHOD0(OnCongestionWindowChange, void());
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index b996127..bc7d111 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -91,9 +91,7 @@
bool using_ssl = request_url.SchemeIs("https") ||
request_url.SchemeIs("wss") || force_spdy_over_ssl;
- HostPortPair origin_host_port =
- HostPortPair(request_url.HostNoBrackets(),
- request_url.EffectiveIntPort());
+ HostPortPair origin_host_port = HostPortPair::FromURL(request_url);
if (!using_ssl && session->params().testing_fixed_http_port != 0) {
origin_host_port.set_port(session->params().testing_fixed_http_port);
diff --git a/net/socket/server_socket.cc b/net/socket/server_socket.cc
index da89b46..7cf6c64 100644
--- a/net/socket/server_socket.cc
+++ b/net/socket/server_socket.cc
@@ -17,7 +17,7 @@
}
int ServerSocket::ListenWithAddressAndPort(const std::string& address_string,
- int port,
+ uint16 port,
int backlog) {
IPAddressNumber address_number;
if (!ParseIPLiteralToNumber(address_string, &address_number)) {
diff --git a/net/socket/server_socket.h b/net/socket/server_socket.h
index 4b9ca8e..828b399 100644
--- a/net/socket/server_socket.h
+++ b/net/socket/server_socket.h
@@ -7,6 +7,7 @@
#include <string>
+#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -30,7 +31,7 @@
// Subclasses may override this function if |address_string| is in a different
// format, for example, unix domain socket path.
virtual int ListenWithAddressAndPort(const std::string& address_string,
- int port,
+ uint16 port,
int backlog);
// Gets current address the socket is bound to.
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 5ae4eee..308de2e 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -682,7 +682,7 @@
new MockUDPClientSocket(data_provider, net_log));
data_provider->set_socket(socket.get());
if (bind_type == DatagramSocket::RANDOM_BIND)
- socket->set_source_port(rand_int_cb.Run(1025, 65535));
+ socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535)));
return socket.Pass();
}
@@ -1917,7 +1917,7 @@
data_provider->set_delegate(socket->AsWeakPtr());
udp_client_sockets().push_back(socket.get());
if (bind_type == DatagramSocket::RANDOM_BIND)
- socket->set_source_port(rand_int_cb.Run(1025, 65535));
+ socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535)));
return socket.Pass();
}
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 7bccdae..7b45c0c 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -881,13 +881,13 @@
void OnReadComplete(const MockRead& data) override;
void OnConnectComplete(const MockConnect& data) override;
- void set_source_port(int port) { source_port_ = port; }
+ void set_source_port(uint16 port) { source_port_ = port; }
private:
bool connected_;
IPEndPoint peer_address_;
DeterministicSocketHelper helper_;
- int source_port_; // Ephemeral source port.
+ uint16 source_port_; // Ephemeral source port.
DISALLOW_COPY_AND_ASSIGN(DeterministicMockUDPClientSocket);
};
@@ -1051,7 +1051,7 @@
void OnReadComplete(const MockRead& data) override;
void OnConnectComplete(const MockConnect& data) override;
- void set_source_port(int port) { source_port_ = port;}
+ void set_source_port(uint16 port) { source_port_ = port;}
private:
int CompleteRead();
@@ -1064,7 +1064,7 @@
int read_offset_;
MockRead read_data_;
bool need_read_data_;
- int source_port_; // Ephemeral source port.
+ uint16 source_port_; // Ephemeral source port.
// Address of the "remote" peer we're connected to.
IPEndPoint peer_addr_;
diff --git a/net/socket/socks5_client_socket_unittest.cc b/net/socket/socks5_client_socket_unittest.cc
index c474a0b..5bcc146 100644
--- a/net/socket/socks5_client_socket_unittest.cc
+++ b/net/socket/socks5_client_socket_unittest.cc
@@ -258,7 +258,7 @@
const char partial1[] = { 0x05, 0x01 };
const char partial2[] = { 0x00 };
MockWrite data_writes[] = {
- MockWrite(ASYNC, arraysize(partial1)),
+ MockWrite(ASYNC, partial1, arraysize(partial1)),
MockWrite(ASYNC, partial2, arraysize(partial2)),
MockWrite(ASYNC, kOkRequest, arraysize(kOkRequest)) };
MockRead data_reads[] = {
diff --git a/net/socket/socks_client_socket_unittest.cc b/net/socket/socks_client_socket_unittest.cc
index fbb84f8..01bffe6 100644
--- a/net/socket/socks_client_socket_unittest.cc
+++ b/net/socket/socks_client_socket_unittest.cc
@@ -287,12 +287,12 @@
const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 };
MockWrite data_writes[] = {
- MockWrite(ASYNC, arraysize(kSOCKSPartialRequest1)),
+ MockWrite(ASYNC, kSOCKSPartialRequest1, arraysize(kSOCKSPartialRequest1)),
// simulate some empty writes
MockWrite(ASYNC, 0),
MockWrite(ASYNC, 0),
- MockWrite(ASYNC, kSOCKSPartialRequest2,
- arraysize(kSOCKSPartialRequest2)) };
+ MockWrite(ASYNC, kSOCKSPartialRequest2, arraysize(kSOCKSPartialRequest2)),
+ };
MockRead data_reads[] = {
MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply)) };
CapturingNetLog log;
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 57aa619..05eb1cb 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -17,6 +17,7 @@
#include "base/environment.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
+#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
#include "crypto/ec_private_key.h"
@@ -899,10 +900,20 @@
}
int SSLClientSocketOpenSSL::DoHandshake() {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed.
+ tracked_objects::ScopedTracker tracking_profile1(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "424386 SSLClientSocketOpenSSL::DoHandshake1"));
+
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
int net_error = OK;
int rv = SSL_do_handshake(ssl_);
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed.
+ tracked_objects::ScopedTracker tracking_profile2(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "424386 SSLClientSocketOpenSSL::DoHandshake2"));
+
if (client_auth_cert_needed_) {
net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
// If the handshake already succeeded (because the server requests but
@@ -1608,6 +1619,11 @@
}
int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "424386 SSLClientSocketOpenSSL::ClientCertRequestCallback"));
+
DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
DCHECK(ssl == ssl_);
@@ -1705,6 +1721,11 @@
}
int SSLClientSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "424386 SSLClientSocketOpenSSL::CertVerifyCallback"));
+
if (!completed_connect_) {
// If the first handshake hasn't completed then we accept any certificates
// because we verify after the handshake.
@@ -1739,6 +1760,11 @@
unsigned char* outlen,
const unsigned char* in,
unsigned int inlen) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "424386 SSLClientSocketOpenSSL::SelectNextProtoCallback"));
+
if (ssl_config_.next_protos.empty()) {
*out = reinterpret_cast<uint8*>(
const_cast<char*>(kDefaultSupportedNPNProtocol));
diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc
index 8ac29ef..23bb111 100644
--- a/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/net/socket/ssl_client_socket_pool_unittest.cc
@@ -239,8 +239,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
SSLClientSocketPoolTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
// Tests that the final socket will connect even if all sockets
// prior to it fail.
diff --git a/net/socket/tcp_listen_socket.cc b/net/socket/tcp_listen_socket.cc
index 585c412..11b2390 100644
--- a/net/socket/tcp_listen_socket.cc
+++ b/net/socket/tcp_listen_socket.cc
@@ -31,7 +31,9 @@
// static
scoped_ptr<TCPListenSocket> TCPListenSocket::CreateAndListen(
- const string& ip, int port, StreamListenSocket::Delegate* del) {
+ const string& ip,
+ uint16 port,
+ StreamListenSocket::Delegate* del) {
SocketDescriptor s = CreateAndBind(ip, port);
if (s == kInvalidSocket)
return scoped_ptr<TCPListenSocket>();
@@ -47,7 +49,7 @@
TCPListenSocket::~TCPListenSocket() {}
-SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip, int port) {
+SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip, uint16 port) {
SocketDescriptor s = CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s != kInvalidSocket) {
#if defined(OS_POSIX)
@@ -74,7 +76,7 @@
}
SocketDescriptor TCPListenSocket::CreateAndBindAnyPort(const string& ip,
- int* port) {
+ uint16* port) {
SocketDescriptor s = CreateAndBind(ip, 0);
if (s == kInvalidSocket)
return kInvalidSocket;
@@ -110,16 +112,4 @@
socket_delegate_->DidAccept(this, sock.Pass());
}
-TCPListenSocketFactory::TCPListenSocketFactory(const string& ip, int port)
- : ip_(ip),
- port_(port) {
-}
-
-TCPListenSocketFactory::~TCPListenSocketFactory() {}
-
-scoped_ptr<StreamListenSocket> TCPListenSocketFactory::CreateAndListen(
- StreamListenSocket::Delegate* delegate) const {
- return TCPListenSocket::CreateAndListen(ip_, port_, delegate);
-}
-
} // namespace net
diff --git a/net/socket/tcp_listen_socket.h b/net/socket/tcp_listen_socket.h
index 1702e50..01a08a1 100644
--- a/net/socket/tcp_listen_socket.h
+++ b/net/socket/tcp_listen_socket.h
@@ -21,14 +21,16 @@
// Listen on port for the specified IP address. Use 127.0.0.1 to only
// accept local connections.
static scoped_ptr<TCPListenSocket> CreateAndListen(
- const std::string& ip, int port, StreamListenSocket::Delegate* del);
+ const std::string& ip,
+ uint16 port,
+ StreamListenSocket::Delegate* del);
// Get raw TCP socket descriptor bound to ip:port.
- static SocketDescriptor CreateAndBind(const std::string& ip, int port);
+ static SocketDescriptor CreateAndBind(const std::string& ip, uint16 port);
// Get raw TCP socket descriptor bound to ip and return port it is bound to.
static SocketDescriptor CreateAndBindAnyPort(const std::string& ip,
- int* port);
+ uint16* port);
protected:
TCPListenSocket(SocketDescriptor s, StreamListenSocket::Delegate* del);
@@ -40,23 +42,6 @@
DISALLOW_COPY_AND_ASSIGN(TCPListenSocket);
};
-// Factory that can be used to instantiate TCPListenSocket.
-class NET_EXPORT TCPListenSocketFactory : public StreamListenSocketFactory {
- public:
- TCPListenSocketFactory(const std::string& ip, int port);
- ~TCPListenSocketFactory() override;
-
- // StreamListenSocketFactory overrides.
- scoped_ptr<StreamListenSocket> CreateAndListen(
- StreamListenSocket::Delegate* delegate) const override;
-
- private:
- const std::string ip_;
- const int port_;
-
- DISALLOW_COPY_AND_ASSIGN(TCPListenSocketFactory);
-};
-
} // namespace net
#endif // NET_SOCKET_TCP_LISTEN_SOCKET_H_
diff --git a/net/socket/tcp_server_socket_unittest.cc b/net/socket/tcp_server_socket_unittest.cc
index 01bae9f..2f6491b 100644
--- a/net/socket/tcp_server_socket_unittest.cc
+++ b/net/socket/tcp_server_socket_unittest.cc
@@ -50,7 +50,7 @@
*success = true;
}
- void ParseAddress(std::string ip_str, int port, IPEndPoint* address) {
+ void ParseAddress(std::string ip_str, uint16 port, IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
if (!rv)
diff --git a/net/socket/tcp_socket_unittest.cc b/net/socket/tcp_socket_unittest.cc
index 1981388..4bfc138 100644
--- a/net/socket/tcp_socket_unittest.cc
+++ b/net/socket/tcp_socket_unittest.cc
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
@@ -56,7 +57,9 @@
*success = true;
}
- void ParseAddress(const std::string& ip_str, int port, IPEndPoint* address) {
+ void ParseAddress(const std::string& ip_str,
+ uint16 port,
+ IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
if (!rv)
diff --git a/net/socket/transport_client_socket_unittest.cc b/net/socket/transport_client_socket_unittest.cc
index d01cbad..e4e060a 100644
--- a/net/socket/transport_client_socket_unittest.cc
+++ b/net/socket/transport_client_socket_unittest.cc
@@ -89,7 +89,7 @@
}
protected:
- int listen_port_;
+ uint16 listen_port_;
CapturingNetLog net_log_;
ClientSocketFactory* const socket_factory_;
scoped_ptr<StreamSocket> sock_;
@@ -105,10 +105,10 @@
// Find a free port to listen on
scoped_ptr<TCPListenSocket> sock;
- int port;
+ uint16 port;
// Range of ports to listen on. Shouldn't need to try many.
- const int kMinPort = 10100;
- const int kMaxPort = 10200;
+ const uint16 kMinPort = 10100;
+ const uint16 kMaxPort = 10200;
#if defined(OS_WIN)
EnsureWinsockInit();
#endif
diff --git a/net/socket/unix_domain_server_socket_posix.cc b/net/socket/unix_domain_server_socket_posix.cc
index 4d63283..6866d36 100644
--- a/net/socket/unix_domain_server_socket_posix.cc
+++ b/net/socket/unix_domain_server_socket_posix.cc
@@ -67,7 +67,7 @@
int UnixDomainServerSocket::ListenWithAddressAndPort(
const std::string& unix_domain_path,
- int port_unused,
+ uint16 port_unused,
int backlog) {
DCHECK(!listen_socket_);
diff --git a/net/socket/unix_domain_server_socket_posix.h b/net/socket/unix_domain_server_socket_posix.h
index 0a26eb3..1097548 100644
--- a/net/socket/unix_domain_server_socket_posix.h
+++ b/net/socket/unix_domain_server_socket_posix.h
@@ -53,7 +53,7 @@
// ServerSocket implementation.
int Listen(const IPEndPoint& address, int backlog) override;
int ListenWithAddressAndPort(const std::string& unix_domain_path,
- int port_unused,
+ uint16 port_unused,
int backlog) override;
int GetLocalAddress(IPEndPoint* address) const override;
int Accept(scoped_ptr<StreamSocket>* socket,
diff --git a/net/spdy/buffered_spdy_framer_unittest.cc b/net/spdy/buffered_spdy_framer_unittest.cc
index 11f8d08..5304f08 100644
--- a/net/spdy/buffered_spdy_framer_unittest.cc
+++ b/net/spdy/buffered_spdy_framer_unittest.cc
@@ -208,8 +208,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
BufferedSpdyFramerTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
TEST_P(BufferedSpdyFramerTest, OnSetting) {
SpdyFramer framer(spdy_version());
diff --git a/net/spdy/hpack_huffman_aggregator.cc b/net/spdy/hpack_huffman_aggregator.cc
index 41a3f48..8080a9b 100644
--- a/net/spdy/hpack_huffman_aggregator.cc
+++ b/net/spdy/hpack_huffman_aggregator.cc
@@ -49,10 +49,8 @@
if (IsCrossOrigin(request)) {
return;
}
- HostPortPair endpoint = HostPortPair(request.url.HostNoBrackets(),
- request.url.EffectiveIntPort());
- HpackEncoder* encoder = ObtainEncoder(
- SpdySessionKey(endpoint, proxy, request.privacy_mode));
+ HpackEncoder* encoder = ObtainEncoder(SpdySessionKey(
+ HostPortPair::FromURL(request.url), proxy, request.privacy_mode));
// Convert and encode the request and response header sets.
{
@@ -108,8 +106,6 @@
bool HpackHuffmanAggregator::IsCrossOrigin(const HttpRequestInfo& request) {
// Require that the request is top-level, or that it shares
// an origin with its referer.
- HostPortPair endpoint = HostPortPair(request.url.HostNoBrackets(),
- request.url.EffectiveIntPort());
if ((request.load_flags & LOAD_MAIN_FRAME) == 0) {
std::string referer_str;
if (!request.extra_headers.GetHeader(HttpRequestHeaders::kReferer,
@@ -118,9 +114,8 @@
return true;
}
GURL referer(referer_str);
- HostPortPair referer_endpoint = HostPortPair(referer.HostNoBrackets(),
- referer.EffectiveIntPort());
- if (!endpoint.Equals(referer_endpoint)) {
+ if (!HostPortPair::FromURL(request.url).Equals(
+ HostPortPair::FromURL(referer))) {
// Cross-origin request.
return true;
}
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index c08b597..f1b1de3 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -1991,7 +1991,8 @@
DCHECK(successful_read);
if (SpdyConstants::IsValidRstStreamStatus(protocol_version(),
status_raw)) {
- status = static_cast<SpdyRstStreamStatus>(status_raw);
+ status =
+ SpdyConstants::ParseRstStreamStatus(protocol_version(), status_raw);
} else {
if (protocol_version() > SPDY3) {
// Treat unrecognized status codes as INTERNAL_ERROR as
@@ -2484,7 +2485,8 @@
builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
}
- builder.WriteUInt32(rst_stream.status());
+ builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus(
+ protocol_version(), rst_stream.status()));
// In SPDY4 and up, RST_STREAM frames may also specify opaque data.
if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 2b7bc4b..2fac61c 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -2474,7 +2474,7 @@
0x00, 0x00, 0x04, 0x03,
0x00, 0x7f, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00,
- 0x06,
+ 0x02,
};
SpdyRstStreamIR rst_stream(0x7FFFFFFF,
RST_STREAM_INTERNAL_ERROR,
diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc
index 574b76a..f22b75f 100644
--- a/net/spdy/spdy_http_stream_unittest.cc
+++ b/net/spdy/spdy_http_stream_unittest.cc
@@ -130,8 +130,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
SpdyHttpStreamTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
// SpdyHttpStream::GetUploadProgress() should still work even before the
// stream is initialized.
@@ -700,9 +699,6 @@
// Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be
// made available is handled correctly.
TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) {
- if (GetParam() < kProtoSPDY3)
- return;
-
scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockWrite writes[] = {
diff --git a/net/spdy/spdy_http_utils.cc b/net/spdy/spdy_http_utils.cc
index b67e699..fc77f5d 100644
--- a/net/spdy/spdy_http_utils.cc
+++ b/net/spdy/spdy_http_utils.cc
@@ -170,42 +170,21 @@
SpdyMajorVersion protocol_version) {
DCHECK_GE(priority, MINIMUM_PRIORITY);
DCHECK_LE(priority, MAXIMUM_PRIORITY);
- if (protocol_version == SPDY2) {
- // SPDY 2 only has 2 bits of priority, but we have 5 RequestPriorities.
- // Map IDLE => 3, LOWEST => 2, LOW => 2, MEDIUM => 1, HIGHEST => 0.
- if (priority > LOWEST) {
- return static_cast<SpdyPriority>(HIGHEST - priority);
- } else {
- return static_cast<SpdyPriority>(HIGHEST - priority - 1);
- }
- } else {
- return static_cast<SpdyPriority>(HIGHEST - priority);
- }
+ return static_cast<SpdyPriority>(MAXIMUM_PRIORITY - priority);
}
NET_EXPORT_PRIVATE RequestPriority ConvertSpdyPriorityToRequestPriority(
SpdyPriority priority,
SpdyMajorVersion protocol_version) {
- // Handle invalid values gracefully, and pick LOW to map 2 back
- // to for SPDY/2.
- SpdyPriority idle_cutoff = (protocol_version == SPDY2) ? 3 : 5;
- return (priority >= idle_cutoff) ?
- IDLE : static_cast<RequestPriority>(HIGHEST - priority);
+ // Handle invalid values gracefully.
+ // Note that SpdyPriority is not an enum, hence the magic constants.
+ return (priority >= 5) ?
+ IDLE : static_cast<RequestPriority>(4 - priority);
}
GURL GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers,
SpdyMajorVersion protocol_version,
bool pushed) {
- // SPDY 2 server push urls are specified in a single "url" header.
- if (pushed && protocol_version == SPDY2) {
- std::string url;
- SpdyHeaderBlock::const_iterator it;
- it = headers.find("url");
- if (it != headers.end())
- url = it->second;
- return GURL(url);
- }
-
const char* scheme_header = protocol_version >= SPDY3 ? ":scheme" : "scheme";
const char* host_header = protocol_version >= SPDY4 ? ":authority" :
(protocol_version >= SPDY3 ? ":host" : "host");
diff --git a/net/spdy/spdy_http_utils_unittest.cc b/net/spdy/spdy_http_utils_unittest.cc
index d811164..b66534b 100644
--- a/net/spdy/spdy_http_utils_unittest.cc
+++ b/net/spdy/spdy_http_utils_unittest.cc
@@ -11,14 +11,6 @@
namespace {
-TEST(SpdyHttpUtilsTest, ConvertRequestPriorityToSpdy2Priority) {
- EXPECT_EQ(0, ConvertRequestPriorityToSpdyPriority(HIGHEST, SPDY2));
- EXPECT_EQ(1, ConvertRequestPriorityToSpdyPriority(MEDIUM, SPDY2));
- EXPECT_EQ(2, ConvertRequestPriorityToSpdyPriority(LOW, SPDY2));
- EXPECT_EQ(2, ConvertRequestPriorityToSpdyPriority(LOWEST, SPDY2));
- EXPECT_EQ(3, ConvertRequestPriorityToSpdyPriority(IDLE, SPDY2));
-}
-
TEST(SpdyHttpUtilsTest, ConvertRequestPriorityToSpdy3Priority) {
EXPECT_EQ(0, ConvertRequestPriorityToSpdyPriority(HIGHEST, SPDY3));
EXPECT_EQ(1, ConvertRequestPriorityToSpdyPriority(MEDIUM, SPDY3));
@@ -27,18 +19,6 @@
EXPECT_EQ(4, ConvertRequestPriorityToSpdyPriority(IDLE, SPDY3));
}
-TEST(SpdyHttpUtilsTest, ConvertSpdy2PriorityToRequestPriority) {
- EXPECT_EQ(HIGHEST, ConvertSpdyPriorityToRequestPriority(0, SPDY2));
- EXPECT_EQ(MEDIUM, ConvertSpdyPriorityToRequestPriority(1, SPDY2));
- EXPECT_EQ(LOW, ConvertSpdyPriorityToRequestPriority(2, SPDY2));
- EXPECT_EQ(IDLE, ConvertSpdyPriorityToRequestPriority(3, SPDY2));
- // These are invalid values, but we should still handle them
- // gracefully.
- for (int i = 4; i < kuint8max; ++i) {
- EXPECT_EQ(IDLE, ConvertSpdyPriorityToRequestPriority(i, SPDY2));
- }
-}
-
TEST(SpdyHttpUtilsTest, ConvertSpdy3PriorityToRequestPriority) {
EXPECT_EQ(HIGHEST, ConvertSpdyPriorityToRequestPriority(0, SPDY3));
EXPECT_EQ(MEDIUM, ConvertSpdyPriorityToRequestPriority(1, SPDY3));
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index edb39e9..3836fd3 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -58,7 +58,7 @@
struct SpdyNetworkTransactionTestParams {
SpdyNetworkTransactionTestParams()
- : protocol(kProtoSPDY3),
+ : protocol(kProtoSPDY31),
ssl_type(SPDYNPN) {}
SpdyNetworkTransactionTestParams(
@@ -717,12 +717,6 @@
Spdy,
SpdyNetworkTransactionTest,
::testing::Values(
- SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNOSSL),
- SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYSSL),
- SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNPN),
- SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNOSSL),
- SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYSSL),
- SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNPN),
SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNOSSL),
SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYSSL),
SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN),
@@ -5843,9 +5837,6 @@
// limitations as described above and it's not deterministic, tests may
// fail under specific circumstances.
TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
- if (GetParam().protocol < kProtoSPDY3)
- return;
-
static int kFrameCount = 2;
scoped_ptr<std::string> content(
new std::string(kMaxSpdyFrameChunkSize, 'a'));
@@ -5934,9 +5925,6 @@
// Test that received data frames and sent WINDOW_UPDATE frames change
// the recv_window_size_ correctly.
TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
- if (GetParam().protocol < kProtoSPDY3)
- return;
-
// Amount of body required to trigger a sent window update.
const size_t kTargetSize = kSpdyStreamInitialWindowSize / 2 + 1;
@@ -6016,9 +6004,6 @@
// Test that WINDOW_UPDATE frame causing overflow is handled correctly.
TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
- if (GetParam().protocol < kProtoSPDY3)
- return;
-
// Number of full frames we hope to write (but will not, used to
// set content-length header correctly)
static int kFrameCount = 3;
@@ -6098,9 +6083,6 @@
// After that, next read is artifically enforced, which causes a
// WINDOW_UPDATE to be read and I/O process resumes.
TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
- if (GetParam().protocol < kProtoSPDY3)
- return;
-
// Number of frames we need to send to zero out the window size: data
// frames plus SYN_STREAM plus the last data frame; also we need another
// data frame that we will send once the WINDOW_UPDATE is received,
@@ -6212,9 +6194,6 @@
// Test we correctly handle the case where the SETTINGS frame results in
// unstalling the send window.
TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
- if (GetParam().protocol < kProtoSPDY3)
- return;
-
// Number of frames we need to send to zero out the window size: data
// frames plus SYN_STREAM plus the last data frame; also we need another
// data frame that we will send once the SETTING is received, therefore +3.
@@ -6333,9 +6312,6 @@
// Test we correctly handle the case where the SETTINGS frame results in a
// negative send window size.
TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
- if (GetParam().protocol < kProtoSPDY3)
- return;
-
// Number of frames we need to send to zero out the window size: data
// frames plus SYN_STREAM plus the last data frame; also we need another
// data frame that we will send once the SETTING is received, therefore +3.
@@ -6390,10 +6366,7 @@
spdy_util_.ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize));
reads.push_back(CreateMockRead(*settings_frame_small, i++));
-
- if (GetParam().protocol >= kProtoSPDY3)
- reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
-
+ reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
reads.push_back(CreateMockRead(*window_update_init_size, i++));
scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
@@ -6557,10 +6530,7 @@
INSTANTIATE_TEST_CASE_P(
Spdy,
SpdyNetworkTransactionNoTLSUsageCheckTest,
- ::testing::Values(SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2,
- SPDYNPN),
- SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNPN),
- SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN)));
+ ::testing::Values(SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN)));
TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSVersionTooOld) {
scoped_ptr<SSLSocketDataProvider> ssl_provider(
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc
index ba5d867..a707ef4 100644
--- a/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -142,8 +142,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
SpdyProxyClientSocketTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
: spdy_util_(GetParam()),
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 08d838a..1c9abce 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -271,6 +271,14 @@
return dict;
}
+base::Value* NetLogSpdyAdoptedPushStreamCallback(
+ SpdyStreamId stream_id, const GURL* url, NetLog::LogLevel log_level) {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ dict->SetInteger("stream_id", stream_id);
+ dict->SetString("url", url->spec());
+ return 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]) {
@@ -1963,7 +1971,9 @@
return base::WeakPtr<SpdyStream>();
}
- net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM);
+ net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM,
+ base::Bind(&NetLogSpdyAdoptedPushStreamCallback,
+ active_it->second.stream->stream_id(), &url));
used_push_streams.Increment();
return active_it->second.stream->GetWeakPtr();
}
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index fc38cc2..9d5e48c 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -51,8 +51,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
SpdySessionPoolTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
// A delegate that opens a new session when it is closed.
class SessionOpeningDelegate : public SpdyStream::Delegate {
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 02e0c74..6ec3383 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -181,8 +181,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
SpdySessionTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
// Try to create a SPDY session that will fail during
// initialization. Nothing should blow up.
@@ -1798,10 +1797,6 @@
data.RunFor(1);
// Regression test of compression performance under the request fixture.
switch (spdy_util_.spdy_version()) {
- case SPDY2:
- histogram_tester.ExpectBucketCount(
- "Net.SpdySynStreamCompressionPercentage", 0, 1);
- break;
case SPDY3:
histogram_tester.ExpectBucketCount(
"Net.SpdySynStreamCompressionPercentage", 30, 1);
@@ -3084,22 +3079,12 @@
EXPECT_EQ(spdy_util_.spdy_version(),
session->buffered_spdy_framer_->protocol_version());
- if (GetParam() == kProtoDeprecatedSPDY2) {
- EXPECT_EQ(SpdySession::FLOW_CONTROL_NONE, session->flow_control_state());
- EXPECT_EQ(0, session->session_send_window_size_);
- EXPECT_EQ(0, session->session_recv_window_size_);
- } else if (GetParam() == kProtoSPDY3) {
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state());
- EXPECT_EQ(0, session->session_send_window_size_);
- EXPECT_EQ(0, session->session_recv_window_size_);
- } else {
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session->flow_control_state());
- EXPECT_EQ(kSpdySessionInitialWindowSize,
- session->session_send_window_size_);
- EXPECT_EQ(kSpdySessionInitialWindowSize,
- session->session_recv_window_size_);
- }
+ EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
+ session->flow_control_state());
+ EXPECT_EQ(kSpdySessionInitialWindowSize,
+ session->session_send_window_size_);
+ EXPECT_EQ(kSpdySessionInitialWindowSize,
+ session->session_recv_window_size_);
EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
}
@@ -3455,9 +3440,6 @@
// The tests below are only for SPDY/3 and above.
TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
- if (GetParam() < kProtoSPDY3)
- return;
-
// Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
// gets sent.
SettingsMap new_settings;
diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc
index 96153bf..e8915bb 100644
--- a/net/spdy/spdy_stream_unittest.cc
+++ b/net/spdy/spdy_stream_unittest.cc
@@ -110,8 +110,7 @@
INSTANTIATE_TEST_CASE_P(
NextProto,
SpdyStreamTest,
- testing::Values(kProtoDeprecatedSPDY2,
- kProtoSPDY3, kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
+ testing::Values(kProtoSPDY31, kProtoSPDY4_14, kProtoSPDY4_15));
TEST_P(SpdyStreamTest, SendDataAfterOpen) {
GURL url(kStreamUrl);
@@ -717,9 +716,6 @@
// to overflow an int32. The SpdyStream should handle that case
// gracefully.
TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
- if (spdy_util_.protocol() < kProtoSPDY3)
- return;
-
session_ =
SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_);
@@ -877,17 +873,11 @@
}
TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseRequestResponse) {
- if (spdy_util_.protocol() < kProtoSPDY3)
- return;
-
RunResumeAfterUnstallRequestResponseTest(
base::Bind(&IncreaseStreamSendWindowSize));
}
TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustRequestResponse) {
- if (spdy_util_.protocol() < kProtoSPDY3)
- return;
-
RunResumeAfterUnstallRequestResponseTest(
base::Bind(&AdjustStreamSendWindowSize));
}
@@ -972,17 +962,11 @@
}
TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeIncreaseBidirectional) {
- if (spdy_util_.protocol() < kProtoSPDY3)
- return;
-
RunResumeAfterUnstallBidirectionalTest(
base::Bind(&IncreaseStreamSendWindowSize));
}
TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) {
- if (spdy_util_.protocol() < kProtoSPDY3)
- return;
-
RunResumeAfterUnstallBidirectionalTest(
base::Bind(&AdjustStreamSendWindowSize));
}
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 801d67d..9543e64 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -54,8 +54,6 @@
NextProtoVector SpdyNextProtos() {
NextProtoVector next_protos;
next_protos.push_back(kProtoHTTP11);
- next_protos.push_back(kProtoDeprecatedSPDY2);
- next_protos.push_back(kProtoSPDY3);
next_protos.push_back(kProtoSPDY31);
next_protos.push_back(kProtoSPDY4_14);
next_protos.push_back(kProtoSPDY4_15);
@@ -720,15 +718,11 @@
void SpdyTestUtil::AddUrlToHeaderBlock(base::StringPiece url,
SpdyHeaderBlock* headers) const {
- if (is_spdy2()) {
- (*headers)["url"] = url.as_string();
- } else {
- std::string scheme, host, path;
- ParseUrl(url, &scheme, &host, &path);
- (*headers)[GetSchemeKey()] = scheme;
- (*headers)[GetHostKey()] = host;
- (*headers)[GetPathKey()] = path;
- }
+ std::string scheme, host, path;
+ ParseUrl(url, &scheme, &host, &path);
+ (*headers)[GetSchemeKey()] = scheme;
+ (*headers)[GetHostKey()] = host;
+ (*headers)[GetPathKey()] = path;
}
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlock(
@@ -739,8 +733,6 @@
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlockForProxy(
base::StringPiece url) const {
scoped_ptr<SpdyHeaderBlock> headers(ConstructGetHeaderBlock(url));
- if (is_spdy2())
- (*headers)[GetPathKey()] = url.data();
return headers.Pass();
}
@@ -963,8 +955,7 @@
bool direct) const {
SpdyHeaderBlock block;
block[GetMethodKey()] = "GET";
- block[GetPathKey()] =
- (is_spdy2() && !direct) ? "http://www.google.com/" : "/";
+ block[GetPathKey()] = "/";
block[GetHostKey()] = "www.google.com";
block[GetSchemeKey()] = "http";
MaybeAddVersionHeader(&block);
@@ -1259,16 +1250,14 @@
}
const char* SpdyTestUtil::GetMethodKey() const {
- return is_spdy2() ? "method" : ":method";
+ return ":method";
}
const char* SpdyTestUtil::GetStatusKey() const {
- return is_spdy2() ? "status" : ":status";
+ return ":status";
}
const char* SpdyTestUtil::GetHostKey() const {
- if (protocol_ < kProtoSPDY3)
- return "host";
if (protocol_ < kProtoSPDY4MinimumVersion)
return ":host";
else
@@ -1276,15 +1265,15 @@
}
const char* SpdyTestUtil::GetSchemeKey() const {
- return is_spdy2() ? "scheme" : ":scheme";
+ return ":scheme";
}
const char* SpdyTestUtil::GetVersionKey() const {
- return is_spdy2() ? "version" : ":version";
+ return ":version";
}
const char* SpdyTestUtil::GetPathKey() const {
- return is_spdy2() ? "url" : ":path";
+ return ":path";
}
scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock(
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index b08657c..0ee59d4 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -551,7 +551,6 @@
NextProto protocol() const { return protocol_; }
SpdyMajorVersion spdy_version() const { return spdy_version_; }
- bool is_spdy2() const { return protocol_ < kProtoSPDY3; }
bool include_version_header() const {
return protocol_ < kProtoSPDY4MinimumVersion;
}
diff --git a/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java b/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
index 66a9bd9..6121a2a 100644
--- a/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
+++ b/net/test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java
@@ -86,8 +86,8 @@
mIsRedirect = isRedirect;
mIsNotFound = isNotFound;
mResponseData = responseData;
- mResponseHeaders = responseHeaders == null ?
- new ArrayList<Pair<String, String>>() : responseHeaders;
+ mResponseHeaders = responseHeaders == null
+ ? new ArrayList<Pair<String, String>>() : responseHeaders;
mResponseAction = responseAction;
}
}
@@ -534,30 +534,30 @@
* single self-generated key. The subject name is "Test Server".
*/
private static final String SERVER_KEYS_BKS =
- "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41" +
- "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" +
- "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" +
- "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw" +
- "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" +
- "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl" +
- "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy" +
- "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV" +
- "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG" +
- "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU" +
- "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV" +
- "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx" +
- "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR" +
- "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN" +
- "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs" +
- "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck" +
- "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM" +
- "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI" +
- "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f" +
- "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx" +
- "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt" +
- "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw" +
- "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl" +
- "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
+ "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41"
+ + "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET"
+ + "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV"
+ + "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw"
+ + "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U"
+ + "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl"
+ + "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy"
+ + "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV"
+ + "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG"
+ + "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU"
+ + "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV"
+ + "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx"
+ + "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR"
+ + "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN"
+ + "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs"
+ + "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck"
+ + "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM"
+ + "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI"
+ + "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f"
+ + "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx"
+ + "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt"
+ + "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw"
+ + "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl"
+ + "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
private static final String PASSWORD = "android";
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc
index 7ac764f..97b5d84 100644
--- a/net/test/embedded_test_server/embedded_test_server.cc
+++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -115,7 +115,7 @@
}
EmbeddedTestServer::EmbeddedTestServer()
- : port_(-1),
+ : port_(0),
weak_factory_(this) {
DCHECK(thread_checker_.CalledOnValidThread());
}
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h
index 24ff8d7..586e1f4 100644
--- a/net/test/embedded_test_server/embedded_test_server.h
+++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -136,7 +136,7 @@
const std::string& relative_url) const;
// Returns the port number used by the server.
- int port() const { return port_; }
+ uint16 port() const { return port_; }
// Registers request handler which serves files from |directory|.
// For instance, a request to "/foo.html" is served by "foo.html" under
@@ -188,7 +188,7 @@
scoped_ptr<base::Thread> io_thread_;
scoped_ptr<HttpListenSocket> listen_socket_;
- int port_;
+ uint16 port_;
GURL base_url_;
// Owns the HttpConnection objects.
diff --git a/net/test/embedded_test_server/embedded_test_server_unittest.cc b/net/test/embedded_test_server/embedded_test_server_unittest.cc
index 28d909e..efa4b0c 100644
--- a/net/test/embedded_test_server/embedded_test_server_unittest.cc
+++ b/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -112,12 +112,12 @@
};
TEST_F(EmbeddedTestServerTest, GetBaseURL) {
- EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%d/", server_->port()),
+ EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/", server_->port()),
server_->base_url().spec());
}
TEST_F(EmbeddedTestServerTest, GetURL) {
- EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%d/path?query=foo",
+ EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/path?query=foo",
server_->port()),
server_->GetURL("/path?query=foo").spec());
}
diff --git a/net/tools/dump_cache/cache_dumper.cc b/net/tools/dump_cache/cache_dumper.cc
index 0ce46a9..99e3dcd 100644
--- a/net/tools/dump_cache/cache_dumper.cc
+++ b/net/tools/dump_cache/cache_dumper.cc
@@ -45,7 +45,6 @@
#ifdef WIN32_LARGE_FILENAME_SUPPORT
// Due to large paths on windows, it can't simply do a
// CreateDirectory("a/b/c"). Instead, create each subdirectory manually.
- bool rv = false;
std::wstring::size_type pos(0);
std::wstring backslash(L"\\");
diff --git a/net/tools/flip_server/spdy_interface_test.cc b/net/tools/flip_server/spdy_interface_test.cc
index 09909e2..d845438 100644
--- a/net/tools/flip_server/spdy_interface_test.cc
+++ b/net/tools/flip_server/spdy_interface_test.cc
@@ -206,8 +206,8 @@
INSTANTIATE_TEST_CASE_P(SpdySMProxyTest,
SpdySMProxyTest,
- Values(SPDY2, SPDY3, SPDY4));
-INSTANTIATE_TEST_CASE_P(SpdySMServerTest, SpdySMServerTest, Values(SPDY2));
+ Values(SPDY3, SPDY4));
+INSTANTIATE_TEST_CASE_P(SpdySMServerTest, SpdySMServerTest, Values(SPDY4));
TEST_P(SpdySMProxyTest, InitSMConnection) {
{
@@ -218,113 +218,7 @@
NULL, NULL, epoll_server_.get(), -1, "", "", "", false);
}
-TEST_P(SpdySMProxyTest, OnSynStream_SPDY2) {
- if (GetParam() != SPDY2) {
- // This test case is for SPDY2.
- return;
- }
- BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
- scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
- uint32 stream_id = 92;
- uint32 associated_id = 43;
- std::string expected = "GET /path HTTP/1.0\r\n"
- "Host: 127.0.0.1\r\n"
- "hoge: fuga\r\n\r\n";
- SpdyHeaderBlock block;
- block["method"] = "GET";
- block["url"] = "/path";
- block["scheme"] = "http";
- block["version"] = "HTTP/1.0";
- block["hoge"] = "fuga";
- StringSaver saver;
- {
- InSequence s;
- EXPECT_CALL(*interface_, FindOrMakeNewSMConnectionInterface(_, _))
- .WillOnce(Return(mock_interface.get()));
- EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
- EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _))
- .WillOnce(DoAll(SaveArg<0>(&saver.data),
- SaveArg<1>(&saver.size),
- InvokeWithoutArgs(&saver, &StringSaver::Save),
- Return(0)));
- }
- visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
- ASSERT_EQ(expected, saver.string);
-}
-
-TEST_P(SpdySMProxyTest, OnSynStream) {
- if (GetParam() == SPDY2) {
- // This test case is not for SPDY2.
- return;
- }
- BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
- scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
- uint32 stream_id = 92;
- uint32 associated_id = 43;
- std::string expected = "GET /path HTTP/1.1\r\n"
- "Host: 127.0.0.1\r\n"
- "foo: bar\r\n\r\n";
- SpdyHeaderBlock block;
- block[":method"] = "GET";
- block[":host"] = "www.example.com";
- block[":path"] = "/path";
- block[":scheme"] = "http";
- block["foo"] = "bar";
- StringSaver saver;
- {
- InSequence s;
- EXPECT_CALL(*interface_,
- FindOrMakeNewSMConnectionInterface(_, _))
- .WillOnce(Return(mock_interface.get()));
- EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
- EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _))
- .WillOnce(DoAll(SaveArg<0>(&saver.data),
- SaveArg<1>(&saver.size),
- InvokeWithoutArgs(&saver, &StringSaver::Save),
- Return(0)));
- }
- visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
- ASSERT_EQ(expected, saver.string);
-}
-
-TEST_P(SpdySMProxyTest, OnStreamFrameData_SPDY2) {
- if (GetParam() != SPDY2) {
- // This test case is for SPDY2.
- return;
- }
- BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
- scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
- uint32 stream_id = 92;
- uint32 associated_id = 43;
- SpdyHeaderBlock block;
- testing::MockFunction<void(int)> checkpoint; // NOLINT
-
- scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12, false));
- block["method"] = "GET";
- block["url"] = "http://www.example.com/path";
- block["scheme"] = "http";
- block["version"] = "HTTP/1.0";
- {
- InSequence s;
- EXPECT_CALL(*interface_, FindOrMakeNewSMConnectionInterface(_, _))
- .WillOnce(Return(mock_interface.get()));
- EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
- EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _)).Times(1);
- EXPECT_CALL(checkpoint, Call(0));
- EXPECT_CALL(*mock_interface,
- ProcessWriteInput(frame->data(), frame->size())).Times(1);
- }
-
- visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
- checkpoint.Call(0);
- visitor->OnStreamFrameData(stream_id, frame->data(), frame->size(), true);
-}
-
TEST_P(SpdySMProxyTest, OnStreamFrameData) {
- if (GetParam() == SPDY2) {
- // This test case is not for SPDY2.
- return;
- }
BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
uint32 stream_id = 92;
@@ -407,14 +301,14 @@
TEST_P(SpdySMProxyTest, CreateFramer) {
interface_->ResetForNewConnection();
- interface_->CreateFramer(SPDY2);
- ASSERT_TRUE(interface_->spdy_framer() != NULL);
- ASSERT_EQ(interface_->spdy_version(), SPDY2);
-
- interface_->ResetForNewConnection();
interface_->CreateFramer(SPDY3);
ASSERT_TRUE(interface_->spdy_framer() != NULL);
ASSERT_EQ(interface_->spdy_version(), SPDY3);
+
+ interface_->ResetForNewConnection();
+ interface_->CreateFramer(SPDY4);
+ ASSERT_TRUE(interface_->spdy_framer() != NULL);
+ ASSERT_EQ(interface_->spdy_version(), SPDY4);
}
TEST_P(SpdySMProxyTest, PostAcceptHook) {
@@ -455,61 +349,7 @@
ASSERT_TRUE(HasStream(stream_id));
}
-TEST_P(SpdySMProxyTest, SendErrorNotFound_SPDY2) {
- if (GetParam() != SPDY2) {
- // This test is for SPDY2.
- return;
- }
- uint32 stream_id = 82;
- SpdyHeaderBlock actual_header_block;
- const char* actual_data;
- size_t actual_size;
- testing::MockFunction<void(int)> checkpoint; // NOLINT
-
- interface_->SendErrorNotFound(stream_id);
-
- ASSERT_EQ(2u, connection_->output_list()->size());
-
- {
- InSequence s;
- if (GetParam() < SPDY4) {
- EXPECT_CALL(*spdy_framer_visitor_, OnSynReply(stream_id, false, _))
- .WillOnce(SaveArg<2>(&actual_header_block));
- } else {
- EXPECT_CALL(*spdy_framer_visitor_,
- OnHeaders(stream_id, false, 0, false, _))
- .WillOnce(SaveArg<4>(&actual_header_block));
- }
- EXPECT_CALL(checkpoint, Call(0));
- EXPECT_CALL(*spdy_framer_visitor_,
- OnDataFrameHeader(stream_id, _, true));
- EXPECT_CALL(*spdy_framer_visitor_,
- OnStreamFrameData(stream_id, _, _, false)).Times(1)
- .WillOnce(DoAll(SaveArg<1>(&actual_data),
- SaveArg<2>(&actual_size)));
- EXPECT_CALL(*spdy_framer_visitor_,
- OnStreamFrameData(stream_id, NULL, 0, true)).Times(1);
- }
-
- std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
- DataFrame* df = *i++;
- spdy_framer_->ProcessInput(df->data, df->size);
- checkpoint.Call(0);
- df = *i++;
- spdy_framer_->ProcessInput(df->data, df->size);
-
- ASSERT_EQ(2, spdy_framer_->frames_received());
- ASSERT_EQ(2u, actual_header_block.size());
- ASSERT_EQ("404 Not Found", actual_header_block["status"]);
- ASSERT_EQ("HTTP/1.1", actual_header_block["version"]);
- ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
-}
-
TEST_P(SpdySMProxyTest, SendErrorNotFound) {
- if (GetParam() == SPDY2) {
- // This test is not for SPDY2.
- return;
- }
uint32 stream_id = 82;
SpdyHeaderBlock actual_header_block;
const char* actual_data;
@@ -556,44 +396,7 @@
ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
}
-TEST_P(SpdySMProxyTest, SendSynStream_SPDY2) {
- if (GetParam() != SPDY2) {
- // This test is for SPDY2.
- return;
- }
- uint32 stream_id = 82;
- BalsaHeaders headers;
- SpdyHeaderBlock actual_header_block;
- headers.AppendHeader("key1", "value1");
- headers.SetRequestFirstlineFromStringPieces("GET", "/path", "HTTP/1.0");
-
- interface_->SendSynStream(stream_id, headers);
-
- ASSERT_EQ(1u, connection_->output_list()->size());
- std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
- DataFrame* df = *i++;
-
- {
- InSequence s;
- EXPECT_CALL(*spdy_framer_visitor_,
- OnSynStream(stream_id, 0, _, false, false, _))
- .WillOnce(SaveArg<5>(&actual_header_block));
- }
-
- spdy_framer_->ProcessInput(df->data, df->size);
- ASSERT_EQ(1, spdy_framer_->frames_received());
- ASSERT_EQ(4u, actual_header_block.size());
- ASSERT_EQ("GET", actual_header_block["method"]);
- ASSERT_EQ("HTTP/1.0", actual_header_block["version"]);
- ASSERT_EQ("/path", actual_header_block["url"]);
- ASSERT_EQ("value1", actual_header_block["key1"]);
-}
-
TEST_P(SpdySMProxyTest, SendSynStream) {
- if (GetParam() == SPDY2) {
- // This test is not for SPDY2.
- return;
- }
uint32 stream_id = 82;
BalsaHeaders headers;
SpdyHeaderBlock actual_header_block;
@@ -624,48 +427,7 @@
ASSERT_EQ("value1", actual_header_block["key1"]);
}
-TEST_P(SpdySMProxyTest, SendSynReply_SPDY2) {
- if (GetParam() != SPDY2) {
- // This test is for SPDY2.
- return;
- }
- uint32 stream_id = 82;
- BalsaHeaders headers;
- SpdyHeaderBlock actual_header_block;
- headers.AppendHeader("key1", "value1");
- headers.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "OK");
-
- interface_->SendSynReply(stream_id, headers);
-
- ASSERT_EQ(1u, connection_->output_list()->size());
- std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
- DataFrame* df = *i++;
-
- {
- InSequence s;
- if (GetParam() < SPDY4) {
- EXPECT_CALL(*spdy_framer_visitor_, OnSynReply(stream_id, false, _))
- .WillOnce(SaveArg<2>(&actual_header_block));
- } else {
- EXPECT_CALL(*spdy_framer_visitor_,
- OnHeaders(stream_id, false, 0, false, _))
- .WillOnce(SaveArg<4>(&actual_header_block));
- }
- }
-
- spdy_framer_->ProcessInput(df->data, df->size);
- ASSERT_EQ(1, spdy_framer_->frames_received());
- ASSERT_EQ(3u, actual_header_block.size());
- ASSERT_EQ("200 OK", actual_header_block["status"]);
- ASSERT_EQ("HTTP/1.1", actual_header_block["version"]);
- ASSERT_EQ("value1", actual_header_block["key1"]);
-}
-
TEST_P(SpdySMProxyTest, SendSynReply) {
- if (GetParam() == SPDY2) {
- // This test is not for SPDY2.
- return;
- }
uint32 stream_id = 82;
BalsaHeaders headers;
SpdyHeaderBlock actual_header_block;
@@ -763,58 +525,6 @@
ASSERT_EQ("c", StringPiece(actual_data, actual_size));
}
-TEST_P(SpdySMProxyTest, SendEOF_SPDY2) {
- // This test is for SPDY2.
- if (GetParam() != SPDY2) {
- return;
- }
-
- uint32 stream_id = 82;
- // SPDY2 data frame
- char empty_data_frame[] = {'\0', '\0', '\0', '\x52', '\x1', '\0', '\0', '\0'};
- MemCacheIter mci;
- mci.stream_id = stream_id;
-
- {
- BalsaHeaders headers;
- std::string filename = "foobar";
- memory_cache_->InsertFile(&headers, filename, "");
- mci.file_data = memory_cache_->GetFileData(filename);
- }
-
- interface_->AddToOutputOrder(mci);
- ASSERT_TRUE(HasStream(stream_id));
- interface_->SendEOF(stream_id);
- ASSERT_FALSE(HasStream(stream_id));
-
- ASSERT_EQ(1u, connection_->output_list()->size());
- std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
- DataFrame* df = *i++;
- ASSERT_EQ(StringPiece(empty_data_frame, sizeof(empty_data_frame)),
- StringPiece(df->data, df->size));
-}
-
-TEST_P(SpdySMProxyTest, SendEmptyDataFrame_SPDY2) {
- // This test is for SPDY2.
- if (GetParam() != SPDY2) {
- return;
- }
-
- uint32 stream_id = 133;
- SpdyDataFlags flags = DATA_FLAG_NONE;
- // SPDY2 data frame
- char expected[] = {'\0', '\0', '\0', '\x85', '\0', '\0', '\0', '\0'};
-
- interface_->SendDataFrame(stream_id, "hello", 0, flags, true);
-
- ASSERT_EQ(1u, connection_->output_list()->size());
- std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
- DataFrame* df = *i++;
-
- ASSERT_EQ(StringPiece(expected, sizeof(expected)),
- StringPiece(df->data, df->size));
-}
-
TEST_P(SpdySMServerTest, OnSynStream) {
BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
uint32 stream_id = 82;
diff --git a/net/tools/gdig/gdig.cc b/net/tools/gdig/gdig.cc
index 179ab78..0f8c1fe 100644
--- a/net/tools/gdig/gdig.cc
+++ b/net/tools/gdig/gdig.cc
@@ -6,6 +6,7 @@
#include <string>
#include "base/at_exit.h"
+#include "base/basictypes.h"
#include "base/bind.h"
#include "base/cancelable_callback.h"
#include "base/command_line.h"
@@ -53,7 +54,7 @@
if (!net::ParseIPLiteralToNumber(ip, &ip_number))
return false;
- *ip_end_point = net::IPEndPoint(ip_number, port);
+ *ip_end_point = net::IPEndPoint(ip_number, static_cast<uint16>(port));
return true;
}
@@ -90,7 +91,7 @@
++i) {
const DnsHostsKey& key = i->first;
std::string host_name = key.first;
- output.append(IPEndPoint(i->second, -1).ToStringWithoutPort());
+ output.append(IPEndPoint(i->second, 0).ToStringWithoutPort());
output.append(" ").append(host_name).append("\n");
}
return output;
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 33f30fc..dcc9345 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -221,7 +221,7 @@
"HTTP/1.1", "200", "OK", kBarResponseBody);
}
- virtual ~EndToEndTest() {
+ ~EndToEndTest() override {
// TODO(rtenneti): port RecycleUnusedPort if needed.
// RecycleUnusedPort(server_address_.port());
QuicInMemoryCachePeer::ResetForTests();
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc
index 5b5c415..496211f 100644
--- a/net/tools/quic/quic_client_session_test.cc
+++ b/net/tools/quic/quic_client_session_test.cc
@@ -46,6 +46,8 @@
session_->InitializeSession(
QuicServerId(kServerHostname, kPort, false, PRIVACY_MODE_DISABLED),
&crypto_config_);
+ // Advance the time, because timers do not like uninitialized times.
+ connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
void CompleteCryptoHandshake() {
diff --git a/net/tools/quic/quic_server_session.cc b/net/tools/quic/quic_server_session.cc
index 45c1379..9db2365 100644
--- a/net/tools/quic/quic_server_session.cc
+++ b/net/tools/quic/quic_server_session.cc
@@ -38,14 +38,29 @@
void QuicServerSession::OnConfigNegotiated() {
QuicSession::OnConfigNegotiated();
- if (!FLAGS_enable_quic_fec ||
- !config()->HasReceivedConnectionOptions() ||
- !net::ContainsQuicTag(config()->ReceivedConnectionOptions(), kFHDR)) {
+
+ if (!config()->HasReceivedConnectionOptions()) {
return;
}
- // kFHDR config maps to FEC protection always for headers stream.
- // TODO(jri): Add crypto stream in addition to headers for kHDR.
- headers_stream_->set_fec_policy(FEC_PROTECT_ALWAYS);
+
+ // If the client has provided a bandwidth estimate from the same serving
+ // region, then pass it to the sent packet manager in preparation for possible
+ // bandwidth resumption.
+ const CachedNetworkParameters* cached_network_params =
+ crypto_stream_->previous_cached_network_params();
+ if (FLAGS_quic_enable_bandwidth_resumption_experiment &&
+ cached_network_params != nullptr &&
+ ContainsQuicTag(config()->ReceivedConnectionOptions(), kBWRE) &&
+ cached_network_params->serving_region() == serving_region_) {
+ connection()->ResumeConnectionState(*cached_network_params);
+ }
+
+ if (FLAGS_enable_quic_fec &&
+ ContainsQuicTag(config()->ReceivedConnectionOptions(), kFHDR)) {
+ // kFHDR config maps to FEC protection always for headers stream.
+ // TODO(jri): Add crypto stream in addition to headers for kHDR.
+ headers_stream_->set_fec_policy(FEC_PROTECT_ALWAYS);
+ }
}
void QuicServerSession::OnConnectionClosed(QuicErrorCode error,
diff --git a/net/tools/quic/quic_server_session_test.cc b/net/tools/quic/quic_server_session_test.cc
index 6a17f53..b0ed5d1 100644
--- a/net/tools/quic/quic_server_session_test.cc
+++ b/net/tools/quic/quic_server_session_test.cc
@@ -292,7 +292,7 @@
explicit MockQuicCryptoServerStream(
const QuicCryptoServerConfig& crypto_config, QuicSession* session)
: QuicCryptoServerStream(crypto_config, session) {}
- virtual ~MockQuicCryptoServerStream() {}
+ ~MockQuicCryptoServerStream() override {}
MOCK_METHOD1(SendServerConfigUpdate,
void(const CachedNetworkParameters* cached_network_parameters));
@@ -383,6 +383,46 @@
session_->OnCongestionWindowChange(now);
}
+TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) {
+ ValueRestore<bool> old_flag(
+ &FLAGS_quic_enable_bandwidth_resumption_experiment, true);
+
+ // Test that if a client provides a CachedNetworkParameters with the same
+ // serving region as the current server, that this data is passed down to the
+ // send algorithm.
+
+ // Client has sent kBWRE connection option to trigger bandwidth resumption.
+ QuicTagVector copt;
+ copt.push_back(kBWRE);
+ QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+
+ const string kTestServingRegion = "a serving region";
+ session_->set_serving_region(kTestServingRegion);
+
+ QuicCryptoServerStream* crypto_stream =
+ static_cast<QuicCryptoServerStream*>(
+ QuicSessionPeer::GetCryptoStream(session_.get()));
+
+ // No effect if no CachedNetworkParameters provided.
+ EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(0);
+ session_->OnConfigNegotiated();
+
+ // No effect if CachedNetworkParameters provided, but different serving
+ // regions.
+ CachedNetworkParameters cached_network_params;
+ cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
+ cached_network_params.set_serving_region("different serving region");
+ crypto_stream->set_previous_cached_network_params(cached_network_params);
+ EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(0);
+ session_->OnConfigNegotiated();
+
+ // Same serving region results in CachedNetworkParameters being stored.
+ cached_network_params.set_serving_region(kTestServingRegion);
+ crypto_stream->set_previous_cached_network_params(cached_network_params);
+ EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(1);
+ session_->OnConfigNegotiated();
+}
+
} // namespace
} // namespace test
} // namespace tools
diff --git a/net/tools/quic/quic_spdy_server_stream_test.cc b/net/tools/quic/quic_spdy_server_stream_test.cc
index 4f5484a..8a3600c 100644
--- a/net/tools/quic/quic_spdy_server_stream_test.cc
+++ b/net/tools/quic/quic_spdy_server_stream_test.cc
@@ -97,7 +97,7 @@
QuicInMemoryCachePeer::ResetForTests();
}
- virtual void SetUp() override {
+ void SetUp() override {
QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance();
BalsaHeaders request_headers, response_headers;
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc
index 05c3954..4e5d7c3 100644
--- a/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -95,9 +95,9 @@
client_address_(net::test::TestPeerIPAddress(), kTestPort),
writer_is_blocked_(false) {}
- virtual ~QuicTimeWaitListManagerTest() override {}
+ ~QuicTimeWaitListManagerTest() override {}
- virtual void SetUp() override {
+ void SetUp() override {
EXPECT_CALL(writer_, IsWriteBlocked())
.WillRepeatedly(ReturnPointee(&writer_is_blocked_));
EXPECT_CALL(writer_, IsWriteBlockedDataBuffered())
diff --git a/net/tools/quic/test_tools/mock_quic_dispatcher.h b/net/tools/quic/test_tools/mock_quic_dispatcher.h
index df32ce4..81f1004 100644
--- a/net/tools/quic/test_tools/mock_quic_dispatcher.h
+++ b/net/tools/quic/test_tools/mock_quic_dispatcher.h
@@ -24,7 +24,7 @@
PacketWriterFactory* packet_writer_factory,
EpollServer* eps);
- virtual ~MockQuicDispatcher();
+ ~MockQuicDispatcher() override;
MOCK_METHOD3(ProcessPacket, void(const IPEndPoint& server_address,
const IPEndPoint& client_address,
diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h
index 9db9fb5..e1220cb 100644
--- a/net/tools/quic/test_tools/quic_test_utils.h
+++ b/net/tools/quic/test_tools/quic_test_utils.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/strings/string_piece.h"
+#include "net/quic/crypto/cached_network_parameters.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_packet_writer.h"
#include "net/quic/quic_session.h"
@@ -94,6 +95,8 @@
MOCK_METHOD0(OnCanWrite, void());
MOCK_CONST_METHOD0(HasPendingWrites, bool());
+ MOCK_METHOD1(ResumeConnectionState, void(const CachedNetworkParameters&));
+
void ReallyProcessUdpPacket(const IPEndPoint& self_address,
const IPEndPoint& peer_address,
const QuicEncryptedPacket& packet) {
diff --git a/net/udp/udp_socket_unittest.cc b/net/udp/udp_socket_unittest.cc
index 83689c7..8282596 100644
--- a/net/udp/udp_socket_unittest.cc
+++ b/net/udp/udp_socket_unittest.cc
@@ -119,7 +119,7 @@
};
// Creates and address from an ip/port and returns it in |address|.
-void CreateUDPAddress(std::string ip_str, int port, IPEndPoint* address) {
+void CreateUDPAddress(std::string ip_str, uint16 port, IPEndPoint* address) {
IPAddressNumber ip_number;
bool rv = ParseIPLiteralToNumber(ip_str, &ip_number);
if (!rv)
@@ -128,7 +128,7 @@
}
TEST_F(UDPSocketTest, Connect) {
- const int kPort = 9999;
+ const uint16 kPort = 9999;
std::string simple_message("hello world!");
// Setup the server to listen.
@@ -216,7 +216,7 @@
#else
TEST_F(UDPSocketTest, Broadcast) {
#endif
- const int kPort = 9999;
+ const uint16 kPort = 9999;
std::string first_message("first message"), second_message("second message");
IPEndPoint broadcast_address;
@@ -369,8 +369,8 @@
// not bind the client's reads to only be from that endpoint, and that we need
// to always use recvfrom() to disambiguate.
TEST_F(UDPSocketTest, VerifyConnectBindsAddr) {
- const int kPort1 = 9999;
- const int kPort2 = 10000;
+ const uint16 kPort1 = 9999;
+ const uint16 kPort2 = 10000;
std::string simple_message("hello world!");
std::string foreign_message("BAD MESSAGE TO GET!!");
@@ -538,7 +538,7 @@
#endif // defined(OS_ANDROID)
TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
- const int kPort = 9999;
+ const uint16 kPort = 9999;
const char* const kGroup = "237.132.100.17";
IPEndPoint bind_address;
@@ -562,7 +562,7 @@
}
TEST_F(UDPSocketTest, MulticastOptions) {
- const int kPort = 9999;
+ const uint16 kPort = 9999;
IPEndPoint bind_address;
CreateUDPAddress("0.0.0.0", kPort, &bind_address);
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
index 11c731f..7be97e8 100644
--- a/net/udp/udp_socket_win.cc
+++ b/net/udp/udp_socket_win.cc
@@ -6,6 +6,7 @@
#include <mstcpip.h>
+#include "base/basictypes.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -808,8 +809,8 @@
DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
for (int i = 0; i < kBindRetries; ++i) {
- int rv = DoBind(IPEndPoint(address,
- rand_int_cb_.Run(kPortStart, kPortEnd)));
+ int rv = DoBind(IPEndPoint(
+ address, static_cast<uint16>(rand_int_cb_.Run(kPortStart, kPortEnd))));
if (rv == OK || rv != ERR_ADDRESS_IN_USE)
return rv;
}
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index a2ce07e..c61a14b 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -650,12 +650,8 @@
response_info_.was_cached = false;
- // If the referrer is secure, but the requested URL is not, the referrer
- // policy should be something non-default. If you hit this, please file a
- // bug.
- if (referrer_policy_ ==
- CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE &&
- GURL(referrer_).SchemeIsSecure() && !url().SchemeIsSecure()) {
+ if (GURL(referrer_) != URLRequestJob::ComputeReferrerForRedirect(
+ referrer_policy_, referrer_, url())) {
if (!network_delegate_ ||
!network_delegate_->CancelURLRequestWithPolicyViolatingReferrerHeader(
*this, url(), GURL(referrer_))) {
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index 6117419..af972bd 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -94,14 +94,22 @@
// referrer header might be cleared, if the protocol changes from HTTPS to
// HTTP. This is the default behavior of URLRequest, corresponding to
// CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE. Alternatively, the
- // referrer policy can be set to never change the referrer header. This
- // behavior corresponds to NEVER_CLEAR_REFERRER. Embedders will want to use
- // NEVER_CLEAR_REFERRER when implementing the meta-referrer support
- // (http://wiki.whatwg.org/wiki/Meta_referrer) and sending requests with a
- // non-default referrer policy. Only the default referrer policy requires
- // the referrer to be cleared on transitions from HTTPS to HTTP.
+ // referrer policy can be set to strip the referrer down to an origin upon
+ // cross-origin navigation (ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN), or
+ // never change the referrer header (NEVER_CLEAR_REFERRER). Embedders will
+ // want to use these options when implementing referrer policy support
+ // (https://w3c.github.io/webappsec/specs/referrer-policy/).
+ //
+ // REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN is a slight variant
+ // on CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE: If the request
+ // downgrades from HTTPS to HTTP, the referrer will be cleared. If the request
+ // transitions cross-origin (but does not downgrade), the referrer's
+ // granularity will be reduced (currently stripped down to an origin rather
+ // than a full URL). Same-origin requests will send the full referrer.
enum ReferrerPolicy {
CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
NEVER_CLEAR_REFERRER,
};
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 41420d5..838aa7b 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -122,11 +122,6 @@
return true;
}
- int OnBeforeSocketStreamConnect(SocketStream* stream,
- const CompletionCallback& callback) override {
- return OK;
- }
-
DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
};
diff --git a/net/url_request/url_request_data_job.cc b/net/url_request/url_request_data_job.cc
index 879b8ba..e074646 100644
--- a/net/url_request/url_request_data_job.cc
+++ b/net/url_request/url_request_data_job.cc
@@ -6,7 +6,6 @@
#include "net/url_request/url_request_data_job.h"
-#include "base/profiler/scoped_tracker.h"
#include "net/base/data_url.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -53,10 +52,6 @@
std::string* charset,
std::string* data,
const CompletionCallback& callback) const {
- // TODO(vadimt): Remove ScopedTracker below once crbug.com/422489 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION("422489 URLRequestDataJob::GetData"));
-
// Check if data URL is valid. If not, don't bother to try to extract data.
// Otherwise, parse the data from the data URL.
const GURL& url = request_->url();
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 33a5088..acf1d07 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -66,17 +66,13 @@
base::Time GetRequestTime() const override;
bool IsCachedContent() const override;
bool IsDownload() const override;
- bool SdchResponseExpected() const override;
+ SdchManager::DictionarySet* SdchDictionariesAdvertised() const override;
int64 GetByteReadCount() const override;
int GetResponseCode() const override;
const URLRequestContext* GetURLRequestContext() const override;
void RecordPacketStats(StatisticSelector statistic) const override;
const BoundNetLog& GetNetLog() const override;
- // Method to allow us to reset filter context for a response that should have
- // been SDCH encoded when there is an update due to an explicit HTTP header.
- void ResetSdchResponseToFalse();
-
private:
URLRequestHttpJob* job_;
@@ -126,13 +122,9 @@
return (job_->request_info_.load_flags & LOAD_IS_DOWNLOAD) != 0;
}
-void URLRequestHttpJob::HttpFilterContext::ResetSdchResponseToFalse() {
- DCHECK(job_->sdch_dictionary_advertised_);
- job_->sdch_dictionary_advertised_ = false;
-}
-
-bool URLRequestHttpJob::HttpFilterContext::SdchResponseExpected() const {
- return job_->sdch_dictionary_advertised_;
+SdchManager::DictionarySet*
+URLRequestHttpJob::HttpFilterContext::SdchDictionariesAdvertised() const {
+ return job_->dictionaries_advertised_.get();
}
int64 URLRequestHttpJob::HttpFilterContext::GetByteReadCount() const {
@@ -200,7 +192,6 @@
base::Unretained(this))),
read_in_progress_(false),
throttling_entry_(NULL),
- sdch_dictionary_advertised_(false),
sdch_test_activated_(false),
sdch_test_control_(false),
is_cached_content_(false),
@@ -273,7 +264,7 @@
// plugin could set a referrer although sending the referrer is inhibited.
request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer);
- // Our consumer should have made sure that this is a safe referrer. See for
+ // Our consumer should have made sure that this is a safe referrer. See for
// instance WebCore::FrameLoader::HideReferrer.
if (referrer.is_valid()) {
request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
@@ -330,6 +321,7 @@
ProcessStrictTransportSecurityHeader();
ProcessPublicKeyPinsHeader();
+ // Handle the server notification of a new SDCH dictionary.
SdchManager* sdch_manager(request()->context()->sdch_manager());
if (sdch_manager) {
SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url());
@@ -371,6 +363,24 @@
}
}
+ // Handle the server signalling no SDCH encoding.
+ if (dictionaries_advertised_) {
+ // We are wary of proxies that discard or damage SDCH encoding. If a server
+ // explicitly states that this is not SDCH content, then we can correct our
+ // assumption that this is an SDCH response, and avoid the need to recover
+ // as though the content is corrupted (when we discover it is not SDCH
+ // encoded).
+ std::string sdch_response_status;
+ void* iter = NULL;
+ while (GetResponseHeaders()->EnumerateHeader(&iter, "X-Sdch-Encode",
+ &sdch_response_status)) {
+ if (sdch_response_status == "0") {
+ dictionaries_advertised_.reset();
+ break;
+ }
+ }
+ }
+
// The HTTP transaction may be restarted several times for the purposes
// of sending authorization information. Each time it restarts, we get
// notified of the headers completion so that we can update the cookie store.
@@ -532,34 +542,34 @@
}
}
}
- std::string avail_dictionaries;
if (advertise_sdch) {
- sdch_manager->GetAvailDictionaryList(request_->url(),
- &avail_dictionaries);
+ dictionaries_advertised_ =
+ sdch_manager->GetDictionarySet(request_->url());
+ }
- // The AllowLatencyExperiment() is only true if we've successfully done a
- // full SDCH compression recently in this browser session for this host.
- // Note that for this path, there might be no applicable dictionaries,
- // and hence we can't participate in the experiment.
- if (!avail_dictionaries.empty() &&
- sdch_manager->AllowLatencyExperiment(request_->url())) {
- // We are participating in the test (or control), and hence we'll
- // eventually record statistics via either SDCH_EXPERIMENT_DECODE or
- // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data.
- packet_timing_enabled_ = true;
- if (base::RandDouble() < .01) {
- sdch_test_control_ = true; // 1% probability.
- advertise_sdch = false;
- } else {
- sdch_test_activated_ = true;
- }
+ // The AllowLatencyExperiment() is only true if we've successfully done a
+ // full SDCH compression recently in this browser session for this host.
+ // Note that for this path, there might be no applicable dictionaries,
+ // and hence we can't participate in the experiment.
+ if (dictionaries_advertised_ &&
+ sdch_manager->AllowLatencyExperiment(request_->url())) {
+ // We are participating in the test (or control), and hence we'll
+ // eventually record statistics via either SDCH_EXPERIMENT_DECODE or
+ // SDCH_EXPERIMENT_HOLDBACK, and we'll need some packet timing data.
+ packet_timing_enabled_ = true;
+ if (base::RandDouble() < .01) {
+ sdch_test_control_ = true; // 1% probability.
+ dictionaries_advertised_.reset();
+ advertise_sdch = false;
+ } else {
+ sdch_test_activated_ = true;
}
}
// Supply Accept-Encoding headers first so that it is more likely that they
- // will be in the first transmitted packet. This can sometimes make it
+ // will be in the first transmitted packet. This can sometimes make it
// easier to filter and analyze the streams to assure that a proxy has not
- // damaged these headers. Some proxies deliberately corrupt Accept-Encoding
+ // damaged these headers. Some proxies deliberately corrupt Accept-Encoding
// headers.
if (!advertise_sdch) {
// Tell the server what compression formats we support (other than SDCH).
@@ -569,15 +579,14 @@
// Include SDCH in acceptable list.
request_info_.extra_headers.SetHeader(
HttpRequestHeaders::kAcceptEncoding, "gzip, deflate, sdch");
- if (!avail_dictionaries.empty()) {
+ if (dictionaries_advertised_) {
request_info_.extra_headers.SetHeader(
kAvailDictionaryHeader,
- avail_dictionaries);
- sdch_dictionary_advertised_ = true;
+ dictionaries_advertised_->GetDictionaryClientHashList());
// Since we're tagging this transaction as advertising a dictionary,
// we'll definitely employ an SDCH filter (or tentative sdch filter)
- // when we get a response. When done, we'll record histograms via
- // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet
+ // when we get a response. When done, we'll record histograms via
+ // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet
// arrival times.
packet_timing_enabled_ = true;
}
@@ -1029,7 +1038,7 @@
void URLRequestHttpJob::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
// If haven't made it far enough to receive any headers, don't return
- // anything. This makes for more consistent behavior in the case of errors.
+ // anything. This makes for more consistent behavior in the case of errors.
if (!transaction_ || receive_headers_end_.is_null())
return;
if (transaction_->GetLoadTimingInfo(load_timing_info))
@@ -1072,23 +1081,6 @@
encoding_types.push_back(Filter::ConvertEncodingToType(encoding_type));
}
- if (filter_context_->SdchResponseExpected()) {
- // We are wary of proxies that discard or damage SDCH encoding. If a server
- // explicitly states that this is not SDCH content, then we can correct our
- // assumption that this is an SDCH response, and avoid the need to recover
- // as though the content is corrupted (when we discover it is not SDCH
- // encoded).
- std::string sdch_response_status;
- iter = NULL;
- while (headers->EnumerateHeader(&iter, "X-Sdch-Encode",
- &sdch_response_status)) {
- if (sdch_response_status == "0") {
- filter_context_->ResetSdchResponseToFalse();
- break;
- }
- }
- }
-
// Even if encoding types are empty, there is a chance that we need to add
// some decoding, as some proxies strip encoding completely. In such cases,
// we may need to add (for example) SDCH filtering (when the context suggests
@@ -1132,7 +1124,7 @@
if (code == -1)
return false;
- // Check if we need either Proxy or WWW Authentication. This could happen
+ // Check if we need either Proxy or WWW Authentication. This could happen
// because we either provided no auth info, or provided incorrect info.
switch (code) {
case 407:
@@ -1266,7 +1258,7 @@
bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const {
// Some servers send the body compressed, but specify the content length as
- // the uncompressed size. Although this violates the HTTP spec we want to
+ // the uncompressed size. Although this violates the HTTP spec we want to
// support it (as IE and FireFox do), but *only* for an exact match.
// See http://crbug.com/79694.
if (rv == net::ERR_CONTENT_LENGTH_MISMATCH ||
@@ -1461,7 +1453,7 @@
!prefilter_bytes_read()) // Zero-byte responses aren't useful.
return;
- // Miniature requests aren't really compressible. Don't count them.
+ // Miniature requests aren't really compressible. Don't count them.
const int kMinSize = 16;
if (prefilter_bytes_read() < kMinSize)
return;
@@ -1478,14 +1470,14 @@
// We want to record how often downloaded resources are compressed.
// But, we recognize that different protocols may have different
- // properties. So, for each request, we'll put it into one of 3
+ // properties. So, for each request, we'll put it into one of 3
// groups:
// a) SSL resources
// Proxies cannot tamper with compression headers with SSL.
// b) Non-SSL, loaded-via-proxy resources
// In this case, we know a proxy might have interfered.
// c) Non-SSL, loaded-without-proxy resources
- // In this case, we know there was no explicit proxy. However,
+ // In this case, we know there was no explicit proxy. However,
// it is possible that a transparent proxy was still interfering.
//
// For each group, we record the same 3 histograms.
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index f4bea7e..3a23e8a 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -15,6 +15,7 @@
#include "net/base/auth.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
+#include "net/base/sdch_manager.h"
#include "net/cookies/cookie_store.h"
#include "net/filter/filter.h"
#include "net/http/http_request_info.h"
@@ -32,7 +33,7 @@
class UploadDataStream;
class URLRequestContext;
-// A URLRequestJob subclass that is built on top of HttpTransaction. It
+// A URLRequestJob subclass that is built on top of HttpTransaction. It
// provides an implementation for both HTTP and HTTPS.
class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob {
public:
@@ -194,17 +195,15 @@
scoped_ptr<HttpTransaction> transaction_;
// This is used to supervise traffic and enforce exponential
- // back-off. May be NULL.
+ // back-off. May be NULL.
scoped_refptr<URLRequestThrottlerEntryInterface> throttling_entry_;
- // Indicated if an SDCH dictionary was advertised, and hence an SDCH
- // compressed response is expected. We use this to help detect (accidental?)
- // proxy corruption of a response, which sometimes marks SDCH content as
- // having no content encoding <oops>.
- bool sdch_dictionary_advertised_;
+ // A handle to the SDCH dictionaries that were advertised in this request.
+ // May be null.
+ scoped_ptr<SdchManager::DictionarySet> dictionaries_advertised_;
// For SDCH latency experiments, when we are able to do SDCH, we may enable
- // either an SDCH latency test xor a pass through test. The following bools
+ // either an SDCH latency test xor a pass through test. The following bools
// indicate what we decided on for this instance.
bool sdch_test_activated_; // Advertising a dictionary for sdch.
bool sdch_test_control_; // Not even accepting-content sdch.
@@ -219,7 +218,7 @@
//
// TODO(jar): improve the quality of the gathered info by gathering most times
// at a lower point in the network stack, assuring we have actual packet
- // boundaries, rather than approximations. Also note that input byte count
+ // boundaries, rather than approximations. Also note that input byte count
// as gathered here is post-SSL, and post-cache-fetch, and does not reflect
// true packet arrival times in such cases.
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 5d32c6f..3cd8cf4 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -20,7 +20,6 @@
#include "net/base/network_delegate.h"
#include "net/filter/filter.h"
#include "net/http/http_response_headers.h"
-#include "net/url_request/url_request.h"
namespace {
@@ -255,6 +254,42 @@
void URLRequestJob::NotifyURLRequestDestroyed() {
}
+// static
+GURL URLRequestJob::ComputeReferrerForRedirect(
+ URLRequest::ReferrerPolicy policy,
+ const std::string& referrer,
+ const GURL& redirect_destination) {
+ GURL original_referrer(referrer);
+ bool secure_referrer_but_insecure_destination =
+ original_referrer.SchemeIsSecure() &&
+ !redirect_destination.SchemeIsSecure();
+ bool same_origin =
+ original_referrer.GetOrigin() == redirect_destination.GetOrigin();
+ switch (policy) {
+ case URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE:
+ return secure_referrer_but_insecure_destination ? GURL()
+ : original_referrer;
+
+ case URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN:
+ if (same_origin) {
+ return original_referrer;
+ } else if (secure_referrer_but_insecure_destination) {
+ return GURL();
+ } else {
+ return original_referrer.GetOrigin();
+ }
+
+ case URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN:
+ return same_origin ? original_referrer : original_referrer.GetOrigin();
+
+ case URLRequest::NEVER_CLEAR_REFERRER:
+ return original_referrer;
+ }
+
+ NOTREACHED();
+ return GURL();
+}
+
URLRequestJob::~URLRequestJob() {
base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
if (power_monitor)
@@ -863,15 +898,11 @@
request_->first_party_for_cookies();
}
- // Suppress the referrer if we're redirecting out of https.
- if (request_->referrer_policy() ==
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE &&
- GURL(request_->referrer()).SchemeIsSecure() &&
- !redirect_info.new_url.SchemeIsSecure()) {
- redirect_info.new_referrer.clear();
- } else {
- redirect_info.new_referrer = request_->referrer();
- }
+ // Alter the referrer if redirecting cross-origin (especially HTTP->HTTPS).
+ redirect_info.new_referrer =
+ ComputeReferrerForRedirect(request_->referrer_policy(),
+ request_->referrer(),
+ redirect_info.new_url).spec();
return redirect_info;
}
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index e824689..ceb71f5 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -20,6 +20,7 @@
#include "net/base/upload_progress.h"
#include "net/cookies/canonical_cookie.h"
#include "net/url_request/redirect_info.h"
+#include "net/url_request/url_request.h"
#include "url/gurl.h"
namespace net {
@@ -36,7 +37,6 @@
class NetworkDelegate;
class SSLCertRequestInfo;
class SSLInfo;
-class URLRequest;
class UploadDataStream;
class URLRequestStatus;
class X509Certificate;
@@ -227,6 +227,12 @@
// canceled by an explicit NetworkDelegate::NotifyURLRequestDestroyed() call.
virtual void NotifyURLRequestDestroyed();
+ // Given |policy|, |referrer|, and |redirect_destination|, returns the
+ // referrer URL mandated by |request|'s referrer policy.
+ static GURL ComputeReferrerForRedirect(URLRequest::ReferrerPolicy policy,
+ const std::string& referrer,
+ const GURL& redirect_destination);
+
protected:
friend class base::RefCounted<URLRequestJob>;
~URLRequestJob() override;
diff --git a/net/url_request/url_request_job_manager.h b/net/url_request/url_request_job_manager.h
index ca67e56..6329eab 100644
--- a/net/url_request/url_request_job_manager.h
+++ b/net/url_request/url_request_job_manager.h
@@ -10,6 +10,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
+#include "net/base/net_export.h"
#include "net/url_request/url_request.h"
template <typename T> struct DefaultSingletonTraits;
@@ -24,7 +25,7 @@
// URLRequest is designed to have all consumers on a single thread, and
// so no attempt is made to support Interceptor instances being
// registered/unregistered or in any way poked on multiple threads.
-class URLRequestJobManager {
+class NET_EXPORT URLRequestJobManager {
public:
// Returns the singleton instance.
static URLRequestJobManager* GetInstance();
diff --git a/net/url_request/url_request_simple_job.cc b/net/url_request/url_request_simple_job.cc
index 55a0f88..060a90e 100644
--- a/net/url_request/url_request_simple_job.cc
+++ b/net/url_request/url_request_simple_job.cc
@@ -47,6 +47,11 @@
bool URLRequestSimpleJob::ReadRawData(IOBuffer* buf, int buf_size,
int* bytes_read) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/422489 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422489 URLRequestSimpleJob::ReadRawData"));
+
DCHECK(bytes_read);
int remaining = byte_range_.last_byte_position() - data_offset_ + 1;
if (buf_size > remaining)
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 8f70ee7..6be7da3 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -604,12 +604,6 @@
return can_throttle_requests_;
}
-int TestNetworkDelegate::OnBeforeSocketStreamConnect(
- SocketStream* socket,
- const CompletionCallback& callback) {
- return OK;
-}
-
bool TestNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
const GURL& target_url,
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 1289db7..1c385b2 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -325,8 +325,6 @@
bool OnCanAccessFile(const URLRequest& request,
const base::FilePath& path) const override;
bool OnCanThrottleRequest(const URLRequest& request) const override;
- int OnBeforeSocketStreamConnect(SocketStream* stream,
- const CompletionCallback& callback) override;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const URLRequest& request,
const GURL& target_url,
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 1d777dc..9892a69 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -3913,32 +3913,6 @@
}
}
-TEST_F(URLRequestTestHTTP, HTTPSToHTTPRedirectNoRefererTest) {
- ASSERT_TRUE(test_server_.Start());
-
- SpawnedTestServer https_test_server(
- SpawnedTestServer::TYPE_HTTPS, SpawnedTestServer::kLocalhost,
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- ASSERT_TRUE(https_test_server.Start());
-
- // An https server is sent a request with an https referer,
- // and responds with a redirect to an http url. The http
- // server should not be sent the referer.
- GURL http_destination = test_server_.GetURL(std::string());
- TestDelegate d;
- scoped_ptr<URLRequest> req(default_context_.CreateRequest(
- https_test_server.GetURL("server-redirect?" + http_destination.spec()),
- DEFAULT_PRIORITY, &d, NULL));
- req->SetReferrer("https://www.referrer.com/");
- req->Start();
- base::RunLoop().Run();
-
- EXPECT_EQ(1, d.response_started_count());
- EXPECT_EQ(1, d.received_redirect_count());
- EXPECT_EQ(http_destination, req->url());
- EXPECT_EQ(std::string(), req->referrer());
-}
-
TEST_F(URLRequestTestHTTP, RedirectLoadTiming) {
ASSERT_TRUE(test_server_.Start());
@@ -6727,6 +6701,219 @@
EXPECT_EQ(2, default_network_delegate()->headers_received_count());
}
+class URLRequestTestReferrerPolicy : public URLRequestTest {
+ public:
+ URLRequestTestReferrerPolicy() {}
+
+ void InstantiateSameOriginServers(SpawnedTestServer::Type origin_type) {
+ origin_server_.reset(new SpawnedTestServer(
+ origin_type, SpawnedTestServer::kLocalhost,
+ origin_type == SpawnedTestServer::TYPE_HTTPS
+ ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
+ : base::FilePath(
+ FILE_PATH_LITERAL("net/data/url_request_unittest"))));
+ ASSERT_TRUE(origin_server_->Start());
+ }
+
+ void InstantiateCrossOriginServers(SpawnedTestServer::Type origin_type,
+ SpawnedTestServer::Type destination_type) {
+ origin_server_.reset(new SpawnedTestServer(
+ origin_type, SpawnedTestServer::kLocalhost,
+ origin_type == SpawnedTestServer::TYPE_HTTPS
+ ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
+ : base::FilePath(
+ FILE_PATH_LITERAL("net/data/url_request_unittest"))));
+ ASSERT_TRUE(origin_server_->Start());
+
+ destination_server_.reset(new SpawnedTestServer(
+ destination_type, SpawnedTestServer::kLocalhost,
+ destination_type == SpawnedTestServer::TYPE_HTTPS
+ ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
+ : base::FilePath(
+ FILE_PATH_LITERAL("net/data/url_request_unittest"))));
+ ASSERT_TRUE(destination_server_->Start());
+ }
+
+ void VerifyReferrerAfterRedirect(URLRequest::ReferrerPolicy policy,
+ const GURL& referrer,
+ const GURL& expected) {
+ // Create and execute the request: we'll only have a |destination_server_|
+ // if the origins are meant to be distinct. Otherwise, we'll use the
+ // |origin_server_| for both endpoints.
+ GURL destination_url =
+ destination_server_ ? destination_server_->GetURL("echoheader?Referer")
+ : origin_server_->GetURL("echoheader?Referer");
+ GURL origin_url =
+ origin_server_->GetURL("server-redirect?" + destination_url.spec());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(
+ default_context_.CreateRequest(origin_url, DEFAULT_PRIORITY, &d, NULL));
+ req->set_referrer_policy(policy);
+ req->SetReferrer(referrer.spec());
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(1, d.received_redirect_count());
+ EXPECT_EQ(destination_url, req->url());
+ EXPECT_TRUE(req->status().is_success());
+ EXPECT_EQ(200, req->response_headers()->response_code());
+
+ EXPECT_EQ(expected.spec(), req->referrer());
+ if (expected.is_empty())
+ EXPECT_EQ("None", d.data_received());
+ else
+ EXPECT_EQ(expected.spec(), d.data_received());
+ }
+
+ SpawnedTestServer* origin_server() const { return origin_server_.get(); }
+
+ private:
+ scoped_ptr<SpawnedTestServer> origin_server_;
+ scoped_ptr<SpawnedTestServer> destination_server_;
+};
+
+TEST_F(URLRequestTestReferrerPolicy, HTTPToSameOriginHTTP) {
+ InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTP);
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+}
+
+TEST_F(URLRequestTestReferrerPolicy, HTTPToCrossOriginHTTP) {
+ InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP,
+ SpawnedTestServer::TYPE_HTTP);
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+}
+
+TEST_F(URLRequestTestReferrerPolicy, HTTPSToSameOriginHTTPS) {
+ InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTPS);
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+}
+
+TEST_F(URLRequestTestReferrerPolicy, HTTPSToCrossOriginHTTPS) {
+ InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS,
+ SpawnedTestServer::TYPE_HTTPS);
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+}
+
+TEST_F(URLRequestTestReferrerPolicy, HTTPToHTTPS) {
+ InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP,
+ SpawnedTestServer::TYPE_HTTPS);
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+}
+
+TEST_F(URLRequestTestReferrerPolicy, HTTPSToHTTP) {
+ InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS,
+ SpawnedTestServer::TYPE_HTTP);
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+ origin_server()->GetURL("path/to/file.html"), GURL());
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"), GURL());
+
+ VerifyReferrerAfterRedirect(
+ URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL(std::string()));
+
+ VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
+ origin_server()->GetURL("path/to/file.html"),
+ origin_server()->GetURL("path/to/file.html"));
+}
+
class HTTPSRequestTest : public testing::Test {
public:
HTTPSRequestTest() : default_context_(true) {
@@ -7981,7 +8168,13 @@
EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}
-TEST_F(HTTPSOCSPTest, RevokedStapled) {
+// Disabled on NSS ports. See https://crbug.com/431716.
+#if defined(USE_NSS)
+#define MAYBE_RevokedStapled DISABLED_RevokedStapled
+#else
+#define MAYBE_RevokedStapled RevokedStapled
+#endif
+TEST_F(HTTPSOCSPTest, MAYBE_RevokedStapled) {
if (!SystemSupportsOCSPStapling()) {
LOG(WARNING)
<< "Skipping test because system doesn't support OCSP stapling";
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc
index 769b802..08ee6ae 100644
--- a/net/websockets/websocket_basic_handshake_stream.cc
+++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -39,8 +39,8 @@
#include "net/websockets/websocket_deflate_stream.h"
#include "net/websockets/websocket_deflater.h"
#include "net/websockets/websocket_extension_parser.h"
+#include "net/websockets/websocket_handshake_challenge.h"
#include "net/websockets/websocket_handshake_constants.h"
-#include "net/websockets/websocket_handshake_handler.h"
#include "net/websockets/websocket_handshake_request_info.h"
#include "net/websockets/websocket_handshake_response_info.h"
#include "net/websockets/websocket_stream.h"
@@ -435,8 +435,8 @@
requested_sub_protocols_,
&enriched_headers);
- ComputeSecWebSocketAccept(handshake_challenge,
- &handshake_challenge_response_);
+ handshake_challenge_response_ =
+ ComputeSecWebSocketAccept(handshake_challenge);
DCHECK(connect_delegate_);
scoped_ptr<WebSocketHandshakeRequestInfo> request(
diff --git a/net/websockets/websocket_handshake_challenge.cc b/net/websockets/websocket_handshake_challenge.cc
new file mode 100644
index 0000000..3a1c3e8
--- /dev/null
+++ b/net/websockets/websocket_handshake_challenge.cc
@@ -0,0 +1,20 @@
+// Copyright 2014 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/websockets/websocket_handshake_challenge.h"
+
+#include "base/base64.h"
+#include "base/sha1.h"
+#include "net/websockets/websocket_handshake_constants.h"
+
+namespace net {
+
+std::string ComputeSecWebSocketAccept(const std::string& key) {
+ std::string accept;
+ std::string hash = base::SHA1HashString(key + websockets::kWebSocketGuid);
+ base::Base64Encode(hash, &accept);
+ return accept;
+}
+
+} // namespace net
diff --git a/net/websockets/websocket_handshake_challenge.h b/net/websockets/websocket_handshake_challenge.h
new file mode 100644
index 0000000..e21f2b0
--- /dev/null
+++ b/net/websockets/websocket_handshake_challenge.h
@@ -0,0 +1,21 @@
+// Copyright 2014 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_WEBSOCKETS_WEBSOCKET_HANDSHAKE_CHALLENGE_H_
+#define NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_CHALLENGE_H_
+
+#include <string>
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+// Given a WebSocket handshake challenge, compute the value that the server
+// should return in the Sec-WebSocket-Accept header.
+NET_EXPORT_PRIVATE std::string ComputeSecWebSocketAccept(
+ const std::string& key);
+
+} // namespace net
+
+#endif // NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_CHALLENGE_H_
diff --git a/net/websockets/websocket_handshake_challenge_test.cc b/net/websockets/websocket_handshake_challenge_test.cc
new file mode 100644
index 0000000..d7e45ca
--- /dev/null
+++ b/net/websockets/websocket_handshake_challenge_test.cc
@@ -0,0 +1,24 @@
+// Copyright 2014 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/websockets/websocket_handshake_challenge.h"
+
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// Test the example challenge from the RFC6455.
+TEST(WebSocketHandshakeChallengeTest, RFC6455) {
+ const std::string key = "dGhlIHNhbXBsZSBub25jZQ==";
+ std::string accept = ComputeSecWebSocketAccept(key);
+ EXPECT_EQ("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", accept);
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/websockets/websocket_handshake_handler.cc b/net/websockets/websocket_handshake_handler.cc
deleted file mode 100644
index 6bcc230..0000000
--- a/net/websockets/websocket_handshake_handler.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/websockets/websocket_handshake_handler.h"
-
-#include "base/base64.h"
-#include "base/logging.h"
-#include "base/sha1.h"
-#include "net/websockets/websocket_handshake_constants.h"
-
-namespace net {
-
-void ComputeSecWebSocketAccept(const std::string& key,
- std::string* accept) {
- DCHECK(accept);
-
- std::string hash =
- base::SHA1HashString(key + websockets::kWebSocketGuid);
- base::Base64Encode(hash, accept);
-}
-
-} // namespace net
diff --git a/net/websockets/websocket_handshake_handler.h b/net/websockets/websocket_handshake_handler.h
deleted file mode 100644
index c65e6d9..0000000
--- a/net/websockets/websocket_handshake_handler.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_HANDLER_H_
-#define NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_HANDLER_H_
-
-#include <string>
-
-namespace net {
-
-// Given a WebSocket handshake challenge, compute the correct response.
-// TODO(ricea): There should probably be a test for this.
-void ComputeSecWebSocketAccept(const std::string& key,
- std::string* accept);
-
-} // namespace net
-
-#endif // NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_HANDLER_H_
diff --git a/net/websockets/websocket_handshake_handler_test.cc b/net/websockets/websocket_handshake_handler_test.cc
deleted file mode 100644
index 8eff571..0000000
--- a/net/websockets/websocket_handshake_handler_test.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 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/websockets/websocket_handshake_handler.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace {
-
-// TODO(ricea): Put a test for ComputeSecWebSocketAccept() here.
-
-} // namespace
-
-} // namespace net