examples: fix more potential resource leaks, and more
No binary (build failed)
—
(log yok)
| @@ -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) { |
| + | |
| + | /* write to this file */ |
| + | curl_easy_setopt(easy, CURLOPT_WRITEDATA, t->out); |
| - | /* set the same URL */ |
| - | curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html"); |
| + | /* set the same URL */ |
| + | curl_easy_setopt(easy, CURLOPT_URL, "https://localhost:8443/index.html"); |
| - | /* 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); |
| + | /* 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); |
| - | /* enlarge the receive buffer for potentially higher transfer speeds */ |
| - | curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 100000L); |
| + | /* enlarge the receive buffer for potentially higher transfer speeds */ |
| + | curl_easy_setopt(easy, CURLOPT_BUFFERSIZE, 100000L); |
| - | /* HTTP/2 please */ |
| - | curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); |
| + | /* 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)) { |
| + | goto error; |
| + | } |
| - | 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].easy); |
| + | } |
| - | /* add the individual transfer */ |
| - | curl_multi_add_handle(multi_handle, trans[i].hnd); |
| - | } |
| + | curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); |
| - | curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); |
| + | /* We do HTTP/2 so let's stick to one connection per host */ |
| + | curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L); |
| - | /* We do HTTP/2 so let's stick to one connection per host */ |
| - | curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L); |
| + | do { |
| + | CURLMcode mc = curl_multi_perform(multi_handle, &still_running); |
| - | do { |
| - | CURLMcode mc = curl_multi_perform(multi_handle, &still_running); |
| + | if(still_running) |
| + | /* wait for activity, timeout or "nothing" */ |
| + | mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); |
| - | if(still_running) |
| - | /* wait for activity, timeout or "nothing" */ |
| - | mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); |
| + | if(mc) |
| + | break; |
| - | if(mc) |
| - | break; |
| + | } while(still_running); |
| - | } while(still_running); |
| + | error: |
| - | for(i = 0; i < num_transfers; i++) |
| - | curl_multi_remove_handle(multi_handle, trans[i].hnd); |
| + | 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); |
| - | |
| - | 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); |
| + | if(curlHandlePtr) { |
| + | CURLcode result; |
| + | |
| + | curl_easy_setopt(curlHandlePtr, CURLOPT_VERBOSE, 1L); |
| + | |
| + | 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); |
| - | |
| - | #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"); |
| - | |
| - | /* 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) |
| + | if(!curl) |
| + | goto error; |
| + | |
| + | /* what call to write: */ |
| + | curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://secure.site.example"); |
| + | curl_easy_setopt(curl, CURLOPT_HEADERDATA, headerfile); |
| + | |
| + | #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 | |
| - | /* always cleanup */ |
| + | |
| + | /* 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); | |
| - | } |
| - | curl_global_cleanup(); |
| + | if(headerfile) |
| + | fclose(headerfile); |
| - | fclose(headerfile); |
| + | curl_global_cleanup(); |
| - | 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) | |