summaryrefslogtreecommitdiffstats
path: root/chrome/browser/url_fetcher.h
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/url_fetcher.h
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/url_fetcher.h')
-rw-r--r--chrome/browser/url_fetcher.h243
1 files changed, 243 insertions, 0 deletions
diff --git a/chrome/browser/url_fetcher.h b/chrome/browser/url_fetcher.h
new file mode 100644
index 0000000..5431872
--- /dev/null
+++ b/chrome/browser/url_fetcher.h
@@ -0,0 +1,243 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This file contains URLFetcher, a wrapper around URLRequest that handles
+// low-level details like thread safety, ref counting, and incremental buffer
+// reading. This is useful for callers who simply want to get the data from a
+// URL and don't care about all the nitty-gritty details.
+
+#ifndef CHROME_BROWSER_URL_FETCHER_H__
+#define CHROME_BROWSER_URL_FETCHER_H__
+
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "chrome/browser/url_fetcher_protect.h"
+#include "net/url_request/url_request.h"
+
+class URLRequestContext;
+
+// To use this class, create an instance with the desired URL and a pointer to
+// the object to be notified when the URL has been loaded:
+// URLFetcher* fetcher = new URLFetcher("http://www.google.com", this);
+//
+// Then, optionally set properties on this object, like the request context or
+// extra headers:
+// fetcher->SetExtraRequestHeaders("X-Foo: bar");
+//
+// Finally, start the request:
+// fetcher->Start();
+//
+// The object you supply as a delegate must inherit from URLFetcher::Delegate;
+// when the fetch is completed, OnURLFetchComplete() will be called with the
+// resulting status and (if applicable) HTTP response code. From that point
+// until the original URLFetcher instance is destroyed, you may examine the
+// provided status and data for the URL. (You should copy these objects if you
+// need them to live longer than the URLFetcher instance.) If the URLFetcher
+// instance is destroyed before the callback happens, the fetch will be
+// canceled and no callback will occur.
+//
+// You may create the URLFetcher instance on any thread; OnURLFetchComplete()
+// will be called back on the same thread you use to create the instance.
+//
+// NOTE: Take extra care when using URLFetcher in services that live on the
+// BrowserProcess; all URLFetcher instances need to be destroyed before
+// the IO thread goes away, since the URLFetcher destructor requests an
+// InvokeLater operation on that thread.
+//
+// NOTE: URLFetcher requests will NOT be intercepted.
+
+class URLFetcher {
+ public:
+ enum RequestType {
+ GET,
+ POST,
+ HEAD,
+ };
+
+ class Delegate {
+ public:
+ // This will be called when the URL has been fetched, successfully or not.
+ // |response_code| is the HTTP response code (200, 404, etc.) if
+ // applicable. |url|, |status| and |data| are all valid until the
+ // URLFetcher instance is destroyed.
+ virtual void OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) = 0;
+ };
+
+ // |url| is the URL to send the request to.
+ // |request_type| is the type of request to make.
+ // |d| the object that will receive the callback on fetch completion.
+ URLFetcher(const GURL& url, RequestType request_type, Delegate* d);
+
+ // This should only be used by unittests, where g_browser_process->io_thread()
+ // does not exist and we must specify an alternate loop. Unfortunately, we
+ // can't put it under #ifdef UNIT_TEST since some callers (which themselves
+ // should only be reached in unit tests) use this. See
+ // chrome/browser/feeds/feed_manager.cc.
+ void set_io_loop(MessageLoop* io_loop) {
+ core_->io_loop_ = io_loop;
+ }
+
+ // Sets data only needed by POSTs. All callers making POST requests should
+ // call this before the request is started. |upload_content_type| is the MIME
+ // type of the content, while |upload_content| is the data to be sent (the
+ // Content-Length header value will be set to the length of this data).
+ void set_upload_data(const std::string& upload_content_type,
+ const std::string& upload_content) {
+ core_->upload_content_type_ = upload_content_type;
+ core_->upload_content_ = upload_content;
+ }
+
+ // Set one or more load flags as defined in net/base/load_flags.h. Must be
+ // called before the request is started.
+ void set_load_flags(int load_flags) {
+ core_->load_flags_ = load_flags;
+ }
+
+ // Set extra headers on the request. Must be called before the request
+ // is started.
+ void set_extra_request_headers(const std::string& extra_request_headers) {
+ core_->extra_request_headers_ = extra_request_headers;
+ }
+
+ // Set the URLRequestContext on the request. Must be called before the
+ // request is started.
+ void set_request_context(URLRequestContext* request_context) {
+ core_->request_context_ = request_context;
+ }
+
+ // Retrieve the response headers from the request. Must only be called after
+ // the OnURLFetchComplete callback has run.
+ net::HttpResponseHeaders* response_headers() const {
+ return core_->response_headers_;
+ }
+
+ // Start the request. After this is called, you may not change any other
+ // settings.
+ void Start() { core_->Start(); }
+
+ // Return the URL that this fetcher is processing.
+ const GURL& url() const {
+ return core_->url_;
+ }
+
+ ~URLFetcher();
+
+ private:
+ // This class is the real guts of URLFetcher.
+ //
+ // When created, delegate_loop_ is set to the message loop of the current
+ // thread, while io_loop_ is set to the message loop of the IO thread. These
+ // are used to ensure that all handling of URLRequests happens on the IO
+ // thread (since that class is not currently threadsafe and relies on
+ // underlying Microsoft APIs that we don't know to be threadsafe), while
+ // keeping the delegate callback on the delegate's thread.
+ class Core : public base::RefCountedThreadSafe<URLFetcher::Core>,
+ public URLRequest::Delegate {
+ public:
+ // For POST requests, set |content_type| to the MIME type of the content
+ // and set |content| to the data to upload. |flags| are flags to apply to
+ // the load operation--these should be one or more of the LOAD_* flags
+ // defined in url_request.h.
+ Core(URLFetcher* fetcher,
+ const GURL& original_url,
+ RequestType request_type,
+ URLFetcher::Delegate* d);
+
+ // Starts the load. It's important that this not happen in the constructor
+ // because it causes the IO thread to begin AddRef()ing and Release()ing
+ // us. If our caller hasn't had time to fully construct us and take a
+ // reference, the IO thread could interrupt things, run a task, Release()
+ // us, and destroy us, leaving the caller with an already-destroyed object
+ // when construction finishes.
+ void Start();
+
+ // Stops any in-progress load and ensures no callback will happen. It is
+ // safe to call this multiple times.
+ void Stop();
+
+ // URLRequest::Delegate implementations
+ virtual void OnReceivedRedirect(URLRequest* request,
+ const GURL& new_url) { }
+ virtual void OnResponseStarted(URLRequest* request);
+ virtual void OnReadCompleted(URLRequest* request, int bytes_read);
+
+ private:
+ // Wrapper functions that allow us to ensure actions happen on the right
+ // thread.
+ void StartURLRequest();
+ void CancelURLRequest();
+ void OnCompletedURLRequest(const URLRequestStatus& status);
+
+ URLFetcher* fetcher_; // Corresponding fetcher object
+ GURL original_url_; // The URL we were asked to fetch
+ GURL url_; // The URL we eventually wound up at
+ RequestType request_type_; // What type of request is this?
+ URLFetcher::Delegate* delegate_; // Object to notify on completion
+ MessageLoop* delegate_loop_; // Message loop of the creating thread
+ MessageLoop* io_loop_; // Message loop of the IO thread
+ URLRequest* request_; // The actual request this wraps
+ int load_flags_; // Flags for the load operation
+ int response_code_; // HTTP status code for the request
+ std::string data_; // Results of the request
+ char buffer_[4096]; // Read buffer
+ scoped_refptr<URLRequestContext> request_context_;
+ // Cookie/cache info for the request
+ ResponseCookies cookies_; // Response cookies
+ std::string extra_request_headers_;// Extra headers for the request, if any
+ scoped_refptr<net::HttpResponseHeaders> response_headers_;
+
+ std::string upload_content_; // HTTP POST payload
+ std::string upload_content_type_; // MIME type of POST payload
+
+ // The overload protection entry for this URL. This is used to
+ // incrementally back off how rapidly we'll send requests to a particular
+ // URL, to avoid placing too much demand on the remote resource. We update
+ // this with the status of all requests as they return, and in turn use it
+ // to determine how long to wait before making another request.
+ ProtectEntry* protect_entry_;
+ // |num_retries_| indicates how many times we've failed to successfully
+ // fetch this URL. Once this value exceeds the maximum number of retries
+ // specified by the protection manager, we'll give up.
+ int num_retries_;
+
+ friend class URLFetcher;
+ DISALLOW_EVIL_CONSTRUCTORS(Core);
+ };
+
+ scoped_refptr<Core> core_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(URLFetcher);
+};
+
+#endif // CHROME_BROWSER_URL_FETCHER_H__