OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // This file contains an implementation of the ResourceLoaderBridge class. | 5 // This file contains an implementation of the ResourceLoaderBridge class. |
6 // The class is implemented using URLRequest, meaning it is a "simple" version | 6 // The class is implemented using net::URLRequest, meaning it is a "simple" |
7 // that directly issues requests. The more complicated one used in the | 7 // version that directly issues requests. The more complicated one used in the |
8 // browser uses IPC. | 8 // browser uses IPC. |
9 // | 9 // |
10 // Because URLRequest only provides an asynchronous resource loading API, this | 10 // Because net::URLRequest only provides an asynchronous resource loading API, |
11 // file makes use of URLRequest from a background IO thread. Requests for | 11 // this file makes use of net::URLRequest from a background IO thread. Requests |
12 // cookies and synchronously loaded resources result in the main thread of the | 12 // for cookies and synchronously loaded resources result in the main thread of |
13 // application blocking until the IO thread completes the operation. (See | 13 // the application blocking until the IO thread completes the operation. (See |
14 // GetCookies and SyncLoad) | 14 // GetCookies and SyncLoad) |
15 // | 15 // |
16 // Main thread IO thread | 16 // Main thread IO thread |
17 // ----------- --------- | 17 // ----------- --------- |
18 // ResourceLoaderBridge <---o---------> RequestProxy (normal case) | 18 // ResourceLoaderBridge <---o---------> RequestProxy (normal case) |
19 // \ -> URLRequest | 19 // \ -> net::URLRequest |
20 // o-------> SyncRequestProxy (synchronous case) | 20 // o-------> SyncRequestProxy (synchronous case) |
21 // -> URLRequest | 21 // -> net::URLRequest |
22 // SetCookie <------------------------> CookieSetter | 22 // SetCookie <------------------------> CookieSetter |
23 // -> net_util::SetCookie | 23 // -> net_util::SetCookie |
24 // GetCookies <-----------------------> CookieGetter | 24 // GetCookies <-----------------------> CookieGetter |
25 // -> net_util::GetCookies | 25 // -> net_util::GetCookies |
26 // | 26 // |
27 // NOTE: The implementation in this file may be used to have WebKit fetch | 27 // NOTE: The implementation in this file may be used to have WebKit fetch |
28 // resources in-process. For example, it is handy for building a single- | 28 // resources in-process. For example, it is handy for building a single- |
29 // process WebKit embedding (e.g., test_shell) that can use URLRequest to | 29 // process WebKit embedding (e.g., test_shell) that can use net::URLRequest to |
30 // perform URL loads. See renderer/resource_dispatcher.h for details on an | 30 // perform URL loads. See renderer/resource_dispatcher.h for details on an |
31 // alternate implementation that defers fetching to another process. | 31 // alternate implementation that defers fetching to another process. |
32 | 32 |
33 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" | 33 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" |
34 | 34 |
35 #include "base/file_path.h" | 35 #include "base/file_path.h" |
36 #include "base/file_util.h" | 36 #include "base/file_util.h" |
37 #include "base/logging.h" | 37 #include "base/logging.h" |
38 #include "base/message_loop.h" | 38 #include "base/message_loop.h" |
39 #include "base/message_loop_proxy.h" | 39 #include "base/message_loop_proxy.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 cache_mode(in_cache_mode), | 90 cache_mode(in_cache_mode), |
91 no_proxy(in_no_proxy), | 91 no_proxy(in_no_proxy), |
92 accept_all_cookies(false) {} | 92 accept_all_cookies(false) {} |
93 | 93 |
94 FilePath cache_path; | 94 FilePath cache_path; |
95 net::HttpCache::Mode cache_mode; | 95 net::HttpCache::Mode cache_mode; |
96 bool no_proxy; | 96 bool no_proxy; |
97 bool accept_all_cookies; | 97 bool accept_all_cookies; |
98 }; | 98 }; |
99 | 99 |
100 static URLRequestJob* BlobURLRequestJobFactory(URLRequest* request, | 100 static URLRequestJob* BlobURLRequestJobFactory(net::URLRequest* request, |
101 const std::string& scheme) { | 101 const std::string& scheme) { |
102 webkit_blob::BlobStorageController* blob_storage_controller = | 102 webkit_blob::BlobStorageController* blob_storage_controller = |
103 static_cast<TestShellRequestContext*>(request->context())-> | 103 static_cast<TestShellRequestContext*>(request->context())-> |
104 blob_storage_controller(); | 104 blob_storage_controller(); |
105 return new webkit_blob::BlobURLRequestJob( | 105 return new webkit_blob::BlobURLRequestJob( |
106 request, | 106 request, |
107 blob_storage_controller->GetBlobDataFromUrl(request->url()), | 107 blob_storage_controller->GetBlobDataFromUrl(request->url()), |
108 NULL); | 108 NULL); |
109 } | 109 } |
110 | 110 |
(...skipping 29 matching lines...) Expand all Loading... |
140 } | 140 } |
141 | 141 |
142 g_request_context->AddRef(); | 142 g_request_context->AddRef(); |
143 | 143 |
144 SimpleAppCacheSystem::InitializeOnIOThread(g_request_context); | 144 SimpleAppCacheSystem::InitializeOnIOThread(g_request_context); |
145 SimpleSocketStreamBridge::InitializeOnIOThread(g_request_context); | 145 SimpleSocketStreamBridge::InitializeOnIOThread(g_request_context); |
146 SimpleFileWriter::InitializeOnIOThread(g_request_context); | 146 SimpleFileWriter::InitializeOnIOThread(g_request_context); |
147 TestShellWebBlobRegistryImpl::InitializeOnIOThread( | 147 TestShellWebBlobRegistryImpl::InitializeOnIOThread( |
148 g_request_context->blob_storage_controller()); | 148 g_request_context->blob_storage_controller()); |
149 | 149 |
150 URLRequest::RegisterProtocolFactory("blob", &BlobURLRequestJobFactory); | 150 net::URLRequest::RegisterProtocolFactory("blob", &BlobURLRequestJobFactory); |
151 } | 151 } |
152 | 152 |
153 virtual void CleanUp() { | 153 virtual void CleanUp() { |
154 // In reverse order of initialization. | 154 // In reverse order of initialization. |
155 TestShellWebBlobRegistryImpl::Cleanup(); | 155 TestShellWebBlobRegistryImpl::Cleanup(); |
156 SimpleFileWriter::CleanupOnIOThread(); | 156 SimpleFileWriter::CleanupOnIOThread(); |
157 SimpleSocketStreamBridge::Cleanup(); | 157 SimpleSocketStreamBridge::Cleanup(); |
158 SimpleAppCacheSystem::CleanupOnIOThread(); | 158 SimpleAppCacheSystem::CleanupOnIOThread(); |
159 | 159 |
160 if (g_request_context) { | 160 if (g_request_context) { |
(...skipping 25 matching lines...) Expand all Loading... |
186 ResourceType::Type request_type; | 186 ResourceType::Type request_type; |
187 int appcache_host_id; | 187 int appcache_host_id; |
188 bool download_to_file; | 188 bool download_to_file; |
189 scoped_refptr<net::UploadData> upload; | 189 scoped_refptr<net::UploadData> upload; |
190 }; | 190 }; |
191 | 191 |
192 // The interval for calls to RequestProxy::MaybeUpdateUploadProgress | 192 // The interval for calls to RequestProxy::MaybeUpdateUploadProgress |
193 static const int kUpdateUploadProgressIntervalMsec = 100; | 193 static const int kUpdateUploadProgressIntervalMsec = 100; |
194 | 194 |
195 // The RequestProxy does most of its work on the IO thread. The Start and | 195 // The RequestProxy does most of its work on the IO thread. The Start and |
196 // Cancel methods are proxied over to the IO thread, where an URLRequest object | 196 // Cancel methods are proxied over to the IO thread, where an net::URLRequest |
197 // is instantiated. | 197 // object is instantiated. |
198 class RequestProxy : public URLRequest::Delegate, | 198 class RequestProxy : public net::URLRequest::Delegate, |
199 public base::RefCountedThreadSafe<RequestProxy> { | 199 public base::RefCountedThreadSafe<RequestProxy> { |
200 public: | 200 public: |
201 // Takes ownership of the params. | 201 // Takes ownership of the params. |
202 RequestProxy() | 202 RequestProxy() |
203 : download_to_file_(false), | 203 : download_to_file_(false), |
204 buf_(new net::IOBuffer(kDataSize)), | 204 buf_(new net::IOBuffer(kDataSize)), |
205 last_upload_position_(0) { | 205 last_upload_position_(0) { |
206 } | 206 } |
207 | 207 |
208 void DropPeer() { | 208 void DropPeer() { |
(...skipping 19 matching lines...) Expand all Loading... |
228 friend class base::RefCountedThreadSafe<RequestProxy>; | 228 friend class base::RefCountedThreadSafe<RequestProxy>; |
229 | 229 |
230 virtual ~RequestProxy() { | 230 virtual ~RequestProxy() { |
231 // If we have a request, then we'd better be on the io thread! | 231 // If we have a request, then we'd better be on the io thread! |
232 DCHECK(!request_.get() || | 232 DCHECK(!request_.get() || |
233 MessageLoop::current() == g_io_thread->message_loop()); | 233 MessageLoop::current() == g_io_thread->message_loop()); |
234 } | 234 } |
235 | 235 |
236 // -------------------------------------------------------------------------- | 236 // -------------------------------------------------------------------------- |
237 // The following methods are called on the owner's thread in response to | 237 // The following methods are called on the owner's thread in response to |
238 // various URLRequest callbacks. The event hooks, defined below, trigger | 238 // various net::URLRequest callbacks. The event hooks, defined below, trigger |
239 // these methods asynchronously. | 239 // these methods asynchronously. |
240 | 240 |
241 void NotifyReceivedRedirect(const GURL& new_url, | 241 void NotifyReceivedRedirect(const GURL& new_url, |
242 const ResourceResponseInfo& info) { | 242 const ResourceResponseInfo& info) { |
243 bool has_new_first_party_for_cookies = false; | 243 bool has_new_first_party_for_cookies = false; |
244 GURL new_first_party_for_cookies; | 244 GURL new_first_party_for_cookies; |
245 if (peer_ && peer_->OnReceivedRedirect(new_url, info, | 245 if (peer_ && peer_->OnReceivedRedirect(new_url, info, |
246 &has_new_first_party_for_cookies, | 246 &has_new_first_party_for_cookies, |
247 &new_first_party_for_cookies)) { | 247 &new_first_party_for_cookies)) { |
248 g_io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 248 g_io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 // actions performed on the owner's thread. | 310 // actions performed on the owner's thread. |
311 | 311 |
312 void AsyncStart(RequestParams* params) { | 312 void AsyncStart(RequestParams* params) { |
313 // Might need to resolve the blob references in the upload data. | 313 // Might need to resolve the blob references in the upload data. |
314 if (params->upload) { | 314 if (params->upload) { |
315 static_cast<TestShellRequestContext*>(g_request_context)-> | 315 static_cast<TestShellRequestContext*>(g_request_context)-> |
316 blob_storage_controller()->ResolveBlobReferencesInUploadData( | 316 blob_storage_controller()->ResolveBlobReferencesInUploadData( |
317 params->upload.get()); | 317 params->upload.get()); |
318 } | 318 } |
319 | 319 |
320 request_.reset(new URLRequest(params->url, this)); | 320 request_.reset(new net::URLRequest(params->url, this)); |
321 request_->set_method(params->method); | 321 request_->set_method(params->method); |
322 request_->set_first_party_for_cookies(params->first_party_for_cookies); | 322 request_->set_first_party_for_cookies(params->first_party_for_cookies); |
323 request_->set_referrer(params->referrer.spec()); | 323 request_->set_referrer(params->referrer.spec()); |
324 net::HttpRequestHeaders headers; | 324 net::HttpRequestHeaders headers; |
325 headers.AddHeadersFromString(params->headers); | 325 headers.AddHeadersFromString(params->headers); |
326 request_->SetExtraRequestHeaders(headers); | 326 request_->SetExtraRequestHeaders(headers); |
327 request_->set_load_flags(params->load_flags); | 327 request_->set_load_flags(params->load_flags); |
328 request_->set_upload(params->upload.get()); | 328 request_->set_upload(params->upload.get()); |
329 request_->set_context(g_request_context); | 329 request_->set_context(g_request_context); |
330 SimpleAppCacheSystem::SetExtraRequestInfo( | 330 SimpleAppCacheSystem::SetExtraRequestInfo( |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 OnReceivedData(bytes_read); | 384 OnReceivedData(bytes_read); |
385 } else if (!request_->status().is_io_pending()) { | 385 } else if (!request_->status().is_io_pending()) { |
386 Done(); | 386 Done(); |
387 } // else wait for OnReadCompleted | 387 } // else wait for OnReadCompleted |
388 } else { | 388 } else { |
389 Done(); | 389 Done(); |
390 } | 390 } |
391 } | 391 } |
392 | 392 |
393 // -------------------------------------------------------------------------- | 393 // -------------------------------------------------------------------------- |
394 // The following methods are event hooks (corresponding to URLRequest | 394 // The following methods are event hooks (corresponding to net::URLRequest |
395 // callbacks) that run on the IO thread. They are designed to be overridden | 395 // callbacks) that run on the IO thread. They are designed to be overridden |
396 // by the SyncRequestProxy subclass. | 396 // by the SyncRequestProxy subclass. |
397 | 397 |
398 virtual void OnReceivedRedirect( | 398 virtual void OnReceivedRedirect( |
399 const GURL& new_url, | 399 const GURL& new_url, |
400 const ResourceResponseInfo& info, | 400 const ResourceResponseInfo& info, |
401 bool* defer_redirect) { | 401 bool* defer_redirect) { |
402 *defer_redirect = true; // See AsyncFollowDeferredRedirect | 402 *defer_redirect = true; // See AsyncFollowDeferredRedirect |
403 owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 403 owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
404 this, &RequestProxy::NotifyReceivedRedirect, new_url, info)); | 404 this, &RequestProxy::NotifyReceivedRedirect, new_url, info)); |
(...skipping 25 matching lines...) Expand all Loading... |
430 file_stream_.Close(); | 430 file_stream_.Close(); |
431 owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 431 owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
432 this, | 432 this, |
433 &RequestProxy::NotifyCompletedRequest, | 433 &RequestProxy::NotifyCompletedRequest, |
434 status, | 434 status, |
435 security_info, | 435 security_info, |
436 complete_time)); | 436 complete_time)); |
437 } | 437 } |
438 | 438 |
439 // -------------------------------------------------------------------------- | 439 // -------------------------------------------------------------------------- |
440 // URLRequest::Delegate implementation: | 440 // net::URLRequest::Delegate implementation: |
441 | 441 |
442 virtual void OnReceivedRedirect(URLRequest* request, | 442 virtual void OnReceivedRedirect(net::URLRequest* request, |
443 const GURL& new_url, | 443 const GURL& new_url, |
444 bool* defer_redirect) { | 444 bool* defer_redirect) { |
445 DCHECK(request->status().is_success()); | 445 DCHECK(request->status().is_success()); |
446 ResourceResponseInfo info; | 446 ResourceResponseInfo info; |
447 PopulateResponseInfo(request, &info); | 447 PopulateResponseInfo(request, &info); |
448 OnReceivedRedirect(new_url, info, defer_redirect); | 448 OnReceivedRedirect(new_url, info, defer_redirect); |
449 } | 449 } |
450 | 450 |
451 virtual void OnResponseStarted(URLRequest* request) { | 451 virtual void OnResponseStarted(net::URLRequest* request) { |
452 if (request->status().is_success()) { | 452 if (request->status().is_success()) { |
453 ResourceResponseInfo info; | 453 ResourceResponseInfo info; |
454 PopulateResponseInfo(request, &info); | 454 PopulateResponseInfo(request, &info); |
455 OnReceivedResponse(info, false); | 455 OnReceivedResponse(info, false); |
456 AsyncReadData(); // start reading | 456 AsyncReadData(); // start reading |
457 } else { | 457 } else { |
458 Done(); | 458 Done(); |
459 } | 459 } |
460 } | 460 } |
461 | 461 |
462 virtual void OnSSLCertificateError(URLRequest* request, | 462 virtual void OnSSLCertificateError(net::URLRequest* request, |
463 int cert_error, | 463 int cert_error, |
464 net::X509Certificate* cert) { | 464 net::X509Certificate* cert) { |
465 // Allow all certificate errors. | 465 // Allow all certificate errors. |
466 request->ContinueDespiteLastError(); | 466 request->ContinueDespiteLastError(); |
467 } | 467 } |
468 | 468 |
469 virtual void OnReadCompleted(URLRequest* request, int bytes_read) { | 469 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) { |
470 if (request->status().is_success() && bytes_read > 0) { | 470 if (request->status().is_success() && bytes_read > 0) { |
471 OnReceivedData(bytes_read); | 471 OnReceivedData(bytes_read); |
472 } else { | 472 } else { |
473 Done(); | 473 Done(); |
474 } | 474 } |
475 } | 475 } |
476 | 476 |
477 // -------------------------------------------------------------------------- | 477 // -------------------------------------------------------------------------- |
478 // Helpers and data: | 478 // Helpers and data: |
479 | 479 |
480 void Done() { | 480 void Done() { |
481 if (upload_progress_timer_.IsRunning()) { | 481 if (upload_progress_timer_.IsRunning()) { |
482 MaybeUpdateUploadProgress(); | 482 MaybeUpdateUploadProgress(); |
483 upload_progress_timer_.Stop(); | 483 upload_progress_timer_.Stop(); |
484 } | 484 } |
485 DCHECK(request_.get()); | 485 DCHECK(request_.get()); |
486 OnCompletedRequest(request_->status(), std::string(), base::Time()); | 486 OnCompletedRequest(request_->status(), std::string(), base::Time()); |
487 request_.reset(); // destroy on the io thread | 487 request_.reset(); // destroy on the io thread |
488 } | 488 } |
489 | 489 |
490 // Called on the IO thread. | 490 // Called on the IO thread. |
491 void MaybeUpdateUploadProgress() { | 491 void MaybeUpdateUploadProgress() { |
492 // If a redirect is received upload is cancelled in URLRequest, we should | 492 // If a redirect is received upload is cancelled in net::URLRequest, we |
493 // try to stop the |upload_progress_timer_| timer and return. | 493 // should try to stop the |upload_progress_timer_| timer and return. |
494 if (!request_->has_upload()) { | 494 if (!request_->has_upload()) { |
495 if (upload_progress_timer_.IsRunning()) | 495 if (upload_progress_timer_.IsRunning()) |
496 upload_progress_timer_.Stop(); | 496 upload_progress_timer_.Stop(); |
497 return; | 497 return; |
498 } | 498 } |
499 | 499 |
500 uint64 size = request_->get_upload()->GetContentLength(); | 500 uint64 size = request_->get_upload()->GetContentLength(); |
501 uint64 position = request_->GetUploadProgress(); | 501 uint64 position = request_->GetUploadProgress(); |
502 if (position == last_upload_position_) | 502 if (position == last_upload_position_) |
503 return; // no progress made since last time | 503 return; // no progress made since last time |
(...skipping 11 matching lines...) Expand all Loading... |
515 bool too_much_time_passed = time_since_last > kOneSecond; | 515 bool too_much_time_passed = time_since_last > kOneSecond; |
516 | 516 |
517 if (is_finished || enough_new_progress || too_much_time_passed) { | 517 if (is_finished || enough_new_progress || too_much_time_passed) { |
518 owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( | 518 owner_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
519 this, &RequestProxy::NotifyUploadProgress, position, size)); | 519 this, &RequestProxy::NotifyUploadProgress, position, size)); |
520 last_upload_ticks_ = base::TimeTicks::Now(); | 520 last_upload_ticks_ = base::TimeTicks::Now(); |
521 last_upload_position_ = position; | 521 last_upload_position_ = position; |
522 } | 522 } |
523 } | 523 } |
524 | 524 |
525 void PopulateResponseInfo(URLRequest* request, | 525 void PopulateResponseInfo(net::URLRequest* request, |
526 ResourceResponseInfo* info) const { | 526 ResourceResponseInfo* info) const { |
527 info->request_time = request->request_time(); | 527 info->request_time = request->request_time(); |
528 info->response_time = request->response_time(); | 528 info->response_time = request->response_time(); |
529 info->headers = request->response_headers(); | 529 info->headers = request->response_headers(); |
530 request->GetMimeType(&info->mime_type); | 530 request->GetMimeType(&info->mime_type); |
531 request->GetCharset(&info->charset); | 531 request->GetCharset(&info->charset); |
532 info->content_length = request->GetExpectedContentSize(); | 532 info->content_length = request->GetExpectedContentSize(); |
533 if (downloaded_file_) | 533 if (downloaded_file_) |
534 info->download_file_path = downloaded_file_->path(); | 534 info->download_file_path = downloaded_file_->path(); |
535 SimpleAppCacheSystem::GetExtraResponseInfo( | 535 SimpleAppCacheSystem::GetExtraResponseInfo( |
536 request, | 536 request, |
537 &info->appcache_id, | 537 &info->appcache_id, |
538 &info->appcache_manifest_url); | 538 &info->appcache_manifest_url); |
539 } | 539 } |
540 | 540 |
541 scoped_ptr<URLRequest> request_; | 541 scoped_ptr<net::URLRequest> request_; |
542 | 542 |
543 // Support for request.download_to_file behavior. | 543 // Support for request.download_to_file behavior. |
544 bool download_to_file_; | 544 bool download_to_file_; |
545 net::FileStream file_stream_; | 545 net::FileStream file_stream_; |
546 scoped_refptr<DeletableFileReference> downloaded_file_; | 546 scoped_refptr<DeletableFileReference> downloaded_file_; |
547 | 547 |
548 // Size of our async IO data buffers | 548 // Size of our async IO data buffers |
549 static const int kDataSize = 16*1024; | 549 static const int kDataSize = 16*1024; |
550 | 550 |
551 // read buffer for async IO | 551 // read buffer for async IO |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 | 928 |
929 // static | 929 // static |
930 scoped_refptr<base::MessageLoopProxy> | 930 scoped_refptr<base::MessageLoopProxy> |
931 SimpleResourceLoaderBridge::GetIoThread() { | 931 SimpleResourceLoaderBridge::GetIoThread() { |
932 if (!EnsureIOThread()) { | 932 if (!EnsureIOThread()) { |
933 LOG(DFATAL) << "Failed to create IO thread."; | 933 LOG(DFATAL) << "Failed to create IO thread."; |
934 return NULL; | 934 return NULL; |
935 } | 935 } |
936 return g_io_thread->message_loop_proxy(); | 936 return g_io_thread->message_loop_proxy(); |
937 } | 937 } |
OLD | NEW |