Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/test/embedded_test_server/embedded_test_server.h" | 5 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 6 | 6 |
| 7 #include "base/memory/weak_ptr.h" | |
| 7 #include "base/path_service.h" | 8 #include "base/path_service.h" |
| 8 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 9 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 10 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 11 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
| 12 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
| 14 #include "crypto/nss_util.h" | |
| 13 #include "net/base/test_completion_callback.h" | 15 #include "net/base/test_completion_callback.h" |
| 14 #include "net/http/http_response_headers.h" | 16 #include "net/http/http_response_headers.h" |
| 15 #include "net/log/test_net_log.h" | 17 #include "net/log/test_net_log.h" |
| 16 #include "net/socket/client_socket_factory.h" | 18 #include "net/socket/client_socket_factory.h" |
| 17 #include "net/socket/stream_socket.h" | 19 #include "net/socket/stream_socket.h" |
| 18 #include "net/test/embedded_test_server/embedded_test_server_connection_listener .h" | 20 #include "net/test/embedded_test_server/embedded_test_server_connection_listener .h" |
| 19 #include "net/test/embedded_test_server/http_request.h" | 21 #include "net/test/embedded_test_server/http_request.h" |
| 20 #include "net/test/embedded_test_server/http_response.h" | 22 #include "net/test/embedded_test_server/http_response.h" |
| 21 #include "net/test/spawned_test_server/base_test_server.h" | 23 #include "net/test/embedded_test_server/request_handler_util.h" |
| 22 #include "net/url_request/url_fetcher.h" | 24 #include "net/url_request/url_fetcher.h" |
| 23 #include "net/url_request/url_fetcher_delegate.h" | 25 #include "net/url_request/url_fetcher_delegate.h" |
| 26 #include "net/url_request/url_request.h" | |
| 24 #include "net/url_request/url_request_test_util.h" | 27 #include "net/url_request/url_request_test_util.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 26 | 29 |
| 30 #if defined(USE_NSS_CERTS) || defined(OS_IOS) | |
| 31 #include "net/cert_net/nss_ocsp.h" | |
| 32 #endif | |
| 33 | |
| 27 namespace net { | 34 namespace net { |
| 28 namespace test_server { | 35 namespace test_server { |
| 29 | 36 |
| 30 namespace { | 37 namespace { |
| 31 | 38 |
| 32 // Gets the content from the given URLFetcher. | 39 // Gets the content from the given URLFetcher. |
| 33 std::string GetContentFromFetcher(const URLFetcher& fetcher) { | 40 std::string GetContentFromFetcher(const URLFetcher& fetcher) { |
| 34 std::string result; | 41 std::string result; |
| 35 const bool success = fetcher.GetResponseAsString(&result); | 42 const bool success = fetcher.GetResponseAsString(&result); |
| 36 EXPECT_TRUE(success); | 43 EXPECT_TRUE(success); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 bool did_read_from_socket_; | 101 bool did_read_from_socket_; |
| 95 | 102 |
| 96 base::RunLoop accept_loop_; | 103 base::RunLoop accept_loop_; |
| 97 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 104 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 98 | 105 |
| 99 mutable base::Lock lock_; | 106 mutable base::Lock lock_; |
| 100 | 107 |
| 101 DISALLOW_COPY_AND_ASSIGN(TestConnectionListener); | 108 DISALLOW_COPY_AND_ASSIGN(TestConnectionListener); |
| 102 }; | 109 }; |
| 103 | 110 |
| 104 class EmbeddedTestServerTest: public testing::Test, | 111 class EmbeddedTestServerTest |
| 105 public URLFetcherDelegate { | 112 : public testing::TestWithParam<EmbeddedTestServer::Type>, |
| 113 public URLFetcherDelegate { | |
| 106 public: | 114 public: |
| 107 EmbeddedTestServerTest() | 115 EmbeddedTestServerTest() |
| 108 : num_responses_received_(0), | 116 : num_responses_received_(0), |
| 109 num_responses_expected_(0), | 117 num_responses_expected_(0), |
| 110 io_thread_("io_thread") { | 118 io_thread_("io_thread") { |
| 111 } | 119 } |
| 112 | 120 |
| 113 void SetUp() override { | 121 void SetUp() override { |
| 122 #if defined(USE_NSS_CERTS) || defined(OS_IOS) | |
| 123 // This is needed so NSS's HTTP client functions are initialized on the | |
| 124 // right thread. These tests create SSLClientSockets on a different thread. | |
| 125 // TODO(davidben): Initialization can't be deferred to SSLClientSocket. See | |
| 126 // https://crbug.com/539520. | |
| 127 crypto::EnsureNSSInit(); | |
| 128 EnsureNSSHttpIOInit(); | |
| 129 #endif | |
| 130 | |
| 114 base::Thread::Options thread_options; | 131 base::Thread::Options thread_options; |
| 115 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 132 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
| 116 ASSERT_TRUE(io_thread_.StartWithOptions(thread_options)); | 133 ASSERT_TRUE(io_thread_.StartWithOptions(thread_options)); |
| 117 | 134 |
| 118 request_context_getter_ = | 135 request_context_getter_ = |
| 119 new TestURLRequestContextGetter(io_thread_.task_runner()); | 136 new TestURLRequestContextGetter(io_thread_.task_runner()); |
| 120 | 137 |
| 121 server_.reset(new EmbeddedTestServer); | 138 server_.reset(new EmbeddedTestServer(GetParam())); |
| 122 server_->SetConnectionListener(&connection_listener_); | 139 server_->SetConnectionListener(&connection_listener_); |
| 123 ASSERT_TRUE(server_->InitializeAndWaitUntilReady()); | |
| 124 } | 140 } |
| 125 | 141 |
| 126 void TearDown() override { | 142 void TearDown() override { |
| 127 ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete()); | 143 if (server_->Started()) |
| 144 ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete()); | |
| 145 #if defined(USE_NSS_CERTS) || defined(OS_IOS) | |
| 146 ShutdownNSSHttpIO(); | |
| 147 #endif | |
| 128 } | 148 } |
| 129 | 149 |
| 130 // URLFetcherDelegate override. | 150 // URLFetcherDelegate override. |
| 131 void OnURLFetchComplete(const URLFetcher* source) override { | 151 void OnURLFetchComplete(const URLFetcher* source) override { |
| 132 ++num_responses_received_; | 152 ++num_responses_received_; |
| 133 if (num_responses_received_ == num_responses_expected_) | 153 if (num_responses_received_ == num_responses_expected_) |
| 134 base::MessageLoop::current()->QuitWhenIdle(); | 154 base::MessageLoop::current()->QuitWhenIdle(); |
| 135 } | 155 } |
| 136 | 156 |
| 137 // Waits until the specified number of responses are received. | 157 // Waits until the specified number of responses are received. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 166 protected: | 186 protected: |
| 167 int num_responses_received_; | 187 int num_responses_received_; |
| 168 int num_responses_expected_; | 188 int num_responses_expected_; |
| 169 std::string request_relative_url_; | 189 std::string request_relative_url_; |
| 170 base::Thread io_thread_; | 190 base::Thread io_thread_; |
| 171 scoped_refptr<TestURLRequestContextGetter> request_context_getter_; | 191 scoped_refptr<TestURLRequestContextGetter> request_context_getter_; |
| 172 TestConnectionListener connection_listener_; | 192 TestConnectionListener connection_listener_; |
| 173 scoped_ptr<EmbeddedTestServer> server_; | 193 scoped_ptr<EmbeddedTestServer> server_; |
| 174 }; | 194 }; |
| 175 | 195 |
| 176 TEST_F(EmbeddedTestServerTest, GetBaseURL) { | 196 TEST_P(EmbeddedTestServerTest, GetBaseURL) { |
| 177 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/", server_->port()), | 197 ASSERT_TRUE(server_->Start()); |
| 178 server_->base_url().spec()); | 198 if (server_->is_using_ssl()) { |
|
davidben
2015/10/26 21:30:08
Nit: I think it's marginally better to condition G
svaldez
2015/10/26 21:37:57
Done.
| |
| 199 EXPECT_EQ(base::StringPrintf("https://127.0.0.1:%u/", server_->port()), | |
| 200 server_->base_url().spec()); | |
| 201 } else { | |
| 202 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/", server_->port()), | |
| 203 server_->base_url().spec()); | |
| 204 } | |
| 179 } | 205 } |
| 180 | 206 |
| 181 TEST_F(EmbeddedTestServerTest, GetURL) { | 207 TEST_P(EmbeddedTestServerTest, GetURL) { |
| 182 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/path?query=foo", | 208 ASSERT_TRUE(server_->Start()); |
| 183 server_->port()), | 209 if (server_->is_using_ssl()) { |
| 184 server_->GetURL("/path?query=foo").spec()); | 210 EXPECT_EQ(base::StringPrintf("https://127.0.0.1:%u/path?query=foo", |
| 211 server_->port()), | |
| 212 server_->GetURL("/path?query=foo").spec()); | |
| 213 } else { | |
| 214 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/path?query=foo", | |
| 215 server_->port()), | |
| 216 server_->GetURL("/path?query=foo").spec()); | |
| 217 } | |
| 185 } | 218 } |
| 186 | 219 |
| 187 TEST_F(EmbeddedTestServerTest, GetURLWithHostname) { | 220 TEST_P(EmbeddedTestServerTest, GetURLWithHostname) { |
| 188 EXPECT_EQ(base::StringPrintf("http://foo.com:%d/path?query=foo", | 221 ASSERT_TRUE(server_->Start()); |
| 189 server_->port()), | 222 if (server_->is_using_ssl()) { |
| 190 server_->GetURL("foo.com", "/path?query=foo").spec()); | 223 EXPECT_EQ(base::StringPrintf("https://foo.com:%d/path?query=foo", |
| 224 server_->port()), | |
| 225 server_->GetURL("foo.com", "/path?query=foo").spec()); | |
| 226 } else { | |
| 227 EXPECT_EQ( | |
| 228 base::StringPrintf("http://foo.com:%d/path?query=foo", server_->port()), | |
| 229 server_->GetURL("foo.com", "/path?query=foo").spec()); | |
| 230 } | |
| 191 } | 231 } |
| 192 | 232 |
| 193 TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) { | 233 TEST_P(EmbeddedTestServerTest, RegisterRequestHandler) { |
| 194 server_->RegisterRequestHandler( | 234 server_->RegisterRequestHandler( |
| 195 base::Bind(&EmbeddedTestServerTest::HandleRequest, | 235 base::Bind(&EmbeddedTestServerTest::HandleRequest, |
| 196 base::Unretained(this), | 236 base::Unretained(this), |
| 197 "/test", | 237 "/test", |
| 198 "<b>Worked!</b>", | 238 "<b>Worked!</b>", |
| 199 "text/html", | 239 "text/html", |
| 200 HTTP_OK)); | 240 HTTP_OK)); |
| 241 ASSERT_TRUE(server_->Start()); | |
| 201 | 242 |
| 202 scoped_ptr<URLFetcher> fetcher = | 243 scoped_ptr<URLFetcher> fetcher = |
| 203 URLFetcher::Create(server_->GetURL("/test?q=foo"), URLFetcher::GET, this); | 244 URLFetcher::Create(server_->GetURL("/test?q=foo"), URLFetcher::GET, this); |
| 204 fetcher->SetRequestContext(request_context_getter_.get()); | 245 fetcher->SetRequestContext(request_context_getter_.get()); |
| 205 fetcher->Start(); | 246 fetcher->Start(); |
| 206 WaitForResponses(1); | 247 WaitForResponses(1); |
| 207 | 248 |
| 208 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); | 249 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); |
| 209 EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode()); | 250 EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode()); |
| 210 EXPECT_EQ("<b>Worked!</b>", GetContentFromFetcher(*fetcher)); | 251 EXPECT_EQ("<b>Worked!</b>", GetContentFromFetcher(*fetcher)); |
| 211 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher)); | 252 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher)); |
| 212 | 253 |
| 213 EXPECT_EQ("/test?q=foo", request_relative_url_); | 254 EXPECT_EQ("/test?q=foo", request_relative_url_); |
| 214 } | 255 } |
| 215 | 256 |
| 216 TEST_F(EmbeddedTestServerTest, ServeFilesFromDirectory) { | 257 TEST_P(EmbeddedTestServerTest, ServeFilesFromDirectory) { |
| 217 base::FilePath src_dir; | 258 base::FilePath src_dir; |
| 218 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); | 259 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); |
| 219 server_->ServeFilesFromDirectory( | 260 server_->ServeFilesFromDirectory( |
| 220 src_dir.AppendASCII("net").AppendASCII("data")); | 261 src_dir.AppendASCII("net").AppendASCII("data")); |
| 262 ASSERT_TRUE(server_->Start()); | |
| 221 | 263 |
| 222 scoped_ptr<URLFetcher> fetcher = | 264 scoped_ptr<URLFetcher> fetcher = |
| 223 URLFetcher::Create(server_->GetURL("/test.html"), URLFetcher::GET, this); | 265 URLFetcher::Create(server_->GetURL("/test.html"), URLFetcher::GET, this); |
| 224 fetcher->SetRequestContext(request_context_getter_.get()); | 266 fetcher->SetRequestContext(request_context_getter_.get()); |
| 225 fetcher->Start(); | 267 fetcher->Start(); |
| 226 WaitForResponses(1); | 268 WaitForResponses(1); |
| 227 | 269 |
| 228 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); | 270 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); |
| 229 EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode()); | 271 EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode()); |
| 230 EXPECT_EQ("<p>Hello World!</p>", GetContentFromFetcher(*fetcher)); | 272 EXPECT_EQ("<p>Hello World!</p>", GetContentFromFetcher(*fetcher)); |
| 231 EXPECT_EQ("", GetContentTypeFromFetcher(*fetcher)); | 273 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher)); |
| 232 } | 274 } |
| 233 | 275 |
| 234 TEST_F(EmbeddedTestServerTest, DefaultNotFoundResponse) { | 276 TEST_P(EmbeddedTestServerTest, DefaultNotFoundResponse) { |
| 277 ASSERT_TRUE(server_->Start()); | |
| 278 | |
| 235 scoped_ptr<URLFetcher> fetcher = URLFetcher::Create( | 279 scoped_ptr<URLFetcher> fetcher = URLFetcher::Create( |
| 236 server_->GetURL("/non-existent"), URLFetcher::GET, this); | 280 server_->GetURL("/non-existent"), URLFetcher::GET, this); |
| 237 fetcher->SetRequestContext(request_context_getter_.get()); | 281 fetcher->SetRequestContext(request_context_getter_.get()); |
| 238 | 282 |
| 239 fetcher->Start(); | 283 fetcher->Start(); |
| 240 WaitForResponses(1); | 284 WaitForResponses(1); |
| 241 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); | 285 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); |
| 242 EXPECT_EQ(HTTP_NOT_FOUND, fetcher->GetResponseCode()); | 286 EXPECT_EQ(HTTP_NOT_FOUND, fetcher->GetResponseCode()); |
| 243 } | 287 } |
| 244 | 288 |
| 245 TEST_F(EmbeddedTestServerTest, ConnectionListenerAccept) { | 289 TEST_P(EmbeddedTestServerTest, ConnectionListenerAccept) { |
| 290 ASSERT_TRUE(server_->Start()); | |
| 291 | |
| 246 TestNetLog net_log; | 292 TestNetLog net_log; |
| 247 net::AddressList address_list; | 293 net::AddressList address_list; |
| 248 EXPECT_TRUE(server_->GetAddressList(&address_list)); | 294 EXPECT_TRUE(server_->GetAddressList(&address_list)); |
| 249 | 295 |
| 250 scoped_ptr<StreamSocket> socket = | 296 scoped_ptr<StreamSocket> socket = |
| 251 ClientSocketFactory::GetDefaultFactory()->CreateTransportClientSocket( | 297 ClientSocketFactory::GetDefaultFactory()->CreateTransportClientSocket( |
| 252 address_list, &net_log, NetLog::Source()); | 298 address_list, &net_log, NetLog::Source()); |
| 253 TestCompletionCallback callback; | 299 TestCompletionCallback callback; |
| 254 ASSERT_EQ(OK, callback.GetResult(socket->Connect(callback.callback()))); | 300 ASSERT_EQ(OK, callback.GetResult(socket->Connect(callback.callback()))); |
| 255 | 301 |
| 256 connection_listener_.WaitUntilFirstConnectionAccepted(); | 302 connection_listener_.WaitUntilFirstConnectionAccepted(); |
| 257 | 303 |
| 258 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount()); | 304 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount()); |
| 259 EXPECT_FALSE(connection_listener_.DidReadFromSocket()); | 305 EXPECT_FALSE(connection_listener_.DidReadFromSocket()); |
| 260 } | 306 } |
| 261 | 307 |
| 262 TEST_F(EmbeddedTestServerTest, ConnectionListenerRead) { | 308 TEST_P(EmbeddedTestServerTest, ConnectionListenerRead) { |
| 309 ASSERT_TRUE(server_->Start()); | |
| 310 | |
| 263 scoped_ptr<URLFetcher> fetcher = URLFetcher::Create( | 311 scoped_ptr<URLFetcher> fetcher = URLFetcher::Create( |
| 264 server_->GetURL("/non-existent"), URLFetcher::GET, this); | 312 server_->GetURL("/non-existent"), URLFetcher::GET, this); |
| 265 fetcher->SetRequestContext(request_context_getter_.get()); | 313 fetcher->SetRequestContext(request_context_getter_.get()); |
| 266 | 314 |
| 267 fetcher->Start(); | 315 fetcher->Start(); |
| 268 WaitForResponses(1); | 316 WaitForResponses(1); |
| 269 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount()); | 317 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount()); |
| 270 EXPECT_TRUE(connection_listener_.DidReadFromSocket()); | 318 EXPECT_TRUE(connection_listener_.DidReadFromSocket()); |
| 271 } | 319 } |
| 272 | 320 |
| 273 TEST_F(EmbeddedTestServerTest, ConcurrentFetches) { | 321 TEST_P(EmbeddedTestServerTest, ConcurrentFetches) { |
| 274 server_->RegisterRequestHandler( | 322 server_->RegisterRequestHandler( |
| 275 base::Bind(&EmbeddedTestServerTest::HandleRequest, | 323 base::Bind(&EmbeddedTestServerTest::HandleRequest, |
| 276 base::Unretained(this), | 324 base::Unretained(this), |
| 277 "/test1", | 325 "/test1", |
| 278 "Raspberry chocolate", | 326 "Raspberry chocolate", |
| 279 "text/html", | 327 "text/html", |
| 280 HTTP_OK)); | 328 HTTP_OK)); |
| 281 server_->RegisterRequestHandler( | 329 server_->RegisterRequestHandler( |
| 282 base::Bind(&EmbeddedTestServerTest::HandleRequest, | 330 base::Bind(&EmbeddedTestServerTest::HandleRequest, |
| 283 base::Unretained(this), | 331 base::Unretained(this), |
| 284 "/test2", | 332 "/test2", |
| 285 "Vanilla chocolate", | 333 "Vanilla chocolate", |
| 286 "text/html", | 334 "text/html", |
| 287 HTTP_OK)); | 335 HTTP_OK)); |
| 288 server_->RegisterRequestHandler( | 336 server_->RegisterRequestHandler( |
| 289 base::Bind(&EmbeddedTestServerTest::HandleRequest, | 337 base::Bind(&EmbeddedTestServerTest::HandleRequest, |
| 290 base::Unretained(this), | 338 base::Unretained(this), |
| 291 "/test3", | 339 "/test3", |
| 292 "No chocolates", | 340 "No chocolates", |
| 293 "text/plain", | 341 "text/plain", |
| 294 HTTP_NOT_FOUND)); | 342 HTTP_NOT_FOUND)); |
| 343 ASSERT_TRUE(server_->Start()); | |
| 295 | 344 |
| 296 scoped_ptr<URLFetcher> fetcher1 = | 345 scoped_ptr<URLFetcher> fetcher1 = |
| 297 URLFetcher::Create(server_->GetURL("/test1"), URLFetcher::GET, this); | 346 URLFetcher::Create(server_->GetURL("/test1"), URLFetcher::GET, this); |
| 298 fetcher1->SetRequestContext(request_context_getter_.get()); | 347 fetcher1->SetRequestContext(request_context_getter_.get()); |
| 299 scoped_ptr<URLFetcher> fetcher2 = | 348 scoped_ptr<URLFetcher> fetcher2 = |
| 300 URLFetcher::Create(server_->GetURL("/test2"), URLFetcher::GET, this); | 349 URLFetcher::Create(server_->GetURL("/test2"), URLFetcher::GET, this); |
| 301 fetcher2->SetRequestContext(request_context_getter_.get()); | 350 fetcher2->SetRequestContext(request_context_getter_.get()); |
| 302 scoped_ptr<URLFetcher> fetcher3 = | 351 scoped_ptr<URLFetcher> fetcher3 = |
| 303 URLFetcher::Create(server_->GetURL("/test3"), URLFetcher::GET, this); | 352 URLFetcher::Create(server_->GetURL("/test3"), URLFetcher::GET, this); |
| 304 fetcher3->SetRequestContext(request_context_getter_.get()); | 353 fetcher3->SetRequestContext(request_context_getter_.get()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 318 EXPECT_EQ(HTTP_OK, fetcher2->GetResponseCode()); | 367 EXPECT_EQ(HTTP_OK, fetcher2->GetResponseCode()); |
| 319 EXPECT_EQ("Vanilla chocolate", GetContentFromFetcher(*fetcher2)); | 368 EXPECT_EQ("Vanilla chocolate", GetContentFromFetcher(*fetcher2)); |
| 320 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher2)); | 369 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher2)); |
| 321 | 370 |
| 322 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher3->GetStatus().status()); | 371 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher3->GetStatus().status()); |
| 323 EXPECT_EQ(HTTP_NOT_FOUND, fetcher3->GetResponseCode()); | 372 EXPECT_EQ(HTTP_NOT_FOUND, fetcher3->GetResponseCode()); |
| 324 EXPECT_EQ("No chocolates", GetContentFromFetcher(*fetcher3)); | 373 EXPECT_EQ("No chocolates", GetContentFromFetcher(*fetcher3)); |
| 325 EXPECT_EQ("text/plain", GetContentTypeFromFetcher(*fetcher3)); | 374 EXPECT_EQ("text/plain", GetContentTypeFromFetcher(*fetcher3)); |
| 326 } | 375 } |
| 327 | 376 |
| 377 namespace { | |
| 378 | |
| 379 class CancelRequestDelegate : public TestDelegate { | |
| 380 public: | |
| 381 CancelRequestDelegate() {} | |
| 382 ~CancelRequestDelegate() override {} | |
| 383 | |
| 384 void OnResponseStarted(URLRequest* request) override { | |
| 385 TestDelegate::OnResponseStarted(request); | |
| 386 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 387 FROM_HERE, run_loop_.QuitClosure(), base::TimeDelta::FromSeconds(1)); | |
| 388 } | |
| 389 | |
| 390 void WaitUntilDone() { run_loop_.Run(); } | |
| 391 | |
| 392 private: | |
| 393 base::RunLoop run_loop_; | |
| 394 | |
| 395 DISALLOW_COPY_AND_ASSIGN(CancelRequestDelegate); | |
| 396 }; | |
| 397 | |
| 398 class InfiniteResponse : public BasicHttpResponse { | |
| 399 public: | |
| 400 InfiniteResponse() : weak_ptr_factory_(this) {} | |
| 401 | |
| 402 void SendResponse(const SendBytesCallback& send, | |
| 403 const SendCompleteCallback& done) override { | |
| 404 send.Run(ToResponseString(), | |
| 405 base::Bind(&InfiniteResponse::SendInfinite, | |
| 406 weak_ptr_factory_.GetWeakPtr(), send)); | |
| 407 } | |
| 408 | |
| 409 private: | |
| 410 void SendInfinite(const SendBytesCallback& send) { | |
| 411 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 412 FROM_HERE, | |
| 413 base::Bind(send, "echo", | |
| 414 base::Bind(&InfiniteResponse::SendInfinite, | |
| 415 weak_ptr_factory_.GetWeakPtr(), send))); | |
| 416 } | |
| 417 | |
| 418 base::WeakPtrFactory<InfiniteResponse> weak_ptr_factory_; | |
| 419 | |
| 420 DISALLOW_COPY_AND_ASSIGN(InfiniteResponse); | |
| 421 }; | |
| 422 | |
| 423 scoped_ptr<HttpResponse> HandleInfiniteRequest(const HttpRequest& request) { | |
| 424 return make_scoped_ptr(new InfiniteResponse); | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 // Tests the case the connection is closed while the server is sending a | |
| 429 // response. May non-deterministically end up at one of three paths | |
| 430 // (Discover the close event synchronously, asynchronously, or server | |
| 431 // shutting down before it is discovered). | |
| 432 TEST_P(EmbeddedTestServerTest, CloseDuringWrite) { | |
| 433 CancelRequestDelegate cancel_delegate; | |
| 434 TestURLRequestContext context; | |
| 435 cancel_delegate.set_cancel_in_response_started(true); | |
| 436 server_->RegisterRequestHandler(base::Bind( | |
| 437 &HandlePrefixedRequest, "/infinite", base::Bind(&HandleInfiniteRequest))); | |
| 438 ASSERT_TRUE(server_->Start()); | |
| 439 | |
| 440 scoped_ptr<URLRequest> request = context.CreateRequest( | |
| 441 server_->GetURL("/infinite"), DEFAULT_PRIORITY, &cancel_delegate); | |
| 442 request->Start(); | |
| 443 cancel_delegate.WaitUntilDone(); | |
| 444 } | |
| 445 | |
| 446 struct CertificateValuesEntry { | |
| 447 const EmbeddedTestServer::ServerCertificate server_cert; | |
| 448 const bool is_expired; | |
| 449 const char* common_name; | |
| 450 const char* root; | |
| 451 }; | |
| 452 | |
| 453 const CertificateValuesEntry kCertificateValuesEntry[] = { | |
| 454 {EmbeddedTestServer::CERT_OK, false, "127.0.0.1", "Test Root CA"}, | |
| 455 {EmbeddedTestServer::CERT_MISMATCHED_NAME, false, "127.0.0.1", | |
| 456 "Test Root CA"}, | |
| 457 {EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN, false, "localhost", | |
| 458 "Test Root CA"}, | |
| 459 {EmbeddedTestServer::CERT_EXPIRED, true, "127.0.0.1", "Test Root CA"}, | |
| 460 {EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT, false, "127.0.0.1", "B CA"}, | |
| 461 #if !defined(OS_WIN) | |
| 462 {EmbeddedTestServer::CERT_BAD_VALIDITY, true, "Leaf Certificate", | |
| 463 "Test Root CA"}, | |
| 464 #endif | |
| 465 }; | |
| 466 | |
| 467 TEST_P(EmbeddedTestServerTest, GetCertificate) { | |
| 468 if (GetParam() != EmbeddedTestServer::TYPE_HTTPS) | |
| 469 return; | |
| 470 | |
| 471 for (const auto& certEntry : kCertificateValuesEntry) { | |
| 472 server_->SetSSLConfig(certEntry.server_cert); | |
| 473 scoped_refptr<X509Certificate> cert = server_->GetCertificate(); | |
| 474 DCHECK(cert.get()); | |
| 475 EXPECT_EQ(cert->HasExpired(), certEntry.is_expired); | |
| 476 EXPECT_EQ(cert->subject().common_name, certEntry.common_name); | |
| 477 EXPECT_EQ(cert->issuer().common_name, certEntry.root); | |
| 478 } | |
| 479 } | |
| 480 | |
| 481 INSTANTIATE_TEST_CASE_P(EmbeddedTestServerTestInstantiation, | |
| 482 EmbeddedTestServerTest, | |
| 483 testing::Values(EmbeddedTestServer::TYPE_HTTP, | |
| 484 EmbeddedTestServer::TYPE_HTTPS)); | |
| 485 | |
| 328 // Below test exercises EmbeddedTestServer's ability to cope with the situation | 486 // Below test exercises EmbeddedTestServer's ability to cope with the situation |
| 329 // where there is no MessageLoop available on the thread at EmbeddedTestServer | 487 // where there is no MessageLoop available on the thread at EmbeddedTestServer |
| 330 // initialization and/or destruction. | 488 // initialization and/or destruction. |
| 331 | 489 |
| 332 typedef std::tr1::tuple<bool, bool> ThreadingTestParams; | 490 typedef std::tr1::tuple<bool, bool, EmbeddedTestServer::Type> |
| 491 ThreadingTestParams; | |
| 333 | 492 |
| 334 class EmbeddedTestServerThreadingTest | 493 class EmbeddedTestServerThreadingTest |
| 335 : public testing::TestWithParam<ThreadingTestParams> {}; | 494 : public testing::TestWithParam<ThreadingTestParams> { |
| 495 void SetUp() override { | |
| 496 #if defined(USE_NSS_CERTS) || defined(OS_IOS) | |
| 497 // This is needed so NSS's HTTP client functions are initialized on the | |
| 498 // right thread. These tests create SSLClientSockets on a different thread. | |
| 499 // TODO(davidben): Initialization can't be deferred to SSLClientSocket. See | |
| 500 // https://crbug.com/539520. | |
| 501 crypto::EnsureNSSInit(); | |
| 502 EnsureNSSHttpIOInit(); | |
| 503 #endif | |
| 504 } | |
| 505 | |
| 506 void TearDown() override { | |
| 507 #if defined(USE_NSS_CERTS) || defined(OS_IOS) | |
| 508 ShutdownNSSHttpIO(); | |
| 509 #endif | |
| 510 } | |
| 511 }; | |
| 336 | 512 |
| 337 class EmbeddedTestServerThreadingTestDelegate | 513 class EmbeddedTestServerThreadingTestDelegate |
| 338 : public base::PlatformThread::Delegate, | 514 : public base::PlatformThread::Delegate, |
| 339 public URLFetcherDelegate { | 515 public URLFetcherDelegate { |
| 340 public: | 516 public: |
| 341 EmbeddedTestServerThreadingTestDelegate( | 517 EmbeddedTestServerThreadingTestDelegate( |
| 342 bool message_loop_present_on_initialize, | 518 bool message_loop_present_on_initialize, |
| 343 bool message_loop_present_on_shutdown) | 519 bool message_loop_present_on_shutdown, |
| 520 EmbeddedTestServer::Type type) | |
| 344 : message_loop_present_on_initialize_(message_loop_present_on_initialize), | 521 : message_loop_present_on_initialize_(message_loop_present_on_initialize), |
| 345 message_loop_present_on_shutdown_(message_loop_present_on_shutdown) {} | 522 message_loop_present_on_shutdown_(message_loop_present_on_shutdown), |
| 523 type_(type) {} | |
| 346 | 524 |
| 347 // base::PlatformThread::Delegate: | 525 // base::PlatformThread::Delegate: |
| 348 void ThreadMain() override { | 526 void ThreadMain() override { |
| 349 scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner; | 527 scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner; |
| 350 base::Thread io_thread("io_thread"); | 528 base::Thread io_thread("io_thread"); |
| 351 base::Thread::Options thread_options; | 529 base::Thread::Options thread_options; |
| 352 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 530 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
| 353 ASSERT_TRUE(io_thread.StartWithOptions(thread_options)); | 531 ASSERT_TRUE(io_thread.StartWithOptions(thread_options)); |
| 354 io_thread_runner = io_thread.task_runner(); | 532 io_thread_runner = io_thread.task_runner(); |
| 355 | 533 |
| 356 scoped_ptr<base::MessageLoop> loop; | 534 scoped_ptr<base::MessageLoop> loop; |
| 357 if (message_loop_present_on_initialize_) | 535 if (message_loop_present_on_initialize_) |
| 358 loop.reset(new base::MessageLoopForIO); | 536 loop.reset(new base::MessageLoopForIO); |
| 359 | 537 |
| 360 // Create the test server instance. | 538 // Create the test server instance. |
| 361 EmbeddedTestServer server; | 539 EmbeddedTestServer server(type_); |
| 362 base::FilePath src_dir; | 540 base::FilePath src_dir; |
| 363 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); | 541 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir)); |
| 364 ASSERT_TRUE(server.InitializeAndWaitUntilReady()); | 542 ASSERT_TRUE(server.Start()); |
| 365 | 543 |
| 366 // Make a request and wait for the reply. | 544 // Make a request and wait for the reply. |
| 367 if (!loop) | 545 if (!loop) |
| 368 loop.reset(new base::MessageLoopForIO); | 546 loop.reset(new base::MessageLoopForIO); |
| 369 | 547 |
| 370 scoped_ptr<URLFetcher> fetcher = | 548 scoped_ptr<URLFetcher> fetcher = |
| 371 URLFetcher::Create(server.GetURL("/test?q=foo"), URLFetcher::GET, this); | 549 URLFetcher::Create(server.GetURL("/test?q=foo"), URLFetcher::GET, this); |
| 372 fetcher->SetRequestContext( | 550 fetcher->SetRequestContext( |
| 373 new TestURLRequestContextGetter(loop->task_runner())); | 551 new TestURLRequestContextGetter(loop->task_runner())); |
| 374 fetcher->Start(); | 552 fetcher->Start(); |
| 375 loop->Run(); | 553 loop->Run(); |
| 376 fetcher.reset(); | 554 fetcher.reset(); |
| 377 | 555 |
| 378 // Shut down. | 556 // Shut down. |
| 379 if (message_loop_present_on_shutdown_) | 557 if (message_loop_present_on_shutdown_) |
| 380 loop.reset(); | 558 loop.reset(); |
| 381 | 559 |
| 382 ASSERT_TRUE(server.ShutdownAndWaitUntilComplete()); | 560 ASSERT_TRUE(server.ShutdownAndWaitUntilComplete()); |
| 383 } | 561 } |
| 384 | 562 |
| 385 // URLFetcherDelegate override. | 563 // URLFetcherDelegate override. |
| 386 void OnURLFetchComplete(const URLFetcher* source) override { | 564 void OnURLFetchComplete(const URLFetcher* source) override { |
| 387 base::MessageLoop::current()->QuitWhenIdle(); | 565 base::MessageLoop::current()->QuitWhenIdle(); |
| 388 } | 566 } |
| 389 | 567 |
| 390 private: | 568 private: |
| 391 bool message_loop_present_on_initialize_; | 569 const bool message_loop_present_on_initialize_; |
| 392 bool message_loop_present_on_shutdown_; | 570 const bool message_loop_present_on_shutdown_; |
| 571 const EmbeddedTestServer::Type type_; | |
| 393 | 572 |
| 394 DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServerThreadingTestDelegate); | 573 DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServerThreadingTestDelegate); |
| 395 }; | 574 }; |
| 396 | 575 |
| 397 TEST_P(EmbeddedTestServerThreadingTest, RunTest) { | 576 TEST_P(EmbeddedTestServerThreadingTest, RunTest) { |
| 398 // The actual test runs on a separate thread so it can screw with the presence | 577 // The actual test runs on a separate thread so it can screw with the presence |
| 399 // of a MessageLoop - the test suite already sets up a MessageLoop for the | 578 // of a MessageLoop - the test suite already sets up a MessageLoop for the |
| 400 // main test thread. | 579 // main test thread. |
| 401 base::PlatformThreadHandle thread_handle; | 580 base::PlatformThreadHandle thread_handle; |
| 402 EmbeddedTestServerThreadingTestDelegate delegate( | 581 EmbeddedTestServerThreadingTestDelegate delegate( |
| 403 std::tr1::get<0>(GetParam()), | 582 std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()), |
| 404 std::tr1::get<1>(GetParam())); | 583 std::tr1::get<2>(GetParam())); |
| 405 ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle)); | 584 ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle)); |
| 406 base::PlatformThread::Join(thread_handle); | 585 base::PlatformThread::Join(thread_handle); |
| 407 } | 586 } |
| 408 | 587 |
| 409 INSTANTIATE_TEST_CASE_P(EmbeddedTestServerThreadingTestInstantiation, | 588 INSTANTIATE_TEST_CASE_P( |
| 410 EmbeddedTestServerThreadingTest, | 589 EmbeddedTestServerThreadingTestInstantiation, |
| 411 testing::Combine(testing::Bool(), testing::Bool())); | 590 EmbeddedTestServerThreadingTest, |
| 591 testing::Combine(testing::Bool(), | |
| 592 testing::Bool(), | |
| 593 testing::Values(EmbeddedTestServer::TYPE_HTTP, | |
| 594 EmbeddedTestServer::TYPE_HTTPS))); | |
| 412 | 595 |
| 413 } // namespace test_server | 596 } // namespace test_server |
| 414 } // namespace net | 597 } // namespace net |
| OLD | NEW |