Chromium Code Reviews| 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 "chrome/common/net/url_fetcher.h" | 5 #include "chrome/common/net/url_fetcher.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_path.h" | |
| 11 #include "base/file_util_proxy.h" | |
| 10 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/memory/scoped_callback_factory.h" | |
| 11 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/message_loop_proxy.h" | 15 #include "base/message_loop_proxy.h" |
| 16 #include "base/platform_file.h" | |
| 13 #include "base/stl_util-inl.h" | 17 #include "base/stl_util-inl.h" |
| 14 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 15 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
| 20 #include "content/browser/browser_thread.h" | |
| 16 #include "googleurl/src/gurl.h" | 21 #include "googleurl/src/gurl.h" |
| 17 #include "net/base/load_flags.h" | 22 #include "net/base/load_flags.h" |
| 18 #include "net/base/io_buffer.h" | 23 #include "net/base/io_buffer.h" |
| 19 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
| 20 #include "net/base/host_port_pair.h" | 25 #include "net/base/host_port_pair.h" |
| 21 #include "net/http/http_request_headers.h" | 26 #include "net/http/http_request_headers.h" |
| 22 #include "net/http/http_response_headers.h" | 27 #include "net/http/http_response_headers.h" |
| 23 #include "net/url_request/url_request.h" | 28 #include "net/url_request/url_request.h" |
| 24 #include "net/url_request/url_request_context.h" | 29 #include "net/url_request/url_request_context.h" |
| 25 #include "net/url_request/url_request_context_getter.h" | 30 #include "net/url_request/url_request_context_getter.h" |
| 26 #include "net/url_request/url_request_throttler_manager.h" | 31 #include "net/url_request/url_request_throttler_manager.h" |
| 27 | 32 |
| 28 static const int kBufferSize = 4096; | 33 static const int kBufferSize = 4096; |
| 34 const int URLFetcher::kInvalidHttpResponseCode = -1; | |
| 29 | 35 |
| 30 class URLFetcher::Core | 36 class URLFetcher::Core |
| 31 : public base::RefCountedThreadSafe<URLFetcher::Core>, | 37 : public base::RefCountedThreadSafe<URLFetcher::Core>, |
| 32 public net::URLRequest::Delegate { | 38 public net::URLRequest::Delegate { |
| 33 public: | 39 public: |
| 34 // For POST requests, set |content_type| to the MIME type of the content | 40 // For POST requests, set |content_type| to the MIME type of the content |
| 35 // and set |content| to the data to upload. |flags| are flags to apply to | 41 // and set |content| to the data to upload. |flags| are flags to apply to |
| 36 // the load operation--these should be one or more of the LOAD_* flags | 42 // the load operation--these should be one or more of the LOAD_* flags |
| 37 // defined in net/base/load_flags.h. | 43 // defined in net/base/load_flags.h. |
| 38 Core(URLFetcher* fetcher, | 44 Core(URLFetcher* fetcher, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 53 void Stop(); | 59 void Stop(); |
| 54 | 60 |
| 55 // Reports that the received content was malformed. | 61 // Reports that the received content was malformed. |
| 56 void ReceivedContentWasMalformed(); | 62 void ReceivedContentWasMalformed(); |
| 57 | 63 |
| 58 // Overridden from net::URLRequest::Delegate: | 64 // Overridden from net::URLRequest::Delegate: |
| 59 virtual void OnResponseStarted(net::URLRequest* request); | 65 virtual void OnResponseStarted(net::URLRequest* request); |
| 60 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read); | 66 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read); |
| 61 | 67 |
| 62 URLFetcher::Delegate* delegate() const { return delegate_; } | 68 URLFetcher::Delegate* delegate() const { return delegate_; } |
| 63 | |
| 64 static void CancelAll(); | 69 static void CancelAll(); |
| 65 | 70 |
| 66 private: | 71 private: |
| 67 friend class base::RefCountedThreadSafe<URLFetcher::Core>; | 72 friend class base::RefCountedThreadSafe<URLFetcher::Core>; |
| 68 | 73 |
| 69 class Registry { | 74 class Registry { |
| 70 public: | 75 public: |
| 71 Registry(); | 76 Registry(); |
| 72 ~Registry(); | 77 ~Registry(); |
| 73 | 78 |
| 74 void AddURLFetcherCore(Core* core); | 79 void AddURLFetcherCore(Core* core); |
| 75 void RemoveURLFetcherCore(Core* core); | 80 void RemoveURLFetcherCore(Core* core); |
| 76 | 81 |
| 77 void CancelAll(); | 82 void CancelAll(); |
| 78 | 83 |
| 79 int size() const { | 84 int size() const { |
| 80 return fetchers_.size(); | 85 return fetchers_.size(); |
| 81 } | 86 } |
| 82 | 87 |
| 83 private: | 88 private: |
| 84 std::set<Core*> fetchers_; | 89 std::set<Core*> fetchers_; |
| 85 | 90 |
| 86 DISALLOW_COPY_AND_ASSIGN(Registry); | 91 DISALLOW_COPY_AND_ASSIGN(Registry); |
| 87 }; | 92 }; |
| 88 | 93 |
| 94 // Class TempFileWriter encapsulates all state involved in writing | |
| 95 // response bytes to a temporary file. It is only used if | |
| 96 // |Core::response_destination_| == TEMP_FILE. | |
| 97 class TempFileWriter { | |
| 98 public: | |
| 99 TempFileWriter( | |
| 100 URLFetcher::Core* core, | |
| 101 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy); | |
| 102 | |
| 103 ~TempFileWriter(); | |
| 104 void CreateTempFile(); | |
| 105 void DidCreateTempFile(base::PlatformFileError error_code, | |
| 106 base::PassPlatformFile file_handle, | |
| 107 FilePath file_path); | |
| 108 void DidCloseTempFile(base::PlatformFileError error_code); | |
| 109 void DidReopenTempFile(base::PlatformFileError error_code, | |
| 110 base::PassPlatformFile file_handle, | |
| 111 bool created); | |
| 112 | |
| 113 // Record |num_bytes_| response bytes in |core_->buffer_| to the file. | |
| 114 void WriteBuffer(int num_bytes); | |
| 115 | |
| 116 // Called when a write has been done. Continues writing if there are | |
| 117 // any more bytes to write. Otherwise, initiates a read in core_. | |
| 118 void ContinueWrite(base::PlatformFileError error_code, | |
| 119 int bytes_written); | |
| 120 | |
| 121 // Drop ownership of the file at path |temp_file_|. This class | |
| 122 // will not delete it or write to it again. | |
| 123 void DisownTempFile(); | |
| 124 | |
| 125 // Remove any file created. | |
| 126 void Destroy(); | |
| 127 | |
| 128 const FilePath& temp_file() const { return temp_file_; } | |
| 129 int64 total_bytes_written() { return total_bytes_written_; } | |
| 130 base::PlatformFileError error_code() const { return error_code_; } | |
| 131 | |
| 132 private: | |
| 133 // The URLFetcher::Core which instantiated this class. | |
| 134 URLFetcher::Core* core_; | |
| 135 | |
| 136 // The last error encountered on a file operation. base::PLATFORM_FILE_OK | |
| 137 // if no error occurred. | |
| 138 base::PlatformFileError error_code_; | |
| 139 | |
| 140 // Callbacks are created for use with base::FileUtilProxy. | |
| 141 base::ScopedCallbackFactory<URLFetcher::Core::TempFileWriter> | |
| 142 callback_factory_; | |
| 143 | |
| 144 // Message loop on which file opperations should happen. | |
| 145 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_; | |
| 146 | |
| 147 // Path to the temporary file. This path is empty when there | |
| 148 // is no temp file. | |
| 149 FilePath temp_file_; | |
| 150 | |
| 151 // Handle to the temp file. | |
| 152 base::PlatformFile temp_file_handle_; | |
| 153 | |
| 154 // We always append to the file. Track the total number of bytes | |
| 155 // written, so that writes know the offset to give. | |
| 156 int64 total_bytes_written_; | |
| 157 | |
| 158 // How many bytes did the last Write() try to write? Needed so | |
| 159 // that if not all the bytes get written on a Write(), we can | |
| 160 // call Write() again with the rest. | |
| 161 int pending_bytes_; | |
| 162 | |
| 163 // When writing, how many bytes from the buffer have been successfully | |
| 164 // written so far? | |
| 165 int buffer_offset_; | |
| 166 }; | |
| 167 | |
| 89 virtual ~Core(); | 168 virtual ~Core(); |
| 90 | 169 |
| 91 // Wrapper functions that allow us to ensure actions happen on the right | 170 // Wrapper functions that allow us to ensure actions happen on the right |
| 92 // thread. | 171 // thread. |
| 93 void StartURLRequest(); | 172 void StartURLRequest(); |
| 94 void StartURLRequestWhenAppropriate(); | 173 void StartURLRequestWhenAppropriate(); |
| 95 void CancelURLRequest(); | 174 void CancelURLRequest(); |
| 96 void OnCompletedURLRequest(const net::URLRequestStatus& status); | 175 void OnCompletedURLRequest(const net::URLRequestStatus& status); |
| 176 void InformDelegateFetchIsComplete(); | |
| 97 void NotifyMalformedContent(); | 177 void NotifyMalformedContent(); |
| 98 | 178 |
| 99 // Deletes the request, removes it from the registry, and removes the | 179 // Deletes the request, removes it from the registry, and removes the |
| 100 // destruction observer. | 180 // destruction observer. |
| 101 void ReleaseRequest(); | 181 void ReleaseRequest(); |
| 102 | 182 |
| 103 // Returns the max value of exponential back-off release time for | 183 // Returns the max value of exponential back-off release time for |
| 104 // |original_url_| and |url_|. | 184 // |original_url_| and |url_|. |
| 105 base::TimeTicks GetBackoffReleaseTime(); | 185 base::TimeTicks GetBackoffReleaseTime(); |
| 106 | 186 |
| 107 void CompleteAddingUploadDataChunk(const std::string& data, | 187 void CompleteAddingUploadDataChunk(const std::string& data, |
| 108 bool is_last_chunk); | 188 bool is_last_chunk); |
| 109 | 189 |
| 110 // Adds a block of data to be uploaded in a POST body. This can only be called | 190 // Adds a block of data to be uploaded in a POST body. This can only be |
| 111 // after Start(). | 191 // called after Start(). |
| 112 void AppendChunkToUpload(const std::string& data, bool is_last_chunk); | 192 void AppendChunkToUpload(const std::string& data, bool is_last_chunk); |
| 113 | 193 |
| 194 // Store the response bytes in |buffer_| in the container indicated by | |
| 195 // |fetcher_->response_destination_|. Return true if the write has been | |
| 196 // done, and another read can overwrite |buffer_|. If this function | |
| 197 // returns false, it will post a task that will read more bytes once the | |
| 198 // write is complete. | |
| 199 bool WriteBuffer(int num_bytes); | |
| 200 | |
| 201 // Read response bytes from the request. | |
| 202 void ReadResponse(); | |
| 203 | |
| 114 URLFetcher* fetcher_; // Corresponding fetcher object | 204 URLFetcher* fetcher_; // Corresponding fetcher object |
| 115 GURL original_url_; // The URL we were asked to fetch | 205 GURL original_url_; // The URL we were asked to fetch |
| 116 GURL url_; // The URL we eventually wound up at | 206 GURL url_; // The URL we eventually wound up at |
| 117 RequestType request_type_; // What type of request is this? | 207 RequestType request_type_; // What type of request is this? |
| 208 net::URLRequestStatus status_; // Status of the request | |
| 118 URLFetcher::Delegate* delegate_; // Object to notify on completion | 209 URLFetcher::Delegate* delegate_; // Object to notify on completion |
| 119 scoped_refptr<base::MessageLoopProxy> delegate_loop_proxy_; | 210 scoped_refptr<base::MessageLoopProxy> delegate_loop_proxy_; |
| 120 // Message loop proxy of the creating | 211 // Message loop proxy of the creating |
| 121 // thread. | 212 // thread. |
| 122 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 213 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
| 123 // The message loop proxy for the thread | 214 // The message loop proxy for the thread |
| 124 // on which the request IO happens. | 215 // on which the request IO happens. |
| 216 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy_; | |
| 217 // The message loop proxy for the thread | |
| 218 // on which file access happens. | |
| 125 scoped_ptr<net::URLRequest> request_; // The actual request this wraps | 219 scoped_ptr<net::URLRequest> request_; // The actual request this wraps |
| 126 int load_flags_; // Flags for the load operation | 220 int load_flags_; // Flags for the load operation |
| 127 int response_code_; // HTTP status code for the request | 221 int response_code_; // HTTP status code for the request |
| 128 std::string data_; // Results of the request | 222 std::string data_; // Results of the request, when we are |
| 223 // storing the response as a string. | |
| 129 scoped_refptr<net::IOBuffer> buffer_; | 224 scoped_refptr<net::IOBuffer> buffer_; |
| 130 // Read buffer | 225 // Read buffer |
| 131 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; | 226 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; |
| 132 // Cookie/cache info for the request | 227 // Cookie/cache info for the request |
| 133 net::ResponseCookies cookies_; // Response cookies | 228 net::ResponseCookies cookies_; // Response cookies |
| 134 net::HttpRequestHeaders extra_request_headers_; | 229 net::HttpRequestHeaders extra_request_headers_; |
| 135 scoped_refptr<net::HttpResponseHeaders> response_headers_; | 230 scoped_refptr<net::HttpResponseHeaders> response_headers_; |
| 136 bool was_fetched_via_proxy_; | 231 bool was_fetched_via_proxy_; |
| 137 net::HostPortPair socket_address_; | 232 net::HostPortPair socket_address_; |
| 138 | 233 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 159 // specified by the owner URLFetcher instance, we'll give up. | 254 // specified by the owner URLFetcher instance, we'll give up. |
| 160 int num_retries_; | 255 int num_retries_; |
| 161 | 256 |
| 162 // True if the URLFetcher has been cancelled. | 257 // True if the URLFetcher has been cancelled. |
| 163 bool was_cancelled_; | 258 bool was_cancelled_; |
| 164 | 259 |
| 165 // Since GetBackoffReleaseTime() can only be called on the IO thread, we cache | 260 // Since GetBackoffReleaseTime() can only be called on the IO thread, we cache |
| 166 // its value to be used by OnCompletedURLRequest on the creating thread. | 261 // its value to be used by OnCompletedURLRequest on the creating thread. |
| 167 base::TimeTicks backoff_release_time_; | 262 base::TimeTicks backoff_release_time_; |
| 168 | 263 |
| 264 // If writing results to a file, |temp_file_writer_| will manage creation, | |
| 265 // writing, and destruction of that file. | |
| 266 scoped_ptr<TempFileWriter> temp_file_writer_; | |
| 267 | |
| 169 static base::LazyInstance<Registry> g_registry; | 268 static base::LazyInstance<Registry> g_registry; |
| 170 | 269 |
| 171 friend class URLFetcher; | 270 friend class URLFetcher; |
| 172 DISALLOW_COPY_AND_ASSIGN(Core); | 271 DISALLOW_COPY_AND_ASSIGN(Core); |
| 173 }; | 272 }; |
| 174 | 273 |
| 175 URLFetcher::Core::Registry::Registry() {} | 274 URLFetcher::Core::Registry::Registry() {} |
| 176 URLFetcher::Core::Registry::~Registry() {} | 275 URLFetcher::Core::Registry::~Registry() {} |
| 177 | 276 |
| 178 void URLFetcher::Core::Registry::AddURLFetcherCore(Core* core) { | 277 void URLFetcher::Core::Registry::AddURLFetcherCore(Core* core) { |
| 179 DCHECK(!ContainsKey(fetchers_, core)); | 278 DCHECK(!ContainsKey(fetchers_, core)); |
| 180 fetchers_.insert(core); | 279 fetchers_.insert(core); |
| 181 } | 280 } |
| 182 | 281 |
| 183 void URLFetcher::Core::Registry::RemoveURLFetcherCore(Core* core) { | 282 void URLFetcher::Core::Registry::RemoveURLFetcherCore(Core* core) { |
| 184 DCHECK(ContainsKey(fetchers_, core)); | 283 DCHECK(ContainsKey(fetchers_, core)); |
| 185 fetchers_.erase(core); | 284 fetchers_.erase(core); |
| 186 } | 285 } |
| 187 | 286 |
| 188 void URLFetcher::Core::Registry::CancelAll() { | 287 void URLFetcher::Core::Registry::CancelAll() { |
| 189 while (!fetchers_.empty()) | 288 while (!fetchers_.empty()) |
| 190 (*fetchers_.begin())->CancelURLRequest(); | 289 (*fetchers_.begin())->CancelURLRequest(); |
| 191 } | 290 } |
| 192 | 291 |
| 193 // static | 292 // static |
| 194 base::LazyInstance<URLFetcher::Core::Registry> | 293 base::LazyInstance<URLFetcher::Core::Registry> |
| 195 URLFetcher::Core::g_registry(base::LINKER_INITIALIZED); | 294 URLFetcher::Core::g_registry(base::LINKER_INITIALIZED); |
| 196 | 295 |
| 296 URLFetcher::Core::TempFileWriter::TempFileWriter( | |
| 297 URLFetcher::Core* core, | |
| 298 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) | |
| 299 : core_(core), | |
| 300 error_code_(base::PLATFORM_FILE_OK), | |
| 301 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | |
| 302 file_message_loop_proxy_(file_message_loop_proxy) { | |
| 303 } | |
| 304 | |
| 305 URLFetcher::Core::TempFileWriter::~TempFileWriter() { | |
| 306 Destroy(); | |
| 307 } | |
| 308 | |
| 309 void URLFetcher::Core::TempFileWriter::CreateTempFile() { | |
| 310 CHECK(file_message_loop_proxy_.get()); | |
| 311 base::FileUtilProxy::CreateTemporary( | |
| 312 file_message_loop_proxy_, | |
| 313 callback_factory_.NewCallback( | |
| 314 &URLFetcher::Core::TempFileWriter::DidCreateTempFile)); | |
| 315 } | |
| 316 | |
| 317 void URLFetcher::Core::TempFileWriter::DidCreateTempFile( | |
| 318 base::PlatformFileError error_code, | |
| 319 base::PassPlatformFile file_handle, | |
| 320 FilePath file_path) { | |
| 321 if (base::PLATFORM_FILE_OK != error_code) { | |
| 322 error_code_ = error_code; | |
| 323 core_->InformDelegateFetchIsComplete(); | |
| 324 return; | |
| 325 } | |
| 326 | |
| 327 temp_file_ = file_path; | |
| 328 | |
| 329 // The file was opened with async writes enabled. FileUtilProxy::Write() | |
| 330 // treats a write that returns IO_PENDING as an error, and does not inform | |
| 331 // the caller. We need to close and reopen the file with asyncronus writes | |
| 332 // disabled. | |
| 333 // TODO(skerner): Make FileUtilProxy::Write() play nice with async IO. | |
| 334 base::FileUtilProxy::Close( | |
| 335 file_message_loop_proxy_, | |
| 336 file_handle.ReleaseValue(), | |
| 337 callback_factory_.NewCallback( | |
| 338 &URLFetcher::Core::TempFileWriter::DidCloseTempFile)); | |
| 339 } | |
| 340 | |
| 341 void URLFetcher::Core::TempFileWriter::DidCloseTempFile( | |
| 342 base::PlatformFileError error_code) { | |
| 343 if (base::PLATFORM_FILE_OK != error_code) { | |
| 344 error_code_ = error_code; | |
| 345 core_->InformDelegateFetchIsComplete(); | |
| 346 return; | |
| 347 } | |
| 348 | |
| 349 int file_flags = | |
| 350 base::PLATFORM_FILE_CREATE_ALWAYS | | |
| 351 base::PLATFORM_FILE_WRITE | | |
| 352 base::PLATFORM_FILE_TEMPORARY; | |
| 353 | |
| 354 base::FileUtilProxy::CreateOrOpen( | |
| 355 file_message_loop_proxy_, | |
| 356 temp_file_, | |
| 357 file_flags, | |
| 358 callback_factory_.NewCallback( | |
| 359 &URLFetcher::Core::TempFileWriter::DidReopenTempFile)); | |
| 360 } | |
| 361 | |
| 362 void URLFetcher::Core::TempFileWriter::DidReopenTempFile( | |
| 363 base::PlatformFileError error_code, | |
| 364 base::PassPlatformFile file_handle, | |
| 365 bool created) { | |
| 366 if (base::PLATFORM_FILE_OK != error_code) { | |
| 367 error_code_ = error_code; | |
| 368 core_->InformDelegateFetchIsComplete(); | |
| 369 return; | |
| 370 } | |
| 371 | |
| 372 temp_file_handle_ = file_handle.ReleaseValue(); | |
| 373 total_bytes_written_ = 0; | |
| 374 | |
| 375 core_->io_message_loop_proxy_->PostTask( | |
| 376 FROM_HERE, | |
| 377 NewRunnableMethod(core_, &Core::StartURLRequestWhenAppropriate)); | |
| 378 } | |
| 379 | |
| 380 void URLFetcher::Core::TempFileWriter::WriteBuffer(int num_bytes) { | |
| 381 // Start writing to the temp file by setting the initial state | |
| 382 // of |pending_bytes_| and |buffer_offset_| to indicate that the | |
| 383 // entire buffer has not yet been written. | |
| 384 pending_bytes_ = num_bytes; | |
| 385 buffer_offset_ = 0; | |
| 386 ContinueWrite(base::PLATFORM_FILE_OK, 0); | |
| 387 } | |
| 388 | |
| 389 void URLFetcher::Core::TempFileWriter::ContinueWrite( | |
| 390 base::PlatformFileError error_code, | |
| 391 int bytes_written) { | |
| 392 if (base::PLATFORM_FILE_OK != error_code) { | |
| 393 error_code_ = error_code; | |
| 394 core_->InformDelegateFetchIsComplete(); | |
|
willchan no longer on Chromium
2011/06/21 13:55:15
This code is wrong. The delegate can only be calle
| |
| 395 return; | |
| 396 } | |
| 397 | |
| 398 total_bytes_written_ += bytes_written; | |
| 399 buffer_offset_ += bytes_written; | |
| 400 pending_bytes_ -= bytes_written; | |
| 401 | |
| 402 if (pending_bytes_ > 0) { | |
| 403 base::FileUtilProxy::Write( | |
| 404 file_message_loop_proxy_, | |
| 405 temp_file_handle_, | |
| 406 total_bytes_written_, // Append to the end | |
| 407 (core_->buffer_->data() + buffer_offset_), | |
| 408 pending_bytes_, | |
| 409 callback_factory_.NewCallback( | |
| 410 &URLFetcher::Core::TempFileWriter::ContinueWrite)); | |
| 411 } else { | |
| 412 // Finished writing core_->buffer_ to the file. Read some more. | |
| 413 core_->ReadResponse(); | |
| 414 } | |
| 415 } | |
| 416 | |
| 417 void URLFetcher::Core::TempFileWriter::DisownTempFile() { | |
| 418 // Forget about any temp file by reseting the path. | |
| 419 if (!temp_file_.empty()) { | |
| 420 base::FileUtilProxy::Close( | |
| 421 file_message_loop_proxy_, | |
| 422 temp_file_handle_, | |
| 423 NULL); | |
| 424 temp_file_ = FilePath(); | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 void URLFetcher::Core::TempFileWriter::Destroy() { | |
| 429 if (!temp_file_.empty()) { | |
| 430 base::FileUtilProxy::Close( | |
| 431 file_message_loop_proxy_, | |
| 432 temp_file_handle_, | |
| 433 NULL); | |
| 434 | |
| 435 base::FileUtilProxy::Delete( | |
| 436 file_message_loop_proxy_, | |
| 437 temp_file_, | |
| 438 false, // No need to recurse, as the path is to a file. | |
| 439 NULL); // No callback. | |
| 440 } | |
| 441 temp_file_ = FilePath(); | |
| 442 } | |
| 443 | |
| 197 // static | 444 // static |
| 198 URLFetcher::Factory* URLFetcher::factory_ = NULL; | 445 URLFetcher::Factory* URLFetcher::factory_ = NULL; |
| 199 | 446 |
| 447 void URLFetcher::Delegate::OnURLFetchComplete( | |
| 448 const URLFetcher* source, | |
| 449 const GURL& url, | |
| 450 const net::URLRequestStatus& status, | |
| 451 int response_code, | |
| 452 const net::ResponseCookies& cookies, | |
| 453 const std::string& data) { | |
| 454 NOTREACHED() << "If you don't implemnt this, the no-params version " | |
| 455 << "should also be implemented, in which case this " | |
| 456 << "method won't be called..."; | |
| 457 } | |
| 458 | |
| 459 // TODO(skerner): This default implementation will be removed, and the | |
| 460 // method made pure virtual, once all users of URLFetcher are updated | |
| 461 // to not expect response data as a string argument. | |
| 462 void URLFetcher::Delegate::OnURLFetchComplete(const URLFetcher* source) { | |
| 463 // A delegate that did not override this method is using the old | |
| 464 // parameter list to OnURLFetchComplete(). If a user asked to save | |
| 465 // the response to a file, they must use the new parameter list, | |
| 466 // in which case we can not get here. | |
| 467 std::string data; | |
| 468 CHECK(source->GetResponseAsString(&data)); | |
| 469 | |
| 470 // To avoid updating all callers, thunk to the old prototype for now. | |
| 471 OnURLFetchComplete(source, | |
| 472 source->url(), | |
| 473 source->status(), | |
| 474 source->response_code(), | |
| 475 source->cookies(), | |
| 476 data); | |
| 477 } | |
| 478 | |
| 200 // static | 479 // static |
| 201 bool URLFetcher::g_interception_enabled = false; | 480 bool URLFetcher::g_interception_enabled = false; |
| 202 | 481 |
| 203 URLFetcher::URLFetcher(const GURL& url, | 482 URLFetcher::URLFetcher(const GURL& url, |
| 204 RequestType request_type, | 483 RequestType request_type, |
| 205 Delegate* d) | 484 Delegate* d) |
| 206 : ALLOW_THIS_IN_INITIALIZER_LIST( | 485 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 207 core_(new Core(this, url, request_type, d))), | 486 core_(new Core(this, url, request_type, d))), |
| 208 automatically_retry_on_5xx_(true), | 487 automatically_retry_on_5xx_(true), |
| 209 max_retries_(0) { | 488 max_retries_(0), |
| 489 response_destination_(STRING) { | |
| 210 } | 490 } |
| 211 | 491 |
| 212 URLFetcher::~URLFetcher() { | 492 URLFetcher::~URLFetcher() { |
| 213 core_->Stop(); | 493 core_->Stop(); |
| 214 } | 494 } |
| 215 | 495 |
| 216 // static | 496 // static |
| 217 URLFetcher* URLFetcher::Create(int id, const GURL& url, | 497 URLFetcher* URLFetcher::Create(int id, const GURL& url, |
| 218 RequestType request_type, Delegate* d) { | 498 RequestType request_type, Delegate* d) { |
| 219 return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) : | 499 return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) : |
| 220 new URLFetcher(url, request_type, d); | 500 new URLFetcher(url, request_type, d); |
| 221 } | 501 } |
| 222 | 502 |
| 223 URLFetcher::Core::Core(URLFetcher* fetcher, | 503 URLFetcher::Core::Core(URLFetcher* fetcher, |
| 224 const GURL& original_url, | 504 const GURL& original_url, |
| 225 RequestType request_type, | 505 RequestType request_type, |
| 226 URLFetcher::Delegate* d) | 506 URLFetcher::Delegate* d) |
| 227 : fetcher_(fetcher), | 507 : fetcher_(fetcher), |
| 228 original_url_(original_url), | 508 original_url_(original_url), |
| 229 request_type_(request_type), | 509 request_type_(request_type), |
| 230 delegate_(d), | 510 delegate_(d), |
| 231 delegate_loop_proxy_(base::MessageLoopProxy::CreateForCurrentThread()), | 511 delegate_loop_proxy_( |
| 512 base::MessageLoopProxy::CreateForCurrentThread()), | |
| 232 request_(NULL), | 513 request_(NULL), |
| 233 load_flags_(net::LOAD_NORMAL), | 514 load_flags_(net::LOAD_NORMAL), |
| 234 response_code_(-1), | 515 response_code_(URLFetcher::kInvalidHttpResponseCode), |
| 235 buffer_(new net::IOBuffer(kBufferSize)), | 516 buffer_(new net::IOBuffer(kBufferSize)), |
| 236 is_chunked_upload_(false), | 517 is_chunked_upload_(false), |
| 237 num_retries_(0), | 518 num_retries_(0), |
| 238 was_cancelled_(false) { | 519 was_cancelled_(false) { |
| 239 } | 520 } |
| 240 | 521 |
| 241 URLFetcher::Core::~Core() { | 522 URLFetcher::Core::~Core() { |
| 242 // |request_| should be NULL. If not, it's unsafe to delete it here since we | 523 // |request_| should be NULL. If not, it's unsafe to delete it here since we |
| 243 // may not be on the IO thread. | 524 // may not be on the IO thread. |
| 244 DCHECK(!request_.get()); | 525 DCHECK(!request_.get()); |
| 245 } | 526 } |
| 246 | 527 |
| 247 void URLFetcher::Core::Start() { | 528 void URLFetcher::Core::Start() { |
| 248 DCHECK(delegate_loop_proxy_); | 529 DCHECK(delegate_loop_proxy_); |
| 249 CHECK(request_context_getter_) << "We need an URLRequestContext!"; | 530 CHECK(request_context_getter_) << "We need an URLRequestContext!"; |
| 250 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); | 531 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); |
| 251 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; | 532 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; |
| 252 | 533 |
| 253 io_message_loop_proxy_->PostTask( | 534 switch (fetcher_->response_destination_) { |
| 254 FROM_HERE, | 535 case STRING: |
| 255 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); | 536 io_message_loop_proxy_->PostTask( |
| 537 FROM_HERE, | |
| 538 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); | |
| 539 break; | |
| 540 | |
| 541 case TEMP_FILE: | |
| 542 CHECK(file_message_loop_proxy_.get()) | |
| 543 << "Need to set the file message loop proxy."; | |
| 544 temp_file_writer_.reset( | |
| 545 new TempFileWriter(this, file_message_loop_proxy_)); | |
| 546 // CreateTempFile() will invoke Core::StartURLRequestWhenAppropriate | |
| 547 // once the file is created. | |
| 548 temp_file_writer_->CreateTempFile(); | |
| 549 break; | |
| 550 | |
| 551 default: | |
| 552 NOTREACHED(); | |
| 553 } | |
| 256 } | 554 } |
| 257 | 555 |
| 258 void URLFetcher::Core::Stop() { | 556 void URLFetcher::Core::Stop() { |
| 259 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); | 557 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); |
| 260 delegate_ = NULL; | 558 delegate_ = NULL; |
| 261 fetcher_ = NULL; | 559 fetcher_ = NULL; |
| 262 if (io_message_loop_proxy_.get()) { | 560 if (io_message_loop_proxy_.get()) { |
| 263 io_message_loop_proxy_->PostTask( | 561 io_message_loop_proxy_->PostTask( |
| 264 FROM_HERE, NewRunnableMethod(this, &Core::CancelURLRequest)); | 562 FROM_HERE, NewRunnableMethod(this, &Core::CancelURLRequest)); |
| 265 } | 563 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 280 void URLFetcher::Core::OnResponseStarted(net::URLRequest* request) { | 578 void URLFetcher::Core::OnResponseStarted(net::URLRequest* request) { |
| 281 DCHECK_EQ(request, request_.get()); | 579 DCHECK_EQ(request, request_.get()); |
| 282 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 580 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 283 if (request_->status().is_success()) { | 581 if (request_->status().is_success()) { |
| 284 response_code_ = request_->GetResponseCode(); | 582 response_code_ = request_->GetResponseCode(); |
| 285 response_headers_ = request_->response_headers(); | 583 response_headers_ = request_->response_headers(); |
| 286 socket_address_ = request_->GetSocketAddress(); | 584 socket_address_ = request_->GetSocketAddress(); |
| 287 was_fetched_via_proxy_ = request_->was_fetched_via_proxy(); | 585 was_fetched_via_proxy_ = request_->was_fetched_via_proxy(); |
| 288 } | 586 } |
| 289 | 587 |
| 290 int bytes_read = 0; | 588 ReadResponse(); |
| 291 // Some servers may treat HEAD requests as GET requests. To free up the | |
| 292 // network connection as soon as possible, signal that the request has | |
| 293 // completed immediately, without trying to read any data back (all we care | |
| 294 // about is the response code and headers, which we already have). | |
| 295 if (request_->status().is_success() && (request_type_ != HEAD)) | |
| 296 request_->Read(buffer_, kBufferSize, &bytes_read); | |
| 297 OnReadCompleted(request_.get(), bytes_read); | |
| 298 } | 589 } |
| 299 | 590 |
| 300 void URLFetcher::Core::CompleteAddingUploadDataChunk( | 591 void URLFetcher::Core::CompleteAddingUploadDataChunk( |
| 301 const std::string& content, bool is_last_chunk) { | 592 const std::string& content, bool is_last_chunk) { |
| 302 DCHECK(is_chunked_upload_); | 593 DCHECK(is_chunked_upload_); |
| 303 DCHECK(request_.get()); | 594 DCHECK(request_.get()); |
| 304 DCHECK(!content.empty()); | 595 DCHECK(!content.empty()); |
| 305 request_->AppendChunkToUpload(content.data(), | 596 request_->AppendChunkToUpload(content.data(), |
| 306 static_cast<int>(content.length()), | 597 static_cast<int>(content.length()), |
| 307 is_last_chunk); | 598 is_last_chunk); |
| 308 } | 599 } |
| 309 | 600 |
| 310 void URLFetcher::Core::AppendChunkToUpload(const std::string& content, | 601 void URLFetcher::Core::AppendChunkToUpload(const std::string& content, |
| 311 bool is_last_chunk) { | 602 bool is_last_chunk) { |
| 312 DCHECK(delegate_loop_proxy_); | 603 DCHECK(delegate_loop_proxy_); |
| 313 CHECK(io_message_loop_proxy_.get()); | 604 CHECK(io_message_loop_proxy_.get()); |
| 314 io_message_loop_proxy_->PostTask( | 605 io_message_loop_proxy_->PostTask( |
| 315 FROM_HERE, | 606 FROM_HERE, |
| 316 NewRunnableMethod(this, &Core::CompleteAddingUploadDataChunk, content, | 607 NewRunnableMethod(this, &Core::CompleteAddingUploadDataChunk, content, |
| 317 is_last_chunk)); | 608 is_last_chunk)); |
| 318 } | 609 } |
| 319 | 610 |
| 611 // Return true if the write was done and reading may continue. | |
| 612 // Return false if the write is pending, and the next read will | |
| 613 // be done later. | |
| 614 bool URLFetcher::Core::WriteBuffer(int num_bytes) { | |
| 615 bool write_complete = false; | |
| 616 switch (fetcher_->response_destination_) { | |
| 617 case STRING: | |
| 618 data_.append(buffer_->data(), num_bytes); | |
| 619 write_complete = true; | |
| 620 break; | |
| 621 | |
| 622 case TEMP_FILE: | |
| 623 temp_file_writer_->WriteBuffer(num_bytes); | |
| 624 // WriteBuffer() sends a request the file thread. | |
| 625 // The write is not done yet. | |
| 626 write_complete = false; | |
| 627 break; | |
| 628 | |
| 629 default: | |
| 630 NOTREACHED(); | |
| 631 } | |
| 632 return write_complete; | |
| 633 } | |
| 634 | |
| 320 void URLFetcher::Core::OnReadCompleted(net::URLRequest* request, | 635 void URLFetcher::Core::OnReadCompleted(net::URLRequest* request, |
| 321 int bytes_read) { | 636 int bytes_read) { |
| 322 DCHECK(request == request_); | 637 DCHECK(request == request_); |
| 323 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 638 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 324 | 639 |
| 325 url_ = request->url(); | 640 url_ = request->url(); |
| 326 url_throttler_entry_ = | 641 url_throttler_entry_ = |
| 327 net::URLRequestThrottlerManager::GetInstance()->RegisterRequestUrl(url_); | 642 net::URLRequestThrottlerManager::GetInstance()->RegisterRequestUrl(url_); |
| 328 | 643 |
| 644 bool waiting_on_write = false; | |
| 329 do { | 645 do { |
| 330 if (!request_->status().is_success() || bytes_read <= 0) | 646 if (!request_->status().is_success() || bytes_read <= 0) |
| 331 break; | 647 break; |
| 332 data_.append(buffer_->data(), bytes_read); | 648 |
| 649 if (!WriteBuffer(bytes_read)) { | |
| 650 // If WriteBuffer() returns false, we have a pending write to | |
| 651 // wait on before reading further. | |
| 652 waiting_on_write = true; | |
| 653 break; | |
| 654 } | |
| 333 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); | 655 } while (request_->Read(buffer_, kBufferSize, &bytes_read)); |
| 334 | 656 |
| 335 if (request_->status().is_success()) | 657 if (request_->status().is_success()) |
| 336 request_->GetResponseCookies(&cookies_); | 658 request_->GetResponseCookies(&cookies_); |
| 337 | 659 |
| 338 // See comments re: HEAD requests in OnResponseStarted(). | 660 // See comments re: HEAD requests in ReadResponse(). |
| 339 if (!request_->status().is_io_pending() || (request_type_ == HEAD)) { | 661 if ((!request_->status().is_io_pending() && !waiting_on_write) || |
| 662 (request_type_ == HEAD)) { | |
| 340 backoff_release_time_ = GetBackoffReleaseTime(); | 663 backoff_release_time_ = GetBackoffReleaseTime(); |
| 341 | 664 |
| 342 bool posted = delegate_loop_proxy_->PostTask( | 665 bool posted = delegate_loop_proxy_->PostTask( |
| 343 FROM_HERE, | 666 FROM_HERE, |
| 344 NewRunnableMethod(this, | 667 NewRunnableMethod(this, |
| 345 &Core::OnCompletedURLRequest, | 668 &Core::OnCompletedURLRequest, |
| 346 request_->status())); | 669 request_->status())); |
| 347 // If the delegate message loop does not exist any more, then the delegate | 670 // If the delegate message loop does not exist any more, then the delegate |
| 348 // should be gone too. | 671 // should be gone too. |
| 349 DCHECK(posted || !delegate_); | 672 DCHECK(posted || !delegate_); |
| 350 ReleaseRequest(); | 673 ReleaseRequest(); |
| 351 } | 674 } |
| 352 } | 675 } |
| 353 | 676 |
| 677 void URLFetcher::Core::ReadResponse() { | |
| 678 // Some servers may treat HEAD requests as GET requests. To free up the | |
| 679 // network connection as soon as possible, signal that the request has | |
| 680 // completed immediately, without trying to read any data back (all we care | |
| 681 // about is the response code and headers, which we already have). | |
| 682 int bytes_read = 0; | |
| 683 if (request_->status().is_success() && (request_type_ != HEAD)) | |
| 684 request_->Read(buffer_, kBufferSize, &bytes_read); | |
| 685 OnReadCompleted(request_.get(), bytes_read); | |
| 686 } | |
| 687 | |
| 354 void URLFetcher::Core::StartURLRequest() { | 688 void URLFetcher::Core::StartURLRequest() { |
| 355 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 689 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 356 | 690 |
| 357 if (was_cancelled_) { | 691 if (was_cancelled_) { |
| 358 // Since StartURLRequest() is posted as a *delayed* task, it may | 692 // Since StartURLRequest() is posted as a *delayed* task, it may |
| 359 // run after the URLFetcher was already stopped. | 693 // run after the URLFetcher was already stopped. |
| 360 return; | 694 return; |
| 361 } | 695 } |
| 362 | 696 |
| 363 CHECK(request_context_getter_); | 697 CHECK(request_context_getter_); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 default: | 733 default: |
| 400 NOTREACHED(); | 734 NOTREACHED(); |
| 401 } | 735 } |
| 402 | 736 |
| 403 if (!extra_request_headers_.IsEmpty()) | 737 if (!extra_request_headers_.IsEmpty()) |
| 404 request_->SetExtraRequestHeaders(extra_request_headers_); | 738 request_->SetExtraRequestHeaders(extra_request_headers_); |
| 405 | 739 |
| 406 // There might be data left over from a previous request attempt. | 740 // There might be data left over from a previous request attempt. |
| 407 data_.clear(); | 741 data_.clear(); |
| 408 | 742 |
| 743 // If we are writing the response to a file, the only caller | |
| 744 // of this function should have created it and not written yet. | |
| 745 CHECK(!temp_file_writer_.get() || | |
| 746 temp_file_writer_->total_bytes_written() == 0); | |
| 747 | |
| 409 request_->Start(); | 748 request_->Start(); |
| 410 } | 749 } |
| 411 | 750 |
| 412 void URLFetcher::Core::StartURLRequestWhenAppropriate() { | 751 void URLFetcher::Core::StartURLRequestWhenAppropriate() { |
| 413 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 752 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 414 | 753 |
| 415 if (was_cancelled_) | 754 if (was_cancelled_) |
| 416 return; | 755 return; |
| 417 | 756 |
| 418 if (original_url_throttler_entry_ == NULL) { | 757 if (original_url_throttler_entry_ == NULL) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 439 if (request_.get()) { | 778 if (request_.get()) { |
| 440 request_->Cancel(); | 779 request_->Cancel(); |
| 441 ReleaseRequest(); | 780 ReleaseRequest(); |
| 442 } | 781 } |
| 443 // Release the reference to the request context. There could be multiple | 782 // Release the reference to the request context. There could be multiple |
| 444 // references to URLFetcher::Core at this point so it may take a while to | 783 // references to URLFetcher::Core at this point so it may take a while to |
| 445 // delete the object, but we cannot delay the destruction of the request | 784 // delete the object, but we cannot delay the destruction of the request |
| 446 // context. | 785 // context. |
| 447 request_context_getter_ = NULL; | 786 request_context_getter_ = NULL; |
| 448 was_cancelled_ = true; | 787 was_cancelled_ = true; |
| 788 temp_file_writer_.reset(); | |
| 449 } | 789 } |
| 450 | 790 |
| 451 void URLFetcher::Core::OnCompletedURLRequest( | 791 void URLFetcher::Core::OnCompletedURLRequest( |
| 452 const net::URLRequestStatus& status) { | 792 const net::URLRequestStatus& status) { |
| 453 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); | 793 DCHECK(delegate_loop_proxy_->BelongsToCurrentThread()); |
| 454 | 794 |
| 795 // Save the status so that delegates can read it. | |
| 796 status_ = status; | |
| 797 | |
| 455 // Checks the response from server. | 798 // Checks the response from server. |
| 456 if (response_code_ >= 500 || | 799 if (response_code_ >= 500 || |
| 457 status.os_error() == net::ERR_TEMPORARILY_THROTTLED) { | 800 status.os_error() == net::ERR_TEMPORARILY_THROTTLED) { |
| 458 // When encountering a server error, we will send the request again | 801 // When encountering a server error, we will send the request again |
| 459 // after backoff time. | 802 // after backoff time. |
| 460 ++num_retries_; | 803 ++num_retries_; |
| 461 // Restarts the request if we still need to notify the delegate. | 804 // Restarts the request if we still need to notify the delegate. |
| 462 if (delegate_) { | 805 if (delegate_) { |
| 463 fetcher_->backoff_delay_ = backoff_release_time_ - base::TimeTicks::Now(); | 806 fetcher_->backoff_delay_ = backoff_release_time_ - base::TimeTicks::Now(); |
| 464 if (fetcher_->backoff_delay_ < base::TimeDelta()) | 807 if (fetcher_->backoff_delay_ < base::TimeDelta()) |
| 465 fetcher_->backoff_delay_ = base::TimeDelta(); | 808 fetcher_->backoff_delay_ = base::TimeDelta(); |
| 466 | 809 |
| 467 if (fetcher_->automatically_retry_on_5xx_ && | 810 if (fetcher_->automatically_retry_on_5xx_ && |
| 468 num_retries_ <= fetcher_->max_retries()) { | 811 num_retries_ <= fetcher_->max_retries()) { |
| 469 io_message_loop_proxy_->PostTask( | 812 io_message_loop_proxy_->PostTask( |
| 470 FROM_HERE, | 813 FROM_HERE, |
| 471 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); | 814 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); |
| 472 } else { | 815 } else { |
| 473 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, | 816 InformDelegateFetchIsComplete(); |
| 474 cookies_, data_); | |
| 475 } | 817 } |
| 476 } | 818 } |
| 477 } else { | 819 } else { |
| 478 if (delegate_) { | 820 if (delegate_) { |
| 479 fetcher_->backoff_delay_ = base::TimeDelta(); | 821 fetcher_->backoff_delay_ = base::TimeDelta(); |
| 480 delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_, | 822 InformDelegateFetchIsComplete(); |
| 481 cookies_, data_); | |
| 482 } | 823 } |
| 483 } | 824 } |
| 484 } | 825 } |
| 485 | 826 |
| 827 void URLFetcher::Core::InformDelegateFetchIsComplete() { | |
| 828 delegate_->OnURLFetchComplete(fetcher_); | |
| 829 } | |
| 830 | |
| 486 void URLFetcher::Core::NotifyMalformedContent() { | 831 void URLFetcher::Core::NotifyMalformedContent() { |
| 487 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 832 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 488 if (url_throttler_entry_ != NULL) | 833 if (url_throttler_entry_ != NULL) |
| 489 url_throttler_entry_->ReceivedContentWasMalformed(); | 834 url_throttler_entry_->ReceivedContentWasMalformed(); |
| 490 } | 835 } |
| 491 | 836 |
| 492 void URLFetcher::Core::ReleaseRequest() { | 837 void URLFetcher::Core::ReleaseRequest() { |
| 493 request_.reset(); | 838 request_.reset(); |
| 494 g_registry.Get().RemoveURLFetcherCore(this); | 839 g_registry.Get().RemoveURLFetcherCore(this); |
| 495 } | 840 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 | 902 |
| 558 void URLFetcher::set_request_context( | 903 void URLFetcher::set_request_context( |
| 559 net::URLRequestContextGetter* request_context_getter) { | 904 net::URLRequestContextGetter* request_context_getter) { |
| 560 core_->request_context_getter_ = request_context_getter; | 905 core_->request_context_getter_ = request_context_getter; |
| 561 } | 906 } |
| 562 | 907 |
| 563 void URLFetcher::set_automatically_retry_on_5xx(bool retry) { | 908 void URLFetcher::set_automatically_retry_on_5xx(bool retry) { |
| 564 automatically_retry_on_5xx_ = retry; | 909 automatically_retry_on_5xx_ = retry; |
| 565 } | 910 } |
| 566 | 911 |
| 912 void URLFetcher::SaveResponseToTemporaryFile( | |
| 913 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { | |
| 914 core_->file_message_loop_proxy_ = file_message_loop_proxy; | |
| 915 response_destination_ = TEMP_FILE; | |
| 916 } | |
| 917 | |
| 567 net::HttpResponseHeaders* URLFetcher::response_headers() const { | 918 net::HttpResponseHeaders* URLFetcher::response_headers() const { |
| 568 return core_->response_headers_; | 919 return core_->response_headers_; |
| 569 } | 920 } |
| 570 | 921 |
| 571 // TODO(panayiotis): socket_address_ is written in the IO thread, | 922 // TODO(panayiotis): socket_address_ is written in the IO thread, |
| 572 // if this is accessed in the UI thread, this could result in a race. | 923 // if this is accessed in the UI thread, this could result in a race. |
| 573 // Same for response_headers_ above and was_fetched_via_proxy_ below. | 924 // Same for response_headers_ above and was_fetched_via_proxy_ below. |
| 574 net::HostPortPair URLFetcher::socket_address() const { | 925 net::HostPortPair URLFetcher::socket_address() const { |
| 575 return core_->socket_address_; | 926 return core_->socket_address_; |
| 576 } | 927 } |
| 577 | 928 |
| 578 bool URLFetcher::was_fetched_via_proxy() const { | 929 bool URLFetcher::was_fetched_via_proxy() const { |
| 579 return core_->was_fetched_via_proxy_; | 930 return core_->was_fetched_via_proxy_; |
| 580 } | 931 } |
| 581 | 932 |
| 582 void URLFetcher::Start() { | 933 void URLFetcher::Start() { |
| 583 core_->Start(); | 934 core_->Start(); |
| 584 } | 935 } |
| 585 | 936 |
| 586 const GURL& URLFetcher::url() const { | 937 const GURL& URLFetcher::url() const { |
| 587 return core_->url_; | 938 return core_->url_; |
| 588 } | 939 } |
| 589 | 940 |
| 941 const net::URLRequestStatus& URLFetcher::status() const { | |
| 942 return core_->status_; | |
| 943 } | |
| 944 | |
| 945 int URLFetcher::response_code() const { | |
| 946 return core_->response_code_; | |
| 947 } | |
| 948 | |
| 949 const net::ResponseCookies& URLFetcher::cookies() const { | |
| 950 return core_->cookies_; | |
| 951 } | |
| 952 | |
| 953 bool URLFetcher::FileErrorOccurred( | |
| 954 base::PlatformFileError* out_error_code) const { | |
| 955 | |
| 956 // Can't have a file error if no file is being created or written to. | |
| 957 if (!core_->temp_file_writer_.get()) { | |
| 958 return false; | |
| 959 } | |
| 960 | |
| 961 base::PlatformFileError error_code = core_->temp_file_writer_->error_code(); | |
| 962 if (error_code == base::PLATFORM_FILE_OK) | |
| 963 return false; | |
| 964 | |
| 965 *out_error_code = error_code; | |
| 966 return true; | |
| 967 } | |
| 968 | |
| 590 void URLFetcher::ReceivedContentWasMalformed() { | 969 void URLFetcher::ReceivedContentWasMalformed() { |
| 591 core_->ReceivedContentWasMalformed(); | 970 core_->ReceivedContentWasMalformed(); |
| 592 } | 971 } |
| 593 | 972 |
| 973 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { | |
| 974 if (response_destination_ != STRING) | |
| 975 return false; | |
| 976 | |
| 977 *out_response_string = core_->data_; | |
| 978 return true; | |
| 979 } | |
| 980 | |
| 981 bool URLFetcher::GetResponseAsFilePath(bool take_ownership, | |
| 982 FilePath* out_response_path) const { | |
| 983 if (response_destination_ != TEMP_FILE || !core_->temp_file_writer_.get()) | |
| 984 return false; | |
| 985 | |
| 986 *out_response_path = core_->temp_file_writer_->temp_file(); | |
| 987 | |
| 988 if (take_ownership) | |
| 989 core_->temp_file_writer_->DisownTempFile(); | |
| 990 | |
| 991 return true; | |
| 992 } | |
| 993 | |
| 594 // static | 994 // static |
| 595 void URLFetcher::CancelAll() { | 995 void URLFetcher::CancelAll() { |
| 596 Core::CancelAll(); | 996 Core::CancelAll(); |
| 597 } | 997 } |
| 598 | 998 |
| 599 // static | 999 // static |
| 600 int URLFetcher::GetNumFetcherCores() { | 1000 int URLFetcher::GetNumFetcherCores() { |
| 601 return Core::g_registry.Get().size(); | 1001 return Core::g_registry.Get().size(); |
| 602 } | 1002 } |
| 603 | 1003 |
| 604 URLFetcher::Delegate* URLFetcher::delegate() const { | 1004 URLFetcher::Delegate* URLFetcher::delegate() const { |
| 605 return core_->delegate(); | 1005 return core_->delegate(); |
| 606 } | 1006 } |
| OLD | NEW |