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); }); }
/* 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); } }