Index: net/url_request/url_request_unittest.cc |
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc |
index 139b6f3ee270e404ab14d9d93af038a02184c667..fdbd3383823e8d7d68e5b005c3452f9fbf501675 100644 |
--- a/net/url_request/url_request_unittest.cc |
+++ b/net/url_request/url_request_unittest.cc |
@@ -72,6 +72,8 @@ |
#include "net/url_request/static_http_user_agent_settings.h" |
#include "net/url_request/url_request.h" |
#include "net/url_request/url_request_http_job.h" |
+#include "net/url_request/url_request_intercepting_job_factory.h" |
+#include "net/url_request/url_request_interceptor.h" |
#include "net/url_request/url_request_job_factory_impl.h" |
#include "net/url_request/url_request_redirect_job.h" |
#include "net/url_request/url_request_test_job.h" |
@@ -635,6 +637,7 @@ class URLRequestTest : public PlatformTest { |
TestURLRequestContext default_context_; |
}; |
+ |
TEST_F(URLRequestTest, AboutBlankTest) { |
TestDelegate d; |
{ |
@@ -1574,11 +1577,737 @@ TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) { |
EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
} |
-LoadTimingInfo RunLoadTimingTest(const LoadTimingInfo& job_load_timing, |
- URLRequestContext* context) { |
- TestInterceptor interceptor; |
- interceptor.intercept_main_request_ = true; |
- interceptor.main_request_load_timing_info_ = job_load_timing; |
+// An Interceptor for use with interceptor tests |
+class MockURLRequestInterceptor : public URLRequestInterceptor { |
+ public: |
+ MockURLRequestInterceptor() |
+ : 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), |
+ use_url_request_http_job_(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) { |
+ } |
+ |
+ ~MockURLRequestInterceptor() override { |
+ } |
+ |
+ virtual URLRequestJob* MaybeInterceptRequest( |
+ URLRequest* request, |
+ NetworkDelegate* network_delegate) const override { |
+ if (restart_main_request_) { |
+ restart_main_request_ = false; |
+ did_restart_main_ = true; |
+ return new RestartTestJob(request, network_delegate); |
+ } |
+ if (cancel_main_request_) { |
+ cancel_main_request_ = false; |
+ did_cancel_main_ = true; |
+ return new CancelTestJob(request, network_delegate); |
+ } |
+ if (cancel_then_restart_main_request_) { |
+ cancel_then_restart_main_request_ = false; |
+ did_cancel_then_restart_main_ = true; |
+ return new CancelThenRestartTestJob(request, network_delegate); |
+ } |
+ 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 |
+ if (use_url_request_http_job_) { |
+ return URLRequestHttpJob::Factory(request, network_delegate, "http"); |
+ } |
+ return new URLRequestTestJob(request, network_delegate, true); |
+ } |
+ if (!intercept_main_request_) |
+ return NULL; |
+ intercept_main_request_ = false; |
+ did_intercept_main_ = true; |
+ URLRequestTestJob* job = new URLRequestTestJob(request, |
+ network_delegate, |
+ main_headers_, |
+ main_data_, |
+ true); |
+ job->set_load_timing_info(main_request_load_timing_info_); |
+ return job; |
+ } |
+ |
+ URLRequestJob* MaybeInterceptRedirect(URLRequest* request, |
+ NetworkDelegate* network_delegate, |
+ const GURL& location) const override { |
+ if (cancel_redirect_request_) { |
+ cancel_redirect_request_ = false; |
+ did_cancel_redirect_ = true; |
+ return new CancelTestJob(request, network_delegate); |
+ } |
+ if (!intercept_redirect_) |
+ return NULL; |
+ intercept_redirect_ = false; |
+ did_intercept_redirect_ = true; |
+ if (use_url_request_http_job_) { |
+ return URLRequestHttpJob::Factory(request, network_delegate, "http"); |
+ } |
+ return new URLRequestTestJob(request, |
+ network_delegate, |
+ redirect_headers_, |
+ redirect_data_, |
+ true); |
+ } |
+ |
+ URLRequestJob* MaybeInterceptResponse( |
+ URLRequest* request, |
+ NetworkDelegate* network_delegate) const override { |
+ if (cancel_final_request_) { |
+ cancel_final_request_ = false; |
+ did_cancel_final_ = true; |
+ return new CancelTestJob(request, network_delegate); |
+ } |
+ if (!intercept_final_response_) |
+ return NULL; |
+ intercept_final_response_ = false; |
+ did_intercept_final_ = true; |
+ if (use_url_request_http_job_) { |
+ return URLRequestHttpJob::Factory(request, network_delegate, "http"); |
+ } |
+ return new URLRequestTestJob(request, |
+ network_delegate, |
+ final_headers_, |
+ final_data_, |
+ true); |
+ } |
+ |
+ // Whether to intercept the main request, and if so the response to return and |
+ // the LoadTimingInfo to use. |
+ mutable bool intercept_main_request_; |
+ mutable std::string main_headers_; |
+ mutable std::string main_data_; |
+ mutable LoadTimingInfo main_request_load_timing_info_; |
+ |
+ // Other actions we take at MaybeIntercept time |
+ mutable bool restart_main_request_; |
+ mutable bool cancel_main_request_; |
+ mutable bool cancel_then_restart_main_request_; |
+ mutable bool simulate_main_network_error_; |
+ |
+ // Whether to intercept redirects, and if so the response to return. |
+ mutable bool intercept_redirect_; |
+ mutable std::string redirect_headers_; |
+ mutable std::string redirect_data_; |
+ |
+ // Other actions we can take at MaybeInterceptRedirect time |
+ mutable bool cancel_redirect_request_; |
+ |
+ // Whether to intercept final response, and if so the response to return. |
+ mutable bool intercept_final_response_; |
+ mutable std::string final_headers_; |
+ mutable std::string final_data_; |
+ |
+ // Other actions we can take at MaybeInterceptResponse time |
+ mutable bool cancel_final_request_; |
+ |
+ mutable bool use_url_request_http_job_; |
+ |
+ // If we did something or not |
+ mutable bool did_intercept_main_; |
+ mutable bool did_restart_main_; |
+ mutable bool did_cancel_main_; |
+ mutable bool did_cancel_then_restart_main_; |
+ mutable bool did_simulate_error_main_; |
+ mutable bool did_intercept_redirect_; |
+ mutable bool did_cancel_redirect_; |
+ mutable bool did_intercept_final_; |
+ mutable 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(); |
+ } |
+}; |
+ |
+// Inherit PlatformTest since we require the autorelease pool on Mac OS X. |
+class URLRequestInterceptorTest : public PlatformTest { |
+ public: |
+ URLRequestInterceptorTest() : default_context_(true) { |
+ default_context_.set_network_delegate(&default_network_delegate_); |
+ default_context_.set_net_log(&net_log_); |
+ job_factory_impl_ = new URLRequestJobFactoryImpl(); |
+ job_factory_.reset(job_factory_impl_); |
+ job_factory_impl_->SetProtocolHandler("data", new DataProtocolHandler); |
+#if !defined(DISABLE_FILE_SUPPORT) |
+ job_factory_impl_->SetProtocolHandler( |
+ "file", new FileProtocolHandler(base::MessageLoopProxy::current())); |
+#endif |
+ interceptor_ = new MockURLRequestInterceptor(); |
+ job_factory_.reset(new URLRequestInterceptingJobFactory( |
+ job_factory_.Pass(), make_scoped_ptr(interceptor_))); |
+ default_context_.set_job_factory(job_factory_.get()); |
+ default_context_.Init(); |
+ } |
+ ~URLRequestInterceptorTest() override { |
+ // URLRequestJobs may post clean-up tasks on destruction. |
+ base::RunLoop().RunUntilIdle(); |
+ } |
+ |
+ protected: |
+ CapturingNetLog net_log_; |
+ TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. |
+ URLRequestJobFactoryImpl* job_factory_impl_; |
+ scoped_ptr<URLRequestJobFactory> job_factory_; |
+ TestURLRequestContext default_context_; |
+ MockURLRequestInterceptor* interceptor_; |
+}; |
+ |
+ |
+TEST_F(URLRequestInterceptorTest, Intercept) { |
+ // intercept the main request and respond with a simple response |
+ interceptor_->intercept_main_request_ = true; |
+ interceptor_->main_headers_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->main_data_ = MockURLRequestInterceptor::ok_data(); |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data(); |
+ base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data(); |
+ base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data(); |
+ req->SetUserData(NULL, user_data0); |
+ req->SetUserData(&user_data1, user_data1); |
+ req->SetUserData(&user_data2, user_data2); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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 we got one good response |
+ EXPECT_TRUE(req->status().is_success()); |
+ EXPECT_EQ(200, req->response_headers()->response_code()); |
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTest, InterceptRedirect) { |
+ // intercept the main request and respond with a redirect |
+ interceptor_->intercept_main_request_ = true; |
+ interceptor_->main_headers_ = MockURLRequestInterceptor::redirect_headers(); |
+ interceptor_->main_data_ = MockURLRequestInterceptor::redirect_data(); |
+ |
+ // intercept that redirect and respond a final OK response |
+ interceptor_->intercept_redirect_ = true; |
+ interceptor_->redirect_headers_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->redirect_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTest, InterceptServerError) { |
+ // intercept the main request to generate a server error response |
+ interceptor_->intercept_main_request_ = true; |
+ interceptor_->main_headers_ = MockURLRequestInterceptor::error_headers(); |
+ interceptor_->main_data_ = MockURLRequestInterceptor::error_data(); |
+ |
+ // intercept that error and respond with an OK response |
+ interceptor_->intercept_final_response_ = true; |
+ interceptor_->final_headers_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->final_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTest, InterceptNetworkError) { |
+ // 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_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->final_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTest, InterceptRestartRequired) { |
+ // 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_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->main_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelMain) { |
+ // 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_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->final_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(URLRequestInterceptorTest, InterceptRespectsCancelRedirect) { |
+ // intercept the main request and respond with a redirect |
+ interceptor_->intercept_main_request_ = true; |
+ interceptor_->main_headers_ = MockURLRequestInterceptor::redirect_headers(); |
+ interceptor_->main_data_ = MockURLRequestInterceptor::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_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->final_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(URLRequestInterceptorTest, InterceptRespectsCancelFinal) { |
+ // 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; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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(URLRequestInterceptorTest, InterceptRespectsCancelInRestart) { |
+ // 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; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().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()); |
+} |
+ |
+ |
+LoadTimingInfo RunLoadTimingTest(const LoadTimingInfo& job_load_timing, |
+ URLRequestContext* context) { |
+ TestInterceptor interceptor; |
+ interceptor.intercept_main_request_ = true; |
+ interceptor.main_request_load_timing_info_ = job_load_timing; |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(context->CreateRequest( |
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
+ req->Start(); |
+ base::RunLoop().Run(); |
+ |
+ LoadTimingInfo resulting_load_timing; |
+ req->GetLoadTimingInfo(&resulting_load_timing); |
+ |
+ // None of these should be modified by the URLRequest. |
+ EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused); |
+ EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id); |
+ EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start); |
+ EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end); |
+ EXPECT_EQ(job_load_timing.receive_headers_end, |
+ resulting_load_timing.receive_headers_end); |
+ |
+ return resulting_load_timing; |
+} |
+ |
+// "Normal" LoadTimingInfo as returned by a job. Everything is in order, not |
+// reused. |connect_time_flags| is used to indicate if there should be dns |
+// or SSL times, and |used_proxy| is used for proxy times. |
+LoadTimingInfo NormalLoadTimingInfo(base::TimeTicks now, |
+ int connect_time_flags, |
+ bool used_proxy) { |
+ LoadTimingInfo load_timing; |
+ load_timing.socket_log_id = 1; |
+ |
+ if (used_proxy) { |
+ load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); |
+ load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); |
+ } |
+ |
+ LoadTimingInfo::ConnectTiming& connect_timing = load_timing.connect_timing; |
+ if (connect_time_flags & CONNECT_TIMING_HAS_DNS_TIMES) { |
+ connect_timing.dns_start = now + base::TimeDelta::FromDays(3); |
+ connect_timing.dns_end = now + base::TimeDelta::FromDays(4); |
+ } |
+ connect_timing.connect_start = now + base::TimeDelta::FromDays(5); |
+ if (connect_time_flags & CONNECT_TIMING_HAS_SSL_TIMES) { |
+ connect_timing.ssl_start = now + base::TimeDelta::FromDays(6); |
+ connect_timing.ssl_end = now + base::TimeDelta::FromDays(7); |
+ } |
+ connect_timing.connect_end = now + base::TimeDelta::FromDays(8); |
+ |
+ load_timing.send_start = now + base::TimeDelta::FromDays(9); |
+ load_timing.send_end = now + base::TimeDelta::FromDays(10); |
+ load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); |
+ return load_timing; |
+} |
+ |
+// Same as above, but in the case of a reused socket. |
+LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now, |
+ bool used_proxy) { |
+ LoadTimingInfo load_timing; |
+ load_timing.socket_log_id = 1; |
+ load_timing.socket_reused = true; |
+ |
+ if (used_proxy) { |
+ load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); |
+ load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); |
+ } |
+ |
+ load_timing.send_start = now + base::TimeDelta::FromDays(9); |
+ load_timing.send_end = now + base::TimeDelta::FromDays(10); |
+ load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); |
+ return load_timing; |
+} |
+ |
+// Basic test that the intercept + load timing tests work. |
+TEST_F(URLRequestTest, InterceptLoadTiming) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ LoadTimingInfo job_load_timing = |
+ NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false); |
+ |
+ LoadTimingInfo load_timing_result = |
+ RunLoadTimingTest(job_load_timing, &default_context_); |
+ |
+ // Nothing should have been changed by the URLRequest. |
+ EXPECT_EQ(job_load_timing.proxy_resolve_start, |
+ load_timing_result.proxy_resolve_start); |
+ EXPECT_EQ(job_load_timing.proxy_resolve_end, |
+ load_timing_result.proxy_resolve_end); |
+ EXPECT_EQ(job_load_timing.connect_timing.dns_start, |
+ load_timing_result.connect_timing.dns_start); |
+ EXPECT_EQ(job_load_timing.connect_timing.dns_end, |
+ load_timing_result.connect_timing.dns_end); |
+ EXPECT_EQ(job_load_timing.connect_timing.connect_start, |
+ load_timing_result.connect_timing.connect_start); |
+ EXPECT_EQ(job_load_timing.connect_timing.connect_end, |
+ load_timing_result.connect_timing.connect_end); |
+ EXPECT_EQ(job_load_timing.connect_timing.ssl_start, |
+ load_timing_result.connect_timing.ssl_start); |
+ EXPECT_EQ(job_load_timing.connect_timing.ssl_end, |
+ load_timing_result.connect_timing.ssl_end); |
+ |
+ // Redundant sanity check. |
+ TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_DNS_TIMES); |
+} |
+ |
+// Another basic test, with proxy and SSL times, but no DNS times. |
+TEST_F(URLRequestTest, InterceptLoadTimingProxy) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ LoadTimingInfo job_load_timing = |
+ NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true); |
+ |
+ LoadTimingInfo load_timing_result = |
+ RunLoadTimingTest(job_load_timing, &default_context_); |
+ |
+ // Nothing should have been changed by the URLRequest. |
+ EXPECT_EQ(job_load_timing.proxy_resolve_start, |
+ load_timing_result.proxy_resolve_start); |
+ EXPECT_EQ(job_load_timing.proxy_resolve_end, |
+ load_timing_result.proxy_resolve_end); |
+ EXPECT_EQ(job_load_timing.connect_timing.dns_start, |
+ load_timing_result.connect_timing.dns_start); |
+ EXPECT_EQ(job_load_timing.connect_timing.dns_end, |
+ load_timing_result.connect_timing.dns_end); |
+ EXPECT_EQ(job_load_timing.connect_timing.connect_start, |
+ load_timing_result.connect_timing.connect_start); |
+ EXPECT_EQ(job_load_timing.connect_timing.connect_end, |
+ load_timing_result.connect_timing.connect_end); |
+ EXPECT_EQ(job_load_timing.connect_timing.ssl_start, |
+ load_timing_result.connect_timing.ssl_start); |
+ EXPECT_EQ(job_load_timing.connect_timing.ssl_end, |
+ load_timing_result.connect_timing.ssl_end); |
+ |
+ // Redundant sanity check. |
+ TestLoadTimingNotReusedWithProxy(load_timing_result, |
+ CONNECT_TIMING_HAS_SSL_TIMES); |
+} |
+ |
+// Make sure that URLRequest correctly adjusts proxy times when they're before |
+// |request_start|, due to already having a connected socket. This happens in |
+// the case of reusing a SPDY session. The connected socket is not considered |
+// reused in this test (May be a preconnect). |
+// |
+// To mix things up from the test above, assumes DNS times but no SSL times. |
+TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ LoadTimingInfo job_load_timing = |
+ NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true); |
+ job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(6); |
+ job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(5); |
+ job_load_timing.connect_timing.dns_start = now - base::TimeDelta::FromDays(4); |
+ job_load_timing.connect_timing.dns_end = now - base::TimeDelta::FromDays(3); |
+ job_load_timing.connect_timing.connect_start = |
+ now - base::TimeDelta::FromDays(2); |
+ job_load_timing.connect_timing.connect_end = |
+ now - base::TimeDelta::FromDays(1); |
+ |
+ LoadTimingInfo load_timing_result = |
+ RunLoadTimingTest(job_load_timing, &default_context_); |
+ |
+ // Proxy times, connect times, and DNS times should all be replaced with |
+ // request_start. |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.proxy_resolve_start); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.proxy_resolve_end); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.dns_start); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.dns_end); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.connect_start); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.connect_end); |
+ |
+ // Other times should have been left null. |
+ TestLoadTimingNotReusedWithProxy(load_timing_result, |
+ CONNECT_TIMING_HAS_DNS_TIMES); |
+} |
+ |
+// Same as above, but in the reused case. |
+TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolutionReused) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true); |
+ job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4); |
+ job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3); |
+ |
+ LoadTimingInfo load_timing_result = |
+ RunLoadTimingTest(job_load_timing, &default_context_); |
+ |
+ // Proxy times and connect times should all be replaced with request_start. |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.proxy_resolve_start); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.proxy_resolve_end); |
+ |
+ // Other times should have been left null. |
+ TestLoadTimingReusedWithProxy(load_timing_result); |
+} |
+ |
+// Make sure that URLRequest correctly adjusts connect times when they're before |
+// |request_start|, due to reusing a connected socket. The connected socket is |
+// not considered reused in this test (May be a preconnect). |
+// |
+// To mix things up, the request has SSL times, but no DNS times. |
+TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ LoadTimingInfo job_load_timing = |
+ NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false); |
+ job_load_timing.connect_timing.connect_start = |
+ now - base::TimeDelta::FromDays(1); |
+ job_load_timing.connect_timing.ssl_start = now - base::TimeDelta::FromDays(2); |
+ job_load_timing.connect_timing.ssl_end = now - base::TimeDelta::FromDays(3); |
+ job_load_timing.connect_timing.connect_end = |
+ now - base::TimeDelta::FromDays(4); |
+ |
+ LoadTimingInfo load_timing_result = |
+ RunLoadTimingTest(job_load_timing, &default_context_); |
+ |
+ // Connect times, and SSL times should be replaced with request_start. |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.connect_start); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.ssl_start); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.ssl_end); |
+ EXPECT_EQ(load_timing_result.request_start, |
+ load_timing_result.connect_timing.connect_end); |
+ |
+ // Other times should have been left null. |
+ TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_SSL_TIMES); |
+} |
+ |
+// Make sure that URLRequest correctly adjusts connect times when they're before |
+// |request_start|, due to reusing a connected socket in the case that there |
+// are also proxy times. The connected socket is not considered reused in this |
+// test (May be a preconnect). |
+// |
+// In this test, there are no SSL or DNS times. |
+TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnectWithProxy) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ LoadTimingInfo job_load_timing = |
+ NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true); |
+ job_load_timing.connect_timing.connect_start = |
+ now - base::TimeDelta::FromDays(1); |
+ job_load_timing.connect_timing.connect_end = |
+ now - base::TimeDelta::FromDays(2); |
+ |
+ LoadTimingInfo load_timing_result = |
+ RunLoadTimingTest(job_load_timing, &default_context_); |
+ |
+ // Connect times should be replaced with proxy_resolve_end. |
+ EXPECT_EQ(load_timing_result.proxy_resolve_end, |
+ load_timing_result.connect_timing.connect_start); |
+ EXPECT_EQ(load_timing_result.proxy_resolve_end, |
+ load_timing_result.connect_timing.connect_end); |
+ |
+ // Other times should have been left null. |
+ TestLoadTimingNotReusedWithProxy(load_timing_result, |
+ CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); |
+} |
+ |
+LoadTimingInfo RunURLRequestInterceptorLoadTimingTest( |
+ const LoadTimingInfo& job_load_timing, |
+ URLRequestContext* context, |
+ MockURLRequestInterceptor* interceptor) { |
+ interceptor->intercept_main_request_ = true; |
+ interceptor->main_request_load_timing_info_ = job_load_timing; |
TestDelegate d; |
scoped_ptr<URLRequest> req(context->CreateRequest( |
GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
@@ -1599,64 +2328,15 @@ LoadTimingInfo RunLoadTimingTest(const LoadTimingInfo& job_load_timing, |
return resulting_load_timing; |
} |
-// "Normal" LoadTimingInfo as returned by a job. Everything is in order, not |
-// reused. |connect_time_flags| is used to indicate if there should be dns |
-// or SSL times, and |used_proxy| is used for proxy times. |
-LoadTimingInfo NormalLoadTimingInfo(base::TimeTicks now, |
- int connect_time_flags, |
- bool used_proxy) { |
- LoadTimingInfo load_timing; |
- load_timing.socket_log_id = 1; |
- |
- if (used_proxy) { |
- load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); |
- load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); |
- } |
- |
- LoadTimingInfo::ConnectTiming& connect_timing = load_timing.connect_timing; |
- if (connect_time_flags & CONNECT_TIMING_HAS_DNS_TIMES) { |
- connect_timing.dns_start = now + base::TimeDelta::FromDays(3); |
- connect_timing.dns_end = now + base::TimeDelta::FromDays(4); |
- } |
- connect_timing.connect_start = now + base::TimeDelta::FromDays(5); |
- if (connect_time_flags & CONNECT_TIMING_HAS_SSL_TIMES) { |
- connect_timing.ssl_start = now + base::TimeDelta::FromDays(6); |
- connect_timing.ssl_end = now + base::TimeDelta::FromDays(7); |
- } |
- connect_timing.connect_end = now + base::TimeDelta::FromDays(8); |
- |
- load_timing.send_start = now + base::TimeDelta::FromDays(9); |
- load_timing.send_end = now + base::TimeDelta::FromDays(10); |
- load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); |
- return load_timing; |
-} |
- |
-// Same as above, but in the case of a reused socket. |
-LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now, |
- bool used_proxy) { |
- LoadTimingInfo load_timing; |
- load_timing.socket_log_id = 1; |
- load_timing.socket_reused = true; |
- |
- if (used_proxy) { |
- load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); |
- load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); |
- } |
- |
- load_timing.send_start = now + base::TimeDelta::FromDays(9); |
- load_timing.send_end = now + base::TimeDelta::FromDays(10); |
- load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); |
- return load_timing; |
-} |
- |
// Basic test that the intercept + load timing tests work. |
-TEST_F(URLRequestTest, InterceptLoadTiming) { |
+TEST_F(URLRequestInterceptorTest, InterceptLoadTiming) { |
base::TimeTicks now = base::TimeTicks::Now(); |
LoadTimingInfo job_load_timing = |
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false); |
LoadTimingInfo load_timing_result = |
- RunLoadTimingTest(job_load_timing, &default_context_); |
+ RunURLRequestInterceptorLoadTimingTest( |
+ job_load_timing, &default_context_, interceptor_); |
// Nothing should have been changed by the URLRequest. |
EXPECT_EQ(job_load_timing.proxy_resolve_start, |
@@ -1681,13 +2361,14 @@ TEST_F(URLRequestTest, InterceptLoadTiming) { |
} |
// Another basic test, with proxy and SSL times, but no DNS times. |
-TEST_F(URLRequestTest, InterceptLoadTimingProxy) { |
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingProxy) { |
base::TimeTicks now = base::TimeTicks::Now(); |
LoadTimingInfo job_load_timing = |
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true); |
LoadTimingInfo load_timing_result = |
- RunLoadTimingTest(job_load_timing, &default_context_); |
+ RunURLRequestInterceptorLoadTimingTest( |
+ job_load_timing, &default_context_, interceptor_); |
// Nothing should have been changed by the URLRequest. |
EXPECT_EQ(job_load_timing.proxy_resolve_start, |
@@ -1718,7 +2399,7 @@ TEST_F(URLRequestTest, InterceptLoadTimingProxy) { |
// reused in this test (May be a preconnect). |
// |
// To mix things up from the test above, assumes DNS times but no SSL times. |
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) { |
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyProxyResolution) { |
base::TimeTicks now = base::TimeTicks::Now(); |
LoadTimingInfo job_load_timing = |
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true); |
@@ -1732,7 +2413,8 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) { |
now - base::TimeDelta::FromDays(1); |
LoadTimingInfo load_timing_result = |
- RunLoadTimingTest(job_load_timing, &default_context_); |
+ RunURLRequestInterceptorLoadTimingTest( |
+ job_load_timing, &default_context_, interceptor_); |
// Proxy times, connect times, and DNS times should all be replaced with |
// request_start. |
@@ -1755,14 +2437,16 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) { |
} |
// Same as above, but in the reused case. |
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolutionReused) { |
+TEST_F(URLRequestInterceptorTest, |
+ InterceptLoadTimingEarlyProxyResolutionReused) { |
base::TimeTicks now = base::TimeTicks::Now(); |
LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true); |
job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4); |
job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3); |
LoadTimingInfo load_timing_result = |
- RunLoadTimingTest(job_load_timing, &default_context_); |
+ RunURLRequestInterceptorLoadTimingTest( |
+ job_load_timing, &default_context_, interceptor_); |
// Proxy times and connect times should all be replaced with request_start. |
EXPECT_EQ(load_timing_result.request_start, |
@@ -1779,7 +2463,7 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolutionReused) { |
// not considered reused in this test (May be a preconnect). |
// |
// To mix things up, the request has SSL times, but no DNS times. |
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) { |
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnect) { |
base::TimeTicks now = base::TimeTicks::Now(); |
LoadTimingInfo job_load_timing = |
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false); |
@@ -1791,7 +2475,8 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) { |
now - base::TimeDelta::FromDays(4); |
LoadTimingInfo load_timing_result = |
- RunLoadTimingTest(job_load_timing, &default_context_); |
+ RunURLRequestInterceptorLoadTimingTest( |
+ job_load_timing, &default_context_, interceptor_); |
// Connect times, and SSL times should be replaced with request_start. |
EXPECT_EQ(load_timing_result.request_start, |
@@ -1813,7 +2498,7 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) { |
// test (May be a preconnect). |
// |
// In this test, there are no SSL or DNS times. |
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnectWithProxy) { |
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnectWithProxy) { |
base::TimeTicks now = base::TimeTicks::Now(); |
LoadTimingInfo job_load_timing = |
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true); |
@@ -1823,7 +2508,8 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnectWithProxy) { |
now - base::TimeDelta::FromDays(2); |
LoadTimingInfo load_timing_result = |
- RunLoadTimingTest(job_load_timing, &default_context_); |
+ RunURLRequestInterceptorLoadTimingTest( |
+ job_load_timing, &default_context_, interceptor_); |
// Connect times should be replaced with proxy_resolve_end. |
EXPECT_EQ(load_timing_result.proxy_resolve_end, |
@@ -6446,6 +7132,241 @@ TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) { |
EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error()); |
} |
+class URLRequestInterceptorTestHTTP : public URLRequestInterceptorTest { |
+ public: |
+ URLRequestInterceptorTestHTTP() |
+ : test_server_(base::FilePath(FILE_PATH_LITERAL( |
+ "net/data/url_request_unittest"))) { |
+ } |
+ |
+ protected: |
+ // Requests |redirect_url|, which must return a HTTP 3xx redirect. |
+ // |request_method| is the method to use for the initial request. |
+ // |redirect_method| is the method that is expected to be used for the second |
+ // request, after redirection. |
+ // If |include_data| is true, data is uploaded with the request. The |
+ // response body is expected to match it exactly, if and only if |
+ // |request_method| == |redirect_method|. |
+ void HTTPRedirectMethodTest(const GURL& redirect_url, |
mmenke
2014/11/05 20:52:49
Per other comment, I'd like to see this test fixtu
|
+ const std::string& request_method, |
+ const std::string& redirect_method, |
+ bool include_data) { |
+ static const char kData[] = "hello world"; |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ redirect_url, DEFAULT_PRIORITY, &d, NULL)); |
+ req->set_method(request_method); |
+ if (include_data) { |
+ req->set_upload(CreateSimpleUploadData(kData)); |
+ HttpRequestHeaders headers; |
+ headers.SetHeader(HttpRequestHeaders::kContentLength, |
+ base::UintToString(arraysize(kData) - 1)); |
+ req->SetExtraRequestHeaders(headers); |
+ } |
+ req->Start(); |
+ base::RunLoop().Run(); |
+ EXPECT_EQ(redirect_method, req->method()); |
+ EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
+ EXPECT_EQ(OK, req->status().error()); |
+ if (include_data) { |
+ if (request_method == redirect_method) { |
+ EXPECT_EQ(kData, d.data_received()); |
+ } else { |
+ EXPECT_NE(kData, d.data_received()); |
+ } |
+ } |
+ if (HasFailure()) |
+ LOG(WARNING) << "Request method was: " << request_method; |
+ } |
+ |
+ void HTTPUploadDataOperationTest(const std::string& method) { |
+ 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'; |
+ |
+ for (int i = 0; i < kIterations; ++i) { |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
+ test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
+ r->set_method(method.c_str()); |
+ |
+ r->set_upload(CreateSimpleUploadData(uploadBytes)); |
+ |
+ r->Start(); |
+ EXPECT_TRUE(r->is_pending()); |
+ |
+ base::RunLoop().Run(); |
+ |
+ ASSERT_EQ(1, d.response_started_count()) |
+ << "request failed: " << r->status().status() |
+ << ", os error: " << r->status().error(); |
+ |
+ EXPECT_FALSE(d.received_data_before_response()); |
+ EXPECT_EQ(uploadBytes, d.data_received()); |
+ } |
+ delete[] uploadBytes; |
+ } |
+ |
+ void AddChunksToUpload(URLRequest* r) { |
+ r->AppendChunkToUpload("a", 1, false); |
+ r->AppendChunkToUpload("bcd", 3, false); |
+ r->AppendChunkToUpload("this is a longer chunk than before.", 35, false); |
+ r->AppendChunkToUpload("\r\n\r\n", 4, false); |
+ r->AppendChunkToUpload("0", 1, false); |
+ r->AppendChunkToUpload("2323", 4, true); |
+ } |
+ |
+ void VerifyReceivedDataMatchesChunks(URLRequest* r, TestDelegate* d) { |
+ // This should match the chunks sent by AddChunksToUpload(). |
+ const std::string expected_data = |
+ "abcdthis is a longer chunk than before.\r\n\r\n02323"; |
+ |
+ ASSERT_EQ(1, d->response_started_count()) |
+ << "request failed: " << r->status().status() |
+ << ", os error: " << r->status().error(); |
+ |
+ EXPECT_FALSE(d->received_data_before_response()); |
+ |
+ EXPECT_EQ(expected_data.size(), static_cast<size_t>(d->bytes_received())); |
+ EXPECT_EQ(expected_data, d->data_received()); |
+ } |
+ |
+ bool DoManyCookiesRequest(int num_cookies) { |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
+ test_server_.GetURL("set-many-cookies?" + |
+ base::IntToString(num_cookies)), |
+ DEFAULT_PRIORITY, &d, NULL)); |
+ |
+ r->Start(); |
+ EXPECT_TRUE(r->is_pending()); |
+ |
+ base::RunLoop().Run(); |
+ |
+ bool is_success = r->status().is_success(); |
+ |
+ if (!is_success) { |
+ EXPECT_TRUE(r->status().error() == ERR_RESPONSE_HEADERS_TOO_BIG); |
+ // The test server appears to be unable to handle subsequent requests |
+ // after this error is triggered. Force it to restart. |
+ EXPECT_TRUE(test_server_.Stop()); |
+ EXPECT_TRUE(test_server_.Start()); |
+ } |
+ |
+ return is_success; |
+ } |
+ |
+ LocalHttpTestServer test_server_; |
+}; |
+ |
+TEST_F(URLRequestInterceptorTestHTTP, |
+ NetworkDelegateNotificationOnRedirectIntercept) { |
mmenke
2014/11/05 20:52:49
Should probably intercept the request and replace
|
+ interceptor_->intercept_redirect_ = true; |
+ interceptor_->redirect_headers_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->redirect_data_ = MockURLRequestInterceptor::ok_data(); |
+ |
+ ASSERT_TRUE(test_server_.Start()); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, |
+ &d, NULL)); |
+ req->Start(); |
+ base::RunLoop().Run(); |
+ |
+ 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(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+ |
+ EXPECT_EQ(1, default_network_delegate_.created_requests()); |
+ EXPECT_EQ(1, default_network_delegate_.before_send_headers_count()); |
+ EXPECT_EQ(1, default_network_delegate_.headers_received_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTestHTTP, |
+ NetworkDelegateNotificationOnErrorIntercept) { |
+ // Intercept that error and respond with an OK response. |
+ interceptor_->intercept_final_response_ = true; |
+ interceptor_->final_headers_ = MockURLRequestInterceptor::ok_headers(); |
+ interceptor_->final_data_ = MockURLRequestInterceptor::ok_data(); |
+ default_network_delegate_.set_can_be_intercepted_on_error(true); |
+ |
+ ASSERT_TRUE(test_server_.Start()); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ test_server_.GetURL("files/two-content-lengths.html"), DEFAULT_PRIORITY, |
+ &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().Run(); |
+ |
+ 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(MockURLRequestInterceptor::ok_data(), d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+ |
+ EXPECT_EQ(1, default_network_delegate_.created_requests()); |
+ EXPECT_EQ(1, default_network_delegate_.before_send_headers_count()); |
+ EXPECT_EQ(0, default_network_delegate_.headers_received_count()); |
+} |
+ |
+TEST_F(URLRequestInterceptorTestHTTP, |
+ NetworkDelegateNotificationOnResponseIntercept) { |
+ // Intercept that error and respond with an OK response. |
+ interceptor_->intercept_final_response_ = true; |
+ |
+ // Intercept with a real URLRequestHttpJob. |
+ interceptor_->use_url_request_http_job_ = true; |
+ |
+ ASSERT_TRUE(test_server_.Start()); |
+ |
+ TestDelegate d; |
+ scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
+ test_server_.GetURL("files/simple.html"), DEFAULT_PRIORITY, |
+ &d, NULL)); |
+ req->set_method("GET"); |
+ req->Start(); |
+ base::RunLoop().Run(); |
+ |
+ 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("hello", d.data_received()); |
+ EXPECT_EQ(1, d.response_started_count()); |
+ EXPECT_EQ(0, d.received_redirect_count()); |
+ |
+ EXPECT_EQ(1, default_network_delegate_.created_requests()); |
+ EXPECT_EQ(2, default_network_delegate_.before_send_headers_count()); |
+ EXPECT_EQ(2, default_network_delegate_.headers_received_count()); |
+} |
+ |
+ |
class HTTPSRequestTest : public testing::Test { |
public: |
HTTPSRequestTest() : default_context_(true) { |