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 14 URLRequestInfoResource::URLRequestInfoResource(Connection connection, 15 PP_Instance instance, 16 const URLRequestInfoData& data) 17 : PluginResource(connection, instance), 18 data_(data) { 19 } 20 21 URLRequestInfoResource::~URLRequestInfoResource() { 22 } 23 24 thunk::PPB_URLRequestInfo_API* 25 URLRequestInfoResource::AsPPB_URLRequestInfo_API() { 26 return this; 27 } 28 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 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 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 106 const URLRequestInfoData& URLRequestInfoResource::GetData() const { 107 return data_; 108 } 109 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 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 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 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