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