Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / renderer / fetchers / resource_fetcher_impl.cc
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/strings/string_util.h"
9 #include "base/time/time.h"
10 #include "third_party/WebKit/public/platform/Platform.h"
11 #include "third_party/WebKit/public/platform/WebHTTPBody.h"
12 #include "third_party/WebKit/public/platform/WebURL.h"
13 #include "third_party/WebKit/public/platform/WebURLError.h"
14 #include "third_party/WebKit/public/platform/WebURLLoader.h"
15 #include "third_party/WebKit/public/platform/WebURLRequest.h"
16 #include "third_party/WebKit/public/web/WebDocument.h"
17 #include "third_party/WebKit/public/web/WebFrame.h"
18 #include "third_party/WebKit/public/web/WebKit.h"
19 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
20
21 using base::TimeDelta;
22 using blink::WebFrame;
23 using blink::WebHTTPBody;
24 using blink::WebSecurityPolicy;
25 using blink::WebURLError;
26 using blink::WebURLLoader;
27 using blink::WebURLRequest;
28 using blink::WebURLResponse;
29
30 namespace content {
31
32 // static
33 ResourceFetcher* ResourceFetcher::Create(const GURL& url) {
34   return new ResourceFetcherImpl(url);
35 }
36
37 ResourceFetcherImpl::ResourceFetcherImpl(const GURL& url)
38     : request_(url),
39       completed_(false) {
40 }
41
42 ResourceFetcherImpl::~ResourceFetcherImpl() {
43   if (!completed_ && loader_)
44     loader_->cancel();
45 }
46
47 void ResourceFetcherImpl::SetMethod(const std::string& method) {
48   DCHECK(!request_.isNull());
49   DCHECK(!loader_);
50
51   request_.setHTTPMethod(blink::WebString::fromUTF8(method));
52 }
53
54 void ResourceFetcherImpl::SetBody(const std::string& body) {
55   DCHECK(!request_.isNull());
56   DCHECK(!loader_);
57
58   WebHTTPBody web_http_body;
59   web_http_body.initialize();
60   web_http_body.appendData(blink::WebData(body));
61   request_.setHTTPBody(web_http_body);
62 }
63
64 void ResourceFetcherImpl::SetHeader(const std::string& header,
65                                     const std::string& value) {
66   DCHECK(!request_.isNull());
67   DCHECK(!loader_);
68
69   if (LowerCaseEqualsASCII(header, "referer")) {
70     blink::WebString referrer = WebSecurityPolicy::generateReferrerHeader(
71         blink::WebReferrerPolicyDefault,
72         request_.url(),
73         blink::WebString::fromUTF8(value));
74     request_.setHTTPReferrer(referrer, blink::WebReferrerPolicyDefault);
75   } else {
76     request_.setHTTPHeaderField(blink::WebString::fromUTF8(header),
77                                 blink::WebString::fromUTF8(value));
78   }
79 }
80
81 void ResourceFetcherImpl::Start(WebFrame* frame,
82                                 WebURLRequest::TargetType target_type,
83                                 const Callback& callback) {
84   DCHECK(!loader_);
85   DCHECK(!request_.isNull());
86   DCHECK(callback_.is_null());
87   DCHECK(!completed_);
88   if (!request_.httpBody().isNull())
89     DCHECK_NE("GET", request_.httpMethod().utf8()) << "GETs can't have bodies.";
90
91   callback_ = callback;
92
93   request_.setTargetType(target_type);
94   request_.setFirstPartyForCookies(frame->document().firstPartyForCookies());
95   frame->dispatchWillSendRequest(request_);
96   loader_.reset(blink::Platform::current()->createURLLoader());
97   loader_->loadAsynchronously(request_, this);
98
99   // No need to hold on to the request.
100   request_.reset();
101 }
102
103 void ResourceFetcherImpl::SetTimeout(const base::TimeDelta& timeout) {
104   DCHECK(loader_);
105   DCHECK(!completed_);
106
107   timeout_timer_.Start(FROM_HERE, timeout, this,
108                        &ResourceFetcherImpl::TimeoutFired);
109 }
110
111 void ResourceFetcherImpl::RunCallback(const WebURLResponse& response,
112                                       const std::string& data) {
113   completed_ = true;
114   timeout_timer_.Stop();
115   if (callback_.is_null())
116     return;
117
118   // Take a reference to the callback as running the callback may lead to our
119   // destruction.
120   Callback callback = callback_;
121   callback.Run(response, data);
122 }
123
124 void ResourceFetcherImpl::TimeoutFired() {
125   DCHECK(!completed_);
126   loader_->cancel();
127   RunCallback(WebURLResponse(), std::string());
128 }
129
130 /////////////////////////////////////////////////////////////////////////////
131 // WebURLLoaderClient methods
132
133 void ResourceFetcherImpl::willSendRequest(
134     WebURLLoader* loader, WebURLRequest& new_request,
135     const WebURLResponse& redirect_response) {
136 }
137
138 void ResourceFetcherImpl::didSendData(
139     WebURLLoader* loader, unsigned long long bytes_sent,
140     unsigned long long total_bytes_to_be_sent) {
141 }
142
143 void ResourceFetcherImpl::didReceiveResponse(
144     WebURLLoader* loader, const WebURLResponse& response) {
145   DCHECK(!completed_);
146   response_ = response;
147 }
148
149 void ResourceFetcherImpl::didReceiveData(
150     WebURLLoader* loader, const char* data, int data_length,
151     int encoded_data_length) {
152   DCHECK(!completed_);
153   DCHECK(data_length > 0);
154
155   data_.append(data, data_length);
156 }
157
158 void ResourceFetcherImpl::didReceiveCachedMetadata(
159     WebURLLoader* loader, const char* data, int data_length) {
160   DCHECK(!completed_);
161   DCHECK(data_length > 0);
162
163   metadata_.assign(data, data_length);
164 }
165
166 void ResourceFetcherImpl::didFinishLoading(
167     WebURLLoader* loader, double finishTime,
168     int64_t total_encoded_data_length) {
169   DCHECK(!completed_);
170
171   RunCallback(response_, data_);
172 }
173
174 void ResourceFetcherImpl::didFail(WebURLLoader* loader,
175                                   const WebURLError& error) {
176   DCHECK(!completed_);
177
178   // Go ahead and tell our delegate that we're done.
179   RunCallback(WebURLResponse(), std::string());
180 }
181
182 }  // namespace content