Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: ppapi/shared_impl/url_request_info_impl.cc

Issue 7706021: Convert FileRefImpl and URLRequestInfo to shared_impl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor fixes Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "ppapi/shared_impl/url_request_info_impl.h"
6
7 #include "base/string_util.h"
8 #include "ppapi/shared_impl/var.h"
9 #include "ppapi/thunk/enter.h"
10 #include "ppapi/thunk/ppb_file_ref_api.h"
11
12 using ppapi::thunk::EnterResourceNoLock;
13
14 namespace ppapi {
15
16 namespace {
17
18 const int32_t kDefaultPrefetchBufferUpperThreshold = 100 * 1000 * 1000;
19 const int32_t kDefaultPrefetchBufferLowerThreshold = 50 * 1000 * 1000;
20
bbudge 2011/08/23 20:35:59 Just a heads up that Darin and I think this logic
21 // These methods are not allowed by the XMLHttpRequest standard.
22 // http://www.w3.org/TR/XMLHttpRequest/#the-open-method
23 const char* const kForbiddenHttpMethods[] = {
24 "connect",
25 "trace",
26 "track",
27 };
28
29 // These are the "known" methods in the Webkit XHR implementation. Also see
30 // the XMLHttpRequest standard.
31 // http://www.w3.org/TR/XMLHttpRequest/#the-open-method
32 const char* const kKnownHttpMethods[] = {
33 "get",
34 "post",
35 "put",
36 "head",
37 "copy",
38 "delete",
39 "index",
40 "lock",
41 "m-post",
42 "mkcol",
43 "move",
44 "options",
45 "propfind",
46 "proppatch",
47 "unlock",
48 };
49
50 bool IsValidToken(const std::string& token) {
51 size_t length = token.size();
52 if (length == 0)
53 return false;
54
55 for (size_t i = 0; i < length; i++) {
56 char c = token[i];
57 if (c >= 127 || c <= 32)
58 return false;
59 if (c == '(' || c == ')' || c == '<' || c == '>' || c == '@' ||
60 c == ',' || c == ';' || c == ':' || c == '\\' || c == '\"' ||
61 c == '/' || c == '[' || c == ']' || c == '?' || c == '=' ||
62 c == '{' || c == '}')
63 return false;
64 }
65 return true;
66 }
67
68 } // namespace
69
70 PPB_URLRequestInfo_Data::BodyItem::BodyItem()
71 : is_file(false),
72 start_offset(0),
73 number_of_bytes(-1),
74 expected_last_modified_time(0.0) {
75 }
76
77 PPB_URLRequestInfo_Data::BodyItem::BodyItem(const std::string& data)
78 : is_file(false),
79 data(data),
80 start_offset(0),
81 number_of_bytes(-1),
82 expected_last_modified_time(0.0) {
83 }
84
85 PPB_URLRequestInfo_Data::BodyItem::BodyItem(
86 Resource* file_ref,
87 int64_t start_offset,
88 int64_t number_of_bytes,
89 PP_Time expected_last_modified_time)
90 : is_file(true),
91 file_ref(file_ref),
92 file_ref_host_resource(file_ref->host_resource()),
93 start_offset(start_offset),
94 number_of_bytes(number_of_bytes),
95 expected_last_modified_time(expected_last_modified_time) {
96 }
97
98 PPB_URLRequestInfo_Data::PPB_URLRequestInfo_Data()
99 : url(),
100 method(),
101 headers(),
bbudge 2011/08/23 20:35:59 Do you really have to have these default construct
brettw 2011/08/24 23:41:09 No, but there were so many initializers I found it
102 stream_to_file(false),
103 follow_redirects(false),
104 record_download_progress(false),
105 record_upload_progress(false),
106 has_custom_referrer_url(false),
107 custom_referrer_url(),
108 allow_cross_origin_requests(false),
109 allow_credentials(false),
110 has_custom_content_transfer_encoding(false),
111 custom_content_transfer_encoding(),
112 prefetch_buffer_upper_threshold(kDefaultPrefetchBufferUpperThreshold),
113 prefetch_buffer_lower_threshold(kDefaultPrefetchBufferLowerThreshold),
114 body() {
115 }
116
117 PPB_URLRequestInfo_Data::~PPB_URLRequestInfo_Data() {
118 }
119
120 URLRequestInfoImpl::URLRequestInfoImpl(PP_Instance instance,
121 const PPB_URLRequestInfo_Data& data)
bbudge 2011/08/23 20:35:59 Alignment with prev param.
122 : Resource(instance),
123 data_(data) {
124 }
125
126 URLRequestInfoImpl::URLRequestInfoImpl(const HostResource& host_resource,
127 const PPB_URLRequestInfo_Data& data)
bbudge 2011/08/23 20:35:59 Alignment.
128 : Resource(host_resource),
129 data_(data) {
130 }
131
132 URLRequestInfoImpl::~URLRequestInfoImpl() {
133 }
134
135 thunk::PPB_URLRequestInfo_API* URLRequestInfoImpl::AsPPB_URLRequestInfo_API() {
136 return this;
137 }
138
139 PP_Bool URLRequestInfoImpl::SetProperty(PP_URLRequestProperty property,
140 PP_Var var) {
141 // IMPORTANT: Do not do security validation of parameters at this level
142 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. This
143 // code is used both in the plugin (which we don't trust) and in the renderer
144 // (which we trust more). When running out-of-process, the plugin calls this
145 // function to configure the PPB_URLRequestInfo_Data, which is then sent to
146 // the renderer and *not* run through SetProperty again.
147 //
148 // This means that anything in the PPB_URLRequestInfo_Data needs to be
149 // validated at the time the URL is requested (which is what ValidateData
150 // does). If your feature requires security checks, it should be in the
151 // implementation in the renderer when the WebKit request is actually
152 // constructed.
153 //
154 // It is legal to do some validation here if you want to report failure to
155 // the plugin as a convenience, as long as you also do it in the renderer
156 // later.
157 PP_Bool result = PP_FALSE;
158 switch (var.type) {
159 case PP_VARTYPE_UNDEFINED:
160 result = PP_FromBool(SetUndefinedProperty(property));
161 break;
162 case PP_VARTYPE_BOOL:
163 result = PP_FromBool(
164 SetBooleanProperty(property, PP_ToBool(var.value.as_bool)));
165 break;
166 case PP_VARTYPE_INT32:
167 result = PP_FromBool(
168 SetIntegerProperty(property, var.value.as_int));
169 break;
170 case PP_VARTYPE_STRING: {
171 StringVar* string = StringVar::FromPPVar(var);
172 if (string)
173 result = PP_FromBool(SetStringProperty(property, string->value()));
174 break;
175 }
176 default:
177 break;
178 }
179 return result;
180 }
181
182 PP_Bool URLRequestInfoImpl::AppendDataToBody(const void* data, uint32_t len) {
183 if (len > 0) {
184 data_.body.push_back(PPB_URLRequestInfo_Data::BodyItem(
185 std::string(static_cast<const char*>(data), len)));
186 }
187 return PP_TRUE;
188 }
189
190 PP_Bool URLRequestInfoImpl::AppendFileToBody(
191 PP_Resource file_ref,
192 int64_t start_offset,
193 int64_t number_of_bytes,
194 PP_Time expected_last_modified_time) {
195 EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref, true);
196 if (enter.failed())
197 return PP_FALSE;
198
199 // Ignore a call to append nothing.
200 if (number_of_bytes == 0)
201 return PP_TRUE;
202
203 // Check for bad values. (-1 means read until end of file.)
204 if (start_offset < 0 || number_of_bytes < -1)
205 return PP_FALSE;
206
207 data_.body.push_back(PPB_URLRequestInfo_Data::BodyItem(
208 enter.resource(),
209 start_offset,
210 number_of_bytes,
211 expected_last_modified_time));
212 return PP_TRUE;
213 }
214
215 const PPB_URLRequestInfo_Data& URLRequestInfoImpl::GetData() const {
216 return data_;
217 }
218
219 // static
220 std::string URLRequestInfoImpl::ValidateMethod(const std::string& method) {
221 if (!IsValidToken(method))
222 return std::string();
223
224 for (size_t i = 0; i < arraysize(kForbiddenHttpMethods); ++i) {
225 if (LowerCaseEqualsASCII(method, kForbiddenHttpMethods[i]))
226 return std::string();
227 }
228 for (size_t i = 0; i < arraysize(kKnownHttpMethods); ++i) {
229 if (LowerCaseEqualsASCII(method, kKnownHttpMethods[i])) {
230 // Convert the method name to upper case to match Webkit and Firefox's
231 // XHR implementation.
232 return StringToUpperASCII(std::string(kKnownHttpMethods[i]));
233 }
234 }
235 // Pass through unknown methods that are not forbidden.
236 return method;
237 }
238
239 bool URLRequestInfoImpl::SetUndefinedProperty(PP_URLRequestProperty property) {
240 // IMPORTANT: Do not do security validation of parameters at this level
241 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
242 // SetProperty() above for why.
243 switch (property) {
244 case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL:
245 data_.has_custom_referrer_url = false;
246 data_.custom_referrer_url = std::string();
247 return true;
248 case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING:
249 data_.has_custom_content_transfer_encoding = false;
250 data_.custom_content_transfer_encoding = std::string();
251 return true;
252 default:
253 return false;
254 }
255 }
256
257 bool URLRequestInfoImpl::SetBooleanProperty(PP_URLRequestProperty property,
258 bool value) {
259 // IMPORTANT: Do not do security validation of parameters at this level
260 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
261 // SetProperty() above for why.
262 switch (property) {
263 case PP_URLREQUESTPROPERTY_STREAMTOFILE:
264 data_.stream_to_file = value;
265 return true;
266 case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS:
267 data_.follow_redirects = value;
268 return true;
269 case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS:
270 data_.record_download_progress = value;
271 return true;
272 case PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS:
273 data_.record_upload_progress = value;
274 return true;
275 case PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS:
276 data_.allow_cross_origin_requests = value;
277 return true;
278 case PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS:
279 data_.allow_credentials = value;
280 return true;
281 default:
282 return false;
283 }
284 }
285
286 bool URLRequestInfoImpl::SetIntegerProperty(PP_URLRequestProperty property,
287 int32_t value) {
288 // IMPORTANT: Do not do security validation of parameters at this level
289 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
290 // SetProperty() above for why.
291 switch (property) {
292 case PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD:
293 data_.prefetch_buffer_upper_threshold = value;
294 return true;
295 case PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD:
296 data_.prefetch_buffer_lower_threshold = value;
297 return true;
298 default:
299 return false;
300 }
301 }
302
303 bool URLRequestInfoImpl::SetStringProperty(PP_URLRequestProperty property,
304 const std::string& value) {
305 // IMPORTANT: Do not do security validation of parameters at this level
306 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
307 // SetProperty() above for why.
308 switch (property) {
309 case PP_URLREQUESTPROPERTY_URL:
310 data_.url = value; // NOTE: This may be a relative URL.
311 return true;
312 case PP_URLREQUESTPROPERTY_METHOD: {
313 // Convenience check for synchronously returning errors to the plugin.
314 // This is re-checked in ValidateData.
315 std::string canonicalized = ValidateMethod(value);
316 if (canonicalized.empty())
317 return false;
318 data_.method = canonicalized;
319 return true;
320 }
321 case PP_URLREQUESTPROPERTY_HEADERS:
322 data_.headers = value;
323 return true;
324 case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL:
325 data_.has_custom_referrer_url = true;
326 data_.custom_referrer_url = value;
327 return true;
328 case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING:
329 data_.has_custom_content_transfer_encoding = true;
330 data_.custom_content_transfer_encoding = value;
331 return true;
332 default:
333 return false;
334 }
335 }
336
337 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698