示例#1
0
    pplx::task<void> cloud_client::upload_service_properties_base_async(const service_properties& properties, const service_properties_includes& includes, const request_options& modified_options, operation_context context, const pplx::cancellation_token& cancellation_token) const
    {
        protocol::service_properties_writer writer;
        concurrency::streams::istream stream(concurrency::streams::bytestream::open_istream(writer.write(properties, includes)));

        auto command = std::make_shared<core::storage_command<void>>(base_uri(), cancellation_token, modified_options.is_maximum_execution_time_customized());
        command->set_build_request(std::bind(protocol::set_service_properties, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        command->set_authentication_handler(authentication_handler());
        command->set_preprocess_response(std::bind(protocol::preprocess_response_void, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        return core::istream_descriptor::create(stream, false, std::numeric_limits<utility::size64_t>::max(), std::numeric_limits<utility::size64_t>::max(), command->get_cancellation_token()).then([command, context, modified_options, cancellation_token] (core::istream_descriptor request_body) -> pplx::task<void>
        {
            command->set_request_body(request_body);
            return core::executor<void>::execute_async(command, modified_options, context);
        });
    }
示例#2
0
/* Set the options on the Curl handle from a Request object. Takes each field
 * in the Request object and uses it to set the appropriate option on the Curl
 * handle.
 */
static void set_options_from_request(VALUE self, VALUE request) {
  struct curl_state* state = get_curl_state(self);
  CURL* curl = state->handle;

  ID    action                = Qnil;
  VALUE headers               = Qnil;
  VALUE url                   = Qnil;
  VALUE timeout               = Qnil;
  VALUE redirects             = Qnil;
  VALUE proxy                 = Qnil;
  VALUE proxy_type            = Qnil;
  VALUE credentials           = Qnil;
  VALUE ignore_content_length = Qnil;
  VALUE insecure              = Qnil;
  VALUE cacert                = Qnil;
  VALUE ssl_version           = Qnil;
  VALUE buffer_size           = Qnil;
  VALUE action_name           = rb_funcall(request, rb_intern("action"), 0);
  VALUE a_c_encoding          = rb_funcall(request, rb_intern("automatic_content_encoding"), 0);

  headers = rb_funcall(request, rb_intern("headers"), 0);
  if (RTEST(headers)) {
    if (rb_type(headers) != T_HASH) {
      rb_raise(rb_eArgError, "Headers must be passed in a hash.");
    }

    rb_hash_foreach(headers, each_http_header, self);
  }

  action = SYM2ID(action_name);
  if(rb_funcall(request, rb_intern("force_ipv4"), 0)) {
    curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
  }
  if (action == rb_intern("get")) {
    VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
    VALUE download_file = rb_funcall(request, rb_intern("file_name"), 0);

    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
    if (RTEST(data)) {
      set_request_body(state, data);
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
    }
    if (RTEST(download_file)) {
      state->download_file = open_file(download_file, "wb");
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, state->download_file);
    } else {
      state->download_file = NULL;
    }
  } else if (action == rb_intern("post") || action == rb_intern("put") || action == rb_intern("patch")) {
    VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
    VALUE filename = rb_funcall(request, rb_intern("file_name"), 0);
    VALUE multipart = rb_funcall(request, rb_intern("multipart"), 0);

    if (action == rb_intern("post")) {
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    } else if (action == rb_intern("put")) {
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
    } else if (action == rb_intern("patch")) {
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
    }
    
    if (RTEST(data) && !RTEST(multipart)) {
      if (action == rb_intern("post")) {
        curl_easy_setopt(curl, CURLOPT_POST, 1);
      }
      set_request_body(state, data);
    } else if (RTEST(filename) && !RTEST(multipart)) {
      set_chunked_encoding(state);
      set_request_body_file(state, filename);
    } else if (RTEST(multipart)) {
      if (action == rb_intern("post")) {
        if(RTEST(data) && RTEST(filename)) {
          if (rb_type(data) == T_HASH && rb_type(filename) == T_HASH) {
            rb_hash_foreach(data, formadd_values, self);
            rb_hash_foreach(filename, formadd_files, self);
          } else {
            rb_raise(rb_eArgError, "Data and Filename must be passed in a hash.");
          }
        }
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, state->post);
      } else {
         rb_raise(rb_eArgError, "Multipart PUT not supported");
      }

    } else {
      rb_raise(rb_eArgError, "Must provide either data or a filename when doing a PUT or POST");
    }

  // support for data passed with a DELETE request (e.g.: used by elasticsearch)
  } else if (action == rb_intern("delete")) {
      VALUE data = rb_funcall(request, rb_intern("upload_data"), 0);
      if (RTEST(data)) {
        long len = RSTRING_LEN(data);
        state->upload_buf = StringValuePtr(data);
        curl_easy_setopt(curl, CURLOPT_POST, 1);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, state->upload_buf);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
      }
      curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");

  } else if (action == rb_intern("head")) {
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
  } else {
    VALUE action_name = rb_funcall(request, rb_intern("action_name"), 0);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, StringValuePtr(action_name));
  }

  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error_buf);

  // Enable automatic content-encoding support via gzip/deflate if set in the request,
  // see https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html
  if(RTEST(a_c_encoding)) {
    #ifdef CURLOPT_ACCEPT_ENCODING
      curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
    #elif defined CURLOPT_ENCODING
      curl_easy_setopt(curl, CURLOPT_ENCODING, "");
    #else
      rb_raise(rb_eArgError,
        "The libcurl version installed doesn't support automatic content negotiation");
    #endif
  }
  
  url = rb_funcall(request, rb_intern("url"), 0);
  if (!RTEST(url)) {
    rb_raise(rb_eArgError, "Must provide a URL");
  }
  curl_easy_setopt(curl, CURLOPT_URL, StringValuePtr(url));
  
#ifdef CURLPROTO_HTTP
  // Security: do not allow Curl to go looking on gopher/SMTP etc.
  // Must prevent situations like this:
  // https://hackerone.com/reports/115748
  curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
  curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
#endif
    
  timeout = rb_funcall(request, rb_intern("timeout"), 0);
  if (RTEST(timeout)) {
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, FIX2INT(timeout));
  }

  timeout = rb_funcall(request, rb_intern("connect_timeout"), 0);
  if (RTEST(timeout)) {
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FIX2INT(timeout));
  }

  redirects = rb_funcall(request, rb_intern("max_redirects"), 0);
  if (RTEST(redirects)) {
    int r = FIX2INT(redirects);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, r == 0 ? 0 : 1);
    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, r);
  }

  proxy = rb_funcall(request, rb_intern("proxy"), 0);
  if (RTEST(proxy)) {
    curl_easy_setopt(curl, CURLOPT_PROXY, StringValuePtr(proxy));
  }

  proxy_type = rb_funcall(request, rb_intern("proxy_type"), 0);
  if (RTEST(proxy_type)) {
    curl_easy_setopt(curl, CURLOPT_PROXYTYPE, NUM2LONG(proxy_type));
  }

  credentials = rb_funcall(request, rb_intern("credentials"), 0);
  if (RTEST(credentials)) {
    VALUE auth_type = rb_funcall(request, rb_intern("auth_type"), 0);
    curl_easy_setopt(curl, CURLOPT_HTTPAUTH, NUM2LONG(auth_type));
    curl_easy_setopt(curl, CURLOPT_USERPWD, StringValuePtr(credentials));
  }

  ignore_content_length = rb_funcall(request, rb_intern("ignore_content_length"), 0);
  if (RTEST(ignore_content_length)) {
    curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1);
  }

  insecure = rb_funcall(request, rb_intern("insecure"), 0);
  if(RTEST(insecure)) {
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
  }

  ssl_version = rb_funcall(request, rb_intern("ssl_version"), 0);
  if(RTEST(ssl_version)) {
    VALUE ssl_version_str = rb_funcall(ssl_version, rb_intern("to_s"), 0);
    char* version = StringValuePtr(ssl_version_str);
    if(strcmp(version, "SSLv2") == 0) {
      curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv2);
    } else if(strcmp(version, "SSLv3") == 0) {
      curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
    } else if(strcmp(version, "TLSv1") == 0) {
      curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
    } else {
      rb_raise(eUnsupportedSSLVersion, "Unsupported SSL version: %s", version);
    }
  }

  cacert = rb_funcall(request, rb_intern("cacert"), 0);
  if(RTEST(cacert)) {
    curl_easy_setopt(curl, CURLOPT_CAINFO, StringValuePtr(cacert));
  }

  buffer_size = rb_funcall(request, rb_intern("buffer_size"), 0);
  if (RTEST(buffer_size)) {
     curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, NUM2LONG(buffer_size));
  }

  if(state->debug_file) {
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
    curl_easy_setopt(curl, CURLOPT_STDERR, state->debug_file);
  }
}