Home | History | Annotate | Download | only in fetchers
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/fetchers/resource_fetcher.h"
      6 
      7 #include "base/logging.h"
      8 #include "third_party/WebKit/public/platform/Platform.h"
      9 #include "third_party/WebKit/public/platform/WebURL.h"
     10 #include "third_party/WebKit/public/platform/WebURLError.h"
     11 #include "third_party/WebKit/public/platform/WebURLLoader.h"
     12 #include "third_party/WebKit/public/platform/WebURLRequest.h"
     13 #include "third_party/WebKit/public/web/WebDocument.h"
     14 #include "third_party/WebKit/public/web/WebFrame.h"
     15 #include "third_party/WebKit/public/web/WebKit.h"
     16 
     17 using base::TimeDelta;
     18 using WebKit::WebFrame;
     19 using WebKit::WebURLError;
     20 using WebKit::WebURLLoader;
     21 using WebKit::WebURLRequest;
     22 using WebKit::WebURLResponse;
     23 
     24 namespace content {
     25 
     26 ResourceFetcher::ResourceFetcher(const GURL& url, WebFrame* frame,
     27                                  WebURLRequest::TargetType target_type,
     28                                  const Callback& callback)
     29     : url_(url),
     30       target_type_(target_type),
     31       completed_(false),
     32       callback_(callback) {
     33   // Can't do anything without a frame.  However, delegate can be NULL (so we
     34   // can do a http request and ignore the results).
     35   DCHECK(frame);
     36   Start(frame);
     37 }
     38 
     39 ResourceFetcher::~ResourceFetcher() {
     40   if (!completed_ && loader_)
     41     loader_->cancel();
     42 }
     43 
     44 void ResourceFetcher::Cancel() {
     45   if (!completed_) {
     46     loader_->cancel();
     47     completed_ = true;
     48   }
     49 }
     50 
     51 void ResourceFetcher::Start(WebFrame* frame) {
     52   WebURLRequest request(url_);
     53   request.setTargetType(target_type_);
     54   request.setFirstPartyForCookies(frame->document().firstPartyForCookies());
     55   frame->dispatchWillSendRequest(request);
     56 
     57   loader_.reset(WebKit::Platform::current()->createURLLoader());
     58   loader_->loadAsynchronously(request, this);
     59 }
     60 
     61 void ResourceFetcher::RunCallback(const WebURLResponse& response,
     62                                   const std::string& data) {
     63   if (callback_.is_null())
     64     return;
     65 
     66   // Take a reference to the callback as running the callback may lead to our
     67   // destruction.
     68   Callback callback = callback_;
     69   callback.Run(response, data);
     70 }
     71 
     72 /////////////////////////////////////////////////////////////////////////////
     73 // WebURLLoaderClient methods
     74 
     75 void ResourceFetcher::willSendRequest(
     76     WebURLLoader* loader, WebURLRequest& new_request,
     77     const WebURLResponse& redirect_response) {
     78 }
     79 
     80 void ResourceFetcher::didSendData(
     81     WebURLLoader* loader, unsigned long long bytes_sent,
     82     unsigned long long total_bytes_to_be_sent) {
     83 }
     84 
     85 void ResourceFetcher::didReceiveResponse(
     86     WebURLLoader* loader, const WebURLResponse& response) {
     87   DCHECK(!completed_);
     88   response_ = response;
     89 }
     90 
     91 void ResourceFetcher::didReceiveData(
     92     WebURLLoader* loader, const char* data, int data_length,
     93     int encoded_data_length) {
     94   DCHECK(!completed_);
     95   DCHECK(data_length > 0);
     96 
     97   data_.append(data, data_length);
     98 }
     99 
    100 void ResourceFetcher::didReceiveCachedMetadata(
    101     WebURLLoader* loader, const char* data, int data_length) {
    102   DCHECK(!completed_);
    103   DCHECK(data_length > 0);
    104 
    105   metadata_.assign(data, data_length);
    106 }
    107 
    108 void ResourceFetcher::didFinishLoading(
    109     WebURLLoader* loader, double finishTime) {
    110   DCHECK(!completed_);
    111   completed_ = true;
    112 
    113   RunCallback(response_, data_);
    114 }
    115 
    116 void ResourceFetcher::didFail(WebURLLoader* loader, const WebURLError& error) {
    117   DCHECK(!completed_);
    118   completed_ = true;
    119 
    120   // Go ahead and tell our delegate that we're done.
    121   RunCallback(WebURLResponse(), std::string());
    122 }
    123 
    124 /////////////////////////////////////////////////////////////////////////////
    125 // A resource fetcher with a timeout
    126 
    127 ResourceFetcherWithTimeout::ResourceFetcherWithTimeout(
    128     const GURL& url, WebFrame* frame, WebURLRequest::TargetType target_type,
    129     int timeout_secs, const Callback& callback)
    130     : ResourceFetcher(url, frame, target_type, callback) {
    131   timeout_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(timeout_secs), this,
    132                        &ResourceFetcherWithTimeout::TimeoutFired);
    133 }
    134 
    135 ResourceFetcherWithTimeout::~ResourceFetcherWithTimeout() {
    136 }
    137 
    138 void ResourceFetcherWithTimeout::TimeoutFired() {
    139   if (!completed_) {
    140     loader_->cancel();
    141     didFail(NULL, WebURLError());
    142   }
    143 }
    144 
    145 }  // namespace content
    146