mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:11:45 +03:00
examples: fix more potential resource leaks, and more
Also: - delete dead code. - sync `http2-download.c` and `http2-upload.c` sources. - simplessl: fix constant expression. - simplessl: avoid `expression is constant` VS2010 warning, drop pragma. - replace large stack buffers with dynamic allocation. - http2-download: fix to fill transfer number. Some of these were pointed out by TIOBE scanner via Coverity 2025.3.0. Closes #19292
This commit is contained in:
parent
4b85e489a4
commit
869143b194
11 changed files with 276 additions and 272 deletions
|
|
@ -80,7 +80,7 @@ static const char *urls[] = {
|
|||
"https://www.un.org",
|
||||
};
|
||||
|
||||
#define MAX_PARALLEL 10 /* number of simultaneous transfers */
|
||||
#define MAX_PARALLEL 10 /* number of simultaneous transfers */
|
||||
#define NUM_URLS sizeof(urls)/sizeof(char *)
|
||||
|
||||
static size_t write_cb(char *data, size_t n, size_t l, void *userp)
|
||||
|
|
@ -88,16 +88,18 @@ static size_t write_cb(char *data, size_t n, size_t l, void *userp)
|
|||
/* take care of the data here, ignored in this example */
|
||||
(void)data;
|
||||
(void)userp;
|
||||
return n*l;
|
||||
return n * l;
|
||||
}
|
||||
|
||||
static void add_transfer(CURLM *cm, unsigned int i, int *left)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
|
||||
curl_multi_add_handle(cm, eh);
|
||||
if(eh) {
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
|
||||
curl_multi_add_handle(cm, eh);
|
||||
}
|
||||
(*left)++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,13 +34,13 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifndef CURLPIPE_MULTIPLEX
|
||||
/* This little trick makes sure that we do not enable pipelining for libcurls
|
||||
old enough to not have this symbol. It is _not_ defined to zero in a recent
|
||||
|
|
@ -49,26 +49,23 @@
|
|||
#endif
|
||||
|
||||
struct transfer {
|
||||
CURL *easy;
|
||||
unsigned int num;
|
||||
FILE *out;
|
||||
CURL *easy;
|
||||
int num;
|
||||
};
|
||||
|
||||
#define NUM_HANDLES 1000
|
||||
|
||||
static void dump(const char *text, unsigned int num, unsigned char *ptr,
|
||||
static void dump(const char *text, int num, unsigned char *ptr,
|
||||
size_t size, char nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
||||
unsigned int width = 0x10;
|
||||
|
||||
if(nohex)
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stderr, "%u %s, %lu bytes (0x%lx)\n",
|
||||
fprintf(stderr, "%d %s, %lu bytes (0x%lx)\n",
|
||||
num, text, (unsigned long)size, (unsigned long)size);
|
||||
|
||||
for(i = 0; i < size; i += width) {
|
||||
|
|
@ -109,12 +106,12 @@ static int my_trace(CURL *handle, curl_infotype type,
|
|||
{
|
||||
const char *text;
|
||||
struct transfer *t = (struct transfer *)userp;
|
||||
unsigned int num = t->num;
|
||||
int num = t->num;
|
||||
(void)handle;
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== %u Info: %s", num, data);
|
||||
fprintf(stderr, "== [%d] Info: %s", num, data);
|
||||
return 0;
|
||||
case CURLINFO_HEADER_OUT:
|
||||
text = "=> Send header";
|
||||
|
|
@ -145,12 +142,12 @@ static int my_trace(CURL *handle, curl_infotype type,
|
|||
static int setup(struct transfer *t, int num)
|
||||
{
|
||||
char filename[128];
|
||||
CURL *hnd;
|
||||
CURL *easy;
|
||||
|
||||
hnd = t->easy = curl_easy_init();
|
||||
easy = t->easy = NULL;
|
||||
|
||||
t->num = num;
|
||||
snprintf(filename, sizeof(filename), "dl-%d", num);
|
||||
|
||||
t->out = fopen(filename, "wb");
|
||||
if(!t->out) {
|
||||
fprintf(stderr, "error: could not open file %s for writing: %s\n",
|
||||
|
|
@ -158,27 +155,31 @@ static int setup(struct transfer *t, int num)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, t->out);
|
||||
easy = t->easy = curl_easy_init();
|
||||
if(easy) {
|
||||
|
||||
/* set the same URL */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html");
|
||||
/* write to this file */
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, t->out);
|
||||
|
||||
/* please be verbose */
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, t);
|
||||
/* set the same URL */
|
||||
curl_easy_setopt(easy, CURLOPT_URL, "https://localhost:8443/index.html");
|
||||
|
||||
/* enlarge the receive buffer for potentially higher transfer speeds */
|
||||
curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 100000L);
|
||||
/* please be verbose */
|
||||
curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(easy, CURLOPT_DEBUGDATA, t);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
/* enlarge the receive buffer for potentially higher transfer speeds */
|
||||
curl_easy_setopt(easy, CURLOPT_BUFFERSIZE, 100000L);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(easy, CURLOPT_PIPEWAIT, 1L);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -188,8 +189,8 @@ static int setup(struct transfer *t, int num)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
CURLcode res;
|
||||
struct transfer trans[NUM_HANDLES];
|
||||
CURLM *multi_handle;
|
||||
struct transfer *trans;
|
||||
CURLM *multi_handle = NULL;
|
||||
int i;
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
int num_transfers;
|
||||
|
|
@ -197,25 +198,30 @@ int main(int argc, char **argv)
|
|||
if(argc > 1) {
|
||||
/* if given a number, do that many transfers */
|
||||
num_transfers = atoi(argv[1]);
|
||||
if((num_transfers < 1) || (num_transfers > NUM_HANDLES))
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
if((num_transfers < 1) || (num_transfers > 1000))
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
}
|
||||
else
|
||||
num_transfers = 3; /* suitable default */
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
|
||||
res = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if(res)
|
||||
return (int)res;
|
||||
|
||||
memset(trans, 0, sizeof(trans));
|
||||
trans = calloc(num_transfers, sizeof(*trans));
|
||||
if(!trans) {
|
||||
fprintf(stderr, "error allocating transfer structs\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
if(!multi_handle)
|
||||
goto error;
|
||||
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
if(setup(&trans[i], i)) {
|
||||
curl_global_cleanup();
|
||||
return 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* add the individual transfer */
|
||||
|
|
@ -233,14 +239,24 @@ int main(int argc, char **argv)
|
|||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
} while(still_running);
|
||||
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
curl_multi_remove_handle(multi_handle, trans[i].easy);
|
||||
curl_easy_cleanup(trans[i].easy);
|
||||
error:
|
||||
|
||||
if(multi_handle) {
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
curl_multi_remove_handle(multi_handle, trans[i].easy);
|
||||
curl_easy_cleanup(trans[i].easy);
|
||||
|
||||
if(trans[i].out)
|
||||
fclose(trans[i].out);
|
||||
}
|
||||
curl_multi_cleanup(multi_handle);
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
free(trans);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -225,14 +225,15 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
if(!multi_handle)
|
||||
goto error;
|
||||
|
||||
easy = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
if(setup(easy, url)) {
|
||||
if(!easy || setup(easy, url)) {
|
||||
fprintf(stderr, "failed\n");
|
||||
curl_global_cleanup();
|
||||
return 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
|
|
@ -272,7 +273,11 @@ int main(int argc, char *argv[])
|
|||
|
||||
} while(transfers); /* as long as we have transfers going */
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
error:
|
||||
|
||||
if(multi_handle)
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
fclose(out_download);
|
||||
|
|
|
|||
|
|
@ -64,8 +64,6 @@
|
|||
#define CURLPIPE_MULTIPLEX 0L
|
||||
#endif
|
||||
|
||||
#define NUM_HANDLES 1000
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define gettimeofday(a, b) my_gettimeofday((a), (b))
|
||||
static int my_gettimeofday(struct timeval *tp, void *tzp)
|
||||
|
|
@ -90,12 +88,12 @@ struct input {
|
|||
FILE *in;
|
||||
FILE *out;
|
||||
size_t bytes_read; /* count up */
|
||||
CURL *hnd;
|
||||
CURL *easy;
|
||||
int num;
|
||||
};
|
||||
|
||||
static void dump(const char *text, int num, unsigned char *ptr, size_t size,
|
||||
char nohex)
|
||||
static void dump(const char *text, int num, unsigned char *ptr,
|
||||
size_t size, char nohex)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
|
|
@ -141,8 +139,8 @@ static void dump(const char *text, int num, unsigned char *ptr, size_t size,
|
|||
}
|
||||
}
|
||||
|
||||
static int my_trace(CURL *handle, curl_infotype type, char *data,
|
||||
size_t size, void *userp)
|
||||
static int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size, void *userp)
|
||||
{
|
||||
char timebuf[60];
|
||||
const char *text;
|
||||
|
|
@ -203,33 +201,33 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
static int setup(struct input *i, int num, const char *upload)
|
||||
static int setup(struct input *t, int num, const char *upload)
|
||||
{
|
||||
char url[256];
|
||||
char filename[128];
|
||||
struct stat file_info;
|
||||
curl_off_t uploadsize;
|
||||
CURL *hnd;
|
||||
CURL *easy;
|
||||
|
||||
hnd = i->hnd = NULL;
|
||||
easy = t->easy = NULL;
|
||||
|
||||
i->num = num;
|
||||
t->num = num;
|
||||
snprintf(filename, sizeof(filename), "dl-%d", num);
|
||||
i->out = fopen(filename, "wb");
|
||||
if(!i->out) {
|
||||
fprintf(stderr, "error: could not open file %s for writing: %s\n", upload,
|
||||
strerror(errno));
|
||||
t->out = fopen(filename, "wb");
|
||||
if(!t->out) {
|
||||
fprintf(stderr, "error: could not open file %s for writing: %s\n",
|
||||
upload, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
snprintf(url, sizeof(url), "https://localhost:8443/upload-%d", num);
|
||||
|
||||
i->in = fopen(upload, "rb");
|
||||
if(!i->in) {
|
||||
fprintf(stderr, "error: could not open file %s for reading: %s\n", upload,
|
||||
strerror(errno));
|
||||
fclose(i->out);
|
||||
i->out = NULL;
|
||||
t->in = fopen(upload, "rb");
|
||||
if(!t->in) {
|
||||
fprintf(stderr, "error: could not open file %s for reading: %s\n",
|
||||
upload, strerror(errno));
|
||||
fclose(t->out);
|
||||
t->out = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -237,51 +235,51 @@ static int setup(struct input *i, int num, const char *upload)
|
|||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
if(stat(upload, &file_info) != 0) {
|
||||
#else
|
||||
if(fstat(fileno(i->in), &file_info) != 0) {
|
||||
if(fstat(fileno(t->in), &file_info) != 0) {
|
||||
#endif
|
||||
fprintf(stderr, "error: could not stat file %s: %s\n", upload,
|
||||
strerror(errno));
|
||||
fclose(i->out);
|
||||
i->out = NULL;
|
||||
fprintf(stderr, "error: could not stat file %s: %s\n",
|
||||
upload, strerror(errno));
|
||||
fclose(t->out);
|
||||
t->out = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uploadsize = file_info.st_size;
|
||||
|
||||
hnd = i->hnd = curl_easy_init();
|
||||
if(hnd) {
|
||||
easy = t->easy = curl_easy_init();
|
||||
if(easy) {
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, i->out);
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, t->out);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(hnd, CURLOPT_READFUNCTION, read_callback);
|
||||
curl_easy_setopt(easy, CURLOPT_READFUNCTION, read_callback);
|
||||
/* read from this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_READDATA, i);
|
||||
curl_easy_setopt(easy, CURLOPT_READDATA, t);
|
||||
/* provide the size of the upload */
|
||||
curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, uploadsize);
|
||||
curl_easy_setopt(easy, CURLOPT_INFILESIZE_LARGE, uploadsize);
|
||||
|
||||
/* send in the URL to store the upload as */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, url);
|
||||
curl_easy_setopt(easy, CURLOPT_URL, url);
|
||||
|
||||
/* upload please */
|
||||
curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
|
||||
curl_easy_setopt(easy, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* please be verbose */
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, i);
|
||||
curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(easy, CURLOPT_DEBUGDATA, t);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
/* we use a self-signed test server, skip verification during debugging */
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
curl_easy_setopt(easy, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(easy, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
curl_easy_setopt(easy, CURLOPT_PIPEWAIT, 1L);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -293,79 +291,83 @@ static int setup(struct input *i, int num, const char *upload)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
CURLcode res;
|
||||
struct input trans[NUM_HANDLES];
|
||||
CURLM *multi_handle;
|
||||
struct input *trans;
|
||||
CURLM *multi_handle = NULL;
|
||||
int i;
|
||||
const char *filename = "index.html";
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
int num_transfers;
|
||||
|
||||
if(argc > 1) {
|
||||
/* if given a number, do that many transfers */
|
||||
num_transfers = atoi(argv[1]);
|
||||
|
||||
if(!num_transfers || (num_transfers > NUM_HANDLES))
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
if((num_transfers < 1) || (num_transfers > 1000))
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
|
||||
if(argc > 2)
|
||||
/* if given a file name, upload this! */
|
||||
filename = argv[2];
|
||||
}
|
||||
else
|
||||
num_transfers = 3;
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
|
||||
res = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if(res)
|
||||
return (int)res;
|
||||
|
||||
memset(trans, 0, sizeof(trans));
|
||||
trans = calloc(num_transfers, sizeof(*trans));
|
||||
if(!trans) {
|
||||
fprintf(stderr, "error allocating transfer structs\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
if(multi_handle) {
|
||||
if(!multi_handle)
|
||||
goto error;
|
||||
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
if(setup(&trans[i], i, filename)) {
|
||||
curl_global_cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* add the individual transfer */
|
||||
curl_multi_add_handle(multi_handle, trans[i].hnd);
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
if(setup(&trans[i], i, filename)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
/* add the individual transfer */
|
||||
curl_multi_add_handle(multi_handle, trans[i].easy);
|
||||
}
|
||||
|
||||
/* We do HTTP/2 so let's stick to one connection per host */
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L);
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
/* We do HTTP/2 so let's stick to one connection per host */
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
} while(still_running);
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
for(i = 0; i < num_transfers; i++)
|
||||
curl_multi_remove_handle(multi_handle, trans[i].hnd);
|
||||
} while(still_running);
|
||||
|
||||
error:
|
||||
|
||||
if(multi_handle) {
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
curl_multi_remove_handle(multi_handle, trans[i].easy);
|
||||
curl_easy_cleanup(trans[i].easy);
|
||||
|
||||
if(trans[i].in)
|
||||
fclose(trans[i].in);
|
||||
if(trans[i].out)
|
||||
fclose(trans[i].out);
|
||||
}
|
||||
curl_multi_cleanup(multi_handle);
|
||||
}
|
||||
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
curl_easy_cleanup(trans[i].hnd);
|
||||
|
||||
if(trans[i].in)
|
||||
fclose(trans[i].in);
|
||||
if(trans[i].out)
|
||||
fclose(trans[i].out);
|
||||
}
|
||||
free(trans);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
|
|
|
|||
|
|
@ -49,28 +49,31 @@ static size_t readfunc(char *ptr, size_t size, size_t nmemb, void *stream)
|
|||
*/
|
||||
static curl_off_t sftpGetRemoteFileSize(const char *i_remoteFile)
|
||||
{
|
||||
CURLcode result = CURLE_GOT_NOTHING;
|
||||
curl_off_t remoteFileSizeByte = -1;
|
||||
CURL *curlHandlePtr = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_VERBOSE, 1L);
|
||||
if(curlHandlePtr) {
|
||||
CURLcode result;
|
||||
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_URL, i_remoteFile);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_NOPROGRESS, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_HEADER, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_FILETIME, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
result = curl_easy_perform(curlHandlePtr);
|
||||
if(CURLE_OK == result) {
|
||||
result = curl_easy_getinfo(curlHandlePtr,
|
||||
CURLINFO_CONTENT_LENGTH_DOWNLOAD_T,
|
||||
&remoteFileSizeByte);
|
||||
if(result)
|
||||
return -1;
|
||||
printf("filesize: %" CURL_FORMAT_CURL_OFF_T "\n", remoteFileSizeByte);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_URL, i_remoteFile);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_NOPROGRESS, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_HEADER, 1L);
|
||||
curl_easy_setopt(curlHandlePtr, CURLOPT_FILETIME, 1L);
|
||||
|
||||
result = curl_easy_perform(curlHandlePtr);
|
||||
if(CURLE_OK == result) {
|
||||
result = curl_easy_getinfo(curlHandlePtr,
|
||||
CURLINFO_CONTENT_LENGTH_DOWNLOAD_T,
|
||||
&remoteFileSizeByte);
|
||||
if(result)
|
||||
return -1;
|
||||
printf("filesize: %" CURL_FORMAT_CURL_OFF_T "\n", remoteFileSizeByte);
|
||||
}
|
||||
curl_easy_cleanup(curlHandlePtr);
|
||||
}
|
||||
curl_easy_cleanup(curlHandlePtr);
|
||||
|
||||
return remoteFileSizeByte;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURL *curl = NULL;
|
||||
CURLcode res;
|
||||
FILE *headerfile;
|
||||
const char *pPassphrase = NULL;
|
||||
|
|
@ -61,98 +61,89 @@ int main(void)
|
|||
const char *pKeyName;
|
||||
const char *pKeyType;
|
||||
|
||||
const char *pEngine;
|
||||
|
||||
#ifdef USE_ENGINE
|
||||
pKeyName = "rsa_test";
|
||||
pKeyType = "ENG";
|
||||
pEngine = "chil"; /* for nCipher HSM... */
|
||||
#else
|
||||
pKeyName = "testkey.pem";
|
||||
pKeyType = "PEM";
|
||||
pEngine = NULL;
|
||||
#endif
|
||||
|
||||
headerfile = fopen(pHeaderFile, "wb");
|
||||
if(!headerfile)
|
||||
return 1;
|
||||
|
||||
res = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if(res) {
|
||||
fclose(headerfile);
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
headerfile = fopen(pHeaderFile, "wb");
|
||||
if(!headerfile)
|
||||
goto error;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* what call to write: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://secure.site.example");
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, headerfile);
|
||||
if(!curl)
|
||||
goto error;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) /* conditional expression is constant */
|
||||
#endif
|
||||
do { /* dummy loop, just to break out from */
|
||||
if(pEngine) {
|
||||
/* use crypto engine */
|
||||
if(curl_easy_setopt(curl, CURLOPT_SSLENGINE, pEngine) != CURLE_OK) {
|
||||
/* load the crypto engine */
|
||||
fprintf(stderr, "cannot set crypto engine\n");
|
||||
break;
|
||||
}
|
||||
if(curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK) {
|
||||
/* set the crypto engine as default */
|
||||
/* only needed for the first time you load
|
||||
an engine in a curl object... */
|
||||
fprintf(stderr, "cannot set crypto engine as default\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* cert is stored PEM coded in file... */
|
||||
/* since PEM is default, we needn't set it for PEM */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
|
||||
/* what call to write: */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://secure.site.example");
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, headerfile);
|
||||
|
||||
/* set the cert for client authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile);
|
||||
|
||||
/* sorry, for engine we must set the passphrase
|
||||
(if the key has one...) */
|
||||
if(pPassphrase)
|
||||
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, pPassphrase);
|
||||
|
||||
/* if we use a key stored in a crypto engine,
|
||||
we must set the key type to "ENG" */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, pKeyType);
|
||||
|
||||
/* set the private key (file or ID in engine) */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyName);
|
||||
|
||||
/* set the file with the certs validating the server */
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, pCACertFile);
|
||||
|
||||
/* disconnect if we cannot validate server's cert */
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
|
||||
/* Perform the request, res gets 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));
|
||||
|
||||
/* we are done... */
|
||||
} while(0);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
#ifdef USE_ENGINE
|
||||
/* use crypto engine. nCipher HSM... */
|
||||
if(curl_easy_setopt(curl, CURLOPT_SSLENGINE, "chil") != CURLE_OK) {
|
||||
/* load the crypto engine */
|
||||
fprintf(stderr, "cannot set crypto engine\n");
|
||||
goto error;
|
||||
}
|
||||
if(curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK) {
|
||||
/* set the crypto engine as default */
|
||||
/* only needed for the first time you load
|
||||
an engine in a curl object... */
|
||||
fprintf(stderr, "cannot set crypto engine as default\n");
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* cert is stored PEM coded in file... */
|
||||
/* since PEM is default, we needn't set it for PEM */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
|
||||
|
||||
/* set the cert for client authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile);
|
||||
|
||||
/* sorry, for engine we must set the passphrase
|
||||
(if the key has one...) */
|
||||
if(pPassphrase)
|
||||
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, pPassphrase);
|
||||
|
||||
/* if we use a key stored in a crypto engine,
|
||||
we must set the key type to "ENG" */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, pKeyType);
|
||||
|
||||
/* set the private key (file or ID in engine) */
|
||||
curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyName);
|
||||
|
||||
/* set the file with the certs validating the server */
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, pCACertFile);
|
||||
|
||||
/* disconnect if we cannot validate server's cert */
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
|
||||
/* Perform the request, res gets 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));
|
||||
|
||||
error:
|
||||
|
||||
/* always cleanup */
|
||||
if(curl)
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(headerfile)
|
||||
fclose(headerfile);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
fclose(headerfile);
|
||||
|
||||
return 0;
|
||||
return (int)res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
size_t room = size * nmemb;
|
||||
size_t len;
|
||||
|
||||
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
|
|
@ -79,17 +80,13 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
|
||||
data = &payload_text[upload_ctx->bytes_read];
|
||||
|
||||
if(data) {
|
||||
size_t len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
size_t room = size * nmemb;
|
||||
size_t len;
|
||||
|
||||
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
|
|
@ -76,17 +77,13 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
|
||||
data = &payload_text[upload_ctx->bytes_read];
|
||||
|
||||
if(data) {
|
||||
size_t len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
size_t room = size * nmemb;
|
||||
size_t len;
|
||||
|
||||
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
|
|
@ -69,17 +70,13 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
|
||||
data = &payload_text[upload_ctx->bytes_read];
|
||||
|
||||
if(data) {
|
||||
size_t len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
size_t room = size * nmemb;
|
||||
size_t len;
|
||||
|
||||
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
|
|
@ -73,17 +74,13 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
|
||||
data = &payload_text[upload_ctx->bytes_read];
|
||||
|
||||
if(data) {
|
||||
size_t len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
size_t room = size * nmemb;
|
||||
size_t len;
|
||||
|
||||
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
|
|
@ -73,17 +74,13 @@ static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
|||
|
||||
data = &payload_text[upload_ctx->bytes_read];
|
||||
|
||||
if(data) {
|
||||
size_t len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue