OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <queue> |
| 6 #include <string> |
5 #include <vector> | 7 #include <vector> |
6 | 8 |
7 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
8 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback.h" |
9 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
10 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
11 #include "base/memory/scoped_vector.h" | 14 #include "base/memory/scoped_vector.h" |
12 #include "base/memory/shared_memory.h" | 15 #include "base/memory/shared_memory.h" |
13 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
14 #include "base/pickle.h" | 17 #include "base/pickle.h" |
15 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
16 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
18 #include "content/browser/browser_thread_impl.h" | 21 #include "content/browser/browser_thread_impl.h" |
(...skipping 12 matching lines...) Expand all Loading... |
31 #include "content/public/browser/resource_context.h" | 34 #include "content/public/browser/resource_context.h" |
32 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 35 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
33 #include "content/public/browser/resource_request_info.h" | 36 #include "content/public/browser/resource_request_info.h" |
34 #include "content/public/browser/resource_throttle.h" | 37 #include "content/public/browser/resource_throttle.h" |
35 #include "content/public/common/process_type.h" | 38 #include "content/public/common/process_type.h" |
36 #include "content/public/common/resource_response.h" | 39 #include "content/public/common/resource_response.h" |
37 #include "content/public/test/test_browser_context.h" | 40 #include "content/public/test/test_browser_context.h" |
38 #include "content/public/test/test_browser_thread_bundle.h" | 41 #include "content/public/test/test_browser_thread_bundle.h" |
39 #include "content/test/test_content_browser_client.h" | 42 #include "content/test/test_content_browser_client.h" |
40 #include "net/base/elements_upload_data_stream.h" | 43 #include "net/base/elements_upload_data_stream.h" |
| 44 #include "net/base/load_flags.h" |
41 #include "net/base/net_errors.h" | 45 #include "net/base/net_errors.h" |
42 #include "net/base/request_priority.h" | 46 #include "net/base/request_priority.h" |
43 #include "net/base/upload_bytes_element_reader.h" | 47 #include "net/base/upload_bytes_element_reader.h" |
44 #include "net/http/http_util.h" | 48 #include "net/http/http_util.h" |
45 #include "net/url_request/url_request.h" | 49 #include "net/url_request/url_request.h" |
46 #include "net/url_request/url_request_context.h" | 50 #include "net/url_request/url_request_context.h" |
47 #include "net/url_request/url_request_job.h" | 51 #include "net/url_request/url_request_job.h" |
48 #include "net/url_request/url_request_job_factory.h" | 52 #include "net/url_request/url_request_job_factory.h" |
49 #include "net/url_request/url_request_simple_job.h" | 53 #include "net/url_request/url_request_simple_job.h" |
50 #include "net/url_request/url_request_test_job.h" | 54 #include "net/url_request/url_request_test_job.h" |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 browser_context_.reset(new TestBrowserContext()); | 782 browser_context_.reset(new TestBrowserContext()); |
779 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); | 783 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); |
780 base::RunLoop().RunUntilIdle(); | 784 base::RunLoop().RunUntilIdle(); |
781 filter_ = MakeForwardingFilter(); | 785 filter_ = MakeForwardingFilter(); |
782 // TODO(cbentzel): Better way to get URLRequestContext? | 786 // TODO(cbentzel): Better way to get URLRequestContext? |
783 net::URLRequestContext* request_context = | 787 net::URLRequestContext* request_context = |
784 browser_context_->GetResourceContext()->GetRequestContext(); | 788 browser_context_->GetResourceContext()->GetRequestContext(); |
785 job_factory_.reset(new TestURLRequestJobFactory(this)); | 789 job_factory_.reset(new TestURLRequestJobFactory(this)); |
786 request_context->set_job_factory(job_factory_.get()); | 790 request_context->set_job_factory(job_factory_.get()); |
787 request_context->set_network_delegate(&network_delegate_); | 791 request_context->set_network_delegate(&network_delegate_); |
| 792 // TODO(ricea): Remove this when it becomes the default. |
| 793 host_.async_revalidation_enabled_ = true; |
788 } | 794 } |
789 | 795 |
790 // IPC::Sender implementation | 796 // IPC::Sender implementation |
791 bool Send(IPC::Message* msg) override { | 797 bool Send(IPC::Message* msg) override { |
792 accum_.AddMessage(*msg); | 798 accum_.AddMessage(*msg); |
793 | 799 |
794 if (send_data_received_acks_ && | 800 if (send_data_received_acks_ && |
795 msg->type() == ResourceMsg_DataReceived::ID) { | 801 msg->type() == ResourceMsg_DataReceived::ID) { |
796 GenerateDataReceivedACK(*msg); | 802 GenerateDataReceivedACK(*msg); |
797 } | 803 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 return old_filter; | 941 return old_filter; |
936 } | 942 } |
937 | 943 |
938 void WaitForRequestComplete() { | 944 void WaitForRequestComplete() { |
939 DCHECK(!wait_for_request_complete_loop_); | 945 DCHECK(!wait_for_request_complete_loop_); |
940 wait_for_request_complete_loop_.reset(new base::RunLoop); | 946 wait_for_request_complete_loop_.reset(new base::RunLoop); |
941 wait_for_request_complete_loop_->Run(); | 947 wait_for_request_complete_loop_->Run(); |
942 wait_for_request_complete_loop_.reset(); | 948 wait_for_request_complete_loop_.reset(); |
943 } | 949 } |
944 | 950 |
| 951 typedef base::Callback<net::URLRequestJob*(net::URLRequest*, |
| 952 net::NetworkDelegate*)> |
| 953 URLRequestJobCreateCallback; |
| 954 |
| 955 void SetCustomURLRequestJobCreateCallback( |
| 956 const URLRequestJobCreateCallback& callback) { |
| 957 custom_url_request_job_create_callback_.reset( |
| 958 new URLRequestJobCreateCallback(callback)); |
| 959 } |
| 960 |
945 scoped_ptr<LoadInfoTestRequestInfo> loader_test_request_info_; | 961 scoped_ptr<LoadInfoTestRequestInfo> loader_test_request_info_; |
946 scoped_ptr<base::RunLoop> wait_for_request_create_loop_; | 962 scoped_ptr<base::RunLoop> wait_for_request_create_loop_; |
947 | 963 |
| 964 scoped_ptr<URLRequestJobCreateCallback> |
| 965 custom_url_request_job_create_callback_; |
| 966 |
948 content::TestBrowserThreadBundle thread_bundle_; | 967 content::TestBrowserThreadBundle thread_bundle_; |
949 scoped_ptr<TestBrowserContext> browser_context_; | 968 scoped_ptr<TestBrowserContext> browser_context_; |
950 scoped_ptr<TestURLRequestJobFactory> job_factory_; | 969 scoped_ptr<TestURLRequestJobFactory> job_factory_; |
951 scoped_refptr<ForwardingFilter> filter_; | 970 scoped_refptr<ForwardingFilter> filter_; |
952 net::TestNetworkDelegate network_delegate_; | 971 net::TestNetworkDelegate network_delegate_; |
953 ResourceDispatcherHostImpl host_; | 972 ResourceDispatcherHostImpl host_; |
954 ResourceIPCAccumulator accum_; | 973 ResourceIPCAccumulator accum_; |
955 std::string response_headers_; | 974 std::string response_headers_; |
956 std::string response_data_; | 975 std::string response_data_; |
957 std::string scheme_; | 976 std::string scheme_; |
(...skipping 2237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3195 url_request_jobs_created_count_++; | 3214 url_request_jobs_created_count_++; |
3196 if (test_fixture_->wait_for_request_create_loop_) | 3215 if (test_fixture_->wait_for_request_create_loop_) |
3197 test_fixture_->wait_for_request_create_loop_->Quit(); | 3216 test_fixture_->wait_for_request_create_loop_->Quit(); |
3198 if (test_fixture_->loader_test_request_info_) { | 3217 if (test_fixture_->loader_test_request_info_) { |
3199 DCHECK_EQ(test_fixture_->loader_test_request_info_->url, request->url()); | 3218 DCHECK_EQ(test_fixture_->loader_test_request_info_->url, request->url()); |
3200 scoped_ptr<LoadInfoTestRequestInfo> info = | 3219 scoped_ptr<LoadInfoTestRequestInfo> info = |
3201 test_fixture_->loader_test_request_info_.Pass(); | 3220 test_fixture_->loader_test_request_info_.Pass(); |
3202 return new URLRequestLoadInfoJob(request, network_delegate, | 3221 return new URLRequestLoadInfoJob(request, network_delegate, |
3203 info->load_state, info->upload_progress); | 3222 info->load_state, info->upload_progress); |
3204 } | 3223 } |
| 3224 if (test_fixture_->custom_url_request_job_create_callback_) { |
| 3225 return test_fixture_->custom_url_request_job_create_callback_->Run( |
| 3226 request, network_delegate); |
| 3227 } |
3205 if (test_fixture_->response_headers_.empty()) { | 3228 if (test_fixture_->response_headers_.empty()) { |
3206 if (delay_start_) { | 3229 if (delay_start_) { |
3207 return new URLRequestTestDelayedStartJob(request, network_delegate); | 3230 return new URLRequestTestDelayedStartJob(request, network_delegate); |
3208 } else if (delay_complete_) { | 3231 } else if (delay_complete_) { |
3209 return new URLRequestTestDelayedCompletionJob(request, | 3232 return new URLRequestTestDelayedCompletionJob(request, |
3210 network_delegate); | 3233 network_delegate); |
3211 } else if (network_start_notification_) { | 3234 } else if (network_start_notification_) { |
3212 return new URLRequestTestDelayedNetworkJob(request, network_delegate); | 3235 return new URLRequestTestDelayedNetworkJob(request, network_delegate); |
3213 } else if (scheme == "big-job") { | 3236 } else if (scheme == "big-job") { |
3214 return new URLRequestBigJob(request, network_delegate); | 3237 return new URLRequestBigJob(request, network_delegate); |
(...skipping 26 matching lines...) Expand all Loading... |
3241 const GURL& location) const { | 3264 const GURL& location) const { |
3242 return nullptr; | 3265 return nullptr; |
3243 } | 3266 } |
3244 | 3267 |
3245 net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse( | 3268 net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse( |
3246 net::URLRequest* request, | 3269 net::URLRequest* request, |
3247 net::NetworkDelegate* network_delegate) const { | 3270 net::NetworkDelegate* network_delegate) const { |
3248 return nullptr; | 3271 return nullptr; |
3249 } | 3272 } |
3250 | 3273 |
| 3274 TEST_F(ResourceDispatcherHostTest, SupportsAsyncRevalidation) { |
| 3275 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3276 HandleScheme("http"); |
| 3277 // Prevent the job from completing synchronously. |
| 3278 job_factory_->SetDelayedCompleteJobGeneration(true); |
| 3279 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete"); |
| 3280 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3281 |
| 3282 net::URLRequest* url_request( |
| 3283 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); |
| 3284 ASSERT_TRUE(url_request); |
| 3285 |
| 3286 EXPECT_TRUE(url_request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3287 } |
| 3288 |
| 3289 TEST_F(ResourceDispatcherHostTest, RequestsNotAsyncByDefault) { |
| 3290 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3291 HandleScheme("http"); |
| 3292 // Prevent the job from completing synchronously. |
| 3293 job_factory_->SetDelayedCompleteJobGeneration(true); |
| 3294 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete"); |
| 3295 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3296 |
| 3297 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( |
| 3298 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); |
| 3299 ASSERT_TRUE(info); |
| 3300 |
| 3301 EXPECT_FALSE(info->IsAsyncRevalidation()); |
| 3302 } |
| 3303 |
| 3304 TEST_F(ResourceDispatcherHostTest, AsyncRevalidationNotSupportedForPOST) { |
| 3305 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3306 HandleScheme("http"); |
| 3307 // Prevent the job from completing synchronously. |
| 3308 job_factory_->SetDelayedCompleteJobGeneration(true); |
| 3309 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete"); |
| 3310 // Create POST request. |
| 3311 ResourceHostMsg_Request request = CreateResourceRequest( |
| 3312 "POST", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/baz.php")); |
| 3313 ResourceHostMsg_RequestResource msg(0, 1, request); |
| 3314 host_.OnMessageReceived(msg, filter_.get()); |
| 3315 KickOffRequest(); |
| 3316 |
| 3317 net::URLRequest* url_request( |
| 3318 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); |
| 3319 ASSERT_TRUE(url_request); |
| 3320 |
| 3321 EXPECT_FALSE(url_request->load_flags() & |
| 3322 net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3323 } |
| 3324 |
| 3325 // A URLRequest job type which sets the |async_revalidation_required| flag on |
| 3326 // the HttpResponseInfo object to true if the request has the |
| 3327 // LOAD_SUPPORT_ASYNC_REVALIDATION flag. |
| 3328 class AsyncRevalidationRequiredURLRequestTestJob |
| 3329 : public net::URLRequestTestJob { |
| 3330 public: |
| 3331 // The Create() method is useful for wrapping the construction of the object |
| 3332 // in a Callback. |
| 3333 static net::URLRequestJob* Create(net::URLRequest* request, |
| 3334 net::NetworkDelegate* network_delegate) { |
| 3335 return new AsyncRevalidationRequiredURLRequestTestJob(request, |
| 3336 network_delegate); |
| 3337 } |
| 3338 |
| 3339 void GetResponseInfo(net::HttpResponseInfo* info) override { |
| 3340 if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) |
| 3341 info->async_revalidation_required = true; |
| 3342 } |
| 3343 |
| 3344 private: |
| 3345 AsyncRevalidationRequiredURLRequestTestJob( |
| 3346 net::URLRequest* request, |
| 3347 net::NetworkDelegate* network_delegate) |
| 3348 : URLRequestTestJob(request, |
| 3349 network_delegate, |
| 3350 net::URLRequestTestJob::test_headers(), |
| 3351 std::string(), |
| 3352 false) {} |
| 3353 |
| 3354 ~AsyncRevalidationRequiredURLRequestTestJob() override {} |
| 3355 |
| 3356 DISALLOW_COPY_AND_ASSIGN(AsyncRevalidationRequiredURLRequestTestJob); |
| 3357 }; |
| 3358 |
| 3359 // A ResourceDispatcherHostDelegate that records the URLRequests that it sees |
| 3360 // in a queue. |
| 3361 class URLRequestRecordingResourceDispatcherHostDelegate |
| 3362 : public ResourceDispatcherHostDelegate { |
| 3363 public: |
| 3364 URLRequestRecordingResourceDispatcherHostDelegate() : requests_() {} |
| 3365 |
| 3366 net::URLRequest* NextRequest() { |
| 3367 CHECK(!requests_.empty()); |
| 3368 net::URLRequest* request = requests_.front(); |
| 3369 requests_.pop(); |
| 3370 return request; |
| 3371 } |
| 3372 |
| 3373 bool IsEmpty() { |
| 3374 return requests_.empty(); |
| 3375 } |
| 3376 |
| 3377 void OnResponseStarted(net::URLRequest* request, |
| 3378 ResourceContext* resource_context, |
| 3379 ResourceResponse* response, |
| 3380 IPC::Sender* sender) override { |
| 3381 requests_.push(request); |
| 3382 } |
| 3383 |
| 3384 private: |
| 3385 std::queue<net::URLRequest*> requests_; |
| 3386 |
| 3387 DISALLOW_COPY_AND_ASSIGN(URLRequestRecordingResourceDispatcherHostDelegate); |
| 3388 }; |
| 3389 |
| 3390 TEST_F(ResourceDispatcherHostTest, AsyncRevalidationIssued) { |
| 3391 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3392 HandleScheme("http"); |
| 3393 // Use the AsyncRevalidationRequiredURLRequestTestJob. |
| 3394 SetCustomURLRequestJobCreateCallback( |
| 3395 base::Bind(&AsyncRevalidationRequiredURLRequestTestJob::Create)); |
| 3396 URLRequestRecordingResourceDispatcherHostDelegate delegate; |
| 3397 host_.SetDelegate(&delegate); |
| 3398 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3399 |
| 3400 net::URLRequest* initial_request = delegate.NextRequest(); |
| 3401 ASSERT_TRUE(initial_request); |
| 3402 ResourceRequestInfoImpl* initial_info = |
| 3403 ResourceRequestInfoImpl::ForRequest(initial_request); |
| 3404 ASSERT_TRUE(initial_info); |
| 3405 |
| 3406 EXPECT_FALSE(initial_info->IsAsyncRevalidation()); |
| 3407 |
| 3408 net::URLRequest* async_request = delegate.NextRequest(); |
| 3409 ASSERT_TRUE(async_request); |
| 3410 ResourceRequestInfoImpl* async_info = |
| 3411 ResourceRequestInfoImpl::ForRequest(async_request); |
| 3412 ASSERT_TRUE(async_info); |
| 3413 |
| 3414 EXPECT_TRUE(async_info->IsAsyncRevalidation()); |
| 3415 } |
| 3416 |
| 3417 TEST_F(ResourceDispatcherHostTest, |
| 3418 AsyncRevalidationsDoNotSupportAsyncRevalidation) { |
| 3419 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3420 HandleScheme("http"); |
| 3421 // Use the AsyncRevalidationRequiredURLRequestTestJob. |
| 3422 SetCustomURLRequestJobCreateCallback( |
| 3423 base::Bind(&AsyncRevalidationRequiredURLRequestTestJob::Create)); |
| 3424 URLRequestRecordingResourceDispatcherHostDelegate delegate; |
| 3425 host_.SetDelegate(&delegate); |
| 3426 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3427 |
| 3428 // Discard the original request. |
| 3429 delegate.NextRequest(); |
| 3430 |
| 3431 // Get the async revalidation request. |
| 3432 net::URLRequest* async_request = delegate.NextRequest(); |
| 3433 |
| 3434 EXPECT_FALSE(async_request->load_flags() & |
| 3435 net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3436 } |
| 3437 |
| 3438 TEST_F(ResourceDispatcherHostTest, AsyncRevalidationsNotDuplicated) { |
| 3439 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3440 HandleScheme("http"); |
| 3441 // Use the AsyncRevalidationRequiredURLRequestTestJob. |
| 3442 SetCustomURLRequestJobCreateCallback( |
| 3443 base::Bind(&AsyncRevalidationRequiredURLRequestTestJob::Create)); |
| 3444 URLRequestRecordingResourceDispatcherHostDelegate delegate; |
| 3445 host_.SetDelegate(&delegate); |
| 3446 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3447 |
| 3448 // Discard the original request. |
| 3449 delegate.NextRequest(); |
| 3450 |
| 3451 // Get the async revalidation request info. |
| 3452 ResourceRequestInfoImpl* async_info = |
| 3453 ResourceRequestInfoImpl::ForRequest(delegate.NextRequest()); |
| 3454 |
| 3455 // Start a second request to the same URL. |
| 3456 MakeTestRequest(0, 2, GURL("http://example.com/baz")); |
| 3457 |
| 3458 ResourceRequestInfoImpl* second_request_info = |
| 3459 ResourceRequestInfoImpl::ForRequest(delegate.NextRequest()); |
| 3460 |
| 3461 EXPECT_TRUE(async_info->IsAsyncRevalidation()); |
| 3462 EXPECT_FALSE(second_request_info->IsAsyncRevalidation()); |
| 3463 EXPECT_TRUE(delegate.IsEmpty()); |
| 3464 } |
| 3465 |
| 3466 // Async revalidation to different URLs should not be treated as duplicates. |
| 3467 TEST_F(ResourceDispatcherHostTest, |
| 3468 AsyncRevalidationsToSeparateURLsAreSeparate) { |
| 3469 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3470 HandleScheme("http"); |
| 3471 // Use the AsyncRevalidationRequiredURLRequestTestJob. |
| 3472 SetCustomURLRequestJobCreateCallback( |
| 3473 base::Bind(&AsyncRevalidationRequiredURLRequestTestJob::Create)); |
| 3474 URLRequestRecordingResourceDispatcherHostDelegate delegate; |
| 3475 host_.SetDelegate(&delegate); |
| 3476 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3477 MakeTestRequest(0, 2, GURL("http://example.com/far")); |
| 3478 |
| 3479 net::URLRequest* initial_request = delegate.NextRequest(); |
| 3480 net::URLRequest* initial_async_revalidation = delegate.NextRequest(); |
| 3481 net::URLRequest* second_request = delegate.NextRequest(); |
| 3482 net::URLRequest* second_async_revalidation = delegate.NextRequest(); |
| 3483 |
| 3484 EXPECT_EQ("http://example.com/baz", initial_request->url().spec()); |
| 3485 EXPECT_EQ("http://example.com/baz", initial_async_revalidation->url().spec()); |
| 3486 EXPECT_EQ("http://example.com/far", second_request->url().spec()); |
| 3487 EXPECT_EQ("http://example.com/far", second_async_revalidation->url().spec()); |
| 3488 } |
| 3489 |
3251 } // namespace content | 3490 } // namespace content |
OLD | NEW |