| // Copyright (c) 2006-2009 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/url_request/url_request_unittest.h" |
| |
| #include "build/build_config.h" |
| |
| #if defined(OS_WIN) |
| #include <windows.h> |
| #include <shlobj.h> |
| #elif defined(OS_LINUX) |
| #include "base/nss_init.h" |
| #endif |
| |
| #include <algorithm> |
| #include <string> |
| |
| #include "base/file_util.h" |
| #include "base/format_macros.h" |
| #include "base/message_loop.h" |
| #include "base/path_service.h" |
| #include "base/process_util.h" |
| #include "base/string_piece.h" |
| #include "base/string_util.h" |
| #include "net/base/cookie_monster.h" |
| #include "net/base/load_flags.h" |
| #include "net/base/load_log.h" |
| #include "net/base/load_log_unittest.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/net_module.h" |
| #include "net/base/net_util.h" |
| #include "net/base/upload_data.h" |
| #include "net/disk_cache/disk_cache.h" |
| #include "net/ftp/ftp_network_layer.h" |
| #include "net/http/http_cache.h" |
| #include "net/http/http_network_layer.h" |
| #include "net/http/http_response_headers.h" |
| #include "net/proxy/proxy_service.h" |
| #include "net/socket/ssl_test_util.h" |
| #include "net/url_request/url_request.h" |
| #include "net/url_request/url_request_file_dir_job.h" |
| #include "net/url_request/url_request_http_job.h" |
| #include "net/url_request/url_request_test_job.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "testing/platform_test.h" |
| |
| using base::Time; |
| |
| namespace { |
| |
| class URLRequestTestContext : public URLRequestContext { |
| public: |
| URLRequestTestContext() { |
| host_resolver_ = net::CreateSystemHostResolver(); |
| proxy_service_ = net::ProxyService::CreateNull(); |
| ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_); |
| ssl_config_service_ = new net::SSLConfigServiceDefaults; |
| http_transaction_factory_ = |
| new net::HttpCache( |
| net::HttpNetworkLayer::CreateFactory(host_resolver_, proxy_service_, |
| ssl_config_service_), |
| disk_cache::CreateInMemoryCacheBackend(0)); |
| // In-memory cookie store. |
| cookie_store_ = new net::CookieMonster(); |
| accept_language_ = "en-us,fr"; |
| accept_charset_ = "iso-8859-1,*,utf-8"; |
| } |
| |
| private: |
| virtual ~URLRequestTestContext() { |
| delete ftp_transaction_factory_; |
| delete http_transaction_factory_; |
| } |
| }; |
| |
| class TestURLRequest : public URLRequest { |
| public: |
| TestURLRequest(const GURL& url, Delegate* delegate) |
| : URLRequest(url, delegate) { |
| set_context(new URLRequestTestContext()); |
| } |
| }; |
| |
| base::StringPiece TestNetResourceProvider(int key) { |
| return "header"; |
| } |
| |
| // Do a case-insensitive search through |haystack| for |needle|. |
| bool ContainsString(const std::string& haystack, const char* needle) { |
| std::string::const_iterator it = |
| std::search(haystack.begin(), |
| haystack.end(), |
| needle, |
| needle + strlen(needle), |
| CaseInsensitiveCompare<char>()); |
| return it != haystack.end(); |
| } |
| |
| void FillBuffer(char* buffer, size_t len) { |
| static bool called = false; |
| if (!called) { |
| called = true; |
| int seed = static_cast<int>(Time::Now().ToInternalValue()); |
| srand(seed); |
| } |
| |
| for (size_t i = 0; i < len; i++) { |
| buffer[i] = static_cast<char>(rand()); |
| if (!buffer[i]) |
| buffer[i] = 'g'; |
| } |
| } |
| |
| scoped_refptr<net::UploadData> CreateSimpleUploadData(const char* data) { |
| scoped_refptr<net::UploadData> upload = new net::UploadData; |
| upload->AppendBytes(data, strlen(data)); |
| return upload; |
| } |
| |
| } // namespace |
| |
| // Inherit PlatformTest since we require the autorelease pool on Mac OS X.f |
| class URLRequestTest : public PlatformTest { |
| }; |
| |
| class URLRequestTestHTTP : public URLRequestTest { |
| protected: |
| static void SetUpTestCase() { |
| server_ = HTTPTestServer::CreateForkingServer( |
| L"net/data/url_request_unittest/"); |
| } |
| |
| static void TearDownTestCase() { |
| server_ = NULL; |
| } |
| |
| static scoped_refptr<HTTPTestServer> server_; |
| }; |
| |
| // static |
| scoped_refptr<HTTPTestServer> URLRequestTestHTTP::server_; |
| |
| TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) { |
| // In this unit test, we're using the HTTPTestServer as a proxy server and |
| // issuing a CONNECT request with the magic host name "www.redirect.com". |
| // The HTTPTestServer will return a 302 response, which we should not |
| // follow. |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| URLRequest r(GURL("https://www.redirect.com/"), &d); |
| std::string proxy("localhost:"); |
| proxy.append(IntToString(kHTTPDefaultPort)); |
| r.set_context(new TestURLRequestContext(proxy)); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(URLRequestStatus::FAILED, r.status().status()); |
| EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error()); |
| EXPECT_EQ(1, d.response_started_count()); |
| // We should not have followed the redirect. |
| EXPECT_EQ(0, d.received_redirect_count()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) { |
| // In this unit test, we're using the HTTPTestServer as a proxy server and |
| // issuing a CONNECT request with the magic host name "www.server-auth.com". |
| // The HTTPTestServer will return a 401 response, which we should balk at. |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| URLRequest r(GURL("https://www.server-auth.com/"), &d); |
| std::string proxy("localhost:"); |
| proxy.append(IntToString(kHTTPDefaultPort)); |
| r.set_context(new TestURLRequestContext(proxy)); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(URLRequestStatus::FAILED, r.status().status()); |
| EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, r.status().os_error()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, GetTest_NoCache) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage(""), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_NE(0, d.bytes_received()); |
| |
| // The first part of the log will be for URL_REQUEST_START. |
| // After that, there should be an HTTP_TRANSACTION_READ_BODY |
| EXPECT_TRUE( |
| net::LogContains(*r.load_log(), 0, |
| net::LoadLog::TYPE_URL_REQUEST_START, |
| net::LoadLog::PHASE_BEGIN)); |
| EXPECT_TRUE( |
| net::LogContains(*r.load_log(), -3, |
| net::LoadLog::TYPE_URL_REQUEST_START, |
| net::LoadLog::PHASE_END)); |
| EXPECT_TRUE( |
| net::LogContains(*r.load_log(), -2, |
| net::LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY, |
| net::LoadLog::PHASE_BEGIN)); |
| EXPECT_TRUE( |
| net::LogContains(*r.load_log(), -1, |
| net::LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY, |
| net::LoadLog::PHASE_END)); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, GetTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage(""), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_NE(0, d.bytes_received()); |
| } |
| } |
| |
| TEST_F(URLRequestTest, QuitTest) { |
| // Don't use shared server here because we order it to quit. |
| // It would impact other tests. |
| scoped_refptr<HTTPTestServer> server = |
| HTTPTestServer::CreateServer(L"", NULL); |
| ASSERT_TRUE(NULL != server.get()); |
| server->SendQuit(); |
| EXPECT_TRUE(server->WaitToFinish(20000)); |
| } |
| |
| class HTTPSRequestTest : public testing::Test { |
| }; |
| |
| #if defined(OS_MACOSX) |
| // Status 6/19/09: |
| // |
| // If these tests are enabled on OSX, the first one (HTTPSGetTest) |
| // will fail. I didn't track it down explicitly, but did observe that |
| // the testserver.py kills itself (e.g. "process_util_posix.cc(84)] |
| // Unable to terminate process."). tlslite and testserver.py are hard |
| // to debug (redirection of stdout/stderr to a file so you can't see |
| // errors; lots of naked "except:" statements, etc), but I did track |
| // down an SSL auth failure as one cause of it deciding to die |
| // silently. |
| // |
| // The next test, HTTPSMismatchedTest, will look like it hangs by |
| // looping over calls to SSLHandshake() (Security framework call) as |
| // called from SSLClientSocketMac::DoHandshake(). Return values are a |
| // repeating pattern of -9803 (come back later) and -9812 (cert valid |
| // but root not trusted). If you don't have the cert in your keychain |
| // as documented on http://dev.chromium.org/developers/testing, the |
| // -9812 becomes a -9813 (no root cert). Interestingly, the handshake |
| // also appears to be a failure point for other disabled tests, such |
| // as (SSLClientSocketTest,Connect) in |
| // net/base/ssl_client_socket_unittest.cc. |
| // |
| // Old comment (not sure if obsolete): |
| // ssl_client_socket_mac.cc crashes currently in GetSSLInfo |
| // when called on a connection with an unrecognized certificate |
| #define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest |
| #define MAYBE_HTTPSMismatchedTest DISABLED_HTTPSMismatchedTest |
| #define MAYBE_HTTPSExpiredTest DISABLED_HTTPSExpiredTest |
| #else |
| #define MAYBE_HTTPSGetTest HTTPSGetTest |
| #define MAYBE_HTTPSMismatchedTest HTTPSMismatchedTest |
| #define MAYBE_HTTPSExpiredTest HTTPSExpiredTest |
| #endif |
| |
| TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { |
| // Note: tools/testserver/testserver.py does not need |
| // a working document root to server the pages / and /hello.html, |
| // so this test doesn't really need to specify a document root. |
| // But if it did, a good one would be net/data/ssl. |
| scoped_refptr<HTTPSTestServer> server = |
| HTTPSTestServer::CreateGoodServer(L"net/data/ssl"); |
| ASSERT_TRUE(NULL != server.get()); |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(server->TestServerPage(""), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_NE(0, d.bytes_received()); |
| } |
| } |
| |
| TEST_F(HTTPSRequestTest, MAYBE_HTTPSMismatchedTest) { |
| scoped_refptr<HTTPSTestServer> server = |
| HTTPSTestServer::CreateMismatchedServer(L"net/data/ssl"); |
| ASSERT_TRUE(NULL != server.get()); |
| |
| bool err_allowed = true; |
| for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) { |
| TestDelegate d; |
| { |
| d.set_allow_certificate_errors(err_allowed); |
| TestURLRequest r(server->TestServerPage(""), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_TRUE(d.have_certificate_errors()); |
| if (err_allowed) |
| EXPECT_NE(0, d.bytes_received()); |
| else |
| EXPECT_EQ(0, d.bytes_received()); |
| } |
| } |
| } |
| |
| TEST_F(HTTPSRequestTest, MAYBE_HTTPSExpiredTest) { |
| scoped_refptr<HTTPSTestServer> server = |
| HTTPSTestServer::CreateExpiredServer(L"net/data/ssl"); |
| ASSERT_TRUE(NULL != server.get()); |
| |
| // Iterate from false to true, just so that we do the opposite of the |
| // previous test in order to increase test coverage. |
| bool err_allowed = false; |
| for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) { |
| TestDelegate d; |
| { |
| d.set_allow_certificate_errors(err_allowed); |
| TestURLRequest r(server->TestServerPage(""), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_TRUE(d.have_certificate_errors()); |
| if (err_allowed) |
| EXPECT_NE(0, d.bytes_received()); |
| else |
| EXPECT_EQ(0, d.bytes_received()); |
| } |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelTest) { |
| TestDelegate d; |
| { |
| TestURLRequest r(GURL("http://www.google.com/"), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| r.Cancel(); |
| |
| MessageLoop::current()->Run(); |
| |
| // We expect to receive OnResponseStarted even though the request has been |
| // cancelled. |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.bytes_received()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelTest2) { |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| // error C2446: '!=' : no conversion from 'HTTPTestServer *const ' |
| // to 'const int' |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage(""), &d); |
| |
| d.set_cancel_in_response_started(true); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.bytes_received()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelTest3) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage(""), &d); |
| |
| d.set_cancel_in_received_data(true); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| // There is no guarantee about how much data was received |
| // before the cancel was issued. It could have been 0 bytes, |
| // or it could have been all the bytes. |
| // EXPECT_EQ(0, d.bytes_received()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelTest4) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage(""), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| // The request will be implicitly canceled when it is destroyed. The |
| // test delegate must not post a quit message when this happens because |
| // this test doesn't actually have a message loop. The quit message would |
| // get put on this thread's message queue and the next test would exit |
| // early, causing problems. |
| d.set_quit_on_complete(false); |
| } |
| // expect things to just cleanup properly. |
| |
| // we won't actually get a received reponse here because we've never run the |
| // message loop |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(0, d.bytes_received()); |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelTest5) { |
| ASSERT_TRUE(NULL != server_.get()); |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| |
| // populate cache |
| { |
| TestDelegate d; |
| URLRequest r(server_->TestServerPage("cachetime"), &d); |
| r.set_context(context); |
| r.Start(); |
| MessageLoop::current()->Run(); |
| EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status()); |
| } |
| |
| // cancel read from cache (see bug 990242) |
| { |
| TestDelegate d; |
| URLRequest r(server_->TestServerPage("cachetime"), &d); |
| r.set_context(context); |
| r.Start(); |
| r.Cancel(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(URLRequestStatus::CANCELED, r.status().status()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.bytes_received()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, PostTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| const int kMsgSize = 20000; // multiple of 10 |
| const int kIterations = 50; |
| char *uploadBytes = new char[kMsgSize+1]; |
| char *ptr = uploadBytes; |
| char marker = 'a'; |
| for (int idx = 0; idx < kMsgSize/10; idx++) { |
| memcpy(ptr, "----------", 10); |
| ptr += 10; |
| if (idx % 100 == 0) { |
| ptr--; |
| *ptr++ = marker; |
| if (++marker > 'z') |
| marker = 'a'; |
| } |
| } |
| uploadBytes[kMsgSize] = '\0'; |
| |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| |
| for (int i = 0; i < kIterations; ++i) { |
| TestDelegate d; |
| URLRequest r(server_->TestServerPage("echo"), &d); |
| r.set_context(context); |
| r.set_method("POST"); |
| |
| r.AppendBytesToUpload(uploadBytes, kMsgSize); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| ASSERT_EQ(1, d.response_started_count()) << "request failed: " << |
| (int) r.status().status() << ", os error: " << r.status().os_error(); |
| |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(uploadBytes, d.data_received()); |
| EXPECT_EQ(memcmp(uploadBytes, d.data_received().c_str(), kMsgSize), 0); |
| EXPECT_EQ(d.data_received().compare(uploadBytes), 0); |
| } |
| delete[] uploadBytes; |
| } |
| |
| TEST_F(URLRequestTestHTTP, PostEmptyTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("echo"), &d); |
| r.set_method("POST"); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| ASSERT_EQ(1, d.response_started_count()) << "request failed: " << |
| (int) r.status().status() << ", os error: " << r.status().os_error(); |
| |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_TRUE(d.data_received().empty()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, PostFileTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("echo"), &d); |
| r.set_method("POST"); |
| |
| FilePath dir; |
| PathService::Get(base::DIR_EXE, &dir); |
| file_util::SetCurrentDirectory(dir); |
| |
| FilePath path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &path); |
| path = path.Append(FILE_PATH_LITERAL("net")); |
| path = path.Append(FILE_PATH_LITERAL("data")); |
| path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
| path = path.Append(FILE_PATH_LITERAL("with-headers.html")); |
| r.AppendFileToUpload(path); |
| |
| // This file should just be ignored in the upload stream. |
| r.AppendFileToUpload(FilePath(FILE_PATH_LITERAL( |
| "c:\\path\\to\\non\\existant\\file.randomness.12345"))); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 longsize; |
| ASSERT_EQ(true, file_util::GetFileSize(path, &longsize)); |
| int size = static_cast<int>(longsize); |
| scoped_array<char> buf(new char[size]); |
| |
| int size_read = static_cast<int>(file_util::ReadFile(path, |
| buf.get(), size)); |
| ASSERT_EQ(size, size_read); |
| |
| ASSERT_EQ(1, d.response_started_count()) << "request failed: " << |
| (int) r.status().status() << ", os error: " << r.status().os_error(); |
| |
| EXPECT_FALSE(d.received_data_before_response()); |
| |
| ASSERT_EQ(size, d.bytes_received()); |
| EXPECT_EQ(0, memcmp(d.data_received().c_str(), buf.get(), size)); |
| } |
| } |
| |
| TEST_F(URLRequestTest, AboutBlankTest) { |
| TestDelegate d; |
| { |
| TestURLRequest r(GURL("about:blank"), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(!r.is_pending()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), 0); |
| } |
| } |
| |
| TEST_F(URLRequestTest, DataURLImageTest) { |
| TestDelegate d; |
| { |
| // Use our nice little Chrome logo. |
| TestURLRequest r(GURL( |
| "data:image/png;base64," |
| "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUBBjG3" |
| "w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQxIEVxitD" |
| "5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI5MpCVdW0gO7t" |
| "vNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKzMx1+fg9bAgK6zHq9" |
| "cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7CkIMDxQpF7r/MWq12UctI1" |
| "dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0WYUqt57yWf2McHTObYPbVD+Z" |
| "wbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2HQQcm43XwmtoYM6vVKleh0uoWvnzW" |
| "3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nkDFHF9ZS+uYVjRUasMeHUmyLYtcklTvzW" |
| "GFZnNOXczThvpKIzjcahSqIzkvDLayDq6D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTb" |
| "xXX1T5xsV9tm9r4TQwHLiZw/pdDZJea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5" |
| "MrVvMzNaI3+ERHfrFzPKQukrQGI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gV" |
| "Md6q5c8GdosynKmSeRuGzpjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq" |
| "/uxxZKzNiZFGD0wRC3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7F" |
| "Ux1qLnV7MGF40smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufB" |
| "JbsysjjW4kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJM" |
| "nlm2O34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfm" |
| "moRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV5En" |
| "hORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="), |
| &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(!r.is_pending()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), 911); |
| } |
| } |
| |
| TEST_F(URLRequestTest, FileTest) { |
| FilePath app_path; |
| PathService::Get(base::FILE_EXE, &app_path); |
| GURL app_url = net::FilePathToFileURL(app_path); |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(app_url, &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = -1; |
| EXPECT_TRUE(file_util::GetFileSize(app_path, &file_size)); |
| |
| EXPECT_TRUE(!r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| TEST_F(URLRequestTest, FileTestFullSpecifiedRange) { |
| const size_t buffer_size = 4000; |
| scoped_array<char> buffer(new char[buffer_size]); |
| FillBuffer(buffer.get(), buffer_size); |
| |
| FilePath temp_path; |
| EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path)); |
| GURL temp_url = net::FilePathToFileURL(temp_path); |
| EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size)); |
| |
| int64 file_size; |
| EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size)); |
| |
| const size_t first_byte_position = 500; |
| const size_t last_byte_position = buffer_size - first_byte_position; |
| const size_t content_length = last_byte_position - first_byte_position + 1; |
| std::string partial_buffer_string(buffer.get() + first_byte_position, |
| buffer.get() + last_byte_position + 1); |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(temp_url, &d); |
| |
| r.SetExtraRequestHeaders( |
| StringPrintf("Range: bytes=%" PRIuS "-%" PRIuS "\n", |
| first_byte_position, last_byte_position)); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| EXPECT_TRUE(!r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(static_cast<int>(content_length), d.bytes_received()); |
| // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed. |
| EXPECT_TRUE(partial_buffer_string == d.data_received()); |
| } |
| |
| EXPECT_TRUE(file_util::Delete(temp_path, false)); |
| } |
| |
| TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) { |
| const size_t buffer_size = 4000; |
| scoped_array<char> buffer(new char[buffer_size]); |
| FillBuffer(buffer.get(), buffer_size); |
| |
| FilePath temp_path; |
| EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path)); |
| GURL temp_url = net::FilePathToFileURL(temp_path); |
| EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size)); |
| |
| int64 file_size; |
| EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size)); |
| |
| const size_t first_byte_position = 500; |
| const size_t last_byte_position = buffer_size - 1; |
| const size_t content_length = last_byte_position - first_byte_position + 1; |
| std::string partial_buffer_string(buffer.get() + first_byte_position, |
| buffer.get() + last_byte_position + 1); |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(temp_url, &d); |
| |
| r.SetExtraRequestHeaders(StringPrintf("Range: bytes=%" PRIuS "-\n", |
| first_byte_position)); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| EXPECT_TRUE(!r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(static_cast<int>(content_length), d.bytes_received()); |
| // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed. |
| EXPECT_TRUE(partial_buffer_string == d.data_received()); |
| } |
| |
| EXPECT_TRUE(file_util::Delete(temp_path, false)); |
| } |
| |
| TEST_F(URLRequestTest, FileTestMultipleRanges) { |
| const size_t buffer_size = 400000; |
| scoped_array<char> buffer(new char[buffer_size]); |
| FillBuffer(buffer.get(), buffer_size); |
| |
| FilePath temp_path; |
| EXPECT_TRUE(file_util::CreateTemporaryFile(&temp_path)); |
| GURL temp_url = net::FilePathToFileURL(temp_path); |
| EXPECT_TRUE(file_util::WriteFile(temp_path, buffer.get(), buffer_size)); |
| |
| int64 file_size; |
| EXPECT_TRUE(file_util::GetFileSize(temp_path, &file_size)); |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(temp_url, &d); |
| |
| r.SetExtraRequestHeaders(StringPrintf("Range: bytes=0-0,10-200,200-300\n")); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| EXPECT_TRUE(d.request_failed()); |
| } |
| |
| EXPECT_TRUE(file_util::Delete(temp_path, false)); |
| } |
| |
| TEST_F(URLRequestTest, InvalidUrlTest) { |
| TestDelegate d; |
| { |
| TestURLRequest r(GURL("invalid url"), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| EXPECT_TRUE(d.request_failed()); |
| } |
| } |
| |
| // This test is disabled because it fails on some computers due to proxies |
| // returning a page in response to this request rather than reporting failure. |
| TEST_F(URLRequestTest, DISABLED_DnsFailureTest) { |
| TestDelegate d; |
| { |
| URLRequest r(GURL("http://thisisnotavalidurl0123456789foo.com/"), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| EXPECT_TRUE(d.request_failed()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, ResponseHeadersTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage("files/with-headers.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| const net::HttpResponseHeaders* headers = req.response_headers(); |
| |
| // Simple sanity check that response_info() accesses the same data. |
| EXPECT_EQ(headers, req.response_info().headers.get()); |
| |
| std::string header; |
| EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header)); |
| EXPECT_EQ("private", header); |
| |
| header.clear(); |
| EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header)); |
| EXPECT_EQ("text/html; charset=ISO-8859-1", header); |
| |
| // The response has two "X-Multiple-Entries" headers. |
| // This verfies our output has them concatenated together. |
| header.clear(); |
| EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header)); |
| EXPECT_EQ("a, b", header); |
| } |
| |
| // TODO(jar): 14801 Remove BZIP code completely. |
| TEST_F(URLRequestTest, DISABLED_BZip2ContentTest) { |
| scoped_refptr<HTTPTestServer> server = |
| HTTPTestServer::CreateServer(L"net/data/filter_unittests", NULL); |
| ASSERT_TRUE(NULL != server.get()); |
| |
| // for localhost domain, we also should support bzip2 encoding |
| // first, get the original file |
| TestDelegate d1; |
| TestURLRequest req1(server->TestServerPage("realfiles/google.txt"), &d1); |
| req1.Start(); |
| MessageLoop::current()->Run(); |
| |
| const std::string& got_content = d1.data_received(); |
| |
| // second, get bzip2 content |
| TestDelegate d2; |
| TestURLRequest req2(server->TestServerPage("realbz2files/google.txt"), &d2); |
| req2.Start(); |
| MessageLoop::current()->Run(); |
| |
| const std::string& got_bz2_content = d2.data_received(); |
| |
| // compare those two results |
| EXPECT_EQ(got_content, got_bz2_content); |
| } |
| |
| // TODO(jar): 14801 Remove BZIP code completely. |
| TEST_F(URLRequestTest, DISABLED_BZip2ContentTest_IncrementalHeader) { |
| scoped_refptr<HTTPTestServer> server = |
| HTTPTestServer::CreateServer(L"net/data/filter_unittests", NULL); |
| ASSERT_TRUE(NULL != server.get()); |
| |
| // for localhost domain, we also should support bzip2 encoding |
| // first, get the original file |
| TestDelegate d1; |
| TestURLRequest req1(server->TestServerPage("realfiles/google.txt"), &d1); |
| req1.Start(); |
| MessageLoop::current()->Run(); |
| |
| const std::string& got_content = d1.data_received(); |
| |
| // second, get bzip2 content. ask the testserver to send the BZ2 header in |
| // two chunks with a delay between them. this tests our fix for bug 867161. |
| TestDelegate d2; |
| TestURLRequest req2(server->TestServerPage( |
| "realbz2files/google.txt?incremental-header"), &d2); |
| req2.Start(); |
| MessageLoop::current()->Run(); |
| |
| const std::string& got_bz2_content = d2.data_received(); |
| |
| // compare those two results |
| EXPECT_EQ(got_content, got_bz2_content); |
| } |
| |
| #if defined(OS_WIN) |
| TEST_F(URLRequestTest, ResolveShortcutTest) { |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("net"); |
| app_path = app_path.AppendASCII("data"); |
| app_path = app_path.AppendASCII("url_request_unittest"); |
| app_path = app_path.AppendASCII("with-headers.html"); |
| |
| std::wstring lnk_path = app_path.value() + L".lnk"; |
| |
| HRESULT result; |
| IShellLink *shell = NULL; |
| IPersistFile *persist = NULL; |
| |
| CoInitialize(NULL); |
| // Temporarily create a shortcut for test |
| result = CoCreateInstance(CLSID_ShellLink, NULL, |
| CLSCTX_INPROC_SERVER, IID_IShellLink, |
| reinterpret_cast<LPVOID*>(&shell)); |
| ASSERT_TRUE(SUCCEEDED(result)); |
| result = shell->QueryInterface(IID_IPersistFile, |
| reinterpret_cast<LPVOID*>(&persist)); |
| ASSERT_TRUE(SUCCEEDED(result)); |
| result = shell->SetPath(app_path.value().c_str()); |
| EXPECT_TRUE(SUCCEEDED(result)); |
| result = shell->SetDescription(L"ResolveShortcutTest"); |
| EXPECT_TRUE(SUCCEEDED(result)); |
| result = persist->Save(lnk_path.c_str(), TRUE); |
| EXPECT_TRUE(SUCCEEDED(result)); |
| if (persist) |
| persist->Release(); |
| if (shell) |
| shell->Release(); |
| |
| TestDelegate d; |
| { |
| TestURLRequest r(net::FilePathToFileURL(FilePath(lnk_path)), &d); |
| |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| WIN32_FILE_ATTRIBUTE_DATA data; |
| GetFileAttributesEx(app_path.value().c_str(), |
| GetFileExInfoStandard, &data); |
| HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ, |
| FILE_SHARE_READ, NULL, OPEN_EXISTING, |
| FILE_ATTRIBUTE_NORMAL, NULL); |
| EXPECT_NE(INVALID_HANDLE_VALUE, file); |
| scoped_array<char> buffer(new char[data.nFileSizeLow]); |
| DWORD read_size; |
| BOOL result; |
| result = ReadFile(file, buffer.get(), data.nFileSizeLow, |
| &read_size, NULL); |
| std::string content(buffer.get(), read_size); |
| CloseHandle(file); |
| |
| EXPECT_TRUE(!r.is_pending()); |
| EXPECT_EQ(1, d.received_redirect_count()); |
| EXPECT_EQ(content, d.data_received()); |
| } |
| |
| // Clean the shortcut |
| DeleteFile(lnk_path.c_str()); |
| CoUninitialize(); |
| } |
| #endif // defined(OS_WIN) |
| |
| TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage( |
| "files/content-type-normalization.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| std::string mime_type; |
| req.GetMimeType(&mime_type); |
| EXPECT_EQ("text/html", mime_type); |
| |
| std::string charset; |
| req.GetCharset(&charset); |
| EXPECT_EQ("utf-8", charset); |
| req.Cancel(); |
| } |
| |
| TEST_F(URLRequestTest, FileDirCancelTest) { |
| // Put in mock resource provider. |
| net::NetModule::SetResourceProvider(TestNetResourceProvider); |
| |
| TestDelegate d; |
| { |
| FilePath file_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &file_path); |
| file_path = file_path.Append(FILE_PATH_LITERAL("net")); |
| file_path = file_path.Append(FILE_PATH_LITERAL("data")); |
| |
| TestURLRequest req(net::FilePathToFileURL(file_path), &d); |
| req.Start(); |
| EXPECT_TRUE(req.is_pending()); |
| |
| d.set_cancel_in_received_data_pending(true); |
| |
| MessageLoop::current()->Run(); |
| } |
| |
| // Take out mock resource provider. |
| net::NetModule::SetResourceProvider(NULL); |
| } |
| |
| TEST_F(URLRequestTest, FileDirRedirectNoCrash) { |
| // There is an implicit redirect when loading a file path that matches a |
| // directory and does not end with a slash. Ensure that following such |
| // redirects does not crash. See http://crbug.com/18686. |
| |
| FilePath path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &path); |
| path = path.Append(FILE_PATH_LITERAL("net")); |
| path = path.Append(FILE_PATH_LITERAL("data")); |
| path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
| |
| TestDelegate d; |
| d.set_quit_on_redirect(true); |
| TestURLRequest req(net::FilePathToFileURL(path), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Let the directory lister have time to finish its work, which will |
| // cause the URLRequestFileDirJob's ref count to drop to 1. |
| URLRequestFileDirJob* job = static_cast<URLRequestFileDirJob*>(req.job()); |
| while (!job->list_complete()) { |
| PlatformThread::Sleep(10); |
| MessageLoop::current()->RunAllPending(); |
| } |
| |
| // Should not crash during this call! |
| req.FollowDeferredRedirect(); |
| |
| // Flush event queue. |
| MessageLoop::current()->RunAllPending(); |
| } |
| |
| TEST_F(URLRequestTestHTTP, RestrictRedirects) { |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage( |
| "files/redirect-to-file.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(URLRequestStatus::FAILED, req.status().status()); |
| EXPECT_EQ(net::ERR_UNSAFE_REDIRECT, req.status().os_error()); |
| } |
| |
| TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) { |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage( |
| "files/redirect-to-invalid-url.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(URLRequestStatus::FAILED, req.status().status()); |
| EXPECT_EQ(net::ERR_INVALID_URL, req.status().os_error()); |
| } |
| |
| TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage( |
| "echoheader?Referer"), &d); |
| req.set_referrer("http://user:pass@foo.com/"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(std::string("http://foo.com/"), d.data_received()); |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelRedirect) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| d.set_cancel_in_received_redirect(true); |
| TestURLRequest req(server_->TestServerPage( |
| "files/redirect-test.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.bytes_received()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, DeferredRedirect) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| d.set_quit_on_redirect(true); |
| TestURLRequest req(server_->TestServerPage( |
| "files/redirect-test.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.received_redirect_count()); |
| |
| req.FollowDeferredRedirect(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(URLRequestStatus::SUCCESS, req.status().status()); |
| |
| FilePath path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &path); |
| path = path.Append(FILE_PATH_LITERAL("net")); |
| path = path.Append(FILE_PATH_LITERAL("data")); |
| path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
| path = path.Append(FILE_PATH_LITERAL("with-headers.html")); |
| |
| std::string contents; |
| EXPECT_TRUE(file_util::ReadFileToString(path, &contents)); |
| EXPECT_EQ(contents, d.data_received()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| d.set_quit_on_redirect(true); |
| TestURLRequest req(server_->TestServerPage( |
| "files/redirect-test.html"), &d); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.received_redirect_count()); |
| |
| req.Cancel(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.bytes_received()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, VaryHeader) { |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| |
| // populate the cache |
| { |
| TestDelegate d; |
| URLRequest req(server_->TestServerPage("echoheader?foo"), &d); |
| req.set_context(context); |
| req.SetExtraRequestHeaders("foo:1"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| } |
| |
| // expect a cache hit |
| { |
| TestDelegate d; |
| URLRequest req(server_->TestServerPage("echoheader?foo"), &d); |
| req.set_context(context); |
| req.SetExtraRequestHeaders("foo:1"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(req.was_cached()); |
| } |
| |
| // expect a cache miss |
| { |
| TestDelegate d; |
| URLRequest req(server_->TestServerPage("echoheader?foo"), &d); |
| req.set_context(context); |
| req.SetExtraRequestHeaders("foo:2"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_FALSE(req.was_cached()); |
| } |
| } |
| |
| TEST_F(URLRequestTestHTTP, BasicAuth) { |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| // populate the cache |
| { |
| TestDelegate d; |
| d.set_username(L"user"); |
| d.set_password(L"secret"); |
| |
| URLRequest r(server_->TestServerPage("auth-basic"), &d); |
| r.set_context(context); |
| r.Start(); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
| } |
| |
| // repeat request with end-to-end validation. since auth-basic results in a |
| // cachable page, we expect this test to result in a 304. in which case, the |
| // response should be fetched from the cache. |
| { |
| TestDelegate d; |
| d.set_username(L"user"); |
| d.set_password(L"secret"); |
| |
| URLRequest r(server_->TestServerPage("auth-basic"), &d); |
| r.set_context(context); |
| r.set_load_flags(net::LOAD_VALIDATE_CACHE); |
| r.Start(); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
| |
| // Should be the same cached document. |
| EXPECT_TRUE(r.was_cached()); |
| } |
| } |
| |
| // Check that Set-Cookie headers in 401 responses are respected. |
| // http://crbug.com/6450 |
| TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) { |
| ASSERT_TRUE(NULL != server_.get()); |
| |
| GURL url_requiring_auth = |
| server_->TestServerPage("auth-basic?set-cookie-if-challenged"); |
| |
| // Request a page that will give a 401 containing a Set-Cookie header. |
| // Verify that when the transaction is restarted, it includes the new cookie. |
| { |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| TestDelegate d; |
| d.set_username(L"user"); |
| d.set_password(L"secret"); |
| |
| URLRequest r(url_requiring_auth, &d); |
| r.set_context(context); |
| r.Start(); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
| |
| // Make sure we sent the cookie in the restarted transaction. |
| EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true") |
| != std::string::npos); |
| } |
| |
| // Same test as above, except this time the restart is initiated earlier |
| // (without user intervention since identity is embedded in the URL). |
| { |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| TestDelegate d; |
| |
| GURL::Replacements replacements; |
| std::string username("user2"); |
| std::string password("secret"); |
| replacements.SetUsernameStr(username); |
| replacements.SetPasswordStr(password); |
| GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements); |
| |
| URLRequest r(url_with_identity, &d); |
| r.set_context(context); |
| r.Start(); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos); |
| |
| // Make sure we sent the cookie in the restarted transaction. |
| EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true") |
| != std::string::npos); |
| } |
| } |
| |
| TEST_F(URLRequestTest, DoNotSendCookies) { |
| scoped_refptr<HTTPTestServer> server = |
| HTTPTestServer::CreateServer(L"", NULL); |
| ASSERT_TRUE(NULL != server.get()); |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| |
| // Set up a cookie. |
| { |
| TestDelegate d; |
| URLRequest req(server->TestServerPage("set-cookie?CookieToNotSend=1"), &d); |
| req.set_context(context); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| } |
| |
| // Verify that the cookie is set. |
| { |
| TestDelegate d; |
| TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d); |
| req.set_context(context); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") |
| != std::string::npos); |
| } |
| |
| // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set. |
| { |
| TestDelegate d; |
| TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d); |
| req.set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES); |
| req.set_context(context); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") |
| == std::string::npos); |
| } |
| } |
| |
| TEST_F(URLRequestTest, DoNotSaveCookies) { |
| scoped_refptr<HTTPTestServer> server = |
| HTTPTestServer::CreateServer(L"", NULL); |
| ASSERT_TRUE(NULL != server.get()); |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| |
| // Set up a cookie. |
| { |
| TestDelegate d; |
| URLRequest req(server->TestServerPage("set-cookie?CookieToNotUpdate=2"), |
| &d); |
| req.set_context(context); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| } |
| |
| // Try to set-up another cookie and update the previous cookie. |
| { |
| scoped_refptr<URLRequestContext> context = new URLRequestTestContext(); |
| TestDelegate d; |
| URLRequest req(server->TestServerPage( |
| "set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), &d); |
| req.set_load_flags(net::LOAD_DO_NOT_SAVE_COOKIES); |
| req.set_context(context); |
| req.Start(); |
| |
| MessageLoop::current()->Run(); |
| } |
| |
| // Verify the cookies weren't saved or updated. |
| { |
| TestDelegate d; |
| TestURLRequest req(server->TestServerPage("echoheader?Cookie"), &d); |
| req.set_context(context); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") |
| == std::string::npos); |
| EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") |
| != std::string::npos); |
| } |
| } |
| |
| // In this test, we do a POST which the server will 302 redirect. |
| // The subsequent transaction should use GET, and should not send the |
| // Content-Type header. |
| // http://code.google.com/p/chromium/issues/detail?id=843 |
| TEST_F(URLRequestTestHTTP, Post302RedirectGet) { |
| const char kData[] = "hello world"; |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage("files/redirect-to-echoall"), &d); |
| req.set_method("POST"); |
| req.set_upload(CreateSimpleUploadData(kData)); |
| |
| // Set headers (some of which are specific to the POST). |
| req.SetExtraRequestHeaders( |
| "Content-Type: multipart/form-data; " |
| "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n" |
| "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9," |
| "text/plain;q=0.8,image/png,*/*;q=0.5\r\n" |
| "Accept-Language: en-US,en\r\n" |
| "Accept-Charset: ISO-8859-1,*,utf-8\r\n" |
| "Content-Length: 11\r\n" |
| "Origin: http://localhost:1337/"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| std::string mime_type; |
| req.GetMimeType(&mime_type); |
| EXPECT_EQ("text/html", mime_type); |
| |
| const std::string& data = d.data_received(); |
| |
| // Check that the post-specific headers were stripped: |
| EXPECT_FALSE(ContainsString(data, "Content-Length:")); |
| EXPECT_FALSE(ContainsString(data, "Content-Type:")); |
| EXPECT_FALSE(ContainsString(data, "Origin:")); |
| |
| // These extra request headers should not have been stripped. |
| EXPECT_TRUE(ContainsString(data, "Accept:")); |
| EXPECT_TRUE(ContainsString(data, "Accept-Language:")); |
| EXPECT_TRUE(ContainsString(data, "Accept-Charset:")); |
| } |
| |
| TEST_F(URLRequestTestHTTP, Post307RedirectPost) { |
| const char kData[] = "hello world"; |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage("files/redirect307-to-echo"), |
| &d); |
| req.set_method("POST"); |
| req.set_upload(CreateSimpleUploadData(kData).get()); |
| req.SetExtraRequestHeaders( |
| "Content-Length: " + UintToString(sizeof(kData) - 1)); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| EXPECT_EQ("POST", req.method()); |
| EXPECT_EQ(kData, d.data_received()); |
| } |
| |
| // Custom URLRequestJobs for use with interceptor tests |
| class RestartTestJob : public URLRequestTestJob { |
| public: |
| explicit RestartTestJob(URLRequest* request) |
| : URLRequestTestJob(request, true) {} |
| protected: |
| virtual void StartAsync() { |
| this->NotifyRestartRequired(); |
| } |
| private: |
| ~RestartTestJob() {} |
| }; |
| |
| class CancelTestJob : public URLRequestTestJob { |
| public: |
| explicit CancelTestJob(URLRequest* request) |
| : URLRequestTestJob(request, true) {} |
| protected: |
| virtual void StartAsync() { |
| request_->Cancel(); |
| } |
| private: |
| ~CancelTestJob() {} |
| }; |
| |
| class CancelThenRestartTestJob : public URLRequestTestJob { |
| public: |
| explicit CancelThenRestartTestJob(URLRequest* request) |
| : URLRequestTestJob(request, true) { |
| } |
| protected: |
| virtual void StartAsync() { |
| request_->Cancel(); |
| this->NotifyRestartRequired(); |
| } |
| private: |
| ~CancelThenRestartTestJob() {} |
| }; |
| |
| // An Interceptor for use with interceptor tests |
| class TestInterceptor : URLRequest::Interceptor { |
| public: |
| TestInterceptor() |
| : intercept_main_request_(false), restart_main_request_(false), |
| cancel_main_request_(false), cancel_then_restart_main_request_(false), |
| simulate_main_network_error_(false), |
| intercept_redirect_(false), cancel_redirect_request_(false), |
| intercept_final_response_(false), cancel_final_request_(false), |
| did_intercept_main_(false), did_restart_main_(false), |
| did_cancel_main_(false), did_cancel_then_restart_main_(false), |
| did_simulate_error_main_(false), |
| did_intercept_redirect_(false), did_cancel_redirect_(false), |
| did_intercept_final_(false), did_cancel_final_(false) { |
| URLRequest::RegisterRequestInterceptor(this); |
| } |
| |
| ~TestInterceptor() { |
| URLRequest::UnregisterRequestInterceptor(this); |
| } |
| |
| virtual URLRequestJob* MaybeIntercept(URLRequest* request) { |
| if (restart_main_request_) { |
| restart_main_request_ = false; |
| did_restart_main_ = true; |
| return new RestartTestJob(request); |
| } |
| if (cancel_main_request_) { |
| cancel_main_request_ = false; |
| did_cancel_main_ = true; |
| return new CancelTestJob(request); |
| } |
| if (cancel_then_restart_main_request_) { |
| cancel_then_restart_main_request_ = false; |
| did_cancel_then_restart_main_ = true; |
| return new CancelThenRestartTestJob(request); |
| } |
| if (simulate_main_network_error_) { |
| simulate_main_network_error_ = false; |
| did_simulate_error_main_ = true; |
| // will error since the requeted url is not one of its canned urls |
| return new URLRequestTestJob(request, true); |
| } |
| if (!intercept_main_request_) |
| return NULL; |
| intercept_main_request_ = false; |
| did_intercept_main_ = true; |
| return new URLRequestTestJob(request, |
| main_headers_, |
| main_data_, |
| true); |
| } |
| |
| virtual URLRequestJob* MaybeInterceptRedirect(URLRequest* request, |
| const GURL& location) { |
| if (cancel_redirect_request_) { |
| cancel_redirect_request_ = false; |
| did_cancel_redirect_ = true; |
| return new CancelTestJob(request); |
| } |
| if (!intercept_redirect_) |
| return NULL; |
| intercept_redirect_ = false; |
| did_intercept_redirect_ = true; |
| return new URLRequestTestJob(request, |
| redirect_headers_, |
| redirect_data_, |
| true); |
| } |
| |
| virtual URLRequestJob* MaybeInterceptResponse(URLRequest* request) { |
| if (cancel_final_request_) { |
| cancel_final_request_ = false; |
| did_cancel_final_ = true; |
| return new CancelTestJob(request); |
| } |
| if (!intercept_final_response_) |
| return NULL; |
| intercept_final_response_ = false; |
| did_intercept_final_ = true; |
| return new URLRequestTestJob(request, |
| final_headers_, |
| final_data_, |
| true); |
| } |
| |
| // Whether to intercept the main request, and if so the response to return. |
| bool intercept_main_request_; |
| std::string main_headers_; |
| std::string main_data_; |
| |
| // Other actions we take at MaybeIntercept time |
| bool restart_main_request_; |
| bool cancel_main_request_; |
| bool cancel_then_restart_main_request_; |
| bool simulate_main_network_error_; |
| |
| // Whether to intercept redirects, and if so the response to return. |
| bool intercept_redirect_; |
| std::string redirect_headers_; |
| std::string redirect_data_; |
| |
| // Other actions we can take at MaybeInterceptRedirect time |
| bool cancel_redirect_request_; |
| |
| // Whether to intercept final response, and if so the response to return. |
| bool intercept_final_response_; |
| std::string final_headers_; |
| std::string final_data_; |
| |
| // Other actions we can take at MaybeInterceptResponse time |
| bool cancel_final_request_; |
| |
| // If we did something or not |
| bool did_intercept_main_; |
| bool did_restart_main_; |
| bool did_cancel_main_; |
| bool did_cancel_then_restart_main_; |
| bool did_simulate_error_main_; |
| bool did_intercept_redirect_; |
| bool did_cancel_redirect_; |
| bool did_intercept_final_; |
| bool did_cancel_final_; |
| |
| // Static getters for canned response header and data strings |
| |
| static std::string ok_data() { |
| return URLRequestTestJob::test_data_1(); |
| } |
| |
| static std::string ok_headers() { |
| return URLRequestTestJob::test_headers(); |
| } |
| |
| static std::string redirect_data() { |
| return std::string(); |
| } |
| |
| static std::string redirect_headers() { |
| return URLRequestTestJob::test_redirect_headers(); |
| } |
| |
| static std::string error_data() { |
| return std::string("ohhh nooooo mr. bill!"); |
| } |
| |
| static std::string error_headers() { |
| return URLRequestTestJob::test_error_headers(); |
| } |
| }; |
| |
| TEST_F(URLRequestTest, Intercept) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request and respond with a simple response |
| interceptor.intercept_main_request_ = true; |
| interceptor.main_headers_ = TestInterceptor::ok_headers(); |
| interceptor.main_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| URLRequest::UserData* user_data0 = new URLRequest::UserData(); |
| URLRequest::UserData* user_data1 = new URLRequest::UserData(); |
| URLRequest::UserData* user_data2 = new URLRequest::UserData(); |
| req.SetUserData(NULL, user_data0); |
| req.SetUserData(&user_data1, user_data1); |
| req.SetUserData(&user_data2, user_data2); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Make sure we can retrieve our specific user data |
| EXPECT_EQ(user_data0, req.GetUserData(NULL)); |
| EXPECT_EQ(user_data1, req.GetUserData(&user_data1)); |
| EXPECT_EQ(user_data2, req.GetUserData(&user_data2)); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_intercept_main_); |
| |
| // Check we got one good response |
| EXPECT_TRUE(req.status().is_success()); |
| EXPECT_EQ(200, req.response_headers()->response_code()); |
| EXPECT_EQ(TestInterceptor::ok_data(), d.data_received()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.received_redirect_count()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptRedirect) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request and respond with a redirect |
| interceptor.intercept_main_request_ = true; |
| interceptor.main_headers_ = TestInterceptor::redirect_headers(); |
| interceptor.main_data_ = TestInterceptor::redirect_data(); |
| |
| // intercept that redirect and respond a final OK response |
| interceptor.intercept_redirect_ = true; |
| interceptor.redirect_headers_ = TestInterceptor::ok_headers(); |
| interceptor.redirect_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_intercept_main_); |
| EXPECT_TRUE(interceptor.did_intercept_redirect_); |
| |
| // Check we got one good response |
| EXPECT_TRUE(req.status().is_success()); |
| if (req.status().is_success()) { |
| EXPECT_EQ(200, req.response_headers()->response_code()); |
| } |
| EXPECT_EQ(TestInterceptor::ok_data(), d.data_received()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.received_redirect_count()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptServerError) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request to generate a server error response |
| interceptor.intercept_main_request_ = true; |
| interceptor.main_headers_ = TestInterceptor::error_headers(); |
| interceptor.main_data_ = TestInterceptor::error_data(); |
| |
| // intercept that error and respond with an OK response |
| interceptor.intercept_final_response_ = true; |
| interceptor.final_headers_ = TestInterceptor::ok_headers(); |
| interceptor.final_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_intercept_main_); |
| EXPECT_TRUE(interceptor.did_intercept_final_); |
| |
| // Check we got one good response |
| EXPECT_TRUE(req.status().is_success()); |
| EXPECT_EQ(200, req.response_headers()->response_code()); |
| EXPECT_EQ(TestInterceptor::ok_data(), d.data_received()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.received_redirect_count()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptNetworkError) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request to simulate a network error |
| interceptor.simulate_main_network_error_ = true; |
| |
| // intercept that error and respond with an OK response |
| interceptor.intercept_final_response_ = true; |
| interceptor.final_headers_ = TestInterceptor::ok_headers(); |
| interceptor.final_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_simulate_error_main_); |
| EXPECT_TRUE(interceptor.did_intercept_final_); |
| |
| // Check we received one good response |
| EXPECT_TRUE(req.status().is_success()); |
| EXPECT_EQ(200, req.response_headers()->response_code()); |
| EXPECT_EQ(TestInterceptor::ok_data(), d.data_received()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.received_redirect_count()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptRestartRequired) { |
| TestInterceptor interceptor; |
| |
| // restart the main request |
| interceptor.restart_main_request_ = true; |
| |
| // then intercept the new main request and respond with an OK response |
| interceptor.intercept_main_request_ = true; |
| interceptor.main_headers_ = TestInterceptor::ok_headers(); |
| interceptor.main_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_restart_main_); |
| EXPECT_TRUE(interceptor.did_intercept_main_); |
| |
| // Check we received one good response |
| EXPECT_TRUE(req.status().is_success()); |
| if (req.status().is_success()) { |
| EXPECT_EQ(200, req.response_headers()->response_code()); |
| } |
| EXPECT_EQ(TestInterceptor::ok_data(), d.data_received()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_EQ(0, d.received_redirect_count()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptRespectsCancelMain) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request and cancel from within the restarted job |
| interceptor.cancel_main_request_ = true; |
| |
| // setup to intercept final response and override it with an OK response |
| interceptor.intercept_final_response_ = true; |
| interceptor.final_headers_ = TestInterceptor::ok_headers(); |
| interceptor.final_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_cancel_main_); |
| EXPECT_FALSE(interceptor.did_intercept_final_); |
| |
| // Check we see a canceled request |
| EXPECT_FALSE(req.status().is_success()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptRespectsCancelRedirect) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request and respond with a redirect |
| interceptor.intercept_main_request_ = true; |
| interceptor.main_headers_ = TestInterceptor::redirect_headers(); |
| interceptor.main_data_ = TestInterceptor::redirect_data(); |
| |
| // intercept the redirect and cancel from within that job |
| interceptor.cancel_redirect_request_ = true; |
| |
| // setup to intercept final response and override it with an OK response |
| interceptor.intercept_final_response_ = true; |
| interceptor.final_headers_ = TestInterceptor::ok_headers(); |
| interceptor.final_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_intercept_main_); |
| EXPECT_TRUE(interceptor.did_cancel_redirect_); |
| EXPECT_FALSE(interceptor.did_intercept_final_); |
| |
| // Check we see a canceled request |
| EXPECT_FALSE(req.status().is_success()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptRespectsCancelFinal) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request to simulate a network error |
| interceptor.simulate_main_network_error_ = true; |
| |
| // setup to intercept final response and cancel from within that job |
| interceptor.cancel_final_request_ = true; |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_simulate_error_main_); |
| EXPECT_TRUE(interceptor.did_cancel_final_); |
| |
| // Check we see a canceled request |
| EXPECT_FALSE(req.status().is_success()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status()); |
| } |
| |
| TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) { |
| TestInterceptor interceptor; |
| |
| // intercept the main request and cancel then restart from within that job |
| interceptor.cancel_then_restart_main_request_ = true; |
| |
| // setup to intercept final response and override it with an OK response |
| interceptor.intercept_final_response_ = true; |
| interceptor.final_headers_ = TestInterceptor::ok_headers(); |
| interceptor.final_data_ = TestInterceptor::ok_data(); |
| |
| TestDelegate d; |
| TestURLRequest req(GURL("http://test_intercept/foo"), &d); |
| req.set_method("GET"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| |
| // Check the interceptor got called as expected |
| EXPECT_TRUE(interceptor.did_cancel_then_restart_main_); |
| EXPECT_FALSE(interceptor.did_intercept_final_); |
| |
| // Check we see a canceled request |
| EXPECT_FALSE(req.status().is_success()); |
| EXPECT_EQ(URLRequestStatus::CANCELED, req.status().status()); |
| } |
| |
| class URLRequestTestFTP : public URLRequestTest { |
| protected: |
| static void SetUpTestCase() { |
| server_ = FTPTestServer::CreateServer(L""); |
| } |
| |
| static void TearDownTestCase() { |
| server_ = NULL; |
| } |
| |
| static scoped_refptr<FTPTestServer> server_; |
| }; |
| |
| // static |
| scoped_refptr<FTPTestServer> URLRequestTestFTP::server_; |
| |
| // Flaky, see http://crbug.com/25045. |
| TEST_F(URLRequestTestFTP, FLAKY_FTPDirectoryListing) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("/"), &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_LT(0, d.bytes_received()); |
| } |
| } |
| |
| TEST_F(URLRequestTestFTP, FTPGetTestAnonymous) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE"), &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| TEST_F(URLRequestTestFTP, FTPGetTest) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE", "chrome", "chrome"), |
| &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| TEST_F(URLRequestTestFTP, FTPCheckWrongPassword) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE", |
| "chrome", "wrong_password"), &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), 0); |
| } |
| } |
| |
| // Flaky, see http://crbug.com/25045. |
| TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongPasswordRestart) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| TestDelegate d; |
| // Set correct login credentials. The delegate will be asked for them when |
| // the initial login with wrong credentials will fail. |
| d.set_username(L"chrome"); |
| d.set_password(L"chrome"); |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE", |
| "chrome", "wrong_password"), &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| TEST_F(URLRequestTestFTP, FTPCheckWrongUser) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| TestDelegate d; |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE", |
| "wrong_user", "chrome"), &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), 0); |
| } |
| } |
| |
| // Flaky, see http://crbug.com/25045. |
| TEST_F(URLRequestTestFTP, FLAKY_FTPCheckWrongUserRestart) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| TestDelegate d; |
| // Set correct login credentials. The delegate will be asked for them when |
| // the initial login with wrong credentials will fail. |
| d.set_username(L"chrome"); |
| d.set_password(L"chrome"); |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE", |
| "wrong_user", "chrome"), &d); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d.response_started_count()); |
| EXPECT_FALSE(d.received_data_before_response()); |
| EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| // Flaky, see http://crbug.com/25045. |
| TEST_F(URLRequestTestFTP, FLAKY_FTPCacheURLCredentials) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| |
| scoped_ptr<TestDelegate> d(new TestDelegate); |
| { |
| // Pass correct login identity in the URL. |
| TestURLRequest r(server_->TestServerPage("/LICENSE", |
| "chrome", "chrome"), |
| d.get()); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d->response_started_count()); |
| EXPECT_FALSE(d->received_data_before_response()); |
| EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
| } |
| |
| d.reset(new TestDelegate); |
| { |
| // This request should use cached identity from previous request. |
| TestURLRequest r(server_->TestServerPage("/LICENSE"), d.get()); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d->response_started_count()); |
| EXPECT_FALSE(d->received_data_before_response()); |
| EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| // Flaky, see http://crbug.com/25045. |
| TEST_F(URLRequestTestFTP, FLAKY_FTPCacheLoginBoxCredentials) { |
| ASSERT_TRUE(NULL != server_.get()); |
| FilePath app_path; |
| PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
| app_path = app_path.AppendASCII("LICENSE"); |
| |
| scoped_ptr<TestDelegate> d(new TestDelegate); |
| // Set correct login credentials. The delegate will be asked for them when |
| // the initial login with wrong credentials will fail. |
| d->set_username(L"chrome"); |
| d->set_password(L"chrome"); |
| { |
| TestURLRequest r(server_->TestServerPage("/LICENSE", |
| "chrome", "wrong_password"), |
| d.get()); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d->response_started_count()); |
| EXPECT_FALSE(d->received_data_before_response()); |
| EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
| } |
| |
| // Use a new delegate without explicit credentials. The cached ones should be |
| // used. |
| d.reset(new TestDelegate); |
| { |
| // Don't pass wrong credentials in the URL, they would override valid cached |
| // ones. |
| TestURLRequest r(server_->TestServerPage("/LICENSE"), d.get()); |
| r.Start(); |
| EXPECT_TRUE(r.is_pending()); |
| |
| MessageLoop::current()->Run(); |
| |
| int64 file_size = 0; |
| file_util::GetFileSize(app_path, &file_size); |
| |
| EXPECT_FALSE(r.is_pending()); |
| EXPECT_EQ(1, d->response_started_count()); |
| EXPECT_FALSE(d->received_data_before_response()); |
| EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
| } |
| } |
| |
| // Check that default A-L header is sent. |
| TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage("echoheader?Accept-Language"), &d); |
| req.set_context(new URLRequestTestContext()); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| EXPECT_EQ(req.context()->accept_language(), d.data_received()); |
| } |
| |
| // Check that if request overrides the A-L header, the default is not appended. |
| // See http://crbug.com/20894 |
| TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest |
| req(server_->TestServerPage("echoheaderoverride?Accept-Language"), &d); |
| req.set_context(new URLRequestTestContext()); |
| req.SetExtraRequestHeaders("Accept-Language: ru"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| EXPECT_EQ(std::string("ru"), d.data_received()); |
| } |
| |
| // Check that default A-C header is sent. |
| TEST_F(URLRequestTestHTTP, DefaultAcceptCharset) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest req(server_->TestServerPage("echoheader?Accept-Charset"), &d); |
| req.set_context(new URLRequestTestContext()); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| EXPECT_EQ(req.context()->accept_charset(), d.data_received()); |
| } |
| |
| // Check that if request overrides the A-C header, the default is not appended. |
| // See http://crbug.com/20894 |
| TEST_F(URLRequestTestHTTP, OverrideAcceptCharset) { |
| ASSERT_TRUE(NULL != server_.get()); |
| TestDelegate d; |
| TestURLRequest |
| req(server_->TestServerPage("echoheaderoverride?Accept-Charset"), &d); |
| req.set_context(new URLRequestTestContext()); |
| req.SetExtraRequestHeaders("Accept-Charset: koi-8r"); |
| req.Start(); |
| MessageLoop::current()->Run(); |
| EXPECT_EQ(std::string("koi-8r"), d.data_received()); |
| } |