summaryrefslogtreecommitdiff
path: root/chromium/net/test
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-18 14:10:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-06-18 13:53:24 +0000
commit813fbf95af77a531c57a8c497345ad2c61d475b3 (patch)
tree821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/net/test
parentaf6588f8d723931a298c995fa97259bb7f7deb55 (diff)
downloadqtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/net/test')
-rw-r--r--chromium/net/test/cert_test_util.h19
-rw-r--r--chromium/net/test/cert_test_util_nss.cc20
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.cc11
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server.h6
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc44
-rw-r--r--chromium/net/test/embedded_test_server/http_request.cc30
-rw-r--r--chromium/net/test/embedded_test_server/http_request.h8
-rw-r--r--chromium/net/test/embedded_test_server/http_request_unittest.cc51
-rw-r--r--chromium/net/test/embedded_test_server/http_response.h4
-rw-r--r--chromium/net/test/event_waiter.h40
-rw-r--r--chromium/net/test/gtest_util.h41
-rw-r--r--chromium/net/test/net_test_suite.cc8
-rw-r--r--chromium/net/test/python_utils.cc106
-rw-r--r--chromium/net/test/run_all_unittests.cc16
-rw-r--r--chromium/net/test/scoped_mock_log.cc58
-rw-r--r--chromium/net/test/scoped_mock_log.h98
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.cc89
-rw-r--r--chromium/net/test/spawned_test_server/base_test_server.h43
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server.cc22
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server.h6
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server_posix.cc3
-rw-r--r--chromium/net/test/spawned_test_server/local_test_server_win.cc64
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server.cc2
-rw-r--r--chromium/net/test/spawned_test_server/remote_test_server.h2
-rw-r--r--chromium/net/test/spawned_test_server/spawner_communicator.cc4
-rw-r--r--chromium/net/test/spawned_test_server/spawner_communicator.h10
-rw-r--r--chromium/net/test/test_certificate_data.h30
-rw-r--r--chromium/net/test/url_request/url_request_failed_job.cc172
-rw-r--r--chromium/net/test/url_request/url_request_failed_job.h49
-rw-r--r--chromium/net/test/url_request/url_request_mock_data_job.cc193
-rw-r--r--chromium/net/test/url_request/url_request_mock_data_job.h63
-rw-r--r--chromium/net/test/url_request/url_request_mock_http_job.cc157
-rw-r--r--chromium/net/test/url_request/url_request_mock_http_job.h32
-rw-r--r--chromium/net/test/url_request/url_request_slow_download_job.cc265
-rw-r--r--chromium/net/test/url_request/url_request_slow_download_job.h99
35 files changed, 1222 insertions, 643 deletions
diff --git a/chromium/net/test/cert_test_util.h b/chromium/net/test/cert_test_util.h
index 6334dd7edd8..219ccd87257 100644
--- a/chromium/net/test/cert_test_util.h
+++ b/chromium/net/test/cert_test_util.h
@@ -11,9 +11,7 @@
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
-#if defined(USE_NSS)
-#include "base/memory/scoped_ptr.h"
-
+#if defined(USE_NSS_CERTS)
// From <pk11pub.h>
typedef struct PK11SlotInfoStr PK11SlotInfo;
#endif
@@ -30,14 +28,13 @@ namespace net {
class EVRootCAMetadata;
-#if defined(USE_NSS)
-// Imports a private key from file |key_filename| in |dir|. The file must
-// contain a PKCS#8 PrivateKeyInfo in DER encoding. The key is imported to
-// |slot|.
-scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
- const base::FilePath& dir,
- const std::string& key_filename,
- PK11SlotInfo* slot);
+#if defined(USE_NSS_CERTS)
+// Imports a private key from file |key_filename| in |dir| into |slot|. The file
+// must contain a PKCS#8 PrivateKeyInfo in DER encoding. Returns true on success
+// and false on failure.
+bool ImportSensitiveKeyFromFile(const base::FilePath& dir,
+ const std::string& key_filename,
+ PK11SlotInfo* slot);
bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,
PK11SlotInfo* slot);
diff --git a/chromium/net/test/cert_test_util_nss.cc b/chromium/net/test/cert_test_util_nss.cc
index ee929e5a41f..4427cebe117 100644
--- a/chromium/net/test/cert_test_util_nss.cc
+++ b/chromium/net/test/cert_test_util_nss.cc
@@ -9,22 +9,22 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
-#include "crypto/rsa_private_key.h"
+#include "crypto/scoped_nss_types.h"
#include "net/cert/cert_type.h"
namespace net {
-scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
- const base::FilePath& dir,
- const std::string& key_filename,
- PK11SlotInfo* slot) {
+bool ImportSensitiveKeyFromFile(const base::FilePath& dir,
+ const std::string& key_filename,
+ PK11SlotInfo* slot) {
base::FilePath key_path = dir.AppendASCII(key_filename);
std::string key_pkcs8;
bool success = base::ReadFileToString(key_path, &key_pkcs8);
if (!success) {
LOG(ERROR) << "Failed to read file " << key_path.value();
- return scoped_ptr<crypto::RSAPrivateKey>();
+ return false;
}
const uint8* key_pkcs8_begin =
@@ -32,12 +32,12 @@ scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
std::vector<uint8> key_vector(key_pkcs8_begin,
key_pkcs8_begin + key_pkcs8.length());
- scoped_ptr<crypto::RSAPrivateKey> private_key(
- crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot,
- key_vector));
+ crypto::ScopedSECKEYPrivateKey private_key(
+ crypto::ImportNSSKeyFromPrivateKeyInfo(slot, key_vector,
+ true /* permanent */));
LOG_IF(ERROR, !private_key) << "Could not create key from file "
<< key_path.value();
- return private_key.Pass();
+ return private_key;
}
bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.cc b/chromium/net/test/embedded_test_server/embedded_test_server.cc
index 7ac764fb708..ac7d3bc14ac 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.cc
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.cc
@@ -49,8 +49,15 @@ scoped_ptr<HttpResponse> HandleFileRequest(
// This is a test-only server. Ignore I/O thread restrictions.
base::ThreadRestrictions::ScopedAllowIO allow_io;
+ std::string relative_url(request.relative_url);
+ // A proxy request will have an absolute path. Simulate the proxy by stripping
+ // the scheme, host, and port.
+ GURL relative_gurl(relative_url);
+ if (relative_gurl.is_valid())
+ relative_url = relative_gurl.PathForRequest();
+
// Trim the first byte ('/').
- std::string request_path(request.relative_url.substr(1));
+ std::string request_path = relative_url.substr(1);
// Remove the query string if present.
size_t query_pos = request_path.find('?');
@@ -115,7 +122,7 @@ void HttpListenSocket::DetachFromThread() {
}
EmbeddedTestServer::EmbeddedTestServer()
- : port_(-1),
+ : port_(0),
weak_factory_(this) {
DCHECK(thread_checker_.CalledOnValidThread());
}
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.h b/chromium/net/test/embedded_test_server/embedded_test_server.h
index 24ff8d7a7b9..8746f0d9a26 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server.h
+++ b/chromium/net/test/embedded_test_server/embedded_test_server.h
@@ -71,7 +71,7 @@ class HttpListenSocket : public TCPListenSocket {
// if (absolute_url.path() != "/test")
// return scoped_ptr<HttpResponse>();
//
-// scoped_ptr<HttpResponse> http_response(new HttpResponse());
+// scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
// http_response->set_code(test_server::SUCCESS);
// http_response->set_content("hello");
// http_response->set_content_type("text/plain");
@@ -136,7 +136,7 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate {
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 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate {
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/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc
index 28d909e6ce8..b5d72f2a1e6 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc
+++ b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -112,12 +112,12 @@ class EmbeddedTestServerTest: public testing::Test,
};
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());
}
@@ -137,10 +137,8 @@ TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) {
"text/html",
HTTP_OK));
- scoped_ptr<URLFetcher> fetcher(
- URLFetcher::Create(server_->GetURL("/test?q=foo"),
- URLFetcher::GET,
- this));
+ scoped_ptr<URLFetcher> fetcher =
+ URLFetcher::Create(server_->GetURL("/test?q=foo"), URLFetcher::GET, this);
fetcher->SetRequestContext(request_context_getter_.get());
fetcher->Start();
WaitForResponses(1);
@@ -159,10 +157,8 @@ TEST_F(EmbeddedTestServerTest, ServeFilesFromDirectory) {
server_->ServeFilesFromDirectory(
src_dir.AppendASCII("net").AppendASCII("data"));
- scoped_ptr<URLFetcher> fetcher(
- URLFetcher::Create(server_->GetURL("/test.html"),
- URLFetcher::GET,
- this));
+ scoped_ptr<URLFetcher> fetcher =
+ URLFetcher::Create(server_->GetURL("/test.html"), URLFetcher::GET, this);
fetcher->SetRequestContext(request_context_getter_.get());
fetcher->Start();
WaitForResponses(1);
@@ -174,10 +170,8 @@ TEST_F(EmbeddedTestServerTest, ServeFilesFromDirectory) {
}
TEST_F(EmbeddedTestServerTest, DefaultNotFoundResponse) {
- scoped_ptr<URLFetcher> fetcher(
- URLFetcher::Create(server_->GetURL("/non-existent"),
- URLFetcher::GET,
- this));
+ scoped_ptr<URLFetcher> fetcher = URLFetcher::Create(
+ server_->GetURL("/non-existent"), URLFetcher::GET, this);
fetcher->SetRequestContext(request_context_getter_.get());
fetcher->Start();
@@ -209,20 +203,14 @@ TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
"text/plain",
HTTP_NOT_FOUND));
- scoped_ptr<URLFetcher> fetcher1 = scoped_ptr<URLFetcher>(
- URLFetcher::Create(server_->GetURL("/test1"),
- URLFetcher::GET,
- this));
+ scoped_ptr<URLFetcher> fetcher1 =
+ URLFetcher::Create(server_->GetURL("/test1"), URLFetcher::GET, this);
fetcher1->SetRequestContext(request_context_getter_.get());
- scoped_ptr<URLFetcher> fetcher2 = scoped_ptr<URLFetcher>(
- URLFetcher::Create(server_->GetURL("/test2"),
- URLFetcher::GET,
- this));
+ scoped_ptr<URLFetcher> fetcher2 =
+ URLFetcher::Create(server_->GetURL("/test2"), URLFetcher::GET, this);
fetcher2->SetRequestContext(request_context_getter_.get());
- scoped_ptr<URLFetcher> fetcher3 = scoped_ptr<URLFetcher>(
- URLFetcher::Create(server_->GetURL("/test3"),
- URLFetcher::GET,
- this));
+ scoped_ptr<URLFetcher> fetcher3 =
+ URLFetcher::Create(server_->GetURL("/test3"), URLFetcher::GET, this);
fetcher3->SetRequestContext(request_context_getter_.get());
// Fetch the three URLs concurrently.
@@ -289,8 +277,8 @@ class EmbeddedTestServerThreadingTestDelegate
if (!loop)
loop.reset(new base::MessageLoopForIO);
- scoped_ptr<URLFetcher> fetcher(URLFetcher::Create(
- server.GetURL("/test?q=foo"), URLFetcher::GET, this));
+ scoped_ptr<URLFetcher> fetcher =
+ URLFetcher::Create(server.GetURL("/test?q=foo"), URLFetcher::GET, this);
fetcher->SetRequestContext(
new TestURLRequestContextGetter(loop->message_loop_proxy()));
fetcher->Start();
diff --git a/chromium/net/test/embedded_test_server/http_request.cc b/chromium/net/test/embedded_test_server/http_request.cc
index 3acb550292f..51d6f064694 100644
--- a/chromium/net/test/embedded_test_server/http_request.cc
+++ b/chromium/net/test/embedded_test_server/http_request.cc
@@ -10,6 +10,7 @@
#include "base/strings/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "net/http/http_chunked_decoder.h"
namespace net {
namespace test_server {
@@ -83,8 +84,10 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
// Parse request's the first header line.
// Request main main header, eg. GET /foobar.html HTTP/1.1
+ std::string request_headers;
{
const std::string header_line = ShiftLine();
+ http_request_->all_headers += header_line + "\r\n";
std::vector<std::string> header_line_tokens;
base::SplitString(header_line, ' ', &header_line_tokens);
DCHECK_EQ(3u, header_line_tokens.size());
@@ -111,6 +114,7 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
if (header_line.empty())
break;
+ http_request_->all_headers += header_line + "\r\n";
if (header_line[0] == ' ' || header_line[0] == '\t') {
// Continuation of the previous multi-line header.
std::string header_value =
@@ -137,6 +141,13 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
http_request_->headers["Content-Length"],
&declared_content_length_);
DCHECK(success) << "Malformed Content-Length header's value.";
+ } else if (http_request_->headers.count("Transfer-Encoding") > 0) {
+ if (http_request_->headers["Transfer-Encoding"] == "chunked") {
+ http_request_->has_content = true;
+ chunked_decoder_.reset(new HttpChunkedDecoder());
+ state_ = STATE_CONTENT;
+ return WAITING;
+ }
}
if (declared_content_length_ == 0) {
// No content data, so parsing is finished.
@@ -152,6 +163,25 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
HttpRequestParser::ParseResult HttpRequestParser::ParseContent() {
const size_t available_bytes = buffer_.size() - buffer_position_;
+ if (chunked_decoder_.get()) {
+ int bytes_written = chunked_decoder_->FilterBuf(
+ const_cast<char*>(buffer_.data()) + buffer_position_, available_bytes);
+ http_request_->content.append(buffer_.data() + buffer_position_,
+ bytes_written);
+
+ if (chunked_decoder_->reached_eof()) {
+ buffer_ =
+ buffer_.substr(buffer_.size() - chunked_decoder_->bytes_after_eof());
+ buffer_position_ = 0;
+ state_ = STATE_ACCEPTED;
+ return ACCEPTED;
+ }
+ buffer_ = "";
+ buffer_position_ = 0;
+ state_ = STATE_CONTENT;
+ return WAITING;
+ }
+
const size_t fetch_bytes = std::min(
available_bytes,
declared_content_length_ - http_request_->content.size());
diff --git a/chromium/net/test/embedded_test_server/http_request.h b/chromium/net/test/embedded_test_server/http_request.h
index cb9144b1449..c2993785664 100644
--- a/chromium/net/test/embedded_test_server/http_request.h
+++ b/chromium/net/test/embedded_test_server/http_request.h
@@ -13,6 +13,9 @@
#include "base/strings/string_piece.h"
namespace net {
+
+class HttpChunkedDecoder;
+
namespace test_server {
// Methods of HTTP requests supported by the test HTTP server.
@@ -36,6 +39,7 @@ struct HttpRequest {
std::string relative_url; // Starts with '/'. Example: "/test?query=foo"
HttpMethod method;
std::string method_string;
+ std::string all_headers;
std::map<std::string, std::string> headers;
std::string content;
bool has_content;
@@ -92,7 +96,7 @@ class HttpRequestParser {
ParseResult ParseHeaders();
// Parses request's content data and returns ACCEPTED if all of it have been
- // processed. Chunked Transfer Encoding *is not* supported.
+ // processed. Chunked Transfer Encoding is supported.
ParseResult ParseContent();
// Fetches the next line from the buffer. Result does not contain \r\n.
@@ -107,6 +111,8 @@ class HttpRequestParser {
// Content length of the request currently being parsed.
size_t declared_content_length_;
+ scoped_ptr<HttpChunkedDecoder> chunked_decoder_;
+
DISALLOW_COPY_AND_ASSIGN(HttpRequestParser);
};
diff --git a/chromium/net/test/embedded_test_server/http_request_unittest.cc b/chromium/net/test/embedded_test_server/http_request_unittest.cc
index 1006e4ede90..ff2ae3cf968 100644
--- a/chromium/net/test/embedded_test_server/http_request_unittest.cc
+++ b/chromium/net/test/embedded_test_server/http_request_unittest.cc
@@ -4,6 +4,7 @@
#include "net/test/embedded_test_server/http_request.h"
+#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -44,6 +45,14 @@ TEST(HttpRequestTest, ParseRequest) {
EXPECT_EQ(1u, request->headers.count("Multi-line-header"));
EXPECT_EQ(1u, request->headers.count("Content-Length"));
+ const char kExpectedAllHeaders[] =
+ "POST /foobar.html HTTP/1.1\r\n"
+ "Host: localhost:1234\r\n"
+ "Multi-line-header: abcd\r\n"
+ " efgh\r\n"
+ " ijkl\r\n"
+ "Content-Length: 10\r\n";
+ EXPECT_EQ(kExpectedAllHeaders, request->all_headers);
EXPECT_EQ("localhost:1234", request->headers["Host"]);
EXPECT_EQ("abcd efgh ijkl", request->headers["Multi-line-header"]);
EXPECT_EQ("10", request->headers["Content-Length"]);
@@ -68,6 +77,48 @@ TEST(HttpRequestTest, ParseRequestWithEmptyBody) {
EXPECT_EQ("0", request->headers["Content-Length"]);
}
+TEST(HttpRequestTest, ParseRequestWithChunkedBody) {
+ HttpRequestParser parser;
+
+ parser.ProcessChunk("POST /foobar.html HTTP/1.1\r\n");
+ parser.ProcessChunk("Transfer-Encoding: chunked\r\n\r\n");
+ parser.ProcessChunk("5\r\nhello\r\n");
+ parser.ProcessChunk("1\r\n \r\n");
+ parser.ProcessChunk("5\r\nworld\r\n");
+ parser.ProcessChunk("0\r\n\r\n");
+ ASSERT_EQ(HttpRequestParser::ACCEPTED, parser.ParseRequest());
+
+ scoped_ptr<HttpRequest> request = parser.GetRequest();
+ EXPECT_EQ("hello world", request->content);
+ EXPECT_TRUE(request->has_content);
+ EXPECT_EQ(1u, request->headers.count("Transfer-Encoding"));
+ EXPECT_EQ("chunked", request->headers["Transfer-Encoding"]);
+}
+
+TEST(HttpRequestTest, ParseRequestWithChunkedBodySlow) {
+ HttpRequestParser parser;
+
+ parser.ProcessChunk("POST /foobar.html HTTP/1.1\r\n");
+ parser.ProcessChunk("Transfer-Encoding: chunked\r\n\r\n");
+ std::string chunked_body = "5\r\nhello\r\n0\r\n\r\n";
+
+ // Send one character at a time, and make the parser parse the request.
+ for (size_t i = 0; i < chunked_body.size(); i++) {
+ parser.ProcessChunk(chunked_body.substr(i, 1));
+ // Except for the last pass, ParseRequest() should give WAITING.
+ if (i != chunked_body.size() - 1) {
+ ASSERT_EQ(HttpRequestParser::WAITING, parser.ParseRequest());
+ }
+ }
+ // All chunked data has been sent, the last ParseRequest should give ACCEPTED.
+ ASSERT_EQ(HttpRequestParser::ACCEPTED, parser.ParseRequest());
+ scoped_ptr<HttpRequest> request = parser.GetRequest();
+ EXPECT_EQ("hello", request->content);
+ EXPECT_TRUE(request->has_content);
+ EXPECT_EQ(1u, request->headers.count("Transfer-Encoding"));
+ EXPECT_EQ("chunked", request->headers["Transfer-Encoding"]);
+}
+
TEST(HttpRequestTest, ParseRequestWithoutBody) {
HttpRequestParser parser;
diff --git a/chromium/net/test/embedded_test_server/http_response.h b/chromium/net/test/embedded_test_server/http_response.h
index 821c02757dc..d4df75b5b85 100644
--- a/chromium/net/test/embedded_test_server/http_response.h
+++ b/chromium/net/test/embedded_test_server/http_response.h
@@ -7,10 +7,10 @@
#include <map>
#include <string>
-#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/strings/string_split.h"
#include "net/http/http_status_code.h"
namespace net {
@@ -60,7 +60,7 @@ class BasicHttpResponse : public HttpResponse {
HttpStatusCode code_;
std::string content_;
std::string content_type_;
- std::vector<std::pair<std::string, std::string> > custom_headers_;
+ base::StringPairs custom_headers_;
DISALLOW_COPY_AND_ASSIGN(BasicHttpResponse);
};
diff --git a/chromium/net/test/event_waiter.h b/chromium/net/test/event_waiter.h
new file mode 100644
index 00000000000..618b8ede462
--- /dev/null
+++ b/chromium/net/test/event_waiter.h
@@ -0,0 +1,40 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_TEST_EVENT_WAITER_H_
+#define NET_TEST_EVENT_WAITER_H_
+
+#include "base/run_loop.h"
+
+namespace net {
+
+// Helper class to run a RunLoop until an expected event is reported.
+template <typename Event>
+class EventWaiter {
+ public:
+ // Runs a RunLoop until NotifyEvent() is called with |event|.
+ void WaitForEvent(Event event) {
+ expected_event_ = event;
+ base::RunLoop run_loop;
+ quit_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ // Unblocks a WaitForEvent() call if it was called with |event|. Otherwise,
+ // has no effect.
+ void NotifyEvent(Event event) {
+ if (event == expected_event_ && !quit_closure_.is_null()) {
+ quit_closure_.Run();
+ quit_closure_.Reset();
+ }
+ }
+
+ private:
+ Event expected_event_;
+ base::Closure quit_closure_;
+};
+
+} // namespace net
+
+#endif // NET_TEST_EVENT_WAITER_H_
diff --git a/chromium/net/test/gtest_util.h b/chromium/net/test/gtest_util.h
index 14492c2a780..1d6708774ff 100644
--- a/chromium/net/test/gtest_util.h
+++ b/chromium/net/test/gtest_util.h
@@ -7,8 +7,8 @@
#ifndef NET_QUIC_TEST_TOOLS_GTEST_UTIL_H_
#define NET_QUIC_TEST_TOOLS_GTEST_UTIL_H_
+#include "base/test/mock_log.h"
#include "net/test/scoped_disable_exit_on_dfatal.h"
-#include "net/test/scoped_mock_log.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,26 +17,25 @@ namespace test {
// Internal implementation for the EXPECT_DFATAL and ASSERT_DFATAL
// macros. Do not use this directly.
-#define GTEST_DFATAL_(statement, matcher, fail) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (true) { \
- ::net::test::ScopedMockLog gtest_log; \
- ::net::test::ScopedDisableExitOnDFatal gtest_disable_exit; \
- using ::testing::_; \
- EXPECT_CALL(gtest_log, Log(_, _, _, _, _)) \
- .WillRepeatedly(::testing::Return(false)); \
- EXPECT_CALL(gtest_log, Log(logging::LOG_DFATAL, _, _, _, matcher)) \
- .Times(::testing::AtLeast(1)) \
- .WillOnce(::testing::Return(false)); \
- gtest_log.StartCapturingLogs(); \
- { statement; } \
- gtest_log.StopCapturingLogs(); \
- if (!testing::Mock::VerifyAndClear(&gtest_log)) { \
- goto GTEST_CONCAT_TOKEN_(gtest_label_dfatal_, __LINE__); \
- } \
- } else \
- GTEST_CONCAT_TOKEN_(gtest_label_dfatal_, __LINE__): \
- fail("")
+#define GTEST_DFATAL_(statement, matcher, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (true) { \
+ ::base::test::MockLog gtest_log; \
+ ::net::test::ScopedDisableExitOnDFatal gtest_disable_exit; \
+ using ::testing::_; \
+ EXPECT_CALL(gtest_log, Log(_, _, _, _, _)) \
+ .WillRepeatedly(::testing::Return(false)); \
+ EXPECT_CALL(gtest_log, Log(logging::LOG_DFATAL, _, _, _, matcher)) \
+ .Times(::testing::AtLeast(1)) \
+ .WillOnce(::testing::Return(false)); \
+ gtest_log.StartCapturingLogs(); \
+ { statement; } \
+ gtest_log.StopCapturingLogs(); \
+ if (!testing::Mock::VerifyAndClear(&gtest_log)) { \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_dfatal_, __LINE__); \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_dfatal_, __LINE__) : fail("")
// The EXPECT_DFATAL and ASSERT_DFATAL macros are lightweight
// alternatives to EXPECT_DEBUG_DEATH and ASSERT_DEBUG_DEATH. They
diff --git a/chromium/net/test/net_test_suite.cc b/chromium/net/test/net_test_suite.cc
index ed8a103ac1e..b14e3fea536 100644
--- a/chromium/net/test/net_test_suite.cc
+++ b/chromium/net/test/net_test_suite.cc
@@ -10,12 +10,12 @@
#include "net/spdy/spdy_session.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(USE_NSS) || defined(OS_IOS)
-#include "net/ocsp/nss_ocsp.h"
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+#include "net/cert_net/nss_ocsp.h"
#endif
class StaticReset : public ::testing::EmptyTestEventListener {
- virtual void OnTestStart(const ::testing::TestInfo& test_info) override {
+ void OnTestStart(const ::testing::TestInfo& test_info) override {
net::HttpStreamFactory::ResetStaticSettingsToInit();
}
};
@@ -38,7 +38,7 @@ void NetTestSuite::Initialize() {
}
void NetTestSuite::Shutdown() {
-#if defined(USE_NSS) || defined(OS_IOS)
+#if defined(USE_NSS_CERTS) || defined(OS_IOS)
net::ShutdownNSSHttpIO();
#endif
diff --git a/chromium/net/test/python_utils.cc b/chromium/net/test/python_utils.cc
index 7e40faefe83..7d137b7c411 100644
--- a/chromium/net/test/python_utils.cc
+++ b/chromium/net/test/python_utils.cc
@@ -9,11 +9,18 @@
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
+#include "base/process/launch.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#if defined(OS_MACOSX)
+#include "base/mac/foundation_util.h"
+#endif
+
const char kPythonPathEnv[] = "PYTHONPATH";
void AppendToPythonPath(const base::FilePath& dir) {
@@ -39,31 +46,6 @@ void AppendToPythonPath(const base::FilePath& dir) {
}
}
-namespace {
-
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
-// Search for |to_try|, rolling up the directory tree from
-// |start_dir|. If found, return true and put the path to |to_try| in
-// |out_dir|. If not, return false and leave |out_dir| untouched.
-bool TryRelativeToDir(const base::FilePath& start_dir,
- const base::FilePath& to_try,
- base::FilePath* out_dir) {
- base::FilePath dir(start_dir);
- while (!base::DirectoryExists(dir.Append(to_try))) {
- base::FilePath parent = dir.DirName();
- if (parent == dir) {
- // We hit the root directory.
- return false;
- }
- dir = parent;
- }
- *out_dir = dir;
- return true;
-}
-#endif // defined(OS_MACOSX) || defined(OS_CHROMEOS)
-
-} // namespace
-
bool GetPyProtoPath(base::FilePath* dir) {
// Locate the Python code generated by the protocol buffers compiler.
base::FilePath generated_code_dir;
@@ -72,44 +54,62 @@ bool GetPyProtoPath(base::FilePath* dir) {
return false;
}
+#if defined(OS_MACOSX)
+ if (base::mac::AmIBundled())
+ generated_code_dir = generated_code_dir.DirName().DirName().DirName();
+#endif
+
+ // Used for GYP. TODO(jam): remove after GN conversion.
const base::FilePath kPyProto(FILE_PATH_LITERAL("pyproto"));
+ if (base::DirectoryExists(generated_code_dir.Append(kPyProto))) {
+ *dir = generated_code_dir.Append(kPyProto);
+ return true;
+ }
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
- base::FilePath source_dir;
- if (!PathService::Get(base::DIR_SOURCE_ROOT, &source_dir)) {
- LOG(ERROR) << "Can't find " << source_dir.value();
- return false;
+ // Used for GN.
+ const base::FilePath kGen(FILE_PATH_LITERAL("gen"));
+ if (base::DirectoryExists(generated_code_dir.Append(kGen))) {
+ *dir = generated_code_dir.Append(kGen);
+ return true;
}
- // On Mac, and possibly Chrome OS, DIR_EXE might be pointing deep
- // into the Release/ (or Debug/) directory and we can't depend on
- // how far down it goes. So we walk upwards from DIR_EXE until we
- // find a likely looking spot.
- if (!TryRelativeToDir(generated_code_dir, kPyProto, dir)) {
- LOG(WARNING) << "Can't find " << kPyProto.value()
- << " next to " << generated_code_dir.value();
- // On Chrome OS, we may have installed the test binaries and support tools
- // in a wholly separate location, relative to DIR_SOURCE_ROOT. We'll want
- // to do a similar investigation from that point as well.
- generated_code_dir = source_dir
- .Append(FILE_PATH_LITERAL("out"))
- .Append(FILE_PATH_LITERAL("Release"));
- if (!TryRelativeToDir(generated_code_dir, kPyProto, dir)) {
- LOG(WARNING) << "Can't find " << kPyProto.value()
- << " next to " << generated_code_dir.value();
- return false;
- }
+
+ return false;
+}
+
+#if defined(OS_WIN)
+struct PythonExePath {
+ PythonExePath() {
+ // This is test-only code, so CHECK with a subprocess invocation is ok.
+ base::CommandLine command(base::FilePath(FILE_PATH_LITERAL("cmd")));
+ command.AppendArg("/c");
+ command.AppendArg("python");
+ command.AppendArg("-c");
+ command.AppendArg("import sys; print sys.executable");
+ std::string output;
+ CHECK(GetAppOutput(command, &output));
+ // This does only work if cmd.exe doesn't use a non-US codepage.
+ path_ = base::ASCIIToUTF16(output);
+ TrimWhitespace(path_, base::TRIM_ALL, &path_);
}
- generated_code_dir = *dir;
+ base::string16 path_;
+};
+static base::LazyInstance<PythonExePath>::Leaky g_python_path;
#endif
- *dir = generated_code_dir.Append(kPyProto);
- VLOG(2) << "Found " << kPyProto.value() << " in " << dir->value();
- return true;
-}
bool GetPythonCommand(base::CommandLine* python_cmd) {
DCHECK(python_cmd);
+#if defined(OS_WIN)
+ // Most developers have depot_tools in their path, which only has a
+ // python.bat, not a python.exe. Go through cmd to find the path to
+ // the python executable.
+ // (Don't just return a a "cmd /c python" command line, because then tests
+ // that try to kill the python process will kill the cmd process instead,
+ // which can cause flakiness.)
+ python_cmd->SetProgram(base::FilePath(g_python_path.Get().path_));
+#else
python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("python")));
+#endif
// Launch python in unbuffered mode, so that python output doesn't mix with
// gtest output in buildbot log files. See http://crbug.com/147368.
diff --git a/chromium/net/test/run_all_unittests.cc b/chromium/net/test/run_all_unittests.cc
index e86487e6fed..25016ca589c 100644
--- a/chromium/net/test/run_all_unittests.cc
+++ b/chromium/net/test/run_all_unittests.cc
@@ -19,12 +19,8 @@
#include "url/android/url_jni_registrar.h"
#endif
-#if !defined(OS_IOS)
-#include "net/proxy/proxy_resolver_v8.h"
-#endif
-
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-#include "gin/public/isolate_holder.h"
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+#include "third_party/mojo/src/mojo/edk/embedder/test_embedder.h"
#endif
using net::internal::ClientSocketPoolBaseHelper;
@@ -61,12 +57,8 @@ int main(int argc, char** argv) {
// single-threaded.
net::EnableSSLServerSockets();
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- gin::IsolateHolder::LoadV8Snapshot();
-#endif
-
-#if !defined(OS_IOS)
- net::ProxyResolverV8::EnsureIsolateCreated();
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ mojo::embedder::test::InitWithSimplePlatformSupport();
#endif
return base::LaunchUnitTests(
diff --git a/chromium/net/test/scoped_mock_log.cc b/chromium/net/test/scoped_mock_log.cc
deleted file mode 100644
index 3bc99cb3d42..00000000000
--- a/chromium/net/test/scoped_mock_log.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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/test/scoped_mock_log.h"
-
-#include "base/logging.h"
-
-namespace net {
-namespace test {
-
-// static
-ScopedMockLog* ScopedMockLog::g_instance_ = NULL;
-
-ScopedMockLog::ScopedMockLog() : is_capturing_logs_(false) {}
-
-ScopedMockLog::~ScopedMockLog() {
- if (is_capturing_logs_) {
- StopCapturingLogs();
- }
-}
-
-void ScopedMockLog::StartCapturingLogs() {
- // We don't use CHECK(), which can generate a new LOG message, and
- // thus can confuse ScopedMockLog objects or other registered
- // LogSinks.
- RAW_CHECK(!is_capturing_logs_);
- RAW_CHECK(!g_instance_);
-
- is_capturing_logs_ = true;
- g_instance_ = this;
- previous_handler_ = logging::GetLogMessageHandler();
- logging::SetLogMessageHandler(LogMessageHandler);
-}
-
-void ScopedMockLog::StopCapturingLogs() {
- // We don't use CHECK(), which can generate a new LOG message, and
- // thus can confuse ScopedMockLog objects or other registered
- // LogSinks.
- RAW_CHECK(is_capturing_logs_);
- RAW_CHECK(g_instance_ == this);
-
- is_capturing_logs_ = false;
- logging::SetLogMessageHandler(previous_handler_);
- g_instance_ = NULL;
-}
-
-// static
-bool ScopedMockLog::LogMessageHandler(int severity,
- const char* file,
- int line,
- size_t message_start,
- const std::string& str) {
- return g_instance_->Log(severity, file, line, message_start, str);
-}
-
-} // namespace test
-} // namespace net
diff --git a/chromium/net/test/scoped_mock_log.h b/chromium/net/test/scoped_mock_log.h
deleted file mode 100644
index e1edfcccde8..00000000000
--- a/chromium/net/test/scoped_mock_log.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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_QUIC_TEST_TOOLS_SCOPED_MOCK_LOG_H_
-#define NET_QUIC_TEST_TOOLS_SCOPED_MOCK_LOG_H_
-
-#include "base/logging.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace test {
-
-// A ScopedMockLog object intercepts LOG() messages issued during its
-// lifespan. Using this together with gMock, it's very easy to test
-// how a piece of code calls LOG(). The typical usage:
-//
-// TEST(FooTest, LogsCorrectly) {
-// ScopedMockLog log;
-//
-// // We expect the WARNING "Something bad!" exactly twice.
-// EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
-// .Times(2);
-//
-// // We allow foo.cc to call LOG(INFO) any number of times.
-// EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
-// .Times(AnyNumber());
-//
-// log.StartCapturingLogs(); // Call this after done setting expectations.
-// Foo(); // Exercises the code under test.
-// }
-//
-// CAVEAT: base/logging does not allow a thread to call LOG() again
-// when it's already inside a LOG() call. Doing so will cause a
-// deadlock. Therefore, it's the user's responsibility to not call
-// LOG() in an action triggered by ScopedMockLog::Log(). You may call
-// RAW_LOG() instead.
-class ScopedMockLog {
- public:
- // Creates a ScopedMockLog object that is not capturing logs.
- // If it were to start to capture logs, it could be a problem if
- // some other threads already exist and are logging, as the user
- // hasn't had a chance to set up expectation on this object yet
- // (calling a mock method before setting the expectation is
- // UNDEFINED behavior).
- ScopedMockLog();
-
- // When the object is destructed, it stops intercepting logs.
- ~ScopedMockLog();
-
- // Starts log capturing if the object isn't already doing so.
- // Otherwise crashes. Usually this method is called in the same
- // thread that created this object. It is the user's responsibility
- // to not call this method if another thread may be calling it or
- // StopCapturingLogs() at the same time.
- void StartCapturingLogs();
-
- // Stops log capturing if the object is capturing logs. Otherwise
- // crashes. Usually this method is called in the same thread that
- // created this object. It is the user's responsibility to not call
- // this method if another thread may be calling it or
- // StartCapturingLogs() at the same time.
- void StopCapturingLogs();
-
- // Sets the Log Message Handler that gets passed every log message before
- // it's sent to other log destinations (if any).
- // Returns true to signal that it handled the message and the message
- // should not be sent to other log destinations.
- MOCK_METHOD5(Log, bool(int severity,
- const char* file,
- int line,
- size_t message_start,
- const std::string& str));
-
- private:
- // The currently active scoped mock log.
- static ScopedMockLog* g_instance_;
-
- // Static function which is set as the logging message handler.
- // Called once for each message.
- static bool LogMessageHandler(int severity,
- const char* file,
- int line,
- size_t message_start,
- const std::string& str);
-
- // True if this object is currently capturing logs.
- bool is_capturing_logs_;
-
- // The previous handler to restore when the ScopedMockLog is destroyed.
- logging::LogMessageHandlerFunction previous_handler_;
-};
-
-} // namespace test
-} // namespace net
-
-#endif // NET_QUIC_TEST_TOOLS_SCOPED_MOCK_LOG_H_
diff --git a/chromium/net/test/spawned_test_server/base_test_server.cc b/chromium/net/test/spawned_test_server/base_test_server.cc
index 0e23c7a3b55..5d97f8dd6bc 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.cc
+++ b/chromium/net/test/spawned_test_server/base_test_server.cc
@@ -16,11 +16,11 @@
#include "net/base/address_list.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
#include "net/base/net_util.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/test_root_certs.h"
#include "net/dns/host_resolver.h"
+#include "net/log/net_log.h"
#include "url/gurl.h"
namespace net {
@@ -29,11 +29,17 @@ namespace {
std::string GetHostname(BaseTestServer::Type type,
const BaseTestServer::SSLOptions& options) {
- if (BaseTestServer::UsingSSL(type) &&
- options.server_certificate ==
- BaseTestServer::SSLOptions::CERT_MISMATCHED_NAME) {
- // Return a different hostname string that resolves to the same hostname.
- return "localhost";
+ if (BaseTestServer::UsingSSL(type)) {
+ if (options.server_certificate ==
+ BaseTestServer::SSLOptions::CERT_MISMATCHED_NAME ||
+ options.server_certificate ==
+ BaseTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN) {
+ // For |CERT_MISMATCHED_NAME|, return a different hostname string
+ // that resolves to the same hostname. For
+ // |CERT_COMMON_NAME_IS_DOMAIN|, the certificate is issued for
+ // "localhost" instead of "127.0.0.1".
+ return "localhost";
+ }
}
// Use the 127.0.0.1 as default.
@@ -44,8 +50,6 @@ std::string GetClientCertType(SSLClientCertType type) {
switch (type) {
case CLIENT_CERT_RSA_SIGN:
return "rsa_sign";
- case CLIENT_CERT_DSS_SIGN:
- return "dss_sign";
case CLIENT_CERT_ECDSA_SIGN:
return "ecdsa_sign";
default:
@@ -59,6 +63,8 @@ void GetKeyExchangesList(int key_exchange, base::ListValue* values) {
values->Append(new base::StringValue("rsa"));
if (key_exchange & BaseTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA)
values->Append(new base::StringValue("dhe_rsa"));
+ if (key_exchange & BaseTestServer::SSLOptions::KEY_EXCHANGE_ECDHE_RSA)
+ values->Append(new base::StringValue("ecdhe_rsa"));
}
void GetCiphersList(int cipher, base::ListValue* values) {
@@ -70,6 +76,8 @@ void GetCiphersList(int cipher, base::ListValue* values) {
values->Append(new base::StringValue("aes256"));
if (cipher & BaseTestServer::SSLOptions::BULK_CIPHER_3DES)
values->Append(new base::StringValue("3des"));
+ if (cipher & BaseTestServer::SSLOptions::BULK_CIPHER_AES128GCM)
+ values->Append(new base::StringValue("aes128gcm"));
}
base::StringValue* GetTLSIntoleranceType(
@@ -101,8 +109,9 @@ BaseTestServer::SSLOptions::SSLOptions()
tls_intolerance_type(TLS_INTOLERANCE_ALERT),
fallback_scsv_enabled(false),
staple_ocsp_response(false),
+ ocsp_server_unavailable(false),
enable_npn(false),
- disable_session_cache(false) {
+ alert_after_handshake(false) {
}
BaseTestServer::SSLOptions::SSLOptions(
@@ -118,8 +127,9 @@ BaseTestServer::SSLOptions::SSLOptions(
tls_intolerance_type(TLS_INTOLERANCE_ALERT),
fallback_scsv_enabled(false),
staple_ocsp_response(false),
+ ocsp_server_unavailable(false),
enable_npn(false),
- disable_session_cache(false) {
+ alert_after_handshake(false) {
}
BaseTestServer::SSLOptions::~SSLOptions() {}
@@ -129,6 +139,8 @@ base::FilePath BaseTestServer::SSLOptions::GetCertificateFile() const {
case CERT_OK:
case CERT_MISMATCHED_NAME:
return base::FilePath(FILE_PATH_LITERAL("ok_cert.pem"));
+ case CERT_COMMON_NAME_IS_DOMAIN:
+ return base::FilePath(FILE_PATH_LITERAL("localhost_cert.pem"));
case CERT_EXPIRED:
return base::FilePath(FILE_PATH_LITERAL("expired_cert.pem"));
case CERT_CHAIN_WRONG_ROOT:
@@ -170,7 +182,8 @@ BaseTestServer::BaseTestServer(Type type, const std::string& host)
: type_(type),
started_(false),
log_to_console_(false),
- ws_basic_auth_(false) {
+ ws_basic_auth_(false),
+ no_anonymous_ftp_user_(false) {
Init(host);
}
@@ -179,7 +192,8 @@ BaseTestServer::BaseTestServer(Type type, const SSLOptions& ssl_options)
type_(type),
started_(false),
log_to_console_(false),
- ws_basic_auth_(false) {
+ ws_basic_auth_(false),
+ no_anonymous_ftp_user_(false) {
DCHECK(UsingSSL(type));
Init(GetHostname(type, ssl_options));
}
@@ -231,7 +245,7 @@ bool BaseTestServer::GetAddressList(AddressList* address_list) const {
BoundNetLog());
if (rv == ERR_IO_PENDING)
rv = callback.WaitForResult();
- if (rv != net::OK) {
+ if (rv != OK) {
LOG(ERROR) << "Failed to resolve hostname: " << host_port_pair_.host();
return false;
}
@@ -296,6 +310,24 @@ bool BaseTestServer::GetFilePathWithReplacements(
return true;
}
+bool BaseTestServer::LoadTestRootCert() const {
+ TestRootCerts* root_certs = TestRootCerts::GetInstance();
+ if (!root_certs)
+ return false;
+
+ // Should always use absolute path to load the root certificate.
+ base::FilePath root_certificate_path = certificates_dir_;
+ if (!certificates_dir_.IsAbsolute()) {
+ base::FilePath src_dir;
+ if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
+ return false;
+ root_certificate_path = src_dir.Append(certificates_dir_);
+ }
+
+ return root_certs->AddFromFile(
+ root_certificate_path.AppendASCII("root_ca_cert.pem"));
+}
+
void BaseTestServer::Init(const std::string& host) {
host_port_pair_ = HostPortPair(host, 0);
@@ -338,24 +370,6 @@ bool BaseTestServer::ParseServerData(const std::string& server_data) {
return true;
}
-bool BaseTestServer::LoadTestRootCert() const {
- TestRootCerts* root_certs = TestRootCerts::GetInstance();
- if (!root_certs)
- return false;
-
- // Should always use absolute path to load the root certificate.
- base::FilePath root_certificate_path = certificates_dir_;
- if (!certificates_dir_.IsAbsolute()) {
- base::FilePath src_dir;
- if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
- return false;
- root_certificate_path = src_dir.Append(certificates_dir_);
- }
-
- return root_certs->AddFromFile(
- root_certificate_path.AppendASCII("root_ca_cert.pem"));
-}
-
bool BaseTestServer::SetupWhenServerStarted() {
DCHECK(host_port_pair_.port());
@@ -395,6 +409,11 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const {
arguments->Set("ws-basic-auth", base::Value::CreateNullValue());
}
+ if (no_anonymous_ftp_user_) {
+ DCHECK_EQ(TYPE_FTP, type_);
+ arguments->Set("no-anonymous-ftp-user", base::Value::CreateNullValue());
+ }
+
if (UsingSSL(type_)) {
// Check the certificate arguments of the HTTPS server.
base::FilePath certificate_path(certificates_dir_);
@@ -476,10 +495,14 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const {
}
if (ssl_options_.staple_ocsp_response)
arguments->Set("staple-ocsp-response", base::Value::CreateNullValue());
+ if (ssl_options_.ocsp_server_unavailable) {
+ arguments->Set("ocsp-server-unavailable",
+ base::Value::CreateNullValue());
+ }
if (ssl_options_.enable_npn)
arguments->Set("enable-npn", base::Value::CreateNullValue());
- if (ssl_options_.disable_session_cache)
- arguments->Set("disable-session-cache", base::Value::CreateNullValue());
+ if (ssl_options_.alert_after_handshake)
+ arguments->Set("alert-after-handshake", base::Value::CreateNullValue());
}
return GenerateAdditionalArguments(arguments);
diff --git a/chromium/net/test/spawned_test_server/base_test_server.h b/chromium/net/test/spawned_test_server/base_test_server.h
index 45ea1cecffa..b72e5d3e05a 100644
--- a/chromium/net/test/spawned_test_server/base_test_server.h
+++ b/chromium/net/test/spawned_test_server/base_test_server.h
@@ -61,6 +61,10 @@ class BaseTestServer {
// TestRootStore) is expected to have a self-signed version of the
// intermediate.
CERT_CHAIN_WRONG_ROOT,
+
+ // Causes the testserver to use a hostname that is a domain
+ // instead of an IP.
+ CERT_COMMON_NAME_IS_DOMAIN,
};
// OCSPStatus enumerates the types of OCSP response that the testserver
@@ -79,10 +83,11 @@ class BaseTestServer {
// Special value used to indicate that any algorithm the server supports
// is acceptable. Preferred over explicitly OR-ing all key exchange
// algorithms.
- KEY_EXCHANGE_ANY = 0,
+ KEY_EXCHANGE_ANY = 0,
- KEY_EXCHANGE_RSA = (1 << 0),
+ KEY_EXCHANGE_RSA = (1 << 0),
KEY_EXCHANGE_DHE_RSA = (1 << 1),
+ KEY_EXCHANGE_ECDHE_RSA = (1 << 2),
};
// Bitmask of bulk encryption algorithms that the test server supports
@@ -90,16 +95,18 @@ class BaseTestServer {
enum BulkCipher {
// Special value used to indicate that any algorithm the server supports
// is acceptable. Preferred over explicitly OR-ing all ciphers.
- BULK_CIPHER_ANY = 0,
+ BULK_CIPHER_ANY = 0,
- BULK_CIPHER_RC4 = (1 << 0),
+ BULK_CIPHER_RC4 = (1 << 0),
BULK_CIPHER_AES128 = (1 << 1),
BULK_CIPHER_AES256 = (1 << 2),
// NOTE: 3DES support in the Python test server has external
// dependencies and not be available on all machines. Clients may not
// be able to connect if only 3DES is specified.
- BULK_CIPHER_3DES = (1 << 3),
+ BULK_CIPHER_3DES = (1 << 3),
+
+ BULK_CIPHER_AES128GCM = (1 << 4),
};
// NOTE: the values of these enumerators are passed to the the Python test
@@ -201,13 +208,15 @@ class BaseTestServer {
// Whether to staple the OCSP response.
bool staple_ocsp_response;
+ // Whether to make the OCSP server unavailable. This does not affect the
+ // stapled OCSP response.
+ bool ocsp_server_unavailable;
+
// Whether to enable NPN support.
bool enable_npn;
- // Whether to disable TLS session caching. When session caching is
- // disabled, the server will use an empty session ID in the
- // ServerHello.
- bool disable_session_cache;
+ // Whether to send a fatal alert immediately after completing the handshake.
+ bool alert_after_handshake;
};
// Pass as the 'host' parameter during construction to server on 127.0.0.1
@@ -253,6 +262,15 @@ class BaseTestServer {
ws_basic_auth_ = ws_basic_auth;
}
+ // Disable creation of anonymous FTP user.
+ void set_no_anonymous_ftp_user(bool no_anonymous_ftp_user) {
+ no_anonymous_ftp_user_ = no_anonymous_ftp_user;
+ }
+
+ // Marks the root certificate of an HTTPS test server as trusted for
+ // the duration of tests.
+ bool LoadTestRootCert() const WARN_UNUSED_RESULT;
+
protected:
virtual ~BaseTestServer();
Type type() const { return type_; }
@@ -291,10 +309,6 @@ class BaseTestServer {
private:
void Init(const std::string& host);
- // Marks the root certificate of an HTTPS test server as trusted for
- // the duration of tests.
- bool LoadTestRootCert() const WARN_UNUSED_RESULT;
-
// Document root of the test server.
base::FilePath document_root_;
@@ -322,6 +336,9 @@ class BaseTestServer {
// Is WebSocket basic HTTP authentication enabled?
bool ws_basic_auth_;
+ // Disable creation of anonymous FTP user?
+ bool no_anonymous_ftp_user_;
+
scoped_ptr<ScopedPortException> allowed_port_;
DISALLOW_COPY_AND_ASSIGN(BaseTestServer);
diff --git a/chromium/net/test/spawned_test_server/local_test_server.cc b/chromium/net/test/spawned_test_server/local_test_server.cc
index c85e05a8dec..77630b175ae 100644
--- a/chromium/net/test/spawned_test_server/local_test_server.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server.cc
@@ -8,7 +8,6 @@
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/path_service.h"
-#include "base/process/kill.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
@@ -121,21 +120,19 @@ bool LocalTestServer::BlockUntilStarted() {
bool LocalTestServer::Stop() {
CleanUpWhenStoppingServer();
- if (!process_handle_)
+ if (!process_.IsValid())
return true;
// First check if the process has already terminated.
- bool ret = base::WaitForSingleProcess(process_handle_, base::TimeDelta());
- if (!ret) {
- ret = base::KillProcess(process_handle_, 1, true);
- }
-
- if (ret) {
- base::CloseProcessHandle(process_handle_);
- process_handle_ = base::kNullProcessHandle;
- } else {
+ int exit_code;
+ bool ret = process_.WaitForExitWithTimeout(base::TimeDelta(), &exit_code);
+ if (!ret)
+ ret = process_.Terminate(1, true);
+
+ if (ret)
+ process_.Close();
+ else
VLOG(1) << "Kill failed?";
- }
return ret;
}
@@ -149,7 +146,6 @@ bool LocalTestServer::Init(const base::FilePath& document_root) {
// number out over a pipe that this TestServer object will read from. Once
// that is complete, the host port pair will contain the actual port.
DCHECK(!GetPort());
- process_handle_ = base::kNullProcessHandle;
base::FilePath src_dir;
if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
diff --git a/chromium/net/test/spawned_test_server/local_test_server.h b/chromium/net/test/spawned_test_server/local_test_server.h
index 37b118588a5..785d7267056 100644
--- a/chromium/net/test/spawned_test_server/local_test_server.h
+++ b/chromium/net/test/spawned_test_server/local_test_server.h
@@ -9,7 +9,7 @@
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
-#include "base/process/process_handle.h"
+#include "base/process/process.h"
#include "net/test/spawned_test_server/base_test_server.h"
#if defined(OS_WIN)
@@ -92,8 +92,8 @@ class LocalTestServer : public BaseTestServer {
// Waits for the server to start. Returns true on success.
bool WaitToStart() WARN_UNUSED_RESULT;
- // Handle of the Python process running the test server.
- base::ProcessHandle process_handle_;
+ // The Python process running the test server.
+ base::Process process_;
#if defined(OS_WIN)
// The pipe file handle we read from.
diff --git a/chromium/net/test/spawned_test_server/local_test_server_posix.cc b/chromium/net/test/spawned_test_server/local_test_server_posix.cc
index 0edbedf1e42..c770152ea6b 100644
--- a/chromium/net/test/spawned_test_server/local_test_server_posix.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server_posix.cc
@@ -139,7 +139,8 @@ bool LocalTestServer::LaunchPython(const base::FilePath& testserver_path) {
base::LaunchOptions options;
options.fds_to_remap = &map_write_fd;
- if (!base::LaunchProcess(python_command, options, &process_handle_)) {
+ process_ = base::LaunchProcess(python_command, options);
+ if (!process_.IsValid()) {
LOG(ERROR) << "Failed to launch " << python_command.GetCommandLineString();
return false;
}
diff --git a/chromium/net/test/spawned_test_server/local_test_server_win.cc b/chromium/net/test/spawned_test_server/local_test_server_win.cc
index 412e4e10c80..0476b907caf 100644
--- a/chromium/net/test/spawned_test_server/local_test_server_win.cc
+++ b/chromium/net/test/spawned_test_server/local_test_server_win.cc
@@ -78,60 +78,6 @@ bool ReadData(HANDLE read_fd, HANDLE write_fd,
return true;
}
-// Class that sets up a temporary path that includes the supplied path
-// at the end.
-//
-// TODO(bratell): By making this more generic we can possibly reuse
-// it at other places such as
-// chrome/common/multi_process_lock_unittest.cc.
-class ScopedPath {
- public:
- // Constructor which sets up the environment to include the path to
- // |path_to_add|.
- explicit ScopedPath(const base::FilePath& path_to_add);
-
- // Destructor that restores the path that were active when the
- // object was constructed.
- ~ScopedPath();
-
- private:
- // The PATH environment variable before it was changed or an empty
- // string if there was no PATH environment variable.
- std::string old_path_;
-
- // The helper object that allows us to read and set environment
- // variables more easily.
- scoped_ptr<base::Environment> environment_;
-
- // A flag saying if we have actually modified the environment.
- bool path_modified_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedPath);
-};
-
-ScopedPath::ScopedPath(const base::FilePath& path_to_add)
- : environment_(base::Environment::Create()),
- path_modified_(false) {
- environment_->GetVar("PATH", &old_path_);
-
- std::string new_value = old_path_;
- if (!new_value.empty())
- new_value += ";";
-
- new_value += base::WideToUTF8(path_to_add.value());
-
- path_modified_ = environment_->SetVar("PATH", new_value);
-}
-
-ScopedPath::~ScopedPath() {
- if (!path_modified_)
- return;
- if (old_path_.empty())
- environment_->UnSetVar("PATH");
- else
- environment_->SetVar("PATH", old_path_);
-}
-
} // namespace
namespace net {
@@ -155,8 +101,9 @@ bool LocalTestServer::LaunchPython(const base::FilePath& testserver_path) {
child_write_fd_.Set(child_write);
// Have the child inherit the write half.
- if (!SetHandleInformation(child_write, HANDLE_FLAG_INHERIT,
- HANDLE_FLAG_INHERIT)) {
+ if (!::DuplicateHandle(::GetCurrentProcess(), child_write,
+ ::GetCurrentProcess(), &child_write, 0, TRUE,
+ DUPLICATE_SAME_ACCESS)) {
PLOG(ERROR) << "Failed to enable pipe inheritance";
return false;
}
@@ -176,11 +123,14 @@ bool LocalTestServer::LaunchPython(const base::FilePath& testserver_path) {
base::LaunchOptions launch_options;
launch_options.inherit_handles = true;
- if (!base::LaunchProcess(python_command, launch_options, &process_handle_)) {
+ process_ = base::LaunchProcess(python_command, launch_options);
+ if (!process_.IsValid()) {
LOG(ERROR) << "Failed to launch " << python_command.GetCommandLineString();
+ ::CloseHandle(child_write);
return false;
}
+ ::CloseHandle(child_write);
return true;
}
diff --git a/chromium/net/test/spawned_test_server/remote_test_server.cc b/chromium/net/test/spawned_test_server/remote_test_server.cc
index 6d098c8f49c..1d1481b9d16 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server.cc
+++ b/chromium/net/test/spawned_test_server/remote_test_server.cc
@@ -95,6 +95,8 @@ bool RemoteTestServer::Start() {
if (!GenerateArguments(&arguments_dict))
return false;
+ arguments_dict.Set("on-remote-server", base::Value::CreateNullValue());
+
// Append the 'server-type' argument which is used by spawner server to
// pass right server type to Python test server.
arguments_dict.SetString("server-type", GetServerTypeString(type()));
diff --git a/chromium/net/test/spawned_test_server/remote_test_server.h b/chromium/net/test/spawned_test_server/remote_test_server.h
index de12e4ebe44..a8b8bb2c235 100644
--- a/chromium/net/test/spawned_test_server/remote_test_server.h
+++ b/chromium/net/test/spawned_test_server/remote_test_server.h
@@ -29,7 +29,7 @@ class RemoteTestServer : public BaseTestServer {
const SSLOptions& ssl_options,
const base::FilePath& document_root);
- virtual ~RemoteTestServer();
+ ~RemoteTestServer() override;
// Starts the Python test server on the host, instead of on the device, and
// blocks until the server is ready.
diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.cc b/chromium/net/test/spawned_test_server/spawner_communicator.cc
index 53484ead585..d16e57a6cdb 100644
--- a/chromium/net/test/spawned_test_server/spawner_communicator.cc
+++ b/chromium/net/test/spawned_test_server/spawner_communicator.cc
@@ -47,7 +47,7 @@ class SpawnerRequestData : public base::SupportsUserData::Data {
data_received_->clear();
}
- virtual ~SpawnerRequestData() {}
+ ~SpawnerRequestData() override {}
bool DoesRequestIdMatch(int request_id) const {
return request_id_ == request_id;
@@ -173,7 +173,7 @@ void SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread(
DCHECK(!cur_request_.get());
context_.reset(new TestURLRequestContext);
cur_request_ = context_->CreateRequest(
- GenerateSpawnerCommandURL(command, port_), DEFAULT_PRIORITY, this, NULL);
+ GenerateSpawnerCommandURL(command, port_), DEFAULT_PRIORITY, this);
DCHECK(cur_request_);
int current_request_id = ++next_id_;
SpawnerRequestData* data = new SpawnerRequestData(current_request_id,
diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.h b/chromium/net/test/spawned_test_server/spawner_communicator.h
index 549ad9158c5..15ae0c5e1c3 100644
--- a/chromium/net/test/spawned_test_server/spawner_communicator.h
+++ b/chromium/net/test/spawned_test_server/spawner_communicator.h
@@ -29,7 +29,7 @@ class ScopedPortException;
// themselves continue running on the device. To control the test server on the
// host machine, a second HTTP server is started, the spawner server, which
// controls the life cycle of remote test servers. Calls to start/kill the
-// net::SpawnedTestServer are then redirected to the spawner server via
+// SpawnedTestServer are then redirected to the spawner server via
// this spawner communicator.
//
// Currently only three commands are supported by spawner.
@@ -58,10 +58,10 @@ class ScopedPortException;
// The internal I/O thread is required by net stack to perform net I/O.
// The Start/StopServer methods block the caller thread until result is
// fetched from spawner server or timed-out.
-class SpawnerCommunicator : public net::URLRequest::Delegate {
+class SpawnerCommunicator : public URLRequest::Delegate {
public:
explicit SpawnerCommunicator(uint16 port);
- virtual ~SpawnerCommunicator();
+ ~SpawnerCommunicator() override;
// Starts an instance of the Python test server on the host/ machine.
// If successfully started, returns true, setting |*port| to the port
@@ -100,8 +100,8 @@ class SpawnerCommunicator : public net::URLRequest::Delegate {
std::string* data_received);
// URLRequest::Delegate methods. Called on the IO thread.
- virtual void OnResponseStarted(URLRequest* request) override;
- virtual void OnReadCompleted(URLRequest* request, int num_bytes) override;
+ void OnResponseStarted(URLRequest* request) override;
+ void OnReadCompleted(URLRequest* request, int num_bytes) override;
// Reads Result from the response. Called on the IO thread.
void ReadResult(URLRequest* request);
diff --git a/chromium/net/test/test_certificate_data.h b/chromium/net/test/test_certificate_data.h
index 3ccda5e34cb..b5346b4d9d1 100644
--- a/chromium/net/test/test_certificate_data.h
+++ b/chromium/net/test/test_certificate_data.h
@@ -9,22 +9,26 @@ static const char kNistSPKIHash[] =
"\x15\x60\xde\x65\x4e\x03\x9f\xd0\x08\x82"
"\xa9\x6a\xc4\x65\x8e\x6f\x92\x06\x84\x35";
-// kSatvedaSPKIs contains the SHA1 hashes of the SPKIs of the satveda.pem
+// kTwitterSPKIs contains the SHA1 hashes of the SPKIs of the twitter-chain.pem
// certificate chain, in order.
-static const char kSatvedaSPKIs[2][21] = {
- "\xd6\x2d\x7a\x12\x02\x7f\x9b\x8e\x4f\x2b"
- "\x07\xc5\xfb\xf9\x2a\x2e\x9a\xcc\x0e\xe3",
- "\xba\x2e\xb5\xa8\x3e\x13\x23\xd9\x53\x4b"
- "\x5e\x65\xbc\xe7\xa3\x13\x5d\xd0\xa9\x96",
+static const char kTwitterSPKIs[3][21] = {
+ "\x26\x9a\x19\xa3\x88\x28\xc1\xdd\x70\x1b"
+ "\xa0\xca\x2c\x98\xdb\xc6\xe1\x4f\x37\x3e",
+ "\x47\x49\xdf\x16\x57\xf4\x6c\x8b\xd2\x8c"
+ "\x79\x1b\x99\xfb\x9f\x28\x81\x2a\x60\xe0",
+ "\xb1\x81\x08\x1a\x19\xa4\xc0\x94\x1f\xfa"
+ "\xe8\x95\x28\xc1\x24\xc9\x9b\x34\xac\xc7",
};
-// kSatvedaSPKIsSHA256 contains the SHA256 hashes of the SPKIs of the
-// satveda.pem certificate chain, in order.
-static const char kSatvedaSPKIsSHA256[2][33] = {
- "\xb9\x42\xab\xf2\x08\x63\xef\x81\x70\x88\x45\xc4\x39\xa2\x6e\x9c"
- "\x2f\x9a\xf9\xf4\xcb\x23\x61\xd4\x83\x97\x61\x6d\xf2\x5b\x27\xa8",
- "\x32\xb6\x4b\x66\x72\x7a\x20\x63\xe4\x06\x6f\x3b\x95\x8c\xb0\xaa"
- "\xee\x57\x6a\x5e\xce\xfd\x95\x33\x99\xbb\x88\x74\x73\x1d\x95\x87",
+// kTwitterSPKIsSHA256 contains the SHA256 hashes of the SPKIs of the
+// twitter-chain.pem certificate chain, in order.
+static const char kTwitterSPKIsSHA256[3][33] = {
+ "\x20\xec\x5d\x0a\xfb\xc6\xc0\xe2\xe1\x95\x56\xc5\x35\x2b\x3c\x60"
+ "\x78\xa6\xed\x95\x55\xc2\xfa\x86\x82\x40\x4f\xdb\x55\x29\xd3\xad",
+ "\x80\xcc\x56\x3a\xb5\xf8\x3c\xc4\x1e\xb0\xaf\x6a\x14\xd6\xd8\x07"
+ "\x18\xc1\x7e\x35\x2f\x96\x49\xff\xbc\xdd\x67\xf8\xbf\x65\x13\x91",
+ "\x25\xb4\x1b\x50\x6e\x49\x30\x95\x28\x23\xa6\xeb\x9f\x1d\x31\xde"
+ "\xf6\x45\xea\x38\xa5\xc6\xc6\xa9\x6d\x71\x95\x7e\x38\x4d\xf0\x58",
};
// Certificates for test data. They're obtained with:
diff --git a/chromium/net/test/url_request/url_request_failed_job.cc b/chromium/net/test/url_request/url_request_failed_job.cc
index c13c3c8c443..ce7ecb332e7 100644
--- a/chromium/net/test/url_request/url_request_failed_job.cc
+++ b/chromium/net/test/url_request/url_request_failed_job.cc
@@ -6,53 +6,140 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/net_errors.h"
+#include "net/base/url_util.h"
+#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_interceptor.h"
namespace net {
+
namespace {
const char kMockHostname[] = "mock.failed.request";
-// Gets the numeric net error code from URL of the form:
-// scheme://kMockHostname/error_code. The error code must be a valid
-// net error code, and not net::OK or net::ERR_IO_PENDING.
-int GetErrorCode(net::URLRequest* request) {
- int net_error;
- std::string path = request->url().path();
- if (path[0] == '/' && base::StringToInt(path.c_str() + 1, &net_error)) {
- CHECK_LT(net_error, 0);
- CHECK_NE(net_error, net::ERR_IO_PENDING);
- return net_error;
+// String names of failure phases matching FailurePhase enum.
+const char* kFailurePhase[]{
+ "start", // START
+ "readsync", // READ_SYNC
+ "readasync", // READ_ASYNC
+};
+
+static_assert(arraysize(kFailurePhase) ==
+ URLRequestFailedJob::FailurePhase::MAX_FAILURE_PHASE,
+ "kFailurePhase must match FailurePhase enum");
+
+class MockJobInterceptor : public URLRequestInterceptor {
+ public:
+ MockJobInterceptor() {}
+ ~MockJobInterceptor() override {}
+
+ // URLRequestJobFactory::ProtocolHandler implementation:
+ URLRequestJob* MaybeInterceptRequest(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override {
+ int net_error = OK;
+ URLRequestFailedJob::FailurePhase phase =
+ URLRequestFailedJob::FailurePhase::MAX_FAILURE_PHASE;
+ for (size_t i = 0; i < arraysize(kFailurePhase); i++) {
+ std::string phase_error_string;
+ if (GetValueForKeyInQuery(request->url(), kFailurePhase[i],
+ &phase_error_string)) {
+ if (base::StringToInt(phase_error_string, &net_error)) {
+ phase = static_cast<URLRequestFailedJob::FailurePhase>(i);
+ break;
+ }
+ }
+ }
+ return new URLRequestFailedJob(request, network_delegate, phase, net_error);
}
- NOTREACHED();
- return net::ERR_UNEXPECTED;
-}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockJobInterceptor);
+};
GURL GetMockUrl(const std::string& scheme,
const std::string& hostname,
+ URLRequestFailedJob::FailurePhase phase,
int net_error) {
- CHECK_LT(net_error, 0);
- CHECK_NE(net_error, net::ERR_IO_PENDING);
- return GURL(scheme + "://" + hostname + "/" + base::IntToString(net_error));
+ CHECK_GE(phase, URLRequestFailedJob::FailurePhase::START);
+ CHECK_LE(phase, URLRequestFailedJob::FailurePhase::READ_ASYNC);
+ CHECK_LT(net_error, OK);
+ return GURL(scheme + "://" + hostname + "/error?" + kFailurePhase[phase] +
+ "=" + base::IntToString(net_error));
}
} // namespace
-URLRequestFailedJob::URLRequestFailedJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
+URLRequestFailedJob::URLRequestFailedJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ FailurePhase phase,
int net_error)
- : net::URLRequestJob(request, network_delegate),
+ : URLRequestJob(request, network_delegate),
+ phase_(phase),
net_error_(net_error),
- weak_factory_(this) {}
+ weak_factory_(this) {
+ CHECK_GE(phase, URLRequestFailedJob::FailurePhase::START);
+ CHECK_LE(phase, URLRequestFailedJob::FailurePhase::READ_ASYNC);
+ CHECK_LT(net_error, OK);
+}
+
+URLRequestFailedJob::URLRequestFailedJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ int net_error)
+ : URLRequestFailedJob(request, network_delegate, START, net_error) {
+}
void URLRequestFailedJob::Start() {
- base::MessageLoop::current()->PostTask(
+ if (phase_ == START) {
+ if (net_error_ != ERR_IO_PENDING) {
+ NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, net_error_));
+ return;
+ }
+ SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
+ return;
+ }
+ response_info_.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
+ NotifyHeadersComplete();
+}
+
+bool URLRequestFailedJob::ReadRawData(IOBuffer* buf,
+ int buf_size,
+ int* bytes_read) {
+ CHECK(phase_ == READ_SYNC || phase_ == READ_ASYNC);
+ if (net_error_ != ERR_IO_PENDING && phase_ == READ_SYNC) {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, net_error_));
+ return false;
+ }
+
+ SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
+
+ if (net_error_ == ERR_IO_PENDING)
+ return false;
+
+ DCHECK_EQ(READ_ASYNC, phase_);
+ DCHECK_NE(ERR_IO_PENDING, net_error_);
+
+ base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
- base::Bind(&URLRequestFailedJob::StartAsync, weak_factory_.GetWeakPtr()));
+ base::Bind(&URLRequestFailedJob::NotifyDone, weak_factory_.GetWeakPtr(),
+ URLRequestStatus(URLRequestStatus::FAILED, net_error_)));
+ return false;
+}
+
+int URLRequestFailedJob::GetResponseCode() const {
+ // If we have headers, get the response code from them.
+ if (response_info_.headers)
+ return response_info_.headers->response_code();
+ return URLRequestJob::GetResponseCode();
+}
+
+void URLRequestFailedJob::GetResponseInfo(HttpResponseInfo* info) {
+ *info = response_info_;
}
// static
@@ -63,10 +150,14 @@ void URLRequestFailedJob::AddUrlHandler() {
// static
void URLRequestFailedJob::AddUrlHandlerForHostname(
const std::string& hostname) {
- // Add |hostname| to net::URLRequestFilter for HTTP and HTTPS.
- net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
- filter->AddHostnameHandler("http", hostname, URLRequestFailedJob::Factory);
- filter->AddHostnameHandler("https", hostname, URLRequestFailedJob::Factory);
+ URLRequestFilter* filter = URLRequestFilter::GetInstance();
+ // Add |hostname| to URLRequestFilter for HTTP and HTTPS.
+ filter->AddHostnameInterceptor(
+ "http", hostname,
+ scoped_ptr<URLRequestInterceptor>(new MockJobInterceptor()));
+ filter->AddHostnameInterceptor(
+ "https", hostname,
+ scoped_ptr<URLRequestInterceptor>(new MockJobInterceptor()));
}
// static
@@ -80,31 +171,26 @@ GURL URLRequestFailedJob::GetMockHttpsUrl(int net_error) {
}
// static
-GURL URLRequestFailedJob::GetMockHttpUrlForHostname(
- int net_error, const std::string& hostname) {
- return GetMockUrl("http", hostname, net_error);
+GURL URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(FailurePhase phase,
+ int net_error) {
+ return GetMockUrl("http", kMockHostname, phase, net_error);
}
// static
-GURL URLRequestFailedJob::GetMockHttpsUrlForHostname(
- int net_error, const std::string& hostname) {
- return GetMockUrl("https", hostname, net_error);
+GURL URLRequestFailedJob::GetMockHttpUrlForHostname(
+ int net_error,
+ const std::string& hostname) {
+ return GetMockUrl("http", hostname, START, net_error);
}
-URLRequestFailedJob::~URLRequestFailedJob() {}
-
// static
-net::URLRequestJob* URLRequestFailedJob::Factory(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- const std::string& scheme) {
- return new URLRequestFailedJob(
- request, network_delegate, GetErrorCode(request));
+GURL URLRequestFailedJob::GetMockHttpsUrlForHostname(
+ int net_error,
+ const std::string& hostname) {
+ return GetMockUrl("https", hostname, START, net_error);
}
-void URLRequestFailedJob::StartAsync() {
- NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net_error_));
+URLRequestFailedJob::~URLRequestFailedJob() {
}
} // namespace net
diff --git a/chromium/net/test/url_request/url_request_failed_job.h b/chromium/net/test/url_request/url_request_failed_job.h
index 4307f91b80b..0413111c87c 100644
--- a/chromium/net/test/url_request/url_request_failed_job.h
+++ b/chromium/net/test/url_request/url_request_failed_job.h
@@ -14,28 +14,56 @@
namespace net {
-// This class simulates a URLRequestJob failing with a given error code while
-// trying to connect.
+// This class simulates a URLRequestJob failing with a given error code at
+// a particular phase while trying to connect.
class URLRequestFailedJob : public URLRequestJob {
public:
+ // A Java counterpart will be generated for this enum.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net.test
+ enum FailurePhase {
+ START = 0,
+ READ_SYNC = 1,
+ READ_ASYNC = 2,
+ MAX_FAILURE_PHASE = 3,
+ };
+
+ URLRequestFailedJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ FailurePhase phase,
+ int net_error);
+
+ // Same as above, except that the job fails at FailurePhase.START.
URLRequestFailedJob(URLRequest* request,
NetworkDelegate* network_delegate,
int net_error);
+ // URLRequestJob implementation:
void Start() override;
+ bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int GetResponseCode() const override;
+ void GetResponseInfo(HttpResponseInfo* info) override;
// Adds the testing URLs to the URLRequestFilter.
static void AddUrlHandler();
static void AddUrlHandlerForHostname(const std::string& hostname);
// Given a net error code, constructs a mock URL that will return that error
- // asynchronously when started. |net_error| must be a valid net error code
- // other than net::OK and net::ERR_IO_PENDING.
+ // asynchronously when started. |net_error| must be a valid net error code
+ // other than net::OK. Passing net::ERR_IO_PENDING for |net_error| causes the
+ // resulting request to hang.
static GURL GetMockHttpUrl(int net_error);
static GURL GetMockHttpsUrl(int net_error);
- // URLRequestFailedJob must be added as a handler for |hostname| for
- // the returned URL to return |net_error|.
+ // Constructs a mock URL that reports |net_error| at given |phase| of the
+ // request. |net_error| must be a valid net error code other than net::OK.
+ // Passing net::ERR_IO_PENDING for |net_error| causes the resulting request to
+ // hang.
+ static GURL GetMockHttpUrlWithFailurePhase(FailurePhase phase, int net_error);
+
+ // Given a net error code and a host name, constructs a mock URL that will
+ // return that error asynchronously when started. |net_error| must be a valid
+ // net error code other than net::OK. Passing net::ERR_IO_PENDING for
+ // |net_error| causes the resulting request to hang.
static GURL GetMockHttpUrlForHostname(int net_error,
const std::string& hostname);
static GURL GetMockHttpsUrlForHostname(int net_error,
@@ -45,13 +73,8 @@ class URLRequestFailedJob : public URLRequestJob {
~URLRequestFailedJob() override;
private:
- static URLRequestJob* Factory(URLRequest* request,
- NetworkDelegate* network_delegate,
- const std::string& scheme);
-
- // Simulate a failure.
- void StartAsync();
-
+ HttpResponseInfo response_info_;
+ const FailurePhase phase_;
const int net_error_;
base::WeakPtrFactory<URLRequestFailedJob> weak_factory_;
diff --git a/chromium/net/test/url_request/url_request_mock_data_job.cc b/chromium/net/test/url_request/url_request_mock_data_job.cc
new file mode 100644
index 00000000000..5425816bb05
--- /dev/null
+++ b/chromium/net/test/url_request/url_request_mock_data_job.cc
@@ -0,0 +1,193 @@
+// 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/test/url_request/url_request_mock_data_job.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/io_buffer.h"
+#include "net/base/url_util.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
+#include "net/url_request/url_request_filter.h"
+
+namespace net {
+namespace {
+
+const char kMockHostname[] = "mock.data";
+
+// Gets the data from URL of the form:
+// scheme://kMockHostname/?data=abc&repeat_count=nnn.
+std::string GetDataFromRequest(const URLRequest& request) {
+ std::string value;
+ if (!GetValueForKeyInQuery(request.url(), "data", &value))
+ return "default_data";
+ return value;
+}
+
+// Gets the numeric repeat count from URL of the form:
+// scheme://kMockHostname/?data=abc&repeat_count=nnn.
+int GetRepeatCountFromRequest(const URLRequest& request) {
+ std::string value;
+ if (!GetValueForKeyInQuery(request.url(), "repeat", &value))
+ return 1;
+
+ int repeat_count;
+ if (!base::StringToInt(value, &repeat_count))
+ return 1;
+
+ DCHECK_GT(repeat_count, 0);
+
+ return repeat_count;
+}
+
+GURL GetMockUrl(const std::string& scheme,
+ const std::string& hostname,
+ const std::string& data,
+ int data_repeat_count) {
+ DCHECK_GT(data_repeat_count, 0);
+ std::string url(scheme + "://" + hostname + "/");
+ url.append("?data=");
+ url.append(data);
+ url.append("&repeat=");
+ url.append(base::IntToString(data_repeat_count));
+ return GURL(url);
+}
+
+class MockJobInterceptor : public URLRequestInterceptor {
+ public:
+ MockJobInterceptor() {}
+ ~MockJobInterceptor() override {}
+
+ // URLRequestInterceptor implementation
+ URLRequestJob* MaybeInterceptRequest(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override {
+ return new URLRequestMockDataJob(request, network_delegate,
+ GetDataFromRequest(*request),
+ GetRepeatCountFromRequest(*request));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockJobInterceptor);
+};
+
+} // namespace
+
+URLRequestMockDataJob::URLRequestMockDataJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const std::string& data,
+ int data_repeat_count)
+ : URLRequestJob(request, network_delegate),
+ data_offset_(0),
+ weak_factory_(this) {
+ DCHECK_GT(data_repeat_count, 0);
+ for (int i = 0; i < data_repeat_count; ++i) {
+ data_.append(data);
+ }
+}
+
+void URLRequestMockDataJob::Start() {
+ // Start reading asynchronously so that all error reporting and data
+ // callbacks happen as they would for network requests.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&URLRequestMockDataJob::StartAsync,
+ weak_factory_.GetWeakPtr()));
+}
+
+URLRequestMockDataJob::~URLRequestMockDataJob() {
+}
+
+bool URLRequestMockDataJob::ReadRawData(IOBuffer* buf,
+ int buf_size,
+ int* bytes_read) {
+ DCHECK(bytes_read);
+ *bytes_read = static_cast<int>(
+ std::min(static_cast<size_t>(buf_size), data_.length() - data_offset_));
+ memcpy(buf->data(), data_.c_str() + data_offset_, *bytes_read);
+ data_offset_ += *bytes_read;
+ return true;
+}
+
+int URLRequestMockDataJob::GetResponseCode() const {
+ HttpResponseInfo info;
+ GetResponseInfoConst(&info);
+ return info.headers->response_code();
+}
+
+// Public virtual version.
+void URLRequestMockDataJob::GetResponseInfo(HttpResponseInfo* info) {
+ // Forward to private const version.
+ GetResponseInfoConst(info);
+}
+
+// Private const version.
+void URLRequestMockDataJob::GetResponseInfoConst(HttpResponseInfo* info) const {
+ // Send back mock headers.
+ std::string raw_headers;
+ raw_headers.append(
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/plain\n");
+ raw_headers.append(base::StringPrintf("Content-Length: %1d\n",
+ static_cast<int>(data_.length())));
+ info->headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
+ raw_headers.c_str(), static_cast<int>(raw_headers.length())));
+}
+
+void URLRequestMockDataJob::StartAsync() {
+ if (!request_)
+ return;
+
+ set_expected_content_size(data_.length());
+ NotifyHeadersComplete();
+}
+
+// static
+void URLRequestMockDataJob::AddUrlHandler() {
+ return AddUrlHandlerForHostname(kMockHostname);
+}
+
+// static
+void URLRequestMockDataJob::AddUrlHandlerForHostname(
+ const std::string& hostname) {
+ // Add |hostname| to URLRequestFilter for HTTP and HTTPS.
+ URLRequestFilter* filter = URLRequestFilter::GetInstance();
+ filter->AddHostnameInterceptor("http", hostname,
+ make_scoped_ptr(new MockJobInterceptor()));
+ filter->AddHostnameInterceptor("https", hostname,
+ make_scoped_ptr(new MockJobInterceptor()));
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpUrl(const std::string& data,
+ int repeat_count) {
+ return GetMockHttpUrlForHostname(kMockHostname, data, repeat_count);
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpsUrl(const std::string& data,
+ int repeat_count) {
+ return GetMockHttpsUrlForHostname(kMockHostname, data, repeat_count);
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpUrlForHostname(
+ const std::string& hostname,
+ const std::string& data,
+ int repeat_count) {
+ return GetMockUrl("http", hostname, data, repeat_count);
+}
+
+// static
+GURL URLRequestMockDataJob::GetMockHttpsUrlForHostname(
+ const std::string& hostname,
+ const std::string& data,
+ int repeat_count) {
+ return GetMockUrl("https", hostname, data, repeat_count);
+}
+
+} // namespace net
diff --git a/chromium/net/test/url_request/url_request_mock_data_job.h b/chromium/net/test/url_request/url_request_mock_data_job.h
new file mode 100644
index 00000000000..3d84e371c35
--- /dev/null
+++ b/chromium/net/test/url_request/url_request_mock_data_job.h
@@ -0,0 +1,63 @@
+// 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_URL_REQUEST_URL_REQUEST_MOCK_DATA_JOB_H_
+#define NET_URL_REQUEST_URL_REQUEST_MOCK_DATA_JOB_H_
+
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+#include "net/base/net_export.h"
+#include "net/url_request/url_request_job.h"
+
+namespace net {
+
+class URLRequest;
+
+// Mock data job, which synchronously returns data repeated multiple times.
+class URLRequestMockDataJob : public URLRequestJob {
+ public:
+ URLRequestMockDataJob(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const std::string& data,
+ int data_repeat_count);
+
+ void Start() override;
+ bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+ int GetResponseCode() const override;
+ void GetResponseInfo(HttpResponseInfo* info) override;
+
+ // Adds the testing URLs to the URLRequestFilter.
+ static void AddUrlHandler();
+ static void AddUrlHandlerForHostname(const std::string& hostname);
+
+ // Given data and repeat cound, constructs a mock URL that will return that
+ // data repeated |repeat_count| times when started. |data| must be safe for
+ // URL.
+ static GURL GetMockHttpUrl(const std::string& data, int repeat_count);
+ static GURL GetMockHttpsUrl(const std::string& data, int repeat_count);
+
+ // URLRequestFailedJob must be added as a handler for |hostname| for
+ // the returned URL to return |net_error|.
+ static GURL GetMockHttpUrlForHostname(const std::string& hostname,
+ const std::string& data,
+ int repeat_count);
+ static GURL GetMockHttpsUrlForHostname(const std::string& hostname,
+ const std::string& data,
+ int repeat_count);
+
+ private:
+ void GetResponseInfoConst(HttpResponseInfo* info) const;
+ ~URLRequestMockDataJob() override;
+
+ void StartAsync();
+
+ std::string data_;
+ size_t data_offset_;
+ base::WeakPtrFactory<URLRequestMockDataJob> weak_factory_;
+};
+
+} // namespace net
+
+#endif // NET_URL_REQUEST_URL_REQUEST_SIMPLE_JOB_H_
diff --git a/chromium/net/test/url_request/url_request_mock_http_job.cc b/chromium/net/test/url_request/url_request_mock_http_job.cc
index ede87cfeabd..b7b4cdbf619 100644
--- a/chromium/net/test/url_request/url_request_mock_http_job.cc
+++ b/chromium/net/test/url_request/url_request_mock_http_job.cc
@@ -28,14 +28,7 @@ const char kMockHostname[] = "mock.http";
const base::FilePath::CharType kMockHeaderFileSuffix[] =
FILE_PATH_LITERAL(".mock-http-headers");
-// String names of failure phases matching FailurePhase enum.
-const char* kFailurePhase[] {
- "start", // START
- "readasync", // READ_ASYNC
- "readsync", // READ_SYNC
-};
-
-class MockJobInterceptor : public net::URLRequestInterceptor {
+class MockJobInterceptor : public URLRequestInterceptor {
public:
// When |map_all_requests_to_base_path| is true, all request should return the
// contents of the file at |base_path|. When |map_all_requests_to_base_path|
@@ -50,10 +43,10 @@ class MockJobInterceptor : public net::URLRequestInterceptor {
worker_pool_(worker_pool) {}
~MockJobInterceptor() override {}
- // net::URLRequestJobFactory::ProtocolHandler implementation
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override {
+ // URLRequestJobFactory::ProtocolHandler implementation
+ URLRequestJob* MaybeInterceptRequest(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override {
return new URLRequestMockHTTPJob(
request,
network_delegate,
@@ -63,15 +56,15 @@ class MockJobInterceptor : public net::URLRequestInterceptor {
}
private:
- base::FilePath GetOnDiskPath(net::URLRequest* request) const {
+ base::FilePath GetOnDiskPath(URLRequest* request) const {
// Conceptually we just want to "return base_path_ + request->url().path()".
// But path in the request URL is in URL space (i.e. %-encoded spaces).
// So first we convert base FilePath to a URL, then append the URL
// path to that, and convert the final URL back to a FilePath.
- GURL file_url(net::FilePathToFileURL(base_path_));
+ GURL file_url(FilePathToFileURL(base_path_));
std::string url = file_url.spec() + request->url().path();
base::FilePath file_path;
- net::FileURLToFilePath(GURL(url), &file_path);
+ FileURLToFilePath(GURL(url), &file_path);
return file_path;
}
@@ -96,78 +89,64 @@ std::string DoFileIO(const base::FilePath& file_path) {
return raw_headers;
}
+// For a given file |path| and |scheme|, return the URL served by the
+// URlRequestMockHTTPJob.
+GURL GetMockUrlForScheme(const base::FilePath& path,
+ const std::string& scheme) {
+ std::string url = scheme + "://" + kMockHostname + "/";
+ std::string path_str = path.MaybeAsASCII();
+ DCHECK(!path_str.empty()); // We only expect ASCII paths in tests.
+ url.append(path_str);
+ return GURL(url);
+}
+
} // namespace
// static
-void URLRequestMockHTTPJob::AddUrlHandler(
+void URLRequestMockHTTPJob::AddUrlHandlers(
const base::FilePath& base_path,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool) {
- // Add kMockHostname to net::URLRequestFilter.
- net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+ // Add kMockHostname to URLRequestFilter, for both HTTP and HTTPS.
+ URLRequestFilter* filter = URLRequestFilter::GetInstance();
filter->AddHostnameInterceptor(
"http", kMockHostname, CreateInterceptor(base_path, worker_pool));
-}
-
-// static
-void URLRequestMockHTTPJob::AddHostnameToFileHandler(
- const std::string& hostname,
- const base::FilePath& file,
- const scoped_refptr<base::SequencedWorkerPool>& worker_pool) {
- net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
- filter->AddHostnameInterceptor(
- "http", hostname, CreateInterceptorForSingleFile(file, worker_pool));
+ filter->AddHostnameInterceptor("https", kMockHostname,
+ CreateInterceptor(base_path, worker_pool));
}
// static
GURL URLRequestMockHTTPJob::GetMockUrl(const base::FilePath& path) {
- std::string url = "http://";
- url.append(kMockHostname);
- url.append("/");
- std::string path_str = path.MaybeAsASCII();
- DCHECK(!path_str.empty()); // We only expect ASCII paths in tests.
- url.append(path_str);
- return GURL(url);
+ return GetMockUrlForScheme(path, "http");
}
// static
-GURL URLRequestMockHTTPJob::GetMockUrlWithFailure(const base::FilePath& path,
- FailurePhase phase,
- int net_error) {
- COMPILE_ASSERT(arraysize(kFailurePhase) == MAX_FAILURE_PHASE,
- kFailurePhase_must_match_FailurePhase_enum);
- DCHECK_GE(phase, START);
- DCHECK_LE(phase, READ_SYNC);
- std::string url(GetMockUrl(path).spec());
- url.append("?");
- url.append(kFailurePhase[phase]);
- url.append("=");
- url.append(base::IntToString(net_error));
- return GURL(url);
+GURL URLRequestMockHTTPJob::GetMockHttpsUrl(const base::FilePath& path) {
+ return GetMockUrlForScheme(path, "https");
}
// static
-scoped_ptr<net::URLRequestInterceptor> URLRequestMockHTTPJob::CreateInterceptor(
+scoped_ptr<URLRequestInterceptor> URLRequestMockHTTPJob::CreateInterceptor(
const base::FilePath& base_path,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool) {
- return scoped_ptr<net::URLRequestInterceptor>(
+ return scoped_ptr<URLRequestInterceptor>(
new MockJobInterceptor(base_path, false, worker_pool));
}
// static
-scoped_ptr<net::URLRequestInterceptor>
+scoped_ptr<URLRequestInterceptor>
URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
const base::FilePath& file,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool) {
- return scoped_ptr<net::URLRequestInterceptor>(
+ return scoped_ptr<URLRequestInterceptor>(
new MockJobInterceptor(file, true, worker_pool));
}
URLRequestMockHTTPJob::URLRequestMockHTTPJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
const base::FilePath& file_path,
const scoped_refptr<base::TaskRunner>& task_runner)
- : net::URLRequestFileJob(request, network_delegate, file_path, task_runner),
+ : URLRequestFileJob(request, network_delegate, file_path, task_runner),
task_runner_(task_runner),
weak_ptr_factory_(this) {
}
@@ -176,22 +155,20 @@ URLRequestMockHTTPJob::~URLRequestMockHTTPJob() {
}
// Public virtual version.
-void URLRequestMockHTTPJob::GetResponseInfo(net::HttpResponseInfo* info) {
+void URLRequestMockHTTPJob::GetResponseInfo(HttpResponseInfo* info) {
// Forward to private const version.
GetResponseInfoConst(info);
}
bool URLRequestMockHTTPJob::IsRedirectResponse(GURL* location,
int* http_status_code) {
- // Override the net::URLRequestFileJob implementation to invoke the default
+ // Override the URLRequestFileJob implementation to invoke the default
// one based on HttpResponseInfo.
- return net::URLRequestJob::IsRedirectResponse(location, http_status_code);
+ return URLRequestJob::IsRedirectResponse(location, http_status_code);
}
// Public virtual version.
void URLRequestMockHTTPJob::Start() {
- if (MaybeReportErrorOnPhase(START))
- return;
base::PostTaskAndReplyWithResult(
task_runner_.get(),
FROM_HERE,
@@ -200,20 +177,7 @@ void URLRequestMockHTTPJob::Start() {
weak_ptr_factory_.GetWeakPtr()));
}
-// Public virtual version.
-bool URLRequestMockHTTPJob::ReadRawData(IOBuffer* buf,
- int buf_size,
- int* bytes_read) {
- if (MaybeReportErrorOnPhase(READ_SYNC))
- return false;
- if (MaybeReportErrorOnPhase(READ_ASYNC))
- return false;
- return URLRequestFileJob::ReadRawData(buf, buf_size, bytes_read);
-}
-
void URLRequestMockHTTPJob::SetHeadersAndStart(const std::string& raw_headers) {
- if (MaybeReportErrorOnPhase(START))
- return;
raw_headers_ = raw_headers;
// Handle CRLF line-endings.
ReplaceSubstringsAfterOffset(&raw_headers_, 0, "\r\n", "\n");
@@ -222,63 +186,28 @@ void URLRequestMockHTTPJob::SetHeadersAndStart(const std::string& raw_headers) {
URLRequestFileJob::Start();
}
-bool URLRequestMockHTTPJob::MaybeReportErrorOnPhase(
- FailurePhase current_phase) {
- DCHECK_GE(current_phase, START);
- DCHECK_LE(current_phase, READ_SYNC);
- std::string phase_key(kFailurePhase[current_phase]);
- std::string phase_error_string;
- if (!GetValueForKeyInQuery(request_->url(), phase_key, &phase_error_string))
- return false;
-
- int net_error;
- if (!base::StringToInt(phase_error_string, &net_error))
- return false;
-
- if (net_error != net::ERR_IO_PENDING &&
- (current_phase == START || current_phase == READ_SYNC)) {
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, net_error));
- return true;
- }
-
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
-
- if (current_phase != READ_ASYNC)
- return true;
-
- base::MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(
- &URLRequestMockHTTPJob::NotifyDone,
- weak_ptr_factory_.GetWeakPtr(),
- net::URLRequestStatus(net::URLRequestStatus::FAILED, net_error)));
-
- return true;
-}
-
// Private const version.
-void URLRequestMockHTTPJob::GetResponseInfoConst(
- net::HttpResponseInfo* info) const {
- info->headers = new net::HttpResponseHeaders(raw_headers_);
+void URLRequestMockHTTPJob::GetResponseInfoConst(HttpResponseInfo* info) const {
+ info->headers = new HttpResponseHeaders(raw_headers_);
}
bool URLRequestMockHTTPJob::GetMimeType(std::string* mime_type) const {
- net::HttpResponseInfo info;
+ HttpResponseInfo info;
GetResponseInfoConst(&info);
return info.headers.get() && info.headers->GetMimeType(mime_type);
}
int URLRequestMockHTTPJob::GetResponseCode() const {
- net::HttpResponseInfo info;
+ HttpResponseInfo info;
GetResponseInfoConst(&info);
// If we have headers, get the response code from them.
if (info.headers.get())
return info.headers->response_code();
- return net::URLRequestJob::GetResponseCode();
+ return URLRequestJob::GetResponseCode();
}
bool URLRequestMockHTTPJob::GetCharset(std::string* charset) {
- net::HttpResponseInfo info;
+ HttpResponseInfo info;
GetResponseInfo(&info);
return info.headers.get() && info.headers->GetCharset(charset);
}
diff --git a/chromium/net/test/url_request/url_request_mock_http_job.h b/chromium/net/test/url_request/url_request_mock_http_job.h
index 6eb3c72b861..06c31009c8b 100644
--- a/chromium/net/test/url_request/url_request_mock_http_job.h
+++ b/chromium/net/test/url_request/url_request_mock_http_job.h
@@ -28,13 +28,6 @@ namespace net {
class URLRequestMockHTTPJob : public URLRequestFileJob {
public:
- enum FailurePhase {
- START = 0,
- READ_ASYNC = 1,
- READ_SYNC = 2,
- MAX_FAILURE_PHASE = 3,
- };
-
// Note that all file IO is done using |worker_pool|.
URLRequestMockHTTPJob(URLRequest* request,
NetworkDelegate* network_delegate,
@@ -42,35 +35,21 @@ class URLRequestMockHTTPJob : public URLRequestFileJob {
const scoped_refptr<base::TaskRunner>& task_runner);
void Start() override;
- bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
bool GetMimeType(std::string* mime_type) const override;
int GetResponseCode() const override;
bool GetCharset(std::string* charset) override;
void GetResponseInfo(HttpResponseInfo* info) override;
bool IsRedirectResponse(GURL* location, int* http_status_code) override;
- // Adds the testing URLs to the URLRequestFilter.
- static void AddUrlHandler(
+ // Adds the testing URLs to the URLRequestFilter, both under HTTP and HTTPS.
+ static void AddUrlHandlers(
const base::FilePath& base_path,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool);
- // Respond to all HTTP requests of |hostname| with contents of the file
- // located at |file_path|.
- static void AddHostnameToFileHandler(
- const std::string& hostname,
- const base::FilePath& file,
- const scoped_refptr<base::SequencedWorkerPool>& worker_pool);
-
// Given the path to a file relative to the path passed to AddUrlHandler(),
// construct a mock URL.
static GURL GetMockUrl(const base::FilePath& path);
-
- // Given the path to a file relative to the path passed to AddUrlHandler(),
- // construct a mock URL that reports |net_error| at given |phase| of the
- // request. Reporting |net_error| ERR_IO_PENDING results in a hung request.
- static GURL GetMockUrlWithFailure(const base::FilePath& path,
- FailurePhase phase,
- int net_error);
+ static GURL GetMockHttpsUrl(const base::FilePath& path);
// Returns a URLRequestJobFactory::ProtocolHandler that serves
// URLRequestMockHTTPJob's responding like an HTTP server. |base_path| is the
@@ -93,11 +72,6 @@ class URLRequestMockHTTPJob : public URLRequestFileJob {
private:
void GetResponseInfoConst(HttpResponseInfo* info) const;
void SetHeadersAndStart(const std::string& raw_headers);
- // Checks query part of request url, and reports an error if it matches.
- // Error is parsed out from the query and is reported synchronously.
- // Reporting ERR_IO_PENDING results in a hung request.
- // The "readasync" error is posted asynchronously.
- bool MaybeReportErrorOnPhase(FailurePhase phase);
std::string raw_headers_;
const scoped_refptr<base::TaskRunner> task_runner_;
diff --git a/chromium/net/test/url_request/url_request_slow_download_job.cc b/chromium/net/test/url_request/url_request_slow_download_job.cc
new file mode 100644
index 00000000000..718a9f05502
--- /dev/null
+++ b/chromium/net/test/url_request/url_request_slow_download_job.cc
@@ -0,0 +1,265 @@
+// 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/test/url_request/url_request_slow_download_job.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_filter.h"
+#include "url/gurl.h"
+
+namespace net {
+
+const char URLRequestSlowDownloadJob::kUnknownSizeUrl[] =
+ "http://url.handled.by.slow.download/download-unknown-size";
+const char URLRequestSlowDownloadJob::kKnownSizeUrl[] =
+ "http://url.handled.by.slow.download/download-known-size";
+const char URLRequestSlowDownloadJob::kFinishDownloadUrl[] =
+ "http://url.handled.by.slow.download/download-finish";
+const char URLRequestSlowDownloadJob::kErrorDownloadUrl[] =
+ "http://url.handled.by.slow.download/download-error";
+
+const int URLRequestSlowDownloadJob::kFirstDownloadSize = 1024 * 35;
+const int URLRequestSlowDownloadJob::kSecondDownloadSize = 1024 * 10;
+
+// static
+base::LazyInstance<URLRequestSlowDownloadJob::SlowJobsSet>::Leaky
+ URLRequestSlowDownloadJob::pending_requests_ = LAZY_INSTANCE_INITIALIZER;
+
+void URLRequestSlowDownloadJob::Start() {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&URLRequestSlowDownloadJob::StartAsync,
+ weak_factory_.GetWeakPtr()));
+}
+
+// static
+void URLRequestSlowDownloadJob::AddUrlHandler() {
+ URLRequestFilter* filter = URLRequestFilter::GetInstance();
+ filter->AddUrlHandler(GURL(kUnknownSizeUrl),
+ &URLRequestSlowDownloadJob::Factory);
+ filter->AddUrlHandler(GURL(kKnownSizeUrl),
+ &URLRequestSlowDownloadJob::Factory);
+ filter->AddUrlHandler(GURL(kFinishDownloadUrl),
+ &URLRequestSlowDownloadJob::Factory);
+ filter->AddUrlHandler(GURL(kErrorDownloadUrl),
+ &URLRequestSlowDownloadJob::Factory);
+}
+
+// static
+URLRequestJob* URLRequestSlowDownloadJob::Factory(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const std::string& scheme) {
+ URLRequestSlowDownloadJob* job =
+ new URLRequestSlowDownloadJob(request, network_delegate);
+ if (request->url().spec() != kFinishDownloadUrl &&
+ request->url().spec() != kErrorDownloadUrl)
+ pending_requests_.Get().insert(job);
+ return job;
+}
+
+// static
+size_t URLRequestSlowDownloadJob::NumberOutstandingRequests() {
+ return pending_requests_.Get().size();
+}
+
+// static
+void URLRequestSlowDownloadJob::FinishPendingRequests() {
+ typedef std::set<URLRequestSlowDownloadJob*> JobList;
+ for (JobList::iterator it = pending_requests_.Get().begin();
+ it != pending_requests_.Get().end(); ++it) {
+ (*it)->set_should_finish_download();
+ }
+}
+
+void URLRequestSlowDownloadJob::ErrorPendingRequests() {
+ typedef std::set<URLRequestSlowDownloadJob*> JobList;
+ for (JobList::iterator it = pending_requests_.Get().begin();
+ it != pending_requests_.Get().end(); ++it) {
+ (*it)->set_should_error_download();
+ }
+}
+
+URLRequestSlowDownloadJob::URLRequestSlowDownloadJob(
+ URLRequest* request,
+ NetworkDelegate* network_delegate)
+ : URLRequestJob(request, network_delegate),
+ bytes_already_sent_(0),
+ should_error_download_(false),
+ should_finish_download_(false),
+ buffer_size_(0),
+ weak_factory_(this) {
+}
+
+void URLRequestSlowDownloadJob::StartAsync() {
+ if (LowerCaseEqualsASCII(kFinishDownloadUrl, request_->url().spec().c_str()))
+ URLRequestSlowDownloadJob::FinishPendingRequests();
+ if (LowerCaseEqualsASCII(kErrorDownloadUrl, request_->url().spec().c_str()))
+ URLRequestSlowDownloadJob::ErrorPendingRequests();
+
+ NotifyHeadersComplete();
+}
+
+// ReadRawData and CheckDoneStatus together implement a state
+// machine. ReadRawData may be called arbitrarily by the network stack.
+// It responds by:
+// * If there are bytes remaining in the first chunk, they are
+// returned.
+// [No bytes remaining in first chunk. ]
+// * If should_finish_download_ is not set, it returns IO_PENDING,
+// and starts calling CheckDoneStatus on a regular timer.
+// [should_finish_download_ set.]
+// * If there are bytes remaining in the second chunk, they are filled.
+// * Otherwise, return *bytes_read = 0 to indicate end of request.
+// CheckDoneStatus is called on a regular basis, in the specific
+// case where we have transmitted all of the first chunk and none of the
+// second. If should_finish_download_ becomes set, it will "complete"
+// the ReadRawData call that spawned off the CheckDoneStatus() repeated call.
+//
+// FillBufferHelper is a helper function that does the actual work of figuring
+// out where in the state machine we are and how we should fill the buffer.
+// It returns an enum indicating the state of the read.
+URLRequestSlowDownloadJob::ReadStatus
+URLRequestSlowDownloadJob::FillBufferHelper(IOBuffer* buf,
+ int buf_size,
+ int* bytes_written) {
+ if (bytes_already_sent_ < kFirstDownloadSize) {
+ int bytes_to_write =
+ std::min(kFirstDownloadSize - bytes_already_sent_, buf_size);
+ for (int i = 0; i < bytes_to_write; ++i) {
+ buf->data()[i] = '*';
+ }
+ *bytes_written = bytes_to_write;
+ bytes_already_sent_ += bytes_to_write;
+ return BUFFER_FILLED;
+ }
+
+ if (!should_finish_download_)
+ return REQUEST_BLOCKED;
+
+ if (bytes_already_sent_ < kFirstDownloadSize + kSecondDownloadSize) {
+ int bytes_to_write =
+ std::min(kFirstDownloadSize + kSecondDownloadSize - bytes_already_sent_,
+ buf_size);
+ for (int i = 0; i < bytes_to_write; ++i) {
+ buf->data()[i] = '*';
+ }
+ *bytes_written = bytes_to_write;
+ bytes_already_sent_ += bytes_to_write;
+ return BUFFER_FILLED;
+ }
+
+ return REQUEST_COMPLETE;
+}
+
+bool URLRequestSlowDownloadJob::ReadRawData(IOBuffer* buf,
+ int buf_size,
+ int* bytes_read) {
+ if (LowerCaseEqualsASCII(kFinishDownloadUrl,
+ request_->url().spec().c_str()) ||
+ LowerCaseEqualsASCII(kErrorDownloadUrl, request_->url().spec().c_str())) {
+ VLOG(10) << __FUNCTION__ << " called w/ kFinish/ErrorDownloadUrl.";
+ *bytes_read = 0;
+ return true;
+ }
+
+ VLOG(10) << __FUNCTION__ << " called at position " << bytes_already_sent_
+ << " in the stream.";
+ ReadStatus status = FillBufferHelper(buf, buf_size, bytes_read);
+ switch (status) {
+ case BUFFER_FILLED:
+ return true;
+ case REQUEST_BLOCKED:
+ buffer_ = buf;
+ buffer_size_ = buf_size;
+ SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(&URLRequestSlowDownloadJob::CheckDoneStatus,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(100));
+ return false;
+ case REQUEST_COMPLETE:
+ *bytes_read = 0;
+ return true;
+ }
+ NOTREACHED();
+ return true;
+}
+
+void URLRequestSlowDownloadJob::CheckDoneStatus() {
+ if (should_finish_download_) {
+ VLOG(10) << __FUNCTION__ << " called w/ should_finish_download_ set.";
+ DCHECK(NULL != buffer_.get());
+ int bytes_written = 0;
+ ReadStatus status =
+ FillBufferHelper(buffer_.get(), buffer_size_, &bytes_written);
+ DCHECK_EQ(BUFFER_FILLED, status);
+ buffer_ = NULL; // Release the reference.
+ SetStatus(URLRequestStatus());
+ NotifyReadComplete(bytes_written);
+ } else if (should_error_download_) {
+ VLOG(10) << __FUNCTION__ << " called w/ should_finish_ownload_ set.";
+ NotifyDone(
+ URLRequestStatus(URLRequestStatus::FAILED, ERR_CONNECTION_RESET));
+ } else {
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(&URLRequestSlowDownloadJob::CheckDoneStatus,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(100));
+ }
+}
+
+// Public virtual version.
+void URLRequestSlowDownloadJob::GetResponseInfo(HttpResponseInfo* info) {
+ // Forward to private const version.
+ GetResponseInfoConst(info);
+}
+
+URLRequestSlowDownloadJob::~URLRequestSlowDownloadJob() {
+ pending_requests_.Get().erase(this);
+}
+
+// Private const version.
+void URLRequestSlowDownloadJob::GetResponseInfoConst(
+ HttpResponseInfo* info) const {
+ // Send back mock headers.
+ std::string raw_headers;
+ if (LowerCaseEqualsASCII(kFinishDownloadUrl,
+ request_->url().spec().c_str()) ||
+ LowerCaseEqualsASCII(kErrorDownloadUrl, request_->url().spec().c_str())) {
+ raw_headers.append(
+ "HTTP/1.1 200 OK\n"
+ "Content-type: text/plain\n");
+ } else {
+ raw_headers.append(
+ "HTTP/1.1 200 OK\n"
+ "Content-type: application/octet-stream\n"
+ "Cache-Control: max-age=0\n");
+
+ if (LowerCaseEqualsASCII(kKnownSizeUrl, request_->url().spec().c_str())) {
+ raw_headers.append(base::StringPrintf(
+ "Content-Length: %d\n", kFirstDownloadSize + kSecondDownloadSize));
+ }
+ }
+
+ // ParseRawHeaders expects \0 to end each header line.
+ ReplaceSubstringsAfterOffset(&raw_headers, 0, "\n", std::string("\0", 1));
+ info->headers = new HttpResponseHeaders(raw_headers);
+}
+
+bool URLRequestSlowDownloadJob::GetMimeType(std::string* mime_type) const {
+ HttpResponseInfo info;
+ GetResponseInfoConst(&info);
+ return info.headers.get() && info.headers->GetMimeType(mime_type);
+}
+
+} // namespace net
diff --git a/chromium/net/test/url_request/url_request_slow_download_job.h b/chromium/net/test/url_request/url_request_slow_download_job.h
new file mode 100644
index 00000000000..a264a84abdf
--- /dev/null
+++ b/chromium/net/test/url_request/url_request_slow_download_job.h
@@ -0,0 +1,99 @@
+// 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.
+// This class simulates a slow download. Requests to |kUnknownSizeUrl| and
+// |kKnownSizeUrl| start downloads that pause after the first N bytes, to be
+// completed by sending a request to |kFinishDownloadUrl|.
+
+#ifndef NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
+#define NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_
+
+#include <set>
+#include <string>
+
+#include "base/lazy_instance.h"
+#include "base/memory/weak_ptr.h"
+#include "net/url_request/url_request_job.h"
+
+namespace net {
+
+class URLRequestSlowDownloadJob : public URLRequestJob {
+ public:
+ // Test URLs.
+ static const char kUnknownSizeUrl[];
+ static const char kKnownSizeUrl[];
+ static const char kFinishDownloadUrl[];
+ static const char kErrorDownloadUrl[];
+
+ // Download sizes.
+ static const int kFirstDownloadSize;
+ static const int kSecondDownloadSize;
+
+ // Timer callback, used to check to see if we should finish our download and
+ // send the second chunk.
+ void CheckDoneStatus();
+
+ // URLRequestJob methods
+ void Start() override;
+ bool GetMimeType(std::string* mime_type) const override;
+ void GetResponseInfo(HttpResponseInfo* info) override;
+ bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
+
+ static URLRequestJob* Factory(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const std::string& scheme);
+
+ // Returns the current number of URLRequestSlowDownloadJobs that have
+ // not yet completed.
+ static size_t NumberOutstandingRequests();
+
+ // Adds the testing URLs to the URLRequestFilter.
+ static void AddUrlHandler();
+
+ private:
+ URLRequestSlowDownloadJob(URLRequest* request,
+ NetworkDelegate* network_delegate);
+ ~URLRequestSlowDownloadJob() override;
+
+ // Enum indicating where we are in the read after a call to
+ // FillBufferHelper.
+ enum ReadStatus {
+ // The buffer was filled with data and may be returned.
+ BUFFER_FILLED,
+
+ // No data was added to the buffer because kFinishDownloadUrl has
+ // not yet been seen and we've already returned the first chunk.
+ REQUEST_BLOCKED,
+
+ // No data was added to the buffer because we've already returned
+ // all the data.
+ REQUEST_COMPLETE
+ };
+ ReadStatus FillBufferHelper(IOBuffer* buf, int buf_size, int* bytes_written);
+
+ void GetResponseInfoConst(HttpResponseInfo* info) const;
+
+ // Mark all pending requests to be finished. We keep track of pending
+ // requests in |pending_requests_|.
+ static void FinishPendingRequests();
+ static void ErrorPendingRequests();
+ typedef std::set<URLRequestSlowDownloadJob*> SlowJobsSet;
+ static base::LazyInstance<SlowJobsSet>::Leaky pending_requests_;
+
+ void StartAsync();
+
+ void set_should_finish_download() { should_finish_download_ = true; }
+ void set_should_error_download() { should_error_download_ = true; }
+
+ int bytes_already_sent_;
+ bool should_error_download_;
+ bool should_finish_download_;
+ scoped_refptr<IOBuffer> buffer_;
+ int buffer_size_;
+
+ base::WeakPtrFactory<URLRequestSlowDownloadJob> weak_factory_;
+};
+
+} // namespace content
+
+#endif // NET_TEST_URL_REQUEST_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_