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 "ppapi/proxy/url_request_info_resource.h"
6
7 #include "ppapi/shared_impl/var.h"
8 #include "ppapi/thunk/enter.h"
9 #include "ppapi/thunk/ppb_file_ref_api.h"
10
11 namespace ppapi {
12 namespace proxy {
13
URLRequestInfoResource(Connection connection,PP_Instance instance,const URLRequestInfoData & data)14 URLRequestInfoResource::URLRequestInfoResource(Connection connection,
15 PP_Instance instance,
16 const URLRequestInfoData& data)
17 : PluginResource(connection, instance),
18 data_(data) {
19 }
20
~URLRequestInfoResource()21 URLRequestInfoResource::~URLRequestInfoResource() {
22 }
23
24 thunk::PPB_URLRequestInfo_API*
AsPPB_URLRequestInfo_API()25 URLRequestInfoResource::AsPPB_URLRequestInfo_API() {
26 return this;
27 }
28
SetProperty(PP_URLRequestProperty property,PP_Var var)29 PP_Bool URLRequestInfoResource::SetProperty(PP_URLRequestProperty property,
30 PP_Var var) {
31 // IMPORTANT: Do not do security validation of parameters at this level
32 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. This
33 // code is used both in the plugin (which we don't trust) and in the renderer
34 // (which we trust more). When running out-of-process, the plugin calls this
35 // function to configure the URLRequestInfoData, which is then sent to
36 // the renderer and *not* run through SetProperty again.
37 //
38 // This means that anything in the PPB_URLRequestInfo_Data needs to be
39 // validated at the time the URL is requested (which is what ValidateData
40 // does). If your feature requires security checks, it should be in the
41 // implementation in the renderer when the WebKit request is actually
42 // constructed.
43 //
44 // It is legal to do some validation here if you want to report failure to
45 // the plugin as a convenience, as long as you also do it in the renderer
46 // later.
47 PP_Bool result = PP_FALSE;
48 switch (var.type) {
49 case PP_VARTYPE_UNDEFINED:
50 result = PP_FromBool(SetUndefinedProperty(property));
51 break;
52 case PP_VARTYPE_BOOL:
53 result = PP_FromBool(
54 SetBooleanProperty(property, PP_ToBool(var.value.as_bool)));
55 break;
56 case PP_VARTYPE_INT32:
57 result = PP_FromBool(
58 SetIntegerProperty(property, var.value.as_int));
59 break;
60 case PP_VARTYPE_STRING: {
61 StringVar* string = StringVar::FromPPVar(var);
62 if (string)
63 result = PP_FromBool(SetStringProperty(property, string->value()));
64 break;
65 }
66 default:
67 break;
68 }
69 return result;
70 }
71
AppendDataToBody(const void * data,uint32_t len)72 PP_Bool URLRequestInfoResource::AppendDataToBody(const void* data,
73 uint32_t len) {
74 if (len > 0) {
75 data_.body.push_back(URLRequestInfoData::BodyItem(
76 std::string(static_cast<const char*>(data), len)));
77 }
78 return PP_TRUE;
79 }
80
AppendFileToBody(PP_Resource file_ref,int64_t start_offset,int64_t number_of_bytes,PP_Time expected_last_modified_time)81 PP_Bool URLRequestInfoResource::AppendFileToBody(
82 PP_Resource file_ref,
83 int64_t start_offset,
84 int64_t number_of_bytes,
85 PP_Time expected_last_modified_time) {
86 thunk::EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref, true);
87 if (enter.failed())
88 return PP_FALSE;
89
90 // Ignore a call to append nothing.
91 if (number_of_bytes == 0)
92 return PP_TRUE;
93
94 // Check for bad values. (-1 means read until end of file.)
95 if (start_offset < 0 || number_of_bytes < -1)
96 return PP_FALSE;
97
98 data_.body.push_back(URLRequestInfoData::BodyItem(
99 enter.resource(),
100 start_offset,
101 number_of_bytes,
102 expected_last_modified_time));
103 return PP_TRUE;
104 }
105
GetData() const106 const URLRequestInfoData& URLRequestInfoResource::GetData() const {
107 return data_;
108 }
109
SetUndefinedProperty(PP_URLRequestProperty property)110 bool URLRequestInfoResource::SetUndefinedProperty(
111 PP_URLRequestProperty property) {
112 // IMPORTANT: Do not do security validation of parameters at this level
113 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
114 // SetProperty() above for why.
115 switch (property) {
116 case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL:
117 data_.has_custom_referrer_url = false;
118 data_.custom_referrer_url = std::string();
119 return true;
120 case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING:
121 data_.has_custom_content_transfer_encoding = false;
122 data_.custom_content_transfer_encoding = std::string();
123 return true;
124 case PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT:
125 data_.has_custom_user_agent = false;
126 data_.custom_user_agent = std::string();
127 return true;
128 default:
129 return false;
130 }
131 }
132
SetBooleanProperty(PP_URLRequestProperty property,bool value)133 bool URLRequestInfoResource::SetBooleanProperty(
134 PP_URLRequestProperty property,
135 bool value) {
136 // IMPORTANT: Do not do security validation of parameters at this level
137 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
138 // SetProperty() above for why.
139 switch (property) {
140 case PP_URLREQUESTPROPERTY_STREAMTOFILE:
141 data_.stream_to_file = value;
142 return true;
143 case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS:
144 data_.follow_redirects = value;
145 return true;
146 case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS:
147 data_.record_download_progress = value;
148 return true;
149 case PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS:
150 data_.record_upload_progress = value;
151 return true;
152 case PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS:
153 data_.allow_cross_origin_requests = value;
154 return true;
155 case PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS:
156 data_.allow_credentials = value;
157 return true;
158 default:
159 return false;
160 }
161 }
162
SetIntegerProperty(PP_URLRequestProperty property,int32_t value)163 bool URLRequestInfoResource::SetIntegerProperty(
164 PP_URLRequestProperty property,
165 int32_t value) {
166 // IMPORTANT: Do not do security validation of parameters at this level
167 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
168 // SetProperty() above for why.
169 switch (property) {
170 case PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD:
171 data_.prefetch_buffer_upper_threshold = value;
172 return true;
173 case PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD:
174 data_.prefetch_buffer_lower_threshold = value;
175 return true;
176 default:
177 return false;
178 }
179 }
180
SetStringProperty(PP_URLRequestProperty property,const std::string & value)181 bool URLRequestInfoResource::SetStringProperty(
182 PP_URLRequestProperty property,
183 const std::string& value) {
184 // IMPORTANT: Do not do security validation of parameters at this level
185 // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See
186 // SetProperty() above for why.
187 switch (property) {
188 case PP_URLREQUESTPROPERTY_URL:
189 data_.url = value; // NOTE: This may be a relative URL.
190 return true;
191 case PP_URLREQUESTPROPERTY_METHOD:
192 data_.method = value;
193 return true;
194 case PP_URLREQUESTPROPERTY_HEADERS:
195 data_.headers = value;
196 return true;
197 case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL:
198 data_.has_custom_referrer_url = true;
199 data_.custom_referrer_url = value;
200 return true;
201 case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING:
202 data_.has_custom_content_transfer_encoding = true;
203 data_.custom_content_transfer_encoding = value;
204 return true;
205 case PP_URLREQUESTPROPERTY_CUSTOMUSERAGENT:
206 data_.has_custom_user_agent = true;
207 data_.custom_user_agent = value;
208 return true;
209 default:
210 return false;
211 }
212 }
213
214 } // namespace proxy
215 } // namespace ppapi
216