StringInfo rest_call_with_lock(char *method, char *url, char *params, StringInfo postData, int64 mutex, bool shared, bool allowCancel) { CURL *curl; struct curl_slist *headers = NULL; char *errorbuff; StringInfo response = makeStringInfo(); CURLcode ret; int64 response_code; errorbuff = (char *) palloc0(CURL_ERROR_SIZE); curl = curl_easy_init(); if (curl) { headers = curl_slist_append(headers, "Transfer-Encoding:"); headers = curl_slist_append(headers, "Expect:"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 0L); /* allow connections to be reused */ if (allowCancel) { curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); /* we want progress ... */ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress_func); /* to go here so we can detect a ^C within postgres */ } curl_easy_setopt(curl, CURLOPT_USERAGENT, "zombodb for PostgreSQL"); curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 0); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_func); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuff); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60 * 60L); /* timeout of 60 minutes */ curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData ? postData->len : 0); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData ? postData->data : NULL); curl_easy_setopt(curl, CURLOPT_POST, (strcmp(method, "POST") == 0) || (strcmp(method, "GET") != 0 && postData && postData->data) ? 1 : 0); } else { elog(IsTransactionState() ? ERROR : WARNING, "Unable to initialize libcurl"); } // if (mutex != 0) // { // if (shared) DirectFunctionCall1(pg_advisory_lock_shared_int8, Int64GetDatum(mutex)); // else DirectFunctionCall1(pg_advisory_lock_int8, Int64GetDatum(mutex)); // } ret = curl_easy_perform(curl); // if (mutex != 0) // { // if (shared) DirectFunctionCall1(pg_advisory_unlock_shared_int8, Int64GetDatum(mutex)); // else DirectFunctionCall1(pg_advisory_unlock_int8, Int64GetDatum(mutex)); // } if (allowCancel && IsTransactionState() && InterruptPending) { /* we might have detected one in the progress function, so check for sure */ CHECK_FOR_INTERRUPTS(); } if (ret != 0) { /* curl messed up */ elog(IsTransactionState() ? ERROR : WARNING, "libcurl error-code: %s(%d); message: %s; req=-X%s %s ", curl_easy_strerror(ret), ret, errorbuff, method, url); } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); if (response_code < 200 || (response_code >=300 && response_code != 404)) { text *errorText = DatumGetTextP(DirectFunctionCall2(json_object_field_text, CStringGetTextDatum(response->data), CStringGetTextDatum("error"))); elog(IsTransactionState() ? ERROR : WARNING, "rc=%ld; %s", response_code, errorText != NULL ? TextDatumGetCString(errorText) : response->data); } if (headers) curl_slist_free_all(headers); curl_easy_cleanup(curl); pfree(errorbuff); return response; }
static auth_result url_remove_listener (auth_client *auth_user) { client_t *client = auth_user->client; auth_url *url = auth_user->auth->state; auth_thread_data *atd = auth_user->thread_data; time_t now = time(NULL), duration = now - client->connection.con_time; char *username, *password, *mount, *server, *ipaddr, *user_agent; const char *qargs, *tmp; char *userpwd = NULL, post [4096]; if (url->removeurl == NULL || client == NULL) return AUTH_OK; if (url->stop_req_until) { if (url->stop_req_until >= now) return AUTH_FAILED; url->stop_req_until = 0; } server = util_url_escape (auth_user->hostname); if (client->username) username = util_url_escape (client->username); else username = strdup (""); if (client->password) password = util_url_escape (client->password); else password = strdup (""); tmp = httpp_getvar(client->parser, "user-agent"); if (tmp == NULL) tmp = "-"; user_agent = util_url_escape (tmp); /* get the full uri (with query params if available) */ qargs = httpp_getvar (client->parser, HTTPP_VAR_QUERYARGS); snprintf (post, sizeof post, "%s%s", auth_user->mount, qargs ? qargs : ""); mount = util_url_escape (post); ipaddr = util_url_escape (client->connection.ip); snprintf (post, sizeof (post), "action=listener_remove&server=%s&port=%d&client=%" PRIu64 "&mount=%s" "&user=%s&pass=%s&ip=%s&duration=%lu&agent=%s&sent=%" PRIu64, server, auth_user->port, client->connection.id, mount, username, password, ipaddr, (long unsigned)duration, user_agent, client->connection.sent_bytes); free (ipaddr); free (server); free (mount); free (username); free (password); free (user_agent); if (strchr (url->removeurl, '@') == NULL) { if (url->userpwd) curl_easy_setopt (atd->curl, CURLOPT_USERPWD, url->userpwd); else { /* auth'd requests may not have a user/pass, but may use query args */ if (client->username && client->password) { int len = strlen (client->username) + strlen (client->password) + 2; userpwd = malloc (len); snprintf (userpwd, len, "%s:%s", client->username, client->password); curl_easy_setopt (atd->curl, CURLOPT_USERPWD, userpwd); } else curl_easy_setopt (atd->curl, CURLOPT_USERPWD, ""); } } else { /* url has user/pass but libcurl may need to clear any existing settings */ curl_easy_setopt (atd->curl, CURLOPT_USERPWD, ""); } curl_easy_setopt (atd->curl, CURLOPT_URL, url->removeurl); curl_easy_setopt (atd->curl, CURLOPT_POSTFIELDS, post); curl_easy_setopt (atd->curl, CURLOPT_WRITEHEADER, auth_user); curl_easy_setopt (atd->curl, CURLOPT_WRITEDATA, auth_user); DEBUG2 ("...handler %d (%s) sending request", auth_user->handler, auth_user->mount); if (curl_easy_perform (atd->curl)) { WARN3 ("auth to server %s (%s) failed with \"%s\"", url->removeurl, auth_user->mount, atd->errormsg); url->stop_req_until = time (NULL) + url->stop_req_duration; /* prevent further attempts for a while */ } else DEBUG2 ("...handler %d (%s) request complete", auth_user->handler, auth_user->mount); free (userpwd); return AUTH_OK; }
static switch_status_t my_on_reporting(switch_core_session_t *session) { struct json_object *json_cdr = NULL; const char *json_text = NULL; char *path = NULL; char *curl_json_text = NULL; const char *logdir = NULL; char *json_text_escaped = NULL; int fd = -1, err_dir_index; uint32_t cur_try; long httpRes; CURL *curl_handle = NULL; struct curl_slist *headers = NULL; struct curl_slist *slist = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_FALSE; int is_b; const char *a_prefix = ""; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; } is_b = channel && switch_channel_get_originator_caller_profile(channel); if (!globals.log_b && is_b) { const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE); if (!switch_true(force_cdr)) { return SWITCH_STATUS_SUCCESS; } } if (!is_b && globals.prefix_a) a_prefix = "a_"; if (generate_json_cdr(session, &json_cdr) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Generating Data!\n"); return SWITCH_STATUS_FALSE; } json_text = json_object_to_json_string(json_cdr); if (!json_text) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); goto error; } switch_thread_rwlock_rdlock(globals.log_path_lock); if (!(logdir = switch_channel_get_variable(channel, "json_cdr_base"))) { logdir = globals.log_dir; } if (!zstr(logdir) && (globals.log_http_and_disk || !globals.url_count)) { path = switch_mprintf("%s%s%s%s.cdr.json", logdir, SWITCH_PATH_SEPARATOR, a_prefix, switch_core_session_get_uuid(session)); switch_thread_rwlock_unlock(globals.log_path_lock); if (path) { #ifdef _MSC_VER if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { #else if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) { #endif int wrote; wrote = write(fd, json_text, (unsigned) strlen(json_text)); close(fd); fd = -1; } else { char ebuf[512] = { 0 }; #ifdef WIN32 strerror_s(ebuf, sizeof(ebuf), errno); #else strerror_r(errno, ebuf, sizeof(ebuf)); #endif switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", path, ebuf); } switch_safe_free(path); } } else { switch_thread_rwlock_unlock(globals.log_path_lock); } /* try to post it to the web server */ if (globals.url_count) { char *destUrl = NULL; curl_handle = curl_easy_init(); if (globals.encode) { switch_size_t need_bytes = strlen(json_text) * 3; json_text_escaped = malloc(need_bytes); switch_assert(json_text_escaped); memset(json_text_escaped, 0, need_bytes); if (globals.encode == ENCODING_DEFAULT) { headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded"); switch_url_encode(json_text, json_text_escaped, need_bytes); } else { headers = curl_slist_append(headers, "Content-Type: application/x-www-form-base64-encoded"); switch_b64_encode((unsigned char *) json_text, need_bytes / 3, (unsigned char *) json_text_escaped, need_bytes); } json_text = json_text_escaped; if (!(curl_json_text = switch_mprintf("cdr=%s", json_text))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); goto error; } } else { headers = curl_slist_append(headers, "Content-Type: application/x-www-form-plaintext"); curl_json_text = (char *)json_text; } if (!zstr(globals.cred)) { curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, globals.auth_scheme); curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred); } curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl_handle, CURLOPT_POST, 1); curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_json_text); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-json/1.0"); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, httpCallBack); if (globals.disable100continue) { slist = curl_slist_append(slist, "Expect:"); curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist); } if (globals.ssl_cert_file) { curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, globals.ssl_cert_file); } if (globals.ssl_key_file) { curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, globals.ssl_key_file); } if (globals.ssl_key_password) { curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, globals.ssl_key_password); } if (globals.ssl_version) { if (!strcasecmp(globals.ssl_version, "SSLv3")) { curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); } else if (!strcasecmp(globals.ssl_version, "TLSv1")) { curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); } } if (globals.ssl_cacert_file) { curl_easy_setopt(curl_handle, CURLOPT_CAINFO, globals.ssl_cacert_file); } /* these were used for testing, optionally they may be enabled if someone desires curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 302 recursion level */ for (cur_try = 0; cur_try < globals.retries; cur_try++) { if (cur_try > 0) { switch_yield(globals.delay * 1000000); } destUrl = switch_mprintf("%s?uuid=%s", globals.urls[globals.url_index], switch_core_session_get_uuid(session)); curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl); if (!strncasecmp(destUrl, "https", 5)) { curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0); } if (globals.enable_cacert_check) { curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, TRUE); } if (globals.enable_ssl_verifyhost) { curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2); } curl_easy_perform(curl_handle); curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes); switch_safe_free(destUrl); if (httpRes == 200) { goto success; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server [%s]\n", httpRes, globals.urls[globals.url_index]); globals.url_index++; switch_assert(globals.url_count <= MAX_URLS); if (globals.url_index >= globals.url_count) { globals.url_index = 0; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retry will be with url [%s]\n", globals.urls[globals.url_index]); } } curl_easy_cleanup(curl_handle); curl_slist_free_all(headers); curl_slist_free_all(slist); slist = NULL; headers = NULL; curl_handle = NULL; /* if we are here the web post failed for some reason */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n"); for (err_dir_index = 0; err_dir_index < globals.err_dir_count; err_dir_index++) { switch_thread_rwlock_rdlock(globals.log_path_lock); path = switch_mprintf("%s%s%s%s.cdr.json", globals.err_log_dir[err_dir_index], SWITCH_PATH_SEPARATOR, a_prefix, switch_core_session_get_uuid(session)); switch_thread_rwlock_unlock(globals.log_path_lock); if (path) { #ifdef _MSC_VER if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { #else if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) { #endif int wrote; wrote = write(fd, json_text, (unsigned) strlen(json_text)); close(fd); fd = -1; break; } else { char ebuf[512] = { 0 }; #ifdef WIN32 strerror_s(ebuf, sizeof(ebuf), errno); #else strerror_r(errno, ebuf, sizeof(ebuf)); #endif switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s! [%s]\n", path, ebuf); } switch_safe_free(path); } } } success: status = SWITCH_STATUS_SUCCESS; error: if (curl_handle) { curl_easy_cleanup(curl_handle); } if (headers) { curl_slist_free_all(headers); } if (slist) { curl_slist_free_all(slist); } if (curl_json_text != json_text) { switch_safe_free(curl_json_text); } json_object_put(json_cdr); switch_safe_free(json_text_escaped); return status; } static void event_handler(switch_event_t *event) { const char *sig = switch_event_get_header(event, "Trapped-Signal"); if (sig && !strcmp(sig, "HUP")) { if (globals.rotate) { set_json_cdr_log_dirs(); } } } static switch_state_handler_table_t state_handlers = { /*.on_init */ NULL, /*.on_routing */ NULL, /*.on_execute */ NULL, /*.on_hangup */ NULL, /*.on_exchange_media */ NULL, /*.on_soft_execute */ NULL, /*.on_consume_media */ NULL, /*.on_hibernate */ NULL, /*.on_reset */ NULL, /*.on_park */ NULL, /*.on_reporting */ my_on_reporting }; SWITCH_MODULE_LOAD_FUNCTION(mod_json_cdr_load) { char *cf = "json_cdr.conf"; switch_xml_t cfg, xml, settings, param; switch_status_t status = SWITCH_STATUS_SUCCESS; /* test global state handlers */ switch_core_add_state_handler(&state_handlers); *module_interface = switch_loadable_module_create_module_interface(pool, modname); memset(&globals, 0, sizeof(globals)); if (switch_event_bind_removable(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } globals.log_http_and_disk = 0; globals.log_b = 1; globals.disable100continue = 0; globals.pool = pool; globals.auth_scheme = CURLAUTH_BASIC; switch_thread_rwlock_create(&globals.log_path_lock, pool); /* parse the config */ if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "cred") && !zstr(val)) { globals.cred = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "url") && !zstr(val)) { if (globals.url_count >= MAX_URLS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum urls configured!\n"); } else { globals.urls[globals.url_count++] = switch_core_strdup(globals.pool, val); } } else if (!strcasecmp(var, "log-http-and-disk")) { globals.log_http_and_disk = switch_true(val); } else if (!strcasecmp(var, "delay") && !zstr(val)) { globals.delay = (uint32_t) atoi(val); } else if (!strcasecmp(var, "log-b-leg")) { globals.log_b = switch_true(val); } else if (!strcasecmp(var, "prefix-a-leg")) { globals.prefix_a = switch_true(val); } else if (!strcasecmp(var, "disable-100-continue") && switch_true(val)) { globals.disable100continue = 1; } else if (!strcasecmp(var, "encode") && !zstr(val)) { if (!strcasecmp(val, "base64")) { globals.encode = ENCODING_BASE64; } else { globals.encode = switch_true(val) ? ENCODING_DEFAULT : ENCODING_NONE; } } else if (!strcasecmp(var, "retries") && !zstr(val)) { globals.retries = (uint32_t) atoi(val); } else if (!strcasecmp(var, "rotate") && !zstr(val)) { globals.rotate = switch_true(val); } else if (!strcasecmp(var, "log-dir")) { if (zstr(val)) { globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } else { if (switch_is_file_path(val)) { globals.base_log_dir = switch_core_strdup(globals.pool, val); } else { globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val); } } } else if (!strcasecmp(var, "err-log-dir")) { if (globals.err_dir_count >= MAX_ERR_DIRS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "maximum error directories configured!\n"); } else { if (zstr(val)) { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } else { if (switch_is_file_path(val)) { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_strdup(globals.pool, val); } else { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, val); } } } } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) { globals.enable_cacert_check = 1; } else if (!strcasecmp(var, "ssl-cert-path")) { globals.ssl_cert_file = val; } else if (!strcasecmp(var, "ssl-key-path")) { globals.ssl_key_file = val; } else if (!strcasecmp(var, "ssl-key-password")) { globals.ssl_key_password = val; } else if (!strcasecmp(var, "ssl-version")) { globals.ssl_version = val; } else if (!strcasecmp(var, "ssl-cacert-file")) { globals.ssl_cacert_file = val; } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) { globals.enable_ssl_verifyhost = 1; } else if (!strcasecmp(var, "auth-scheme")) { if (*val == '=') { globals.auth_scheme = 0; val++; } if (!strcasecmp(val, "basic")) { globals.auth_scheme |= CURLAUTH_BASIC; } else if (!strcasecmp(val, "digest")) { globals.auth_scheme |= CURLAUTH_DIGEST; } else if (!strcasecmp(val, "NTLM")) { globals.auth_scheme |= CURLAUTH_NTLM; } else if (!strcasecmp(val, "GSS-NEGOTIATE")) { globals.auth_scheme |= CURLAUTH_GSSNEGOTIATE; } else if (!strcasecmp(val, "any")) { globals.auth_scheme = CURLAUTH_ANY; } } } if (!globals.err_dir_count) { if (!zstr(globals.base_log_dir)) { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_strdup(globals.pool, globals.base_log_dir); } else { globals.base_err_log_dir[globals.err_dir_count++] = switch_core_sprintf(globals.pool, "%s%sjson_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); } } } if (globals.retries < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retries is negative, setting to 0\n"); globals.retries = 0; } if (globals.retries && globals.delay <= 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Retries set but delay 0 setting to 5000ms\n"); globals.delay = 5000; } globals.retries++; set_json_cdr_log_dirs(); switch_xml_free(xml); return status; } SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_json_cdr_shutdown) { int err_dir_index = 0; globals.shutdown = 1; switch_safe_free(globals.log_dir); for (;err_dir_index < globals.err_dir_count; err_dir_index++) { switch_safe_free(globals.err_log_dir[err_dir_index]); } switch_event_unbind(&globals.node); switch_core_remove_state_handler(&state_handlers); switch_thread_rwlock_destroy(globals.log_path_lock); return SWITCH_STATUS_SUCCESS; }
/* * This function uses libcurl to send a simple HTTP POST * request with no Content-Type header. * TLS peer verification is enabled, but not HTTP authentication. * The parameters are: * * ctx: Ptr to ACVP_CTX, which contains the server name * url: URL to use for the GET request * data: data to POST to the server * writefunc: Function pointer to handle writing the data * from the HTTP body received from the server. * * Return value is the HTTP status value from the server * (e.g. 200 for HTTP OK) */ static long acvp_curl_http_post(ACVP_CTX *ctx, char *url, char *data, int data_len) { long http_code = 0; CURL *hnd; CURLcode crv; struct curl_slist *slist; char user_agent_str[USER_AGENT_STR_MAX + 1]; /* * Set the Content-Type header in the HTTP request */ slist = NULL; slist = curl_slist_append(slist, "Content-Type:application/json"); /* * Create the Authorzation header if needed */ slist = acvp_add_auth_hdr(ctx, slist); ctx->curl_read_ctr = 0; /* * Create the HTTP User Agent value */ snprintf(user_agent_str, USER_AGENT_STR_MAX, "libacvp/%s", ACVP_VERSION); /* * Setup Curl */ hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_URL, url); curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(hnd, CURLOPT_USERAGENT, user_agent_str); curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist); curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(hnd, CURLOPT_POST, 1L); curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, data); curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)data_len); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(hnd, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); /* * Always verify the server */ curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 1L); if (ctx->cacerts_file) { curl_easy_setopt(hnd, CURLOPT_CAINFO, ctx->cacerts_file); curl_easy_setopt(hnd, CURLOPT_CERTINFO, 1L); } /* * Mutual-auth */ if (ctx->tls_cert && ctx->tls_key) { curl_easy_setopt(hnd, CURLOPT_SSLCERTTYPE, "PEM"); curl_easy_setopt(hnd, CURLOPT_SSLCERT, ctx->tls_cert); curl_easy_setopt(hnd, CURLOPT_SSLKEYTYPE, "PEM"); curl_easy_setopt(hnd, CURLOPT_SSLKEY, ctx->tls_key); } /* * To record the HTTP data recieved from the server, * set the callback function. */ curl_easy_setopt(hnd, CURLOPT_WRITEDATA, ctx); curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, &acvp_curl_write_callback); if (ctx->curl_buf) { /* Clear the HTTP buffer for next server response */ memzero_s(ctx->curl_buf, ACVP_CURL_BUF_MAX); } /* * Send the HTTP POST request */ crv = curl_easy_perform(hnd); if (crv != CURLE_OK) { ACVP_LOG_ERR("Curl failed with code %d (%s)\n", crv, curl_easy_strerror(crv)); } /* * Get the HTTP reponse status code from the server */ curl_easy_getinfo(hnd, CURLINFO_RESPONSE_CODE, &http_code); curl_easy_cleanup(hnd); hnd = NULL; curl_slist_free_all(slist); slist = NULL; return http_code; }
int main(int argc, char **argv) { CURL *curl; CURLcode res; struct curl_slist* slist = NULL; struct stringbuffer buffer; long resp_code = 0; char *token = NULL; curl = curl_easy_init(); stringbuffer_init(&buffer); if (curl) { /** Let it be known that I refuse to write manual, string-quoted JSON. */ slist = curl_slist_append(slist, "Content-type: application/json"); json_object *body_obj = json_object_new_object(); json_object *auth_obj = json_object_new_object(); json_object *cred_obj = json_object_new_object(); json_object *tenant_str = json_object_new_string(KEYSTONE_TENANT); json_object *user_str = json_object_new_string(KEYSTONE_USER); json_object *pass_str = json_object_new_string(KEYSTONE_PASS); json_object_object_add(body_obj, "auth", auth_obj); json_object_object_add(auth_obj, "passwordCredentials", cred_obj); json_object_object_add(auth_obj, "tenantName", tenant_str); json_object_object_add(cred_obj, "username", user_str); json_object_object_add(cred_obj, "password", pass_str); const char* body = json_object_to_json_string(body_obj); //printf("body[%d]:\n%s\n\n", strlen(body), body); curl_easy_setopt(curl, CURLOPT_URL, KEYSTONE_URL); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (void*) http_received_data); res = curl_easy_perform(curl); json_object_put(body_obj); json_object_put(auth_obj); json_object_put(cred_obj); json_object_put(user_str); json_object_put(pass_str); json_object_put(tenant_str); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp_code); //printf("HTTP %d\n", resp_code); //printf("body[%d]\n%s\n\n", buffer.len, buffer.ptr); if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } else if (resp_code == 200) { json_object *json = json_tokener_parse(buffer.ptr); json_object *access_obj = json_object_object_get(json, "access"); json_object *token_obj = json_object_object_get(access_obj, "token"); json_object *id_obj = json_object_object_get(token_obj, "id"); const char* tmp_token = json_object_get_string(id_obj); token = malloc(strlen(tmp_token) + 1); strcpy(token, tmp_token); json_object_put(id_obj); json_object_put(token_obj); json_object_put(access_obj); json_object_put(json); } else { fprintf(stderr, "Could not authenticate (HTTP %d received).\n", resp_code); } stringbuffer_free(&buffer); curl_easy_cleanup(curl); curl_slist_free_all(slist); } if (token != NULL) { printf("token is %s\n", token); } return 0; }
int Service::PostSoap( char *wsdlUrl,char *SoapActionStr,char *xmlbuffer, char *failstr) { m_resp_buffer=""; m_resp_header=""; //默认写入写出都是UTF-8模式 XML不用再次转换 struct curl_slist *headers = NULL; /* headers = curl_slist_append(headers, "Content-Type: text/xml;charset=UTF-8"); //targetNamespace + 方法名 name //headers = curl_slist_append(headers, "SOAPAction: \"http://push.services.webService.vm.yr.com/videoReadPushSend\""); headers = curl_slist_append(headers, SoapActionStr); */ //headers = curl_slist_append(headers, "Content-Type: application/soap+xml;charset=UTF-8;action=\"urn:initSystem\""); //headers = curl_slist_append(headers, SoapActionStr); //headers = curl_slist_append(headers, "Content-Type: text/xml;charset=UTF-8"); CURL *curl = curl_easy_init(); if ( curl ) { //WSDL路径 //curl_easy_setopt(curl, CURLOPT_URL, "http://10.142.50.248:8086/uvss/services/infoPushSend"); curl_easy_setopt(curl, CURLOPT_URL,wsdlUrl); char errorBuffer[CURL_ERROR_SIZE]={0}; curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer); // curl_easy_setopt(curl, CURLOPT_HEADER, 1); // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, xmlbuffer); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(xmlbuffer)); curl_easy_setopt(curl, CURLOPT_POST, 1); //回报数据 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); int timeout=10; //设置URL地址错误 重连N次后推出 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); //设置最低速度。为了中途拔网线 curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 10); curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, timeout); if(CSERVER_DEBUG) curl_easy_setopt(curl, CURLOPT_VERBOSE , 1); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //curl_easy_setopt(curl, CURLOPT_PROXY, "10.142.50.140:808"); CURLcode curl_code = curl_easy_perform(curl); /* always cleanup */ int http_code = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); // clean up curl_easy_cleanup(curl); // curl_slist_free_all(headers); if ( curl_code != CURLE_OK ) { cout << "\nError: [" << curl_code << "] - " << errorBuffer; //DebugPrintA(2, "\nError--%s\n",errorBuffer); error_str = errorBuffer; //linux modify callback error info???? //::MessageBoxA(NULL,error_str.c_str(),"HttpReq-ER",0); sprintf(failstr,"Cservice postcode %s",curl_easy_strerror(curl_code)); return curl_code; } else if ( 400 <= http_code ) { //DebugPrintA(3, "Http-code=%d",http_code); int start, end; start = m_resp_buffer.find("<internalReason>"); end = m_resp_buffer.find("</internalReason>"); if( start>=0 && end>=0 && end>start ) { start += 16; error_str = m_resp_buffer.substr(start, end-start); } else error_str = m_resp_buffer; sprintf(failstr,"Cservice httpcode %d",http_code); return http_code; } else error_str = ""; return CURLE_OK; } else { sprintf(failstr,"Cservice postinit fail"); return CURLE_FAILED_INIT; } }
/* test function */ int test(char *URL) { int res; CURLSHcode scode = CURLSHE_OK; CURLcode code = CURLE_OK; char *url = NULL; struct Tdata tdata; CURL *curl; CURLSH *share; struct curl_slist *headers = NULL; struct curl_slist *cookies = NULL; struct curl_slist *next_cookie = NULL; int i; struct userdata user; user.text = "Pigs in space"; user.counter = 0; printf("GLOBAL_INIT\n"); if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { fprintf(stderr, "curl_global_init() failed\n"); return TEST_ERR_MAJOR_BAD; } /* prepare share */ printf("SHARE_INIT\n"); share = curl_share_init(); if(!share) { fprintf(stderr, "curl_share_init() failed\n"); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } if(CURLSHE_OK == scode) { printf("CURLSHOPT_LOCKFUNC\n"); scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, my_lock); } if(CURLSHE_OK == scode) { printf("CURLSHOPT_UNLOCKFUNC\n"); scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, my_unlock); } if(CURLSHE_OK == scode) { printf("CURLSHOPT_USERDATA\n"); scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user); } if(CURLSHE_OK == scode) { printf("CURL_LOCK_DATA_COOKIE\n"); scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); } if(CURLSHE_OK == scode) { printf("CURL_LOCK_DATA_DNS\n"); scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); } if(CURLSHE_OK != scode) { fprintf(stderr, "curl_share_setopt() failed\n"); curl_share_cleanup(share); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } /* initial cookie manipulation */ curl = curl_easy_init(); if(!curl) { fprintf(stderr, "curl_easy_init() failed\n"); curl_share_cleanup(share); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } printf("CURLOPT_SHARE\n"); test_setopt(curl, CURLOPT_SHARE, share); printf("CURLOPT_COOKIELIST injected_and_clobbered\n"); test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: injected_and_clobbered=yes; " "domain=host.foo.com; expires=Sat Feb 2 11:56:27 GMT 2030"); printf("CURLOPT_COOKIELIST ALL\n"); test_setopt(curl, CURLOPT_COOKIELIST, "ALL"); printf("CURLOPT_COOKIELIST session\n"); test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: session=elephants"); printf("CURLOPT_COOKIELIST injected\n"); test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: injected=yes; domain=host.foo.com; " "expires=Sat Feb 2 11:56:27 GMT 2030"); printf("CURLOPT_COOKIELIST SESS\n"); test_setopt(curl, CURLOPT_COOKIELIST, "SESS"); printf("CLEANUP\n"); curl_easy_cleanup(curl); res = 0; /* start treads */ for(i=1; i<=THREADS; i++) { /* set thread data */ tdata.url = suburl(URL, i); /* must be curl_free()d */ tdata.share = share; /* simulate thread, direct call of "thread" function */ printf("*** run %d\n",i); fire(&tdata); curl_free(tdata.url); } /* fetch a another one and save cookies */ printf("*** run %d\n", i); curl = curl_easy_init(); if(!curl) { fprintf(stderr, "curl_easy_init() failed\n"); curl_share_cleanup(share); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } url = suburl(URL, i); headers = sethost(NULL); test_setopt(curl, CURLOPT_HTTPHEADER, headers); test_setopt(curl, CURLOPT_URL, url); printf("CURLOPT_SHARE\n"); test_setopt(curl, CURLOPT_SHARE, share); printf("CURLOPT_COOKIEJAR\n"); test_setopt(curl, CURLOPT_COOKIEJAR, JAR); printf("CURLOPT_COOKIELIST FLUSH\n"); test_setopt(curl, CURLOPT_COOKIELIST, "FLUSH"); printf("PERFORM\n"); curl_easy_perform(curl); printf("CLEANUP\n"); curl_easy_cleanup(curl); curl_free(url); curl_slist_free_all(headers); /* load cookies */ curl = curl_easy_init(); if(!curl) { fprintf(stderr, "curl_easy_init() failed\n"); curl_share_cleanup(share); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } url = suburl(URL, i); headers = sethost(NULL); test_setopt(curl, CURLOPT_HTTPHEADER, headers); test_setopt(curl, CURLOPT_URL, url); printf("CURLOPT_SHARE\n"); test_setopt(curl, CURLOPT_SHARE, share); printf("CURLOPT_COOKIELIST ALL\n"); test_setopt(curl, CURLOPT_COOKIELIST, "ALL"); printf("CURLOPT_COOKIEJAR\n"); test_setopt(curl, CURLOPT_COOKIEFILE, JAR); printf("CURLOPT_COOKIELIST RELOAD\n"); test_setopt(curl, CURLOPT_COOKIELIST, "RELOAD"); code = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); if(code != CURLE_OK) { fprintf(stderr, "curl_easy_getinfo() failed\n"); res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } printf("loaded cookies:\n"); if(!cookies) { fprintf(stderr, " reloading cookies from '%s' failed\n", JAR); res = TEST_ERR_MAJOR_BAD; goto test_cleanup; } printf("-----------------\n"); next_cookie = cookies; while(next_cookie) { printf(" %s\n", next_cookie->data); next_cookie = next_cookie->next; } printf("-----------------\n"); curl_slist_free_all(cookies); /* try to free share, expect to fail because share is in use*/ printf("try SHARE_CLEANUP...\n"); scode = curl_share_cleanup(share); if(scode==CURLSHE_OK) { fprintf(stderr, "curl_share_cleanup succeed but error expected\n"); share = NULL; } else { printf("SHARE_CLEANUP failed, correct\n"); } test_cleanup: /* clean up last handle */ printf("CLEANUP\n"); curl_easy_cleanup(curl); curl_slist_free_all(headers); curl_free(url); /* free share */ printf("SHARE_CLEANUP\n"); scode = curl_share_cleanup(share); if(scode!=CURLSHE_OK) fprintf(stderr, "curl_share_cleanup failed, code errno %d\n", (int)scode); printf("GLOBAL_CLEANUP\n"); curl_global_cleanup(); return res; }
int GetSignedURL(char* Auth_token, char* signedURL, char* upfile) { CURL* curl; CURLcode res; FILE* temfile; struct curl_slist* headers = NULL; char Auth_signedurl[128]; char auth_header[] = "Authorization: Bearer "; logger_cloud("%s: Entering ...", __FUNCTION__); memset((char*)&Auth_signedurl[0], '\0', 128); //Setup file name json format sprintf((char*)&Filename[0], "{\"filename\":\"%s\"}", upfile); //headers = curl_slist_append(headers, Accept); headers = curl_slist_append(headers, CLOUD_ACCEPT); headers = curl_slist_append(headers, CLOUD_DEVICE); headers = curl_slist_append(headers, Content); //Authorization for GetSignedURL must get from GetToken strcat((char*)&Auth_signedurl[0], (char*)&auth_header[0]); strcat((char*)&Auth_signedurl[0], Auth_token); headers = curl_slist_append(headers, (char*)&Auth_signedurl[0]); /* In windows, this will init the Winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GetSignedURL_Response); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, GetSignedURL_Header_Response); if (endpoint_url == 1) { curl_easy_setopt(curl, CURLOPT_URL, QA_AWS_SIGNED); curl_easy_setopt(curl, CURLOPT_CAPATH, "/odi/conf/m2mqtt_ca_qa.crt"); } else { curl_easy_setopt(curl, CURLOPT_URL, PROD_AWS_SIGNED); curl_easy_setopt(curl, CURLOPT_CAPATH, "/odi/conf/m2mqtt_ca_prod.crt"); } curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Filename); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); /* Check for errors */ if (res != CURLE_OK) { logger_cloud("%s:curl_easy_perform() failed: %s\n", __FUNCTION__, curl_easy_strerror(res)); GetSignedURL_ret = SIGNEDURL_ERR; } /* always cleanup */ curl_easy_cleanup(curl); } memcpy(signedURL, (char*)&local_signedURL[0], SIGNEDURL_SIZE); curl_global_cleanup(); return GetSignedURL_ret; }
static upyun_ret_e upyun_request_internal(upyun_t* thiz, upyun_request_t* request, struct curl_slist** headers) { return_val_if_fail(s_inited > 0, UPYUN_RET_NOT_INITED); return_val_if_fail(thiz != NULL && request != NULL && request->method >= UPYUN_HTTP_METHOD_GET && request->method <= UPYUN_HTTP_METHOD_DELETE && request->path != NULL && request->path[0] == '/', UPYUN_RET_INVALID_PARAMS); const upyun_content_t* content = request->upload_content; if(content != NULL) { if(content->type == UPYUN_CONTENT_FILE) { return_val_if_fail(content->u.fp != NULL && content->len > 0, UPYUN_RET_INVALID_PARAMS); } else if(content->type == UPYUN_CONTENT_STR) { return_val_if_fail(content->u.data != NULL && content->len > 0, UPYUN_RET_INVALID_PARAMS); } else return UPYUN_RET_INVALID_PARAMS; } struct curl_slist* curl_headers = *headers; upyun_ret_e ret = UPYUN_RET_OK; CURL *curl = thiz->curl; curl_easy_reset(curl); upyun_content_t copy_upload_content = {0}; char url[MAX_QUOTED_URL_LEN] = {0}; size_t prefix_len = strlen("http://") + strlen(upyun_endpoints[thiz->config->endpoint]) - strlen("Host: "); sprintf(url, "http://%s", upyun_endpoints[thiz->config->endpoint] + sizeof("Host: ") - 1); char* quoted_uri = url + prefix_len; if(!url_encode(request->path, quoted_uri, MAX_QUOTED_URL_LEN - prefix_len)) { ret = UPYUN_RET_URL_TOO_LONG; goto DONE; } /* printf("full path: %s\n", url); */ curl_easy_setopt(curl, CURLOPT_URL, url); if(request->method == UPYUN_HTTP_METHOD_GET) { curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); } else if(request->method == UPYUN_HTTP_METHOD_HEAD) { curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); } else if(request->method == UPYUN_HTTP_METHOD_POST) { /* curl_easy_setopt(curl, CURLOPT_POST, 1L); */ curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"POST"); } else if(request->method == UPYUN_HTTP_METHOD_PUT) { curl_easy_setopt(curl, CURLOPT_PUT, 1L); } else if(request->method == UPYUN_HTTP_METHOD_DELETE) { curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"DELETE"); } if(request->method == UPYUN_HTTP_METHOD_PUT || request->method == UPYUN_HTTP_METHOD_POST) { if(request->upload_content != NULL) { copy_upload_content = *(request->upload_content); curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_content_callback); curl_easy_setopt(curl, CURLOPT_READDATA, ©_upload_content); } } if(request->need_headers_out) { curl_easy_setopt(curl, CURLOPT_HEADERDATA, &request->headers_out); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, response_header_callback); } size_t content_len = 0; if(request->method == UPYUN_HTTP_METHOD_POST || request->method == UPYUN_HTTP_METHOD_PUT) { content_len = request->upload_content != NULL ? request->upload_content->len : 0; } char time_buf[MAX_BUF_LEN] = {0}; get_rfc1123_date(time_buf, 100); char auth_header[MAX_BUF_LEN] = {0}; upyun_generate_auth_header(thiz->config->user, thiz->config->passwd, request->method, content_len, quoted_uri, auth_header, time_buf); curl_headers = curl_slist_append(curl_headers, auth_header); curl_headers = curl_slist_append(curl_headers, upyun_endpoints[thiz->config->endpoint]); char buf[MAX_BUF_LEN] = {0}; snprintf(buf, MAX_BUF_LEN, "DATE: %s", time_buf); curl_headers = curl_slist_append(curl_headers, buf); if(request->upload_content) { curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)(request->upload_content->len)); /*sprintf(buf, "Content-Length: %zu", request->upload_content->len);*/ if(request->upload_content->md5) { char md5_buf[34] = {0}; if(upyun_content_md5(request->upload_content, md5_buf) == 0) goto DONE; sprintf(buf, "Content-MD5: %s", md5_buf); curl_slist_append(curl_headers, buf); } } else { curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 0); strcpy(buf, "Content-Length: 0"); curl_headers = curl_slist_append(curl_headers, buf); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers); if(request->content_callback) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, request->content_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, request->content_ctx); } if(request->timeout <= 0) curl_easy_setopt(curl, CURLOPT_TIMEOUT, 0); else curl_easy_setopt(curl, CURLOPT_TIMEOUT, request->timeout); /* No signals allowed in case of multithreaded apps */ /* TODO what if there is problem in dns parsing? */ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); if(thiz->config->debug) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); else curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); CURLcode rv = curl_easy_perform(curl); if(rv != CURLE_OK) ret = UPYUN_RET_HTTP_FAIL; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &request->status); DONE: *headers = curl_headers; return ret; }
static JSBool go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) { CurlState state; JSString* jsbody; JSBool ret = JS_FALSE; jsval tmp; state.cx = cx; state.http = http; state.sendbuf = body; state.sendlen = bodylen; state.sent = 0; state.sent_once = 0; state.recvbuf = NULL; state.recvlen = 0; state.read = 0; if(HTTP_HANDLE == NULL) { HTTP_HANDLE = curl_easy_init(); curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION, (curl_seek_callback) seek_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF); curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, "http://127.0.0.1:5984/"); curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT, "CouchHTTP Client - Relax"); } if(!HTTP_HANDLE) { JS_ReportError(cx, "Failed to initialize cURL handle."); goto done; } if(http->method < 0 || http->method > OPTIONS) { JS_ReportError(cx, "INTERNAL: Unknown method."); goto done; } curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]); curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0); if(http->method == HEAD) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } else if(http->method == POST || http->method == PUT) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } if(body && bodylen) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen); } else { curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0); } // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url); curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers); curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state); if(curl_easy_perform(HTTP_HANDLE) != 0) { JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF); goto done; } if(!state.resp_headers) { JS_ReportError(cx, "Failed to recieve HTTP headers."); goto done; } tmp = OBJECT_TO_JSVAL(state.resp_headers); if(!JS_DefineProperty( cx, obj, "_headers", tmp, NULL, NULL, JSPROP_READONLY )) { JS_ReportError(cx, "INTERNAL: Failed to set response headers."); goto done; } if(state.recvbuf) { state.recvbuf[state.read] = '\0'; jsbody = dec_string(cx, state.recvbuf, state.read+1); if(!jsbody) { // If we can't decode the body as UTF-8 we forcefully // convert it to a string by just forcing each byte // to a jschar. jsbody = str_from_binary(cx, state.recvbuf, state.read); if(!jsbody) { if(!JS_IsExceptionPending(cx)) { JS_ReportError(cx, "INTERNAL: Failed to decode body."); } goto done; } } tmp = STRING_TO_JSVAL(jsbody); } else { tmp = JS_GetEmptyStringValue(cx); } if(!JS_DefineProperty( cx, obj, "responseText", tmp, NULL, NULL, JSPROP_READONLY )) { JS_ReportError(cx, "INTERNAL: Failed to set responseText."); goto done; } ret = JS_TRUE; done: if(state.recvbuf) JS_free(cx, state.recvbuf); return ret; }
int nsp_feed_update_icon(NspFeed *feed) { NspNetData *data; char *icon_url = NULL; char *icon_path = NULL; GRegex *regex; GMatchInfo *match_info; CURL *curl; CURLcode result; GdkPixbufLoader *loader = NULL; GError *error = NULL; char *feed_id_string = NULL; /* Download web page */ data = nsp_net_new(); if ( nsp_net_load_url(feed->site_url, data) ) { g_warning("ERROR: %s\n", data->error); nsp_net_free(data); return 1; } /* Find <link> tag reffering to the icon */ regex = g_regex_new ("<link[^>]*?rel=[\"'](icon|shortcut icon)[\"'][^>]*?href=[\"'](?<href>.*?)[\"'][^>]*?>", 0, 0, NULL); g_regex_match (regex, data->content, 0, &match_info); while (g_match_info_matches (match_info)) { gchar *word = g_match_info_fetch_named (match_info, "href"); if ( !g_str_has_prefix(word, "http") ) { icon_url = g_strdup_printf("%s/%s", feed->site_url, word); g_free(word); break; } g_free (word); g_match_info_next (match_info, NULL); } g_match_info_free (match_info); g_regex_unref (regex); nsp_net_free(data); /* If no image is found - use home url + /favicon.ico */ if ( icon_url == NULL ) { regex = g_regex_new ("^(?<hostname>https?://[^/]*)", 0, 0, NULL); g_regex_match (regex, feed->site_url, 0, &match_info); if (g_match_info_matches (match_info)) { gchar *word = g_match_info_fetch_named (match_info, "hostname"); icon_url = g_strdup_printf("%s/favicon.ico", word); g_free (word); } g_match_info_free (match_info); g_regex_unref (regex); } /* Store the image to a GtkPixbufLoader */ loader = gdk_pixbuf_loader_new(); curl = curl_easy_init(); curl_easy_setopt (curl, CURLOPT_URL, icon_url); curl_easy_setopt (curl, CURLOPT_HEADER, 0); curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, nsp_feed_download_icon_cb ); curl_easy_setopt (curl, CURLOPT_WRITEDATA, loader); curl_easy_setopt (curl, CURLOPT_TIMEOUT, 60); curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); result = curl_easy_perform (curl); curl_easy_cleanup(curl); g_free(icon_url); if ( result != 0) { return 1; } gdk_pixbuf_loader_close (loader, NULL); feed->icon = gdk_pixbuf_loader_get_pixbuf (loader); if ( !GDK_IS_PIXBUF(feed->icon) ) { feed->icon = NULL; return 1; } /* Resize and save the image */ if (gdk_pixbuf_get_width (feed->icon) != 16 || gdk_pixbuf_get_height (feed->icon) != 16) { GdkPixbuf *old = feed->icon; feed->icon = gdk_pixbuf_scale_simple (old, 16, 16, GDK_INTERP_BILINEAR); g_object_unref (G_OBJECT (old)); } feed_id_string = malloc(sizeof(char)*9); g_snprintf (feed_id_string, 9, "%i", feed->id); icon_path = g_build_filename( g_get_user_data_dir(), PACKAGE, "/icons", NULL); g_mkdir_with_parents(icon_path, 0700); icon_path = g_build_filename( icon_path, "/", feed_id_string, NULL); gdk_pixbuf_save(feed->icon, icon_path, "png", &error, NULL); if ( error != NULL ) { g_warning("ERROR: %s\n", error->message); g_error_free(error); } g_free(icon_path); free(feed_id_string); return 0; }
struct block getrequest(CURL *curl_handle, const char *url, FILE *hfile) { char *ct = NULL; struct block b, h; int res; struct HeaderStruct head; struct MemoryStruct chunk; chunk.memory = (char *)malloc(1); /* will be grown as needed by the realloc above */ chunk.size = 0; /* no data at this point */ head.memory = (char *)malloc(1); /* will be grown as needed by the realloc above */ head.size = 0; /* no data at this point */ head.download = 0; /* not yet known at this point */ setmainheaders(curl_handle, url); setrequestheaders(curl_handle, GET); if(curl_handle) { /* we pass our 'chunk' struct or 'hfile' to the callback function */ if(hfile) { /* send all data to this function */ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writedata); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)hfile); } else { curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, parseheader); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *)&head); } if ((res = curl_easy_perform(curl_handle)) != 0) /*error!*/ { if (res == CURLE_ABORTED_BY_CALLBACK) { h.size = DSTOPPED; return h; } if (res == CURLE_WRITE_ERROR) { fillstruct(curl_handle, &head, &h); free(head.memory); return h; } Debug(curl_easy_strerror((CURLcode)res)); return emptyblock; } if(CURLE_OK != curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &ct) || !ct) return emptyblock; } else return emptyblock; b.data = chunk.memory; b.size = chunk.size; findChr(ct, ';'); strcpy(b.type, ct); free(head.memory); if(hfile) { h.size = DCOMPLETE; fclose(hfile); return h; } return b; }
struct block postrequest(CURL *curl_handle, const char *url, curl_httppost *data) { char *ct = NULL; char *post = findRchr(url, '?'); struct block b, h; int res; struct HeaderStruct head; struct MemoryStruct chunk; chunk.memory = (char *)malloc(1); /* will be grown as needed by the realloc above */ chunk.size = 0; /* no data at this point */ head.memory = (char *)malloc(1); /* will be grown as needed by the realloc above */ head.size = 0; /* no data at this point */ head.download = 0; /* not yet known at this point */ setmainheaders(curl_handle, url); setrequestheaders(curl_handle, POST); if(curl_handle) { /* we pass our 'chunk' struct to the callback function */ curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, parseheader); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *)&head); if (data == NULL) curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, post+1); else curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, data); if ((res = curl_easy_perform(curl_handle)) != 0) /*error!*/ { if (data) curl_formfree(data); if (res == CURLE_WRITE_ERROR) { fillstruct(curl_handle, &head, &h); free(head.memory); return h; } Debug(curl_easy_strerror((CURLcode)res)); return emptyblock; } if (data) curl_formfree(data); if(CURLE_OK != curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_TYPE, &ct) || !ct) return emptyblock; } else return emptyblock; b.data = chunk.memory; b.size = chunk.size; free(head.memory); findChr(ct, ';'); strcpy(b.type, ct); return b; }
int main(int argc, char **argv) { int c; int num_threads = 4; int img = 1; bool received_all_fragments = false; bool * received_fragments = calloc(N, sizeof(bool)); while ((c = getopt (argc, argv, "t:i:")) != -1) { switch (c) { case 't': num_threads = strtoul(optarg, NULL, 10); if (num_threads == 0) { printf("%s: option requires an argument > 0 -- 't'\n", argv[0]); return -1; } break; case 'i': img = strtoul(optarg, NULL, 10); if (img == 0) { printf("%s: option requires an argument > 0 -- 'i'\n", argv[0]); return -1; } break; default: return -1; } } CURL *curl; CURLcode res; png_structp png_ptr; png_infop info_ptr; png_byte * output_buffer = calloc(WIDTH*HEIGHT*4, sizeof(png_byte)); curl = curl_easy_init(); if (!curl) abort_("[main] could not initialize curl"); char * url = malloc(sizeof(char)*strlen(BASE_URL)+4*5); png_bytep input_buffer = malloc(sizeof(png_byte)*BUF_SIZE); struct bufdata bd; bd.buf = input_buffer; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bd); struct headerdata hd; hd.received_fragments = received_fragments; curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hd); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb); // request appropriate URL sprintf(url, BASE_URL, img); printf("requesting URL %s\n", url); curl_easy_setopt(curl, CURLOPT_URL, url); do { png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[main] png_create_read_struct failed"); // reset input buffer bd.len = bd.pos = 0; bd.max_size = BUF_SIZE; // do curl request; check for errors res = curl_easy_perform(curl); if(res != CURLE_OK) abort_("[main] curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); // read PNG (as downloaded from network) and copy it to output buffer png_bytep* row_pointers = read_png_file(png_ptr, &info_ptr, &bd); paint_destination(png_ptr, row_pointers, hd.n*BUF_WIDTH, 0, output_buffer); // free allocated memory for (int y=0; y<BUF_HEIGHT; y++) free(row_pointers[y]); free(row_pointers); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); // check for unreceived fragments received_all_fragments = true; for (int i = 0; i < N; i++) if (!received_fragments[i]) received_all_fragments = false; } while (!received_all_fragments); free(url); free(input_buffer); curl_easy_cleanup(curl); // now, write the array back to disk using write_png_file png_bytep * output_row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * HEIGHT); for (int i = 0; i < HEIGHT; i++) output_row_pointers[i] = &output_buffer[i*WIDTH*4]; write_png_file("output.png", output_row_pointers); free(output_row_pointers); free(output_buffer); free(received_fragments); return 0; }
static int rlimit(int keep_open) { int *tmpfd; int nitems, i; int *memchunk = NULL; char *fmt; struct rlimit rl; char strbuff[256]; char strbuff1[81]; char fmt_u[] = "%u"; char fmt_lu[] = "%lu"; #ifdef HAVE_LONGLONG char fmt_llu[] = "%llu"; if (sizeof(rl.rlim_max) > sizeof(long)) fmt = fmt_llu; else #endif fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu; /* get initial open file limits */ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("getrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -1; } /* show initial open file limits */ #ifdef RLIM_INFINITY if (rl.rlim_cur == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_cur); fprintf(stderr, "initial soft limit: %s\n", strbuff); #ifdef RLIM_INFINITY if (rl.rlim_max == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_max); fprintf(stderr, "initial hard limit: %s\n", strbuff); /* * if soft limit and hard limit are different we ask the * system to raise soft limit all the way up to the hard * limit. Due to some other system limit the soft limit * might not be raised up to the hard limit. So from this * point the resulting soft limit is our limit. Trying to * open more than soft limit file descriptors will fail. */ if (rl.rlim_cur != rl.rlim_max) { fprintf(stderr, "raising soft limit up to hard limit\n"); rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("setrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -2; } /* get current open file limits */ if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { store_errmsg("getrlimit() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -3; } /* show current open file limits */ #ifdef RLIM_INFINITY if (rl.rlim_cur == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_cur); fprintf(stderr, "current soft limit: %s\n", strbuff); #ifdef RLIM_INFINITY if (rl.rlim_max == RLIM_INFINITY) strcpy(strbuff, "INFINITY"); else #endif sprintf(strbuff, fmt, rl.rlim_max); fprintf(stderr, "current hard limit: %s\n", strbuff); } /* (rl.rlim_cur != rl.rlim_max) */ /* * test 537 is all about testing libcurl functionality * when the system has nearly exhausted the number of * available file descriptors. Test 537 will try to run * with a very small number of file descriptors available. * This implies that any file descriptor which is open * when the test runs will have a number in the high range * of whatever the system supports. */ /* * reserve a chunk of memory before opening file descriptors to * avoid a low memory condition once the file descriptors are * open. System conditions that could make the test fail should * be addressed in the precheck phase. This chunk of memory shall * be always free()ed before exiting the rlimit() function so * that it becomes available to the test. */ for (nitems = i = 1; nitems <= i; i *= 2) nitems = i; if (nitems > 0x7fff) nitems = 0x40000; do { num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems; sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "allocating memchunk %s byte array\n", strbuff); memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); if (!memchunk) { fprintf(stderr, "memchunk, malloc() failed\n"); nitems /= 2; } } while (nitems && !memchunk); if (!memchunk) { store_errmsg("memchunk, malloc() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); return -4; } /* initialize it to fight lazy allocation */ fprintf(stderr, "initializing memchunk array\n"); for (i = 0; i < nitems; i++) memchunk[i] = -1; /* set the number of file descriptors we will try to open */ #ifdef RLIM_INFINITY if ((rl.rlim_cur > 0) && (rl.rlim_cur != RLIM_INFINITY)) { #else if (rl.rlim_cur > 0) { #endif /* soft limit minus SAFETY_MARGIN */ num_open.rlim_max = rl.rlim_cur - SAFETY_MARGIN; } else { /* a huge number of file descriptors */ for (nitems = i = 1; nitems <= i; i *= 2) nitems = i; if (nitems > 0x7fff) nitems = 0x40000; num_open.rlim_max = nitems; } /* verify that we won't overflow size_t in malloc() */ if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) { sprintf(strbuff1, fmt, num_open.rlim_max); sprintf(strbuff, "unable to allocate an array for %s " "file descriptors, would overflow size_t", strbuff1); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); free(memchunk); return -5; } /* allocate array for file descriptors */ do { sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "allocating array for %s file descriptors\n", strbuff); fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max)); if (!fd) { fprintf(stderr, "fd, malloc() failed\n"); num_open.rlim_max /= 2; } } while (num_open.rlim_max && !fd); if (!fd) { store_errmsg("fd, malloc() failed", ERRNO); fprintf(stderr, "%s\n", msgbuff); free(memchunk); return -6; } /* initialize it to fight lazy allocation */ fprintf(stderr, "initializing fd array\n"); for (num_open.rlim_cur = 0; num_open.rlim_cur < num_open.rlim_max; num_open.rlim_cur++) fd[num_open.rlim_cur] = -1; sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "trying to open %s file descriptors\n", strbuff); /* open a dummy descriptor */ fd[0] = open(DEV_NULL, O_RDONLY); if (fd[0] < 0) { sprintf(strbuff, "opening of %s failed", DEV_NULL); store_errmsg(strbuff, ERRNO); fprintf(stderr, "%s\n", msgbuff); free(fd); fd = NULL; free(memchunk); return -7; } /* create a bunch of file descriptors */ for (num_open.rlim_cur = 1; num_open.rlim_cur < num_open.rlim_max; num_open.rlim_cur++) { fd[num_open.rlim_cur] = dup(fd[0]); if (fd[num_open.rlim_cur] < 0) { fd[num_open.rlim_cur] = -1; sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "dup() attempt %s failed", strbuff1); fprintf(stderr, "%s\n", strbuff); sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "fds system limit seems close to %s", strbuff1); fprintf(stderr, "%s\n", strbuff); num_open.rlim_max = num_open.rlim_cur - SAFETY_MARGIN; num_open.rlim_cur -= num_open.rlim_max; sprintf(strbuff1, fmt, num_open.rlim_cur); sprintf(strbuff, "closing %s file descriptors", strbuff1); fprintf(stderr, "%s\n", strbuff); for (num_open.rlim_cur = num_open.rlim_max; fd[num_open.rlim_cur] >= 0; num_open.rlim_cur++) { close(fd[num_open.rlim_cur]); fd[num_open.rlim_cur] = -1; } sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "shrinking array for %s file descriptors\n", strbuff); /* we don't care if we can't shrink it */ tmpfd = realloc(fd, sizeof(*fd) * (size_t)(num_open.rlim_max)); if (tmpfd) { fd = tmpfd; tmpfd = NULL; } break; } } sprintf(strbuff, fmt, num_open.rlim_max); fprintf(stderr, "%s file descriptors open\n", strbuff); #if !defined(HAVE_POLL_FINE) && \ !defined(USE_WINSOCK) && \ !defined(TPF) /* * when using select() instead of poll() we cannot test * libcurl functionality with a socket number equal or * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK * in lib/select.c enforces this check and protects libcurl * from a possible crash. The effect of this protection * is that test 537 will always fail, since the actual * call to select() never takes place. We skip test 537 * with an indication that select limit would be exceeded. */ num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; if (num_open.rlim_max > num_open.rlim_cur) { sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); close_file_descriptors(); free(memchunk); return -8; } num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; for (rl.rlim_cur = 0; rl.rlim_cur < num_open.rlim_max; rl.rlim_cur++) { if (fd[rl.rlim_cur] > num_open.rlim_cur) { sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); store_errmsg(strbuff, 0); fprintf(stderr, "%s\n", msgbuff); close_file_descriptors(); free(memchunk); return -9; } } #endif /* using a FD_SETSIZE bound select() */ /* * Old or 'backwards compatible' implementations of stdio do not allow * handling of streams with an underlying file descriptor number greater * than 255, even when allowing high numbered file descriptors for sockets. * At this point we have a big number of file descriptors which have been * opened using dup(), so lets test the stdio implementation and discover * if it is capable of fopen()ing some additional files. */ if (!fopen_works()) { sprintf(strbuff1, fmt, num_open.rlim_max); sprintf(strbuff, "stdio fopen() fails with %s fds open()", strbuff1); fprintf(stderr, "%s\n", msgbuff); sprintf(strbuff, "stdio fopen() fails with lots of fds open()"); store_errmsg(strbuff, 0); close_file_descriptors(); free(memchunk); return -10; } /* free the chunk of memory we were reserving so that it becomes becomes available to the test */ free(memchunk); /* close file descriptors unless instructed to keep them */ if (!keep_open) { close_file_descriptors(); } return 0; } int test(char *URL) { CURLcode res; CURL *curl; if(!strcmp(URL, "check")) { /* used by the test script to ask if we can run this test or not */ if(rlimit(FALSE)) { fprintf(stdout, "rlimit problem: %s\n", msgbuff); return 1; } return 0; /* sure, run this! */ } if (rlimit(TRUE)) { /* failure */ return TEST_ERR_MAJOR_BAD; } /* run the test with the bunch of open file descriptors and close them all once the test is over */ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { fprintf(stderr, "curl_global_init() failed\n"); close_file_descriptors(); return TEST_ERR_MAJOR_BAD; } if ((curl = curl_easy_init()) == NULL) { fprintf(stderr, "curl_easy_init() failed\n"); close_file_descriptors(); curl_global_cleanup(); return TEST_ERR_MAJOR_BAD; } curl_easy_setopt(curl, CURLOPT_URL, URL); curl_easy_setopt(curl, CURLOPT_HEADER, TRUE); res = curl_easy_perform(curl); close_file_descriptors(); curl_easy_cleanup(curl); curl_global_cleanup(); return (int)res; }
json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass, const char *rpc_req, int *curl_err, int flags) { json_t *val, *err_val, *res_val; int rc; long http_rc; struct data_buffer all_data = {0}; struct upload_buffer upload_data; char *json_buf; json_error_t err; struct curl_slist *headers = NULL; char len_hdr[64]; char curl_err_str[CURL_ERROR_SIZE]; long timeout = (flags & JSON_RPC_LONGPOLL) ? opt_timeout : 30; struct header_info hi = {0}; /* it is assumed that 'curl' is freshly [re]initialized at this pt */ if (opt_protocol) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_URL, url); if (opt_cert) curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert); curl_easy_setopt(curl, CURLOPT_ENCODING, ""); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data); curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data_cb); curl_easy_setopt(curl, CURLOPT_READDATA, &upload_data); #if LIBCURL_VERSION_NUM >= 0x071200 curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, &seek_data_cb); curl_easy_setopt(curl, CURLOPT_SEEKDATA, &upload_data); #endif curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str); if (opt_redirect) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hi); if (opt_proxy) { curl_easy_setopt(curl, CURLOPT_PROXY, opt_proxy); curl_easy_setopt(curl, CURLOPT_PROXYTYPE, opt_proxy_type); } if (userpass) { curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); } #if LIBCURL_VERSION_NUM >= 0x070f06 if (flags & JSON_RPC_LONGPOLL) curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb); #endif curl_easy_setopt(curl, CURLOPT_POST, 1); if (opt_protocol) applog(LOG_DEBUG, "JSON protocol request:\n%s\n", rpc_req); upload_data.buf = rpc_req; upload_data.len = strlen(rpc_req); upload_data.pos = 0; sprintf(len_hdr, "Content-Length: %lu", (unsigned long) upload_data.len); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, len_hdr); headers = curl_slist_append(headers, "User-Agent: " USER_AGENT); headers = curl_slist_append(headers, "X-Mining-Extensions: midstate"); headers = curl_slist_append(headers, "Accept:"); /* disable Accept hdr*/ headers = curl_slist_append(headers, "Expect:"); /* disable Expect hdr*/ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); rc = curl_easy_perform(curl); if (curl_err != NULL) *curl_err = rc; if (rc) { curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_rc); if (!((flags & JSON_RPC_LONGPOLL) && rc == CURLE_OPERATION_TIMEDOUT) && !((flags & JSON_RPC_QUIET_404) && http_rc == 404)) applog(LOG_ERR, "HTTP request failed: %s", curl_err_str); if (curl_err && (flags & JSON_RPC_QUIET_404) && http_rc == 404) *curl_err = CURLE_OK; goto err_out; } /* If X-Stratum was found, activate Stratum */ if (want_stratum && hi.stratum_url && !strncasecmp(hi.stratum_url, "stratum+tcp://", 14)) { have_stratum = true; tq_push(thr_info[stratum_thr_id].q, hi.stratum_url); hi.stratum_url = NULL; } /* If X-Long-Polling was found, activate long polling */ if (!have_longpoll && want_longpoll && hi.lp_path && !have_gbt && allow_getwork && !have_stratum) { have_longpoll = true; tq_push(thr_info[longpoll_thr_id].q, hi.lp_path); hi.lp_path = NULL; } if (!all_data.buf) { applog(LOG_ERR, "Empty data received in json_rpc_call."); goto err_out; } json_buf = hack_json_numbers(all_data.buf); errno = 0; /* needed for Jansson < 2.1 */ val = JSON_LOADS(json_buf, &err); free(json_buf); if (!val) { applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text); goto err_out; } if (opt_protocol) { char *s = json_dumps(val, JSON_INDENT(3)); applog(LOG_DEBUG, "JSON protocol response:\n%s", s); free(s); } /* JSON-RPC valid response returns a 'result' and a null 'error'. */ res_val = json_object_get(val, "result"); err_val = json_object_get(val, "error"); if (!res_val || (err_val && !json_is_null(err_val))) { char *s; if (err_val) s = json_dumps(err_val, JSON_INDENT(3)); else s = strdup("(unknown reason)"); applog(LOG_ERR, "JSON-RPC call failed: %s", s); free(s); goto err_out; } if (hi.reason) json_object_set_new(val, "reject-reason", json_string(hi.reason)); databuf_free(&all_data); curl_slist_free_all(headers); curl_easy_reset(curl); return val; err_out: free(hi.lp_path); free(hi.reason); free(hi.stratum_url); databuf_free(&all_data); curl_slist_free_all(headers); curl_easy_reset(curl); return NULL; }
static int testLongHeaderGet () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; char *url; struct curl_slist *header = NULL; int i; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ , 11080, &apc_all, NULL, &ahc_echo, "GET", MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (VERY_LONG / 2), MHD_OPTION_END); if (d == NULL) return 16; zzuf_socat_start (); for (i = 0; i < LOOP_COUNT; i++) { fprintf (stderr, "."); c = curl_easy_init (); url = malloc (VERY_LONG); memset (url, 'a', VERY_LONG); url[VERY_LONG - 1] = '\0'; url[VERY_LONG / 2] = ':'; url[VERY_LONG / 2 + 1] = ' '; header = curl_slist_append (header, url); curl_easy_setopt (c, CURLOPT_HTTPHEADER, header); curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world"); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, CURL_TIMEOUT); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, CURL_TIMEOUT); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // NOTE: use of CONNECTTIMEOUT without also // setting NOSIGNAL results in really weird // crashes on my system! curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); curl_easy_perform (c); curl_slist_free_all (header); header = NULL; curl_easy_cleanup (c); } fprintf (stderr, "\n"); zzuf_socat_stop (); MHD_stop_daemon (d); free (url); return 0; }
static int testLongUrlGet () { struct MHD_Daemon *d; CURL *c; char buf[2048]; struct CBC cbc; char *url; long code; cbc.buf = buf; cbc.size = 2048; cbc.pos = 0; d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ , 1080, &apc_all, NULL, &ahc_echo, "GET", MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (VERY_LONG / 2), MHD_OPTION_END); if (d == NULL) return 1; c = curl_easy_init (); url = malloc (VERY_LONG); if (url == NULL) { MHD_stop_daemon (d); return 1; } memset (url, 'a', VERY_LONG); url[VERY_LONG - 1] = '\0'; memcpy (url, "http://localhost:1080/", strlen ("http://localhost:1080/")); curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (c, CURLOPT_FAILONERROR, 1); curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L); if (oneone) curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); else curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); /* NOTE: use of CONNECTTIMEOUT without also setting NOSIGNAL results in really weird crashes on my system! */ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1); if (CURLE_OK == curl_easy_perform (c)) { curl_easy_cleanup (c); MHD_stop_daemon (d); free (url); return 2; } if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) { curl_easy_cleanup (c); MHD_stop_daemon (d); free (url); return 4; } curl_easy_cleanup (c); MHD_stop_daemon (d); free (url); if (code != MHD_HTTP_REQUEST_URI_TOO_LONG) return 8; return 0; }
int main( void ) { CURL *curl; CURLcode res; char sourceFileName[] = "/tmp/file"; char targetFileName[] = "/tmp/curlTargetTest.dat"; char sourceHost[] = "source"; char targetHost[] = "target"; char sourceUserPass[] = "user:pass"; char targetUserPass[] = "user:pass"; char url[100]; struct curl_slist *source_pre_cmd = NULL; struct curl_slist *target_pre_cmd = NULL; struct curl_slist *source_post_cmd = NULL; struct curl_slist *target_post_cmd = NULL; char cmd[] = "PWD"; /* just to test */ curl_global_init( CURL_GLOBAL_DEFAULT ); curl = curl_easy_init(); if ( curl ) { sprintf( url, "ftp://%s@%s/%s", targetUserPass, targetHost, targetFileName ); printf( "%s\n", url ); curl_easy_setopt( curl, CURLOPT_URL, url ); /* Set a proxy host */ curl_easy_setopt( curl, CURLOPT_SOURCE_HOST, sourceHost ); /* Set a proxy user and password */ curl_easy_setopt( curl, CURLOPT_SOURCE_USERPWD, sourceUserPass ); /* Set a proxy full file name */ curl_easy_setopt( curl, CURLOPT_SOURCE_PATH, sourceFileName ); /* Set a proxy passive host */ curl_easy_setopt( curl, CURLOPT_PASV_HOST, 0 ); /* optional */ /* build a list of commands to pass to libcurl */ source_pre_cmd = curl_slist_append( source_pre_cmd, cmd ); /* Set a proxy pre-quote command */ curl_easy_setopt( curl, CURLOPT_SOURCE_PREQUOTE, source_pre_cmd ); /* build a list of commands to pass to libcurl */ target_pre_cmd = curl_slist_append( target_pre_cmd, cmd ); /* Set a pre-quote command */ curl_easy_setopt( curl, CURLOPT_PREQUOTE, target_pre_cmd ); /* build a list of commands to pass to libcurl */ source_post_cmd = curl_slist_append( source_post_cmd, cmd ); /* Set a proxy post-quote command */ curl_easy_setopt( curl, CURLOPT_SOURCE_POSTQUOTE, source_post_cmd ); /* build a list of commands to pass to libcurl */ target_post_cmd = curl_slist_append( target_post_cmd, cmd ); /* Set a post-quote command */ curl_easy_setopt( curl, CURLOPT_POSTQUOTE, target_post_cmd ); /* Switch on full protocol/debug output */ curl_easy_setopt( curl, CURLOPT_VERBOSE, 1 ); res = curl_easy_perform( curl ); /* clean up the FTP commands list */ curl_slist_free_all( source_pre_cmd ); curl_slist_free_all( target_pre_cmd ); curl_slist_free_all( source_post_cmd ); curl_slist_free_all( target_post_cmd ); /* always cleanup */ curl_easy_cleanup( curl ); if ( CURLE_OK != res ) { /* we failed */ fprintf( stderr, "curl told us %d\n", res ); } } curl_global_cleanup(); return 0; }
int main(int argc, char **argv) { CURL *curl; CURLcode res; int hd ; struct stat file_info; char *file; char *url; if(argc < 3) return 1; file= argv[1]; url = argv[2]; /* get the file size of the local file */ hd = open(file, O_RDONLY) ; fstat(hd, &file_info); /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if(curl) { /* we want to use our own read function */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); /* which file to upload */ curl_easy_setopt(curl, CURLOPT_READDATA, hd); /* set the ioctl function */ curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl); /* pass the file descriptor to the ioctl callback as well */ curl_easy_setopt(curl, CURLOPT_IOCTLDATA, hd); /* enable "uploading" (which means PUT when doing HTTP) */ curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ; /* specify target URL, and note that this URL should also include a file name, not only a directory (as you can do with GTP uploads) */ curl_easy_setopt(curl,CURLOPT_URL, url); /* and give the size of the upload, this supports large file sizes on systems that have general support for it */ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_info.st_size); /* tell libcurl we can use "any" auth, which lets the lib pick one, but it also costs one extra round-trip and possibly sending of all the PUT data twice!!! */ curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); /* set user name and password for the authentication */ curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password"); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); } close(hd); /* close the local file */ curl_global_cleanup(); return 0; }
/* * This function uses libcurl to send a simple HTTP GET * request with no Content-Type header. * TLS peer verification is enabled, but not HTTP authentication. * The parameters are: * * ctx: Ptr to ACVP_CTX, which contains the server name * url: URL to use for the GET request * * Return value is the HTTP status value from the server * (e.g. 200 for HTTP OK) */ static long acvp_curl_http_get(ACVP_CTX *ctx, char *url) { long http_code = 0; CURL *hnd; struct curl_slist *slist; char user_agent_str[USER_AGENT_STR_MAX + 1]; slist = NULL; /* * Create the Authorzation header if needed */ slist = acvp_add_auth_hdr(ctx, slist); ctx->curl_read_ctr = 0; /* * Create the HTTP User Agent value */ snprintf(user_agent_str, USER_AGENT_STR_MAX, "libacvp/%s", ACVP_VERSION); /* * Setup Curl */ hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_URL, url); curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(hnd, CURLOPT_USERAGENT, user_agent_str); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(hnd, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); if (slist) { curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist); } /* * Always verify the server */ curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 1L); if (ctx->cacerts_file) { curl_easy_setopt(hnd, CURLOPT_CAINFO, ctx->cacerts_file); curl_easy_setopt(hnd, CURLOPT_CERTINFO, 1L); } /* * Mutual-auth */ if (ctx->tls_cert && ctx->tls_key) { curl_easy_setopt(hnd, CURLOPT_SSLCERTTYPE, "PEM"); curl_easy_setopt(hnd, CURLOPT_SSLCERT, ctx->tls_cert); curl_easy_setopt(hnd, CURLOPT_SSLKEYTYPE, "PEM"); curl_easy_setopt(hnd, CURLOPT_SSLKEY, ctx->tls_key); } /* * To record the HTTP data recieved from the server, * set the callback function. */ curl_easy_setopt(hnd, CURLOPT_WRITEDATA, ctx); curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, &acvp_curl_write_callback); if (ctx->curl_buf) { /* Clear the HTTP buffer for next server response */ memzero_s(ctx->curl_buf, ACVP_CURL_BUF_MAX); } /* * Send the HTTP GET request */ curl_easy_perform(hnd); /* * Get the HTTP reponse status code from the server */ curl_easy_getinfo(hnd, CURLINFO_RESPONSE_CODE, &http_code); curl_easy_cleanup(hnd); hnd = NULL; if (slist) { curl_slist_free_all(slist); slist = NULL; } return http_code; }
feed parser::parse_url(const std::string& url, time_t lastmodified, const std::string& etag, newsbeuter::remote_api * api, const std::string& cookie_cache) { std::string buf; CURLcode ret; CURL * easyhandle = curl_easy_init(); if (!easyhandle) { throw exception(_("couldn't initialize libcurl")); } if (ua) { curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, ua); } if (api) { api->configure_handle(easyhandle); } curl_easy_setopt(easyhandle, CURLOPT_URL, url.c_str()); curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, my_write_data); curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &buf); curl_easy_setopt(easyhandle, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(easyhandle, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(easyhandle, CURLOPT_MAXREDIRS, 10); curl_easy_setopt(easyhandle, CURLOPT_FAILONERROR, 1); curl_easy_setopt(easyhandle, CURLOPT_ENCODING, "gzip, deflate"); if (cookie_cache != "") { curl_easy_setopt(easyhandle, CURLOPT_COOKIEFILE, cookie_cache.c_str()); curl_easy_setopt(easyhandle, CURLOPT_COOKIEJAR, cookie_cache.c_str()); } if (to != 0) curl_easy_setopt(easyhandle, CURLOPT_TIMEOUT, to); if (prx) curl_easy_setopt(easyhandle, CURLOPT_PROXY, prx); if (prxauth) { curl_easy_setopt(easyhandle, CURLOPT_PROXYAUTH, CURLAUTH_ANY); curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, prxauth); } curl_easy_setopt(easyhandle, CURLOPT_PROXYTYPE, prxtype); header_values hdrs = { 0, "" }; curl_slist * custom_headers = NULL; if (lastmodified != 0) { curl_easy_setopt(easyhandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); curl_easy_setopt(easyhandle, CURLOPT_TIMEVALUE, lastmodified); curl_easy_setopt(easyhandle, CURLOPT_HEADERDATA, &hdrs); curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, handle_headers); } if (etag.length() > 0) { custom_headers = curl_slist_append(custom_headers, utils::strprintf("If-None-Match: %s", etag.c_str()).c_str()); curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, custom_headers); curl_easy_setopt(easyhandle, CURLOPT_HEADERDATA, &hdrs); curl_easy_setopt(easyhandle, CURLOPT_HEADERFUNCTION, handle_headers); } ret = curl_easy_perform(easyhandle); lm = hdrs.lastmodified; et = hdrs.etag; if (custom_headers) { curl_slist_free_all(custom_headers); } LOG(LOG_DEBUG, "rsspp::parser::parse_url: ret = %d", ret); long status; curl_easy_getinfo(easyhandle, CURLINFO_HTTP_CONNECTCODE, &status); if (status >= 400) { LOG(LOG_USERERROR, _("Error: trying to download feed `%s' returned HTTP status code %ld."), url.c_str(), status); } curl_easy_cleanup(easyhandle); if (ret != 0) { LOG(LOG_ERROR, "rsspp::parser::parse_url: curl_easy_perform returned err %d: %s", ret, curl_easy_strerror(ret)); throw exception(curl_easy_strerror(ret)); } LOG(LOG_INFO, "parser::parse_url: retrieved data for %s: %s", url.c_str(), buf.c_str()); if (buf.length() > 0) { LOG(LOG_DEBUG, "parser::parse_url: handing over data to parse_buffer()"); return parse_buffer(buf.c_str(), buf.length(), url.c_str()); } return feed(); }
int RD_ListCarts(struct rd_cart *carts[], const char hostname[], const char username[], const char passwd[], const char group_name[], const char filter[], const char type[], unsigned *numrecs) { char post[1500]; char url[1500]; CURL *curl=NULL; XML_Parser parser; struct xml_data xml_data; long response_code; char errbuf[CURL_ERROR_SIZE]; CURLcode res; /* Set number of recs so if fail already set */ *numrecs = 0; /* * Setup the CURL call */ memset(&xml_data,0,sizeof(xml_data)); parser=XML_ParserCreate(NULL); XML_SetUserData(parser,&xml_data); XML_SetElementHandler(parser,__ListCartsElementStart, __ListCartsElementEnd); XML_SetCharacterDataHandler(parser,__ListCartsElementData); snprintf(url,1500,"http://%s/rd-bin/rdxport.cgi",hostname); snprintf(post,1500,"COMMAND=6&LOGIN_NAME=%s&PASSWORD=%s&GROUP_NAME=%s&FILTER=%s&TYPE=%s", username,passwd,group_name,filter,type); if((curl=curl_easy_init())==NULL) { return -1; } curl_easy_setopt(curl,CURLOPT_WRITEDATA,parser); curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,__ListCartsCallback); curl_easy_setopt(curl,CURLOPT_URL,url); curl_easy_setopt(curl,CURLOPT_POST,1); curl_easy_setopt(curl,CURLOPT_POSTFIELDS,post); curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1); curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errbuf); // curl_easy_setopt(curl,CURLOPT_VERBOSE,1); res = curl_easy_perform(curl); if(res != CURLE_OK) { size_t len = strlen(errbuf); fprintf(stderr, "\nlibcurl error: (%d)", res); if (len) fprintf(stderr, "%s%s", errbuf, ((errbuf[len-1] != '\n') ? "\n" : "")); else fprintf(stderr, "%s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); return -1; } /* The response OK - so figure out if we got what we wanted.. */ curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code); curl_easy_cleanup(curl); if (response_code > 199 && response_code < 300) { *carts=xml_data.carts; *numrecs = xml_data.carts_quan; return 0; } else { fprintf(stderr," Call Returned Error: %s\n",xml_data.strbuf); return (int)response_code; } }
bool NetworkClient::doUploadMultipartData() { private_initTransfer(); std::vector<FILE *> openedFiles; struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; { std::vector<QueryParam>::iterator it, end = m_QueryParams.end(); for(it=m_QueryParams.begin(); it!=end; it++) { if(it->isFile) { curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, simple_read_callback); std::string fileName = it->value; FILE * curFile = IuCoreUtils::fopen_utf8(it->value.c_str(), "rb"); /* open file to upload */ if(!curFile) { CloseFileList(openedFiles); return false; /* can't continue */ } openedFiles.push_back(curFile); // FIXME: 64bit file size support! long curFileSize = IuCoreUtils::getFileSize(fileName); if(it->contentType.empty()) curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, it->name.c_str(), CURLFORM_FILENAME, it->displayName.c_str(), CURLFORM_STREAM, /*it->value.c_str()*/curFile, CURLFORM_CONTENTSLENGTH, curFileSize, CURLFORM_END); else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, it->name.c_str(), CURLFORM_FILENAME, it->displayName.c_str(), CURLFORM_STREAM, /*it->value.c_str()*/curFile, CURLFORM_CONTENTSLENGTH, curFileSize, CURLFORM_CONTENTTYPE, it->contentType.c_str(), CURLFORM_END); } else { curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, it->name.c_str(), CURLFORM_COPYCONTENTS, it->value.c_str(), CURLFORM_END); } } } curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, formpost); m_currentActionType = atUpload; curl_result = curl_easy_perform(curl_handle); CloseFileList(openedFiles); curl_formfree(formpost); return private_on_finish_request(); }
void notifyCentralServerofShare(uint32 shareErrorCode, float shareValue, char* rejectReason) { CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { /* to keep the response */ std::stringstream responseData; char sURL[256]; bool bValidShare; if( shareErrorCode == 0 ){ bValidShare=true; } else{ bValidShare=false; } //hostname, api key, machine id, validShare, shareValue, rejectReason sprintf(sURL, "http://%s/report.php?key=%s&workerid=%s&validshare=%d&sharevalue=%g&rejectreason=%s", commandlineInput.centralServer, curl_easy_escape(curl, commandlineInput.csApiKey, 0), curl_easy_escape(curl, jsonRequestTarget.authUser, 0), bValidShare, shareValue, curl_easy_escape(curl, rejectReason , 0)); printf("URL Tried: %s", sURL); curl_easy_setopt(curl, CURLOPT_URL, sURL); // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); /* setting a callback function to return the data */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_func); /* passing the pointer to the response as the callback parameter */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData); //curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ //if(res != CURLE_OK) // fprintf(stderr, "curl_easy_perform() failed: %s\n", // curl_easy_strerror(res)); /* always cleanup */ curl_easy_cleanup(curl); std::cout << std::endl << "Reponse from server: " << responseData.str() << std::endl; } curl_global_cleanup(); }
static int perform_authentication(const char* pUrl, const char* pUsername, const char* pPassword, const char* pCaFile, const char* pKey, const char* pHost, const int timeout) { CURL* pCurl = curl_easy_init(); int res = -1; long http_code = 0; struct curl_slist *headers = NULL; char* pUserPass; int len = strlen(pUsername) + strlen(pPassword) + 2; // : separator & trailing null if (!pCurl) { return 0; } syslog(LOG_DEBUG, "Authenticating user %s with %s ...", pUsername, pUrl); pUserPass = malloc(len); sprintf(pUserPass, "%s:%s", pUsername, pPassword); curl_easy_setopt(pCurl, CURLOPT_URL, pUrl); curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, writeFn); curl_easy_setopt(pCurl, CURLOPT_USERPWD, pUserPass); curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, 1); // we don't care about progress curl_easy_setopt(pCurl, CURLOPT_FAILONERROR, 1); // curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, _read_headers); // curl_easy_setopt(pCurl, CURLOPT_WRITEHEADER, stderr); // we don't want to leave our user waiting at the login prompt forever curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, timeout); if (pKey) { int len = 11 + strlen(pKey) + 2; char* pHeader = malloc(len); syslog(LOG_DEBUG, "Authenticating with key %s", pKey); sprintf(pHeader, "X-Api-Key: %s\r\n", pKey); headers = curl_slist_append(headers, pHeader); curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, headers); memset(pHeader, '\0', len); free(pHeader); } if (pHost) { int len = 11 + strlen(pKey) + 2; char* pHeader = malloc(len); sprintf(pHeader, "X-Real-IP: %s\r\n", pKey); headers = curl_slist_append(headers, pHeader); curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, headers); memset(pHeader, '\0', len); free(pHeader); } // SSL needs 16k of random stuff. We'll give it some space in RAM. if (strlen(pUrl) > 5 && strncmp(pUrl, "https", 5) == 0) { curl_easy_setopt(pCurl, CURLOPT_RANDOM_FILE, "/dev/urandom"); curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(pCurl, CURLOPT_USE_SSL, CURLUSESSL_ALL); if (pCaFile) { curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 2); curl_easy_setopt(pCurl, CURLOPT_CAINFO, pCaFile); } else { curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0); } } // synchronous, but we don't really care res = curl_easy_perform(pCurl); memset(pUserPass, '\0', len); free(pUserPass); if (headers) { curl_slist_free_all(headers); } if (res) { curl_easy_getinfo (pCurl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code != 200) res = 22; } curl_easy_cleanup(pCurl); syslog(LOG_DEBUG, "Authentication %s.", res != 22 ? "successful" : "failed"); return res; }
static auth_result url_add_listener (auth_client *auth_user) { client_t *client = auth_user->client; auth_t *auth = auth_user->auth; auth_url *url = auth->state; auth_thread_data *atd = auth_user->thread_data; int res = 0, ret = AUTH_FAILED, poffset = 0; struct build_intro_contents *x; char *userpwd = NULL, post [8192]; if (url->addurl == NULL || client == NULL) return AUTH_OK; if (url->stop_req_until) { time_t now = time(NULL); if (url->stop_req_until <= now) { INFO1 ("restarting url after timeout on %s", auth_user->mount); url->stop_req_until = 0; } else { if (auth->flags & AUTH_SKIP_IF_SLOW) { client->flags |= CLIENT_AUTHENTICATED; return AUTH_OK; } return AUTH_FAILED; } } do { ice_config_t *config = config_get_config (); char *user_agent, *username, *password, *mount, *ipaddr, *referer, *current_listeners, *server = util_url_escape (config->hostname); int port = config->port; config_release_config (); const char *tmp = httpp_getvar (client->parser, "user-agent"); if (tmp == NULL) tmp = "-"; user_agent = util_url_escape (tmp); if (client->username) username = util_url_escape (client->username); else username = strdup (""); if (client->password) password = util_url_escape (client->password); else password = strdup (""); /* get the full uri (with query params if available) */ tmp = httpp_getvar (client->parser, HTTPP_VAR_QUERYARGS); snprintf (post, sizeof post, "%s%s", auth_user->mount, tmp ? tmp : ""); mount = util_url_escape (post); ipaddr = util_url_escape (client->connection.ip); tmp = httpp_getvar (client->parser, "referer"); referer = tmp ? util_url_escape (tmp) : strdup (""); current_listeners = stats_get_value(auth->mount, "listeners"); if (current_listeners == NULL) current_listeners = strdup(""); poffset = snprintf (post, sizeof (post), "action=listener_add&server=%s&port=%d&client=%" PRIu64 "&mount=%s" "&user=%s&pass=%s&ip=%s&agent=%s&referer=%s&listeners=%s", server, port, client->connection.id, mount, username, password, ipaddr, user_agent, referer, current_listeners); free (current_listeners); free (server); free (mount); free (referer); free (user_agent); free (username); free (password); free (ipaddr); } while (0); if (url->header_chk_list) { int c = url->header_chk_count, remaining = sizeof(post) - poffset; char *cur_header = url->header_chk_list; const char *prefix = (url->header_chk_prefix && isalnum (url->header_chk_prefix[0])) ? url->header_chk_prefix : "ClientHeader-"; for (; c ; c--) { int len = strlen (cur_header); const char *val = httpp_getvar (client->parser, cur_header); if (val) { char *valesc = util_url_escape (val); int r = snprintf (post+poffset, remaining, "&%s%s=%s", prefix, cur_header, valesc); free (valesc); if (ret < 0 || ret > remaining) { WARN2 ("client from %s (on %s), with long POST", &client->connection.ip[0], auth_user->mount); return AUTH_FAILED; } poffset += r; } cur_header += (len + 1); // get past next nul } } if (strchr (url->addurl, '@') == NULL) { if (url->userpwd) curl_easy_setopt (atd->curl, CURLOPT_USERPWD, url->userpwd); else { /* auth'd requests may not have a user/pass, but may use query args */ if (client->username && client->password) { int len = strlen (client->username) + strlen (client->password) + 2; userpwd = malloc (len); snprintf (userpwd, len, "%s:%s", client->username, client->password); curl_easy_setopt (atd->curl, CURLOPT_USERPWD, userpwd); } else curl_easy_setopt (atd->curl, CURLOPT_USERPWD, ""); } } else { /* url has user/pass but libcurl may need to clear any existing settings */ curl_easy_setopt (atd->curl, CURLOPT_USERPWD, ""); } curl_easy_setopt (atd->curl, CURLOPT_URL, url->addurl); curl_easy_setopt (atd->curl, CURLOPT_POSTFIELDS, post); curl_easy_setopt (atd->curl, CURLOPT_WRITEHEADER, auth_user); curl_easy_setopt (atd->curl, CURLOPT_WRITEDATA, auth_user); atd->errormsg[0] = '\0'; free (atd->location); atd->location = NULL; /* setup in case intro data is returned */ x = (void *)client->refbuf->data; x->type = 0; x->head = NULL; x->intro_len = 0; x->tailp = &x->head; DEBUG2 ("handler %d (%s) sending request", auth_user->handler, auth_user->mount); res = curl_easy_perform (atd->curl); DEBUG2 ("handler %d (%s) request finished", auth_user->handler, auth_user->mount); free (userpwd); if (client->flags & CLIENT_AUTHENTICATED) { if (client->flags & CLIENT_HAS_INTRO_CONTENT) { client->refbuf->next = x->head; DEBUG3 ("intro (%d) received %lu for %s", x->type, (unsigned long)x->intro_len, client->connection.ip); } if (x->head == NULL) client->flags &= ~CLIENT_HAS_INTRO_CONTENT; x->head = NULL; ret = AUTH_OK; } if (res) { url->stop_req_until = time (NULL) + url->stop_req_duration; /* prevent further attempts for a while */ WARN3 ("auth to server %s (%s) failed with %s", url->addurl, auth_user->mount, atd->errormsg); INFO1 ("will not auth new listeners for %d seconds", url->stop_req_duration); if (auth->flags & AUTH_SKIP_IF_SLOW) { client->flags |= CLIENT_AUTHENTICATED; ret = AUTH_OK; } } /* better cleanup memory */ while (x->head) { refbuf_t *n = x->head; x->head = n->next; n->next = NULL; refbuf_release (n); } if (x->type) mpeg_cleanup (&x->sync); if (atd->location) { client_send_302 (client, atd->location); auth_user->client = NULL; free (atd->location); atd->location = NULL; } else if (atd->errormsg[0]) { INFO3 ("listener %s (%s) returned \"%s\"", client->connection.ip, url->addurl, atd->errormsg); if (atoi (atd->errormsg) == 403) { auth_user->client = NULL; client_send_403 (client, atd->errormsg+4); } } return ret; }
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params) { static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle; char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; if ( didinit == 0 ) { didinit = 1; curl_global_init(CURL_GLOBAL_ALL); //init the curl session } if ( USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0) ) { if ( (databuf= Jay_NXTrequest(command,params)) != 0 ) return(databuf); } numretries = 0; if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 ) specialcase = 1; else specialcase = 0; if ( url[0] == 0 ) strcpy(url,"http://127.0.0.1:7876/nxt"); if ( specialcase != 0 && 0 ) printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params); try_again: if ( retstrp != 0 ) *retstrp = 0; starttime = OS_milliseconds(); curl_handle = curl_easy_init(); init_string(&s); headers = curl_slist_append(0,"Expect:"); curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl_handle,CURLOPT_URL, url); curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback if ( strncmp(url,"https",5) == 0 ) { curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0); curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0); } if ( userpass != 0 ) curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass); databuf = 0; if ( params != 0 ) { if ( command != 0 && specialcase == 0 ) { len = strlen(params); if ( len > 0 && params[0] == '[' && params[len-1] == ']' ) { bracket0 = bracket1 = (char *)""; } else { bracket0 = (char *)"["; bracket1 = (char *)"]"; } databuf = (char *)malloc(256 + strlen(command) + strlen(params)); sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1); //printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf); // } //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params); curl_easy_setopt(curl_handle,CURLOPT_POST,1L); if ( databuf != 0 ) curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,databuf); else curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,params); } //laststart = milliseconds(); res = curl_easy_perform(curl_handle); curl_slist_free_all(headers); curl_easy_cleanup(curl_handle); if ( databuf != 0 ) // clean up temporary buffer { free(databuf); databuf = 0; } if ( res != CURLE_OK ) { numretries++; if ( specialcase != 0 ) { printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); free(s.ptr); return(0); } else if ( numretries >= 1 ) { printf("Maximum number of retries exceeded!\n"); free(s.ptr); return(0); } printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); free(s.ptr); sleep((1<<numretries)); goto try_again; } else { if ( command != 0 && specialcase == 0 ) { count++; elapsedsum += (OS_milliseconds() - starttime); if ( (count % 10000) == 0) printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url); if ( retstrp != 0 ) { *retstrp = s.ptr; return(s.ptr); } return(post_process_bitcoind_RPC(debugstr,command,s.ptr,params)); } else { if ( 0 && specialcase != 0 ) fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,s.ptr); count2++; elapsedsum2 += (OS_milliseconds() - starttime); if ( (count2 % 10000) == 0) printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command); return(s.ptr); } } printf("bitcoind_RPC: impossible case\n"); free(s.ptr); return(0); }
int main(void) { CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if(curl) { char nline[256]; curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* start cookie engine */ res = curl_easy_perform(curl); if(res != CURLE_OK) { fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res)); return 1; } print_cookies(curl); printf("Erasing curl's knowledge of cookies!\n"); curl_easy_setopt(curl, CURLOPT_COOKIELIST, "ALL"); print_cookies(curl); printf("-----------------------------------------------\n" "Setting a cookie \"PREF\" via cookie interface:\n"); #ifdef WIN32 #define snprintf _snprintf #endif /* Netscape format cookie */ snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%lu\t%s\t%s", ".google.com", "TRUE", "/", "FALSE", (unsigned long)time(NULL) + 31337UL, "PREF", "hello google, i like you very much!"); res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline); if(res != CURLE_OK) { fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res)); return 1; } /* HTTP-header style cookie. If you use the Set-Cookie format and don't specify a domain then the cookie is sent for any domain and will not be modified, likely not what you intended. Starting in 7.43.0 any-domain cookies will not be exported either. For more information refer to the CURLOPT_COOKIELIST documentation. */ snprintf(nline, sizeof(nline), "Set-Cookie: OLD_PREF=3d141414bf4209321; " "expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com"); res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline); if(res != CURLE_OK) { fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res)); return 1; } print_cookies(curl); res = curl_easy_perform(curl); if(res != CURLE_OK) { fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res)); return 1; } curl_easy_cleanup(curl); } else { fprintf(stderr, "Curl init failed!\n"); return 1; } curl_global_cleanup(); return 0; }
int main(int argc, char* argv[]) { CURL* curl; CURLcode res; struct curl_httppost* formpost = NULL; struct curl_httppost* lastptr = NULL; struct curl_slist* headerlist = NULL; static const char buf[] = "Expect:"; int fd; struct stat fst; char* fbuf = NULL; int i; if ((fd = open(FILENAME, O_RDONLY)) < 0) { perror(FILENAME); return EXIT_FAILURE; } if (fstat(fd, &fst) < 0) { perror(FILENAME); return EXIT_FAILURE; } if ((fbuf = (char*) malloc(fst.st_size)) == NULL) { perror("malloc"); return EXIT_FAILURE; } if (read(fd, (void*) fbuf, fst.st_size) < 0) { perror(FILENAME); return EXIT_FAILURE; } close(fd); curl_global_init(CURL_GLOBAL_NOTHING); /* Init curl vars */ /* Add the file to the request */ curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "sendfile", CURLFORM_BUFFER, FILENAME, CURLFORM_BUFFERPTR, fbuf, CURLFORM_BUFFERLENGTH, fst.st_size, CURLFORM_END); for (i = 0; i < 10; i++) { printf("%d\n", i); curl = curl_easy_init(); /* Init an easy_session */ headerlist = curl_slist_append(headerlist, buf); if (curl) { /* Set the request uri */ curl_easy_setopt(curl, CURLOPT_URL, SERVER); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); /* Send the request */ res = curl_easy_perform(curl); if (res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); } else { fprintf(stderr, "curl: init failed\n"); } } curl_slist_free_all(headerlist); curl_formfree(formpost); curl_global_cleanup(); free(fbuf); return EXIT_SUCCESS; }