Home | History | Annotate | Download | only in proxy
      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