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