OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 "webkit/glue/plugins/pepper_url_request_info.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/string_util.h" | |
9 #include "googleurl/src/gurl.h" | |
10 #include "net/http/http_util.h" | |
11 #include "ppapi/c/pp_var.h" | |
12 #include "third_party/WebKit/WebKit/chromium/public/WebData.h" | |
13 #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" | |
14 #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" | |
15 #include "third_party/WebKit/WebKit/chromium/public/WebHTTPBody.h" | |
16 #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" | |
17 #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" | |
18 #include "webkit/glue/plugins/pepper_common.h" | |
19 #include "webkit/glue/plugins/pepper_file_ref.h" | |
20 #include "webkit/glue/plugins/pepper_plugin_module.h" | |
21 #include "webkit/glue/plugins/pepper_string.h" | |
22 #include "webkit/glue/plugins/pepper_var.h" | |
23 #include "webkit/glue/webkit_glue.h" | |
24 | |
25 using WebKit::WebData; | |
26 using WebKit::WebHTTPBody; | |
27 using WebKit::WebString; | |
28 using WebKit::WebFrame; | |
29 using WebKit::WebURL; | |
30 using WebKit::WebURLRequest; | |
31 | |
32 namespace pepper { | |
33 | |
34 namespace { | |
35 | |
36 // If any of these request headers are specified, they will not be sent. | |
37 // TODO(darin): Add more based on security considerations? | |
38 const char* const kIgnoredRequestHeaders[] = { | |
39 "content-length" | |
40 }; | |
41 | |
42 PP_Bool IsIgnoredRequestHeader(const std::string& name) { | |
43 for (size_t i = 0; i < arraysize(kIgnoredRequestHeaders); ++i) { | |
44 if (LowerCaseEqualsASCII(name, kIgnoredRequestHeaders[i])) | |
45 return PP_TRUE; | |
46 } | |
47 return PP_FALSE; | |
48 } | |
49 | |
50 PP_Resource Create(PP_Module module_id) { | |
51 PluginModule* module = ResourceTracker::Get()->GetModule(module_id); | |
52 if (!module) | |
53 return 0; | |
54 | |
55 URLRequestInfo* request = new URLRequestInfo(module); | |
56 | |
57 return request->GetReference(); | |
58 } | |
59 | |
60 PP_Bool IsURLRequestInfo(PP_Resource resource) { | |
61 return BoolToPPBool(!!Resource::GetAs<URLRequestInfo>(resource)); | |
62 } | |
63 | |
64 PP_Bool SetProperty(PP_Resource request_id, | |
65 PP_URLRequestProperty property, | |
66 PP_Var var) { | |
67 scoped_refptr<URLRequestInfo> request( | |
68 Resource::GetAs<URLRequestInfo>(request_id)); | |
69 if (!request) | |
70 return PP_FALSE; | |
71 | |
72 if (var.type == PP_VARTYPE_BOOL) { | |
73 return BoolToPPBool( | |
74 request->SetBooleanProperty(property, | |
75 PPBoolToBool(var.value.as_bool))); | |
76 } | |
77 | |
78 if (var.type == PP_VARTYPE_STRING) { | |
79 scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); | |
80 if (string) { | |
81 return BoolToPPBool(request->SetStringProperty(property, | |
82 string->value())); | |
83 } | |
84 } | |
85 | |
86 return PP_FALSE; | |
87 } | |
88 | |
89 PP_Bool AppendDataToBody(PP_Resource request_id, | |
90 const char* data, | |
91 uint32_t len) { | |
92 scoped_refptr<URLRequestInfo> request( | |
93 Resource::GetAs<URLRequestInfo>(request_id)); | |
94 if (!request) | |
95 return PP_FALSE; | |
96 | |
97 return BoolToPPBool(request->AppendDataToBody(std::string(data, len))); | |
98 } | |
99 | |
100 PP_Bool AppendFileToBody(PP_Resource request_id, | |
101 PP_Resource file_ref_id, | |
102 int64_t start_offset, | |
103 int64_t number_of_bytes, | |
104 PP_Time expected_last_modified_time) { | |
105 scoped_refptr<URLRequestInfo> request( | |
106 Resource::GetAs<URLRequestInfo>(request_id)); | |
107 if (!request) | |
108 return PP_FALSE; | |
109 | |
110 scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); | |
111 if (!file_ref) | |
112 return PP_FALSE; | |
113 | |
114 return BoolToPPBool(request->AppendFileToBody(file_ref, | |
115 start_offset, | |
116 number_of_bytes, | |
117 expected_last_modified_time)); | |
118 } | |
119 | |
120 const PPB_URLRequestInfo ppb_urlrequestinfo = { | |
121 &Create, | |
122 &IsURLRequestInfo, | |
123 &SetProperty, | |
124 &AppendDataToBody, | |
125 &AppendFileToBody | |
126 }; | |
127 | |
128 } // namespace | |
129 | |
130 struct URLRequestInfo::BodyItem { | |
131 BodyItem(const std::string& data) | |
132 : data(data), | |
133 start_offset(0), | |
134 number_of_bytes(-1), | |
135 expected_last_modified_time(0.0) { | |
136 } | |
137 | |
138 BodyItem(FileRef* file_ref, | |
139 int64_t start_offset, | |
140 int64_t number_of_bytes, | |
141 PP_Time expected_last_modified_time) | |
142 : file_ref(file_ref), | |
143 start_offset(start_offset), | |
144 number_of_bytes(number_of_bytes), | |
145 expected_last_modified_time(expected_last_modified_time) { | |
146 } | |
147 | |
148 std::string data; | |
149 scoped_refptr<FileRef> file_ref; | |
150 int64_t start_offset; | |
151 int64_t number_of_bytes; | |
152 PP_Time expected_last_modified_time; | |
153 }; | |
154 | |
155 URLRequestInfo::URLRequestInfo(PluginModule* module) | |
156 : Resource(module), | |
157 stream_to_file_(false), | |
158 follow_redirects_(true), | |
159 record_download_progress_(false), | |
160 record_upload_progress_(false) { | |
161 } | |
162 | |
163 URLRequestInfo::~URLRequestInfo() { | |
164 } | |
165 | |
166 // static | |
167 const PPB_URLRequestInfo* URLRequestInfo::GetInterface() { | |
168 return &ppb_urlrequestinfo; | |
169 } | |
170 | |
171 URLRequestInfo* URLRequestInfo::AsURLRequestInfo() { | |
172 return this; | |
173 } | |
174 | |
175 bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty property, | |
176 bool value) { | |
177 switch (property) { | |
178 case PP_URLREQUESTPROPERTY_STREAMTOFILE: | |
179 stream_to_file_ = value; | |
180 return true; | |
181 case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS: | |
182 follow_redirects_ = value; | |
183 return true; | |
184 case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS: | |
185 record_download_progress_ = value; | |
186 return true; | |
187 case PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS: | |
188 record_upload_progress_ = value; | |
189 return true; | |
190 default: | |
191 //NOTIMPLEMENTED(); // TODO(darin): Implement me! | |
192 return false; | |
193 } | |
194 } | |
195 | |
196 bool URLRequestInfo::SetStringProperty(PP_URLRequestProperty property, | |
197 const std::string& value) { | |
198 // TODO(darin): Validate input. Perhaps at a different layer? | |
199 switch (property) { | |
200 case PP_URLREQUESTPROPERTY_URL: | |
201 url_ = value; // NOTE: This may be a relative URL. | |
202 return true; | |
203 case PP_URLREQUESTPROPERTY_METHOD: | |
204 method_ = value; | |
205 return true; | |
206 case PP_URLREQUESTPROPERTY_HEADERS: | |
207 headers_ = value; | |
208 return true; | |
209 default: | |
210 return false; | |
211 } | |
212 } | |
213 | |
214 bool URLRequestInfo::AppendDataToBody(const std::string& data) { | |
215 if (!data.empty()) | |
216 body_.push_back(BodyItem(data)); | |
217 return true; | |
218 } | |
219 | |
220 bool URLRequestInfo::AppendFileToBody(FileRef* file_ref, | |
221 int64_t start_offset, | |
222 int64_t number_of_bytes, | |
223 PP_Time expected_last_modified_time) { | |
224 // Ignore a call to append nothing. | |
225 if (number_of_bytes == 0) | |
226 return true; | |
227 | |
228 // Check for bad values. (-1 means read until end of file.) | |
229 if (start_offset < 0 || number_of_bytes < -1) | |
230 return false; | |
231 | |
232 body_.push_back(BodyItem(file_ref, | |
233 start_offset, | |
234 number_of_bytes, | |
235 expected_last_modified_time)); | |
236 return true; | |
237 } | |
238 | |
239 WebURLRequest URLRequestInfo::ToWebURLRequest(WebFrame* frame) const { | |
240 WebURLRequest web_request; | |
241 web_request.initialize(); | |
242 web_request.setURL(frame->document().completeURL(WebString::fromUTF8(url_))); | |
243 web_request.setDownloadToFile(stream_to_file_); | |
244 | |
245 if (!method_.empty()) | |
246 web_request.setHTTPMethod(WebString::fromUTF8(method_)); | |
247 | |
248 if (!headers_.empty()) { | |
249 net::HttpUtil::HeadersIterator it(headers_.begin(), headers_.end(), "\n"); | |
250 while (it.GetNext()) { | |
251 if (!IsIgnoredRequestHeader(it.name())) { | |
252 web_request.addHTTPHeaderField( | |
253 WebString::fromUTF8(it.name()), | |
254 WebString::fromUTF8(it.values())); | |
255 } | |
256 } | |
257 } | |
258 | |
259 if (!body_.empty()) { | |
260 WebHTTPBody http_body; | |
261 http_body.initialize(); | |
262 for (size_t i = 0; i < body_.size(); ++i) { | |
263 if (body_[i].file_ref) { | |
264 http_body.appendFileRange( | |
265 webkit_glue::FilePathToWebString( | |
266 body_[i].file_ref->GetSystemPath()), | |
267 body_[i].start_offset, | |
268 body_[i].number_of_bytes, | |
269 body_[i].expected_last_modified_time); | |
270 } else { | |
271 DCHECK(!body_[i].data.empty()); | |
272 http_body.appendData(WebData(body_[i].data)); | |
273 } | |
274 } | |
275 web_request.setHTTPBody(http_body); | |
276 } | |
277 | |
278 frame->setReferrerForRequest(web_request, WebURL()); // Use default. | |
279 return web_request; | |
280 } | |
281 | |
282 } // namespace pepper | |
OLD | NEW |