| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/common/net/url_fetcher.h" | 5 #include "content/common/net/url_fetcher.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 10 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 11 #include "base/file_util_proxy.h" | 13 #include "base/file_util_proxy.h" |
| 12 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 13 #include "base/memory/scoped_callback_factory.h" | |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/weak_ptr.h" |
| 15 #include "base/message_loop_proxy.h" | 17 #include "base/message_loop_proxy.h" |
| 16 #include "base/platform_file.h" | 18 #include "base/platform_file.h" |
| 17 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 18 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 19 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
| 20 #include "googleurl/src/gurl.h" | 22 #include "googleurl/src/gurl.h" |
| 21 #include "net/base/host_port_pair.h" | 23 #include "net/base/host_port_pair.h" |
| 22 #include "net/base/io_buffer.h" | 24 #include "net/base/io_buffer.h" |
| 23 #include "net/base/load_flags.h" | 25 #include "net/base/load_flags.h" |
| 24 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
| 25 #include "net/http/http_request_headers.h" | 27 #include "net/http/http_request_headers.h" |
| 26 #include "net/http/http_response_headers.h" | 28 #include "net/http/http_response_headers.h" |
| 27 #include "net/url_request/url_request.h" | 29 #include "net/url_request/url_request.h" |
| 28 #include "net/url_request/url_request_context.h" | 30 #include "net/url_request/url_request_context.h" |
| 29 #include "net/url_request/url_request_context_getter.h" | 31 #include "net/url_request/url_request_context_getter.h" |
| 30 #include "net/url_request/url_request_throttler_manager.h" | 32 #include "net/url_request/url_request_throttler_manager.h" |
| 31 | 33 |
| 32 static const int kBufferSize = 4096; | 34 static const int kBufferSize = 4096; |
| 33 const int URLFetcher::kInvalidHttpResponseCode = -1; | 35 const int URLFetcher::kInvalidHttpResponseCode = -1; |
| 34 | 36 |
| 37 using base::FileUtilProxy; |
| 38 using base::PlatformFileError; |
| 39 |
| 35 class URLFetcher::Core | 40 class URLFetcher::Core |
| 36 : public base::RefCountedThreadSafe<URLFetcher::Core>, | 41 : public base::RefCountedThreadSafe<URLFetcher::Core>, |
| 37 public net::URLRequest::Delegate { | 42 public net::URLRequest::Delegate { |
| 38 public: | 43 public: |
| 39 // For POST requests, set |content_type| to the MIME type of the content | 44 // For POST requests, set |content_type| to the MIME type of the content |
| 40 // and set |content| to the data to upload. |flags| are flags to apply to | 45 // and set |content| to the data to upload. |flags| are flags to apply to |
| 41 // the load operation--these should be one or more of the LOAD_* flags | 46 // the load operation--these should be one or more of the LOAD_* flags |
| 42 // defined in net/base/load_flags.h. | 47 // defined in net/base/load_flags.h. |
| 43 Core(URLFetcher* fetcher, | 48 Core(URLFetcher* fetcher, |
| 44 const GURL& original_url, | 49 const GURL& original_url, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 // Callback which gets the result of closing the temp file. | 144 // Callback which gets the result of closing the temp file. |
| 140 void DidCloseTempFile(base::PlatformFileError error); | 145 void DidCloseTempFile(base::PlatformFileError error); |
| 141 | 146 |
| 142 // The URLFetcher::Core which instantiated this class. | 147 // The URLFetcher::Core which instantiated this class. |
| 143 URLFetcher::Core* core_; | 148 URLFetcher::Core* core_; |
| 144 | 149 |
| 145 // The last error encountered on a file operation. base::PLATFORM_FILE_OK | 150 // The last error encountered on a file operation. base::PLATFORM_FILE_OK |
| 146 // if no error occurred. | 151 // if no error occurred. |
| 147 base::PlatformFileError error_code_; | 152 base::PlatformFileError error_code_; |
| 148 | 153 |
| 149 // Callbacks are created for use with base::FileUtilProxy. | 154 // For file_util calls on the FileThread. |
| 150 base::ScopedCallbackFactory<URLFetcher::Core::TempFileWriter> | 155 base::WeakPtrFactory<URLFetcher::Core::TempFileWriter> |
| 151 callback_factory_; | 156 weak_factory_; |
| 152 | 157 |
| 153 // Message loop on which file opperations should happen. | 158 // Message loop on which file opperations should happen. |
| 154 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_; | 159 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_; |
| 155 | 160 |
| 156 // Path to the temporary file. This path is empty when there | 161 // Path to the temporary file. This path is empty when there |
| 157 // is no temp file. | 162 // is no temp file. |
| 158 FilePath temp_file_; | 163 FilePath temp_file_; |
| 159 | 164 |
| 160 // Handle to the temp file. | 165 // Handle to the temp file. |
| 161 base::PlatformFile temp_file_handle_; | 166 base::PlatformFile temp_file_handle_; |
| 162 | 167 |
| 168 // Bytes written by the last ContinueWrite. |
| 169 int bytes_written_; |
| 170 |
| 163 // We always append to the file. Track the total number of bytes | 171 // We always append to the file. Track the total number of bytes |
| 164 // written, so that writes know the offset to give. | 172 // written, so that writes know the offset to give. |
| 165 int64 total_bytes_written_; | 173 int64 total_bytes_written_; |
| 166 | 174 |
| 167 // How many bytes did the last Write() try to write? Needed so | 175 // How many bytes did the last Write() try to write? Needed so |
| 168 // that if not all the bytes get written on a Write(), we can | 176 // that if not all the bytes get written on a Write(), we can |
| 169 // call Write() again with the rest. | 177 // call Write() again with the rest. |
| 170 int pending_bytes_; | 178 int pending_bytes_; |
| 171 | 179 |
| 172 // When writing, how many bytes from the buffer have been successfully | 180 // When writing, how many bytes from the buffer have been successfully |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 | 320 |
| 313 // static | 321 // static |
| 314 base::LazyInstance<URLFetcher::Core::Registry> | 322 base::LazyInstance<URLFetcher::Core::Registry> |
| 315 URLFetcher::Core::g_registry(base::LINKER_INITIALIZED); | 323 URLFetcher::Core::g_registry(base::LINKER_INITIALIZED); |
| 316 | 324 |
| 317 URLFetcher::Core::TempFileWriter::TempFileWriter( | 325 URLFetcher::Core::TempFileWriter::TempFileWriter( |
| 318 URLFetcher::Core* core, | 326 URLFetcher::Core* core, |
| 319 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) | 327 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) |
| 320 : core_(core), | 328 : core_(core), |
| 321 error_code_(base::PLATFORM_FILE_OK), | 329 error_code_(base::PLATFORM_FILE_OK), |
| 322 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 330 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 323 file_message_loop_proxy_(file_message_loop_proxy), | 331 file_message_loop_proxy_(file_message_loop_proxy), |
| 324 temp_file_handle_(base::kInvalidPlatformFileValue) { | 332 temp_file_handle_(base::kInvalidPlatformFileValue) { |
| 325 } | 333 } |
| 326 | 334 |
| 327 URLFetcher::Core::TempFileWriter::~TempFileWriter() { | 335 URLFetcher::Core::TempFileWriter::~TempFileWriter() { |
| 328 RemoveTempFile(); | 336 RemoveTempFile(); |
| 329 } | 337 } |
| 330 | 338 |
| 331 void URLFetcher::Core::TempFileWriter::CreateTempFile() { | 339 void URLFetcher::Core::TempFileWriter::CreateTempFile() { |
| 332 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 340 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 333 CHECK(file_message_loop_proxy_.get()); | 341 CHECK(file_message_loop_proxy_.get()); |
| 334 base::FileUtilProxy::CreateTemporary( | 342 FileUtilProxy::CreateTemporary( |
| 335 file_message_loop_proxy_, | 343 file_message_loop_proxy_, |
| 336 0, // No additional file flags. | 344 0, // No additional file flags. |
| 337 callback_factory_.NewCallback( | 345 base::Bind(&URLFetcher::Core::TempFileWriter::DidCreateTempFile, |
| 338 &URLFetcher::Core::TempFileWriter::DidCreateTempFile)); | 346 weak_factory_.GetWeakPtr())); |
| 339 } | 347 } |
| 340 | 348 |
| 341 void URLFetcher::Core::TempFileWriter::DidCreateTempFile( | 349 void URLFetcher::Core::TempFileWriter::DidCreateTempFile( |
| 342 base::PlatformFileError error_code, | 350 base::PlatformFileError error_code, |
| 343 base::PassPlatformFile file_handle, | 351 base::PassPlatformFile file_handle, |
| 344 FilePath file_path) { | 352 FilePath file_path) { |
| 345 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 353 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 346 | 354 |
| 347 if (base::PLATFORM_FILE_OK != error_code) { | 355 if (base::PLATFORM_FILE_OK != error_code) { |
| 348 error_code_ = error_code; | 356 error_code_ = error_code; |
| 349 RemoveTempFile(); | 357 RemoveTempFile(); |
| 350 core_->delegate_loop_proxy_->PostTask( | 358 core_->delegate_loop_proxy_->PostTask( |
| 351 FROM_HERE, | 359 FROM_HERE, |
| 352 NewRunnableMethod(core_, &Core::InformDelegateFetchIsComplete)); | 360 base::Bind(&Core::InformDelegateFetchIsComplete, core_)); |
| 353 return; | 361 return; |
| 354 } | 362 } |
| 355 | 363 |
| 356 temp_file_ = file_path; | 364 temp_file_ = file_path; |
| 357 temp_file_handle_ = file_handle.ReleaseValue(); | 365 temp_file_handle_ = file_handle.ReleaseValue(); |
| 358 total_bytes_written_ = 0; | 366 total_bytes_written_ = 0; |
| 359 | 367 |
| 360 core_->io_message_loop_proxy_->PostTask( | 368 core_->io_message_loop_proxy_->PostTask( |
| 361 FROM_HERE, | 369 FROM_HERE, |
| 362 NewRunnableMethod(core_, &Core::StartURLRequestWhenAppropriate)); | 370 base::Bind(&Core::StartURLRequestWhenAppropriate, core_)); |
| 363 } | 371 } |
| 364 | 372 |
| 365 void URLFetcher::Core::TempFileWriter::WriteBuffer(int num_bytes) { | 373 void URLFetcher::Core::TempFileWriter::WriteBuffer(int num_bytes) { |
| 366 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 374 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 367 | 375 |
| 368 // Start writing to the temp file by setting the initial state | 376 // Start writing to the temp file by setting the initial state |
| 369 // of |pending_bytes_| and |buffer_offset_| to indicate that the | 377 // of |pending_bytes_| and |buffer_offset_| to indicate that the |
| 370 // entire buffer has not yet been written. | 378 // entire buffer has not yet been written. |
| 371 pending_bytes_ = num_bytes; | 379 pending_bytes_ = num_bytes; |
| 372 buffer_offset_ = 0; | 380 buffer_offset_ = 0; |
| 373 ContinueWrite(base::PLATFORM_FILE_OK, 0); | 381 ContinueWrite(base::PLATFORM_FILE_OK, 0); |
| 374 } | 382 } |
| 375 | 383 |
| 376 void URLFetcher::Core::TempFileWriter::ContinueWrite( | 384 void URLFetcher::Core::TempFileWriter::ContinueWrite( |
| 377 base::PlatformFileError error_code, | 385 base::PlatformFileError error_code, |
| 378 int bytes_written) { | 386 int bytes_written) { |
| 379 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 387 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 380 | 388 |
| 381 if (base::PLATFORM_FILE_OK != error_code) { | 389 if (base::PLATFORM_FILE_OK != error_code) { |
| 382 error_code_ = error_code; | 390 error_code_ = error_code; |
| 383 RemoveTempFile(); | 391 RemoveTempFile(); |
| 384 core_->delegate_loop_proxy_->PostTask( | 392 core_->delegate_loop_proxy_->PostTask( |
| 385 FROM_HERE, | 393 FROM_HERE, |
| 386 NewRunnableMethod(core_, &Core::InformDelegateFetchIsComplete)); | 394 base::Bind(&Core::InformDelegateFetchIsComplete, core_)); |
| 387 return; | 395 return; |
| 388 } | 396 } |
| 389 | 397 |
| 390 total_bytes_written_ += bytes_written; | 398 total_bytes_written_ += bytes_written; |
| 391 buffer_offset_ += bytes_written; | 399 buffer_offset_ += bytes_written; |
| 392 pending_bytes_ -= bytes_written; | 400 pending_bytes_ -= bytes_written; |
| 393 | 401 |
| 394 if (pending_bytes_ > 0) { | 402 if (pending_bytes_ > 0) { |
| 395 base::FileUtilProxy::Write( | 403 FileUtilProxy::Write( |
| 396 file_message_loop_proxy_, | 404 file_message_loop_proxy_, |
| 397 temp_file_handle_, | 405 temp_file_handle_, |
| 398 total_bytes_written_, // Append to the end | 406 total_bytes_written_, // Append to the end |
| 399 (core_->buffer_->data() + buffer_offset_), | 407 (core_->buffer_->data() + buffer_offset_), |
| 400 pending_bytes_, | 408 pending_bytes_, |
| 401 callback_factory_.NewCallback( | 409 base::Bind(&URLFetcher::Core::TempFileWriter::ContinueWrite, |
| 402 &URLFetcher::Core::TempFileWriter::ContinueWrite)); | 410 weak_factory_.GetWeakPtr())); |
| 403 } else { | 411 } else { |
| 404 // Finished writing core_->buffer_ to the file. Read some more. | 412 // Finished writing core_->buffer_ to the file. Read some more. |
| 405 core_->ReadResponse(); | 413 core_->ReadResponse(); |
| 406 } | 414 } |
| 407 } | 415 } |
| 408 | 416 |
| 409 void URLFetcher::Core::TempFileWriter::DisownTempFile() { | 417 void URLFetcher::Core::TempFileWriter::DisownTempFile() { |
| 410 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 418 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 411 | 419 |
| 412 // Disowning is done by the delegate's OnURLFetchComplete method. | 420 // Disowning is done by the delegate's OnURLFetchComplete method. |
| 413 // The temp file should be closed by the time that method is called. | 421 // The temp file should be closed by the time that method is called. |
| 414 DCHECK(temp_file_handle_ == base::kInvalidPlatformFileValue); | 422 DCHECK(temp_file_handle_ == base::kInvalidPlatformFileValue); |
| 415 | 423 |
| 416 // Forget about any temp file by reseting the path. | 424 // Forget about any temp file by reseting the path. |
| 417 temp_file_ = FilePath(); | 425 temp_file_ = FilePath(); |
| 418 } | 426 } |
| 419 | 427 |
| 420 void URLFetcher::Core::TempFileWriter::CloseTempFileAndCompleteRequest() { | 428 void URLFetcher::Core::TempFileWriter::CloseTempFileAndCompleteRequest() { |
| 421 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 429 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 422 | 430 |
| 423 if (temp_file_handle_ != base::kInvalidPlatformFileValue) { | 431 if (temp_file_handle_ != base::kInvalidPlatformFileValue) { |
| 424 base::FileUtilProxy::Close( | 432 FileUtilProxy::PostFileTaskAndReplyStatus<bool, PlatformFileError>( |
| 425 file_message_loop_proxy_, | 433 file_message_loop_proxy_, |
| 426 temp_file_handle_, | 434 FROM_HERE, |
| 427 callback_factory_.NewCallback( | 435 base::Bind(&base::ClosePlatformFile, temp_file_handle_), |
| 428 &URLFetcher::Core::TempFileWriter::DidCloseTempFile)); | 436 base::Bind(&URLFetcher::Core::TempFileWriter::DidCloseTempFile, |
| 437 weak_factory_.GetWeakPtr())); |
| 429 temp_file_handle_ = base::kInvalidPlatformFileValue; | 438 temp_file_handle_ = base::kInvalidPlatformFileValue; |
| 430 } | 439 } |
| 431 } | 440 } |
| 432 | 441 |
| 433 void URLFetcher::Core::TempFileWriter::DidCloseTempFile( | 442 void URLFetcher::Core::TempFileWriter::DidCloseTempFile( |
| 434 base::PlatformFileError error_code) { | 443 base::PlatformFileError error_code) { |
| 435 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 444 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 436 | 445 |
| 437 if (base::PLATFORM_FILE_OK != error_code) { | 446 if (base::PLATFORM_FILE_OK != error_code) { |
| 438 error_code_ = error_code; | 447 error_code_ = error_code; |
| 439 RemoveTempFile(); | 448 RemoveTempFile(); |
| 440 core_->delegate_loop_proxy_->PostTask( | 449 core_->delegate_loop_proxy_->PostTask( |
| 441 FROM_HERE, | 450 FROM_HERE, |
| 442 NewRunnableMethod(core_, &Core::InformDelegateFetchIsComplete)); | 451 base::Bind(&Core::InformDelegateFetchIsComplete, core_)); |
| 443 return; | 452 return; |
| 444 } | 453 } |
| 445 | 454 |
| 446 // If the file was successfully closed, then the URL request is complete. | 455 // If the file was successfully closed, then the URL request is complete. |
| 447 core_->RetryOrCompleteUrlFetch(); | 456 core_->RetryOrCompleteUrlFetch(); |
| 448 } | 457 } |
| 449 | 458 |
| 450 void URLFetcher::Core::TempFileWriter::RemoveTempFile() { | 459 void URLFetcher::Core::TempFileWriter::RemoveTempFile() { |
| 451 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); | 460 DCHECK(core_->io_message_loop_proxy_->BelongsToCurrentThread()); |
| 452 | 461 |
| 453 // Close the temp file if it is open. | 462 // Close the temp file if it is open. |
| 454 if (temp_file_handle_ != base::kInvalidPlatformFileValue) { | 463 if (temp_file_handle_ != base::kInvalidPlatformFileValue) { |
| 455 base::FileUtilProxy::Close( | 464 file_message_loop_proxy_->PostTask( |
| 456 file_message_loop_proxy_, | 465 FROM_HERE, |
| 457 temp_file_handle_, | 466 base::IgnoreReturn(base::Callback<bool(void)>( |
| 458 NULL); // No callback: Ignore errors. | 467 base::Bind(&base::ClosePlatformFile, temp_file_handle_)))); |
| 459 temp_file_handle_ = base::kInvalidPlatformFileValue; | 468 temp_file_handle_ = base::kInvalidPlatformFileValue; |
| 460 } | 469 } |
| 461 | 470 |
| 462 if (!temp_file_.empty()) { | 471 if (!temp_file_.empty()) { |
| 463 base::FileUtilProxy::Delete( | 472 file_message_loop_proxy_->PostTask( |
| 464 file_message_loop_proxy_, | 473 FROM_HERE, |
| 465 temp_file_, | 474 base::IgnoreReturn(base::Callback<bool(void)>( |
| 466 false, // No need to recurse, as the path is to a file. | 475 base::Bind(&file_util::Delete, temp_file_, |
| 467 NULL); // No callback: Ignore errors. | 476 false /* recursive */)))); |
| 468 DisownTempFile(); | 477 DisownTempFile(); |
| 469 } | 478 } |
| 470 } | 479 } |
| 471 | 480 |
| 472 // static | 481 // static |
| 473 URLFetcher::Factory* URLFetcher::factory_ = NULL; | 482 URLFetcher::Factory* URLFetcher::factory_ = NULL; |
| 474 | 483 |
| 475 void URLFetcher::Delegate::OnURLFetchComplete( | 484 void URLFetcher::Delegate::OnURLFetchComplete( |
| 476 const URLFetcher* source, | 485 const URLFetcher* source, |
| 477 const GURL& url, | 486 const GURL& url, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 if (io_message_loop_proxy_) { | 568 if (io_message_loop_proxy_) { |
| 560 DCHECK_EQ(io_message_loop_proxy_, | 569 DCHECK_EQ(io_message_loop_proxy_, |
| 561 request_context_getter_->GetIOMessageLoopProxy()); | 570 request_context_getter_->GetIOMessageLoopProxy()); |
| 562 } else { | 571 } else { |
| 563 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); | 572 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); |
| 564 } | 573 } |
| 565 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; | 574 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; |
| 566 | 575 |
| 567 io_message_loop_proxy_->PostTask( | 576 io_message_loop_proxy_->PostTask( |
| 568 FROM_HERE, | 577 FROM_HERE, |
| 569 NewRunnableMethod(this, &Core::StartOnIOThread)); | 578 base::Bind(&Core::StartOnIOThread, this)); |
| 570 } | 579 } |
| 571 | 580 |
| 572 void URLFetcher::Core::StartOnIOThread() { | 581 void URLFetcher::Core::StartOnIOThread() { |
| 573 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 582 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 574 | 583 |
| 575 switch (response_destination_) { | 584 switch (response_destination_) { |
| 576 case STRING: | 585 case STRING: |
| 577 StartURLRequestWhenAppropriate(); | 586 StartURLRequestWhenAppropriate(); |
| 578 break; | 587 break; |
| 579 | 588 |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 } | 1132 } |
| 1124 | 1133 |
| 1125 // static | 1134 // static |
| 1126 int URLFetcher::GetNumFetcherCores() { | 1135 int URLFetcher::GetNumFetcherCores() { |
| 1127 return Core::g_registry.Get().size(); | 1136 return Core::g_registry.Get().size(); |
| 1128 } | 1137 } |
| 1129 | 1138 |
| 1130 URLFetcher::Delegate* URLFetcher::delegate() const { | 1139 URLFetcher::Delegate* URLFetcher::delegate() const { |
| 1131 return core_->delegate(); | 1140 return core_->delegate(); |
| 1132 } | 1141 } |
| OLD | NEW |