Loading docs/curl.1 +3 −0 Original line number Diff line number Diff line Loading @@ -608,6 +608,9 @@ time only. make it discard all "session cookies". This will basically have the same effect as if a new session is started. Typical browsers always discard session cookies when they're closed down. .IP "-J/--remote-header-name" (HTTP) This option tells the -O/--remote-name option to use the server-specified Content-Disposition filename instead of extracting a filename from the URL. .IP "-k/--insecure" (SSL) This option explicitly allows curl to perform "insecure" SSL connections and transfers. All SSL connections are attempted to be made secure by using Loading src/main.c +131 −14 Original line number Diff line number Diff line Loading @@ -615,6 +615,7 @@ struct Configurable { bool post302; bool nokeepalive; /* for keepalive needs */ long alivetime; bool content_disposition; /* use Content-disposition filename */ int default_node_flags; /* default flags to seach for each 'node', which is basically each given URL to transfer */ Loading Loading @@ -819,6 +820,7 @@ static void help(void) " --krb <level> Enable Kerberos with specified security level (F)", " --libcurl <file> Dump libcurl equivalent code of this command line", " --limit-rate <rate> Limit transfer speed to this rate", " -J/--remote-header-name Use the header-provided filename (H)", " -l/--list-only List only names of an FTP directory (F)", " --local-port <num>[-num] Force use of these local port numbers", " -L/--location Follow Location: hints (H)", Loading Loading @@ -1792,6 +1794,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"i", "include", FALSE}, {"I", "head", FALSE}, {"j", "junk-session-cookies", FALSE}, {"J", "remote-header-name", FALSE}, {"k", "insecure", FALSE}, {"K", "config", TRUE}, {"l", "list-only", FALSE}, Loading Loading @@ -2664,6 +2667,14 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ &config->httpreq)) return PARAM_BAD_USE; break; case 'J': /* --remote-header-name */ if (config->include_headers) { warnf(config, "--include and --remote-header-name cannot be combined.\n"); return PARAM_BAD_USE; } config->content_disposition = toggle; break; case 'k': /* allow insecure SSL connects */ config->insecure_ok = toggle; break; Loading Loading @@ -3314,24 +3325,41 @@ static void go_sleep(long ms) static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream) { int res; size_t rc; struct OutStruct *out=(struct OutStruct *)stream; struct Configurable *config = out->config; if(!out->stream) { /* open file for writing */ out->stream=fopen(out->filename, "wb"); if(!out->stream) { warnf(config, "Failed to create the file %s\n", out->filename); /* * Once that libcurl has called back my_fwrite() the returned value * is checked against the amount that was intended to be written, if * it does not match then it fails with CURLE_WRITE_ERROR. So at this * point returning a value different from sz*nmemb indicates failure. */ rc = (0 == (sz * nmemb)) ? 1 : 0; return rc; /* failure */ const size_t err_rc = (sz * nmemb) ? 0 : 1; if(!out->stream) { if (!out->filename) { warnf(config, "Remote filename has no length!\n"); return err_rc; /* Failure */ } if (config->content_disposition) { /* don't overwrite existing files */ FILE* f = fopen(out->filename, "r"); if (f) { fclose(f); warnf(config, "Refusing to overwrite %s: %s\n", out->filename, strerror(EEXIST)); return err_rc; /* Failure */ } } /* open file for writing */ out->stream=fopen(out->filename, "wb"); if(!out->stream) { warnf(config, "Failed to create the file %s: %s\n", out->filename, strerror(errno)); return err_rc; /* failure */ } } Loading @@ -3349,11 +3377,10 @@ static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream) if(config->nobuffer) { /* disable output buffering */ res = fflush(out->stream); int res = fflush(out->stream); if(res) { /* return a value that isn't the same as sz * nmemb */ rc = (0 == (sz * nmemb)) ? 1 : 0; return rc; /* failure */ return err_rc; /* failure */ } } Loading Loading @@ -4049,6 +4076,87 @@ static bool stdin_upload(const char *uploadfile) return curlx_strequal(uploadfile, "-") || curlx_strequal(uploadfile, "."); } static char* parse_filename(char *ptr, int len) { char* copy; char* p; char* q; char quote = 0; /* simple implementation of strndup() */ copy = malloc(len+1); if (!copy) return NULL; strncpy(copy, ptr, len); copy[len] = 0; p = copy; if (*p == '\'' || *p == '"') { /* store the starting quote */ quote = *p; p++; } /* if the filename contains a path, only use filename portion */ q = strrchr(copy, '/'); if (q) { p=q+1; if (!*p) { free(copy); return NULL; } } q = strrchr(p, quote); if (q) *q = 0; if (copy!=p) memmove(copy, p, strlen(p)+1); return copy; } static size_t header_callback(void *ptr, size_t size, size_t nmemb, void *stream) { struct OutStruct* outs = (struct OutStruct*)stream; const char* str = (char*)ptr; const size_t cb = size*nmemb; const char* end = (char*)ptr + cb; if (cb > 20 && curlx_strnequal(str, "Content-disposition:", 20)) { char *p = (char*)str + 20; /* look for the 'filename=' parameter (encoded filenames (*=) are not supported) */ while (1) { char *filename; while (p < end && !isalpha(*p)) p++; if (p > end-9) break; if (memcmp(p, "filename=", 9)) { /* no match, find next parameter */ while ((p < end) && (*p != ';')) p++; continue; } p+=9; filename = parse_filename(p, cb - (p - str)); if (filename) { outs->filename = filename; break; } } } return cb; } static int operate(struct Configurable *config, int argc, argv_item_t argv[]) { Loading Loading @@ -4431,7 +4539,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) pc++; outfile = *pc ? strdup(pc): NULL; } if(!outfile || !*outfile) { if((!outfile || !*outfile) && !config->content_disposition) { helpf(config->errors, "Remote file name has no length!\n"); res = CURLE_WRITE_ERROR; free(url); Loading Loading @@ -5046,6 +5154,12 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) if(config->ftp_pret) my_setopt(curl, CURLOPT_FTP_USE_PRET, TRUE); if ((urlnode->flags & GETOUT_USEREMOTE) && config->content_disposition) { my_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); my_setopt(curl, CURLOPT_HEADERDATA, &outs); } retry_numretries = config->req_retry; retrystart = cutil_tvnow(); Loading @@ -5057,6 +5171,9 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) break; } if (config->content_disposition && outs.stream && !config->mute) printf("curl: Saved to filename '%s'\n", outs.filename); /* if retry-max-time is non-zero, make sure we haven't exceeded the time */ if(retry_numretries && Loading Loading
docs/curl.1 +3 −0 Original line number Diff line number Diff line Loading @@ -608,6 +608,9 @@ time only. make it discard all "session cookies". This will basically have the same effect as if a new session is started. Typical browsers always discard session cookies when they're closed down. .IP "-J/--remote-header-name" (HTTP) This option tells the -O/--remote-name option to use the server-specified Content-Disposition filename instead of extracting a filename from the URL. .IP "-k/--insecure" (SSL) This option explicitly allows curl to perform "insecure" SSL connections and transfers. All SSL connections are attempted to be made secure by using Loading
src/main.c +131 −14 Original line number Diff line number Diff line Loading @@ -615,6 +615,7 @@ struct Configurable { bool post302; bool nokeepalive; /* for keepalive needs */ long alivetime; bool content_disposition; /* use Content-disposition filename */ int default_node_flags; /* default flags to seach for each 'node', which is basically each given URL to transfer */ Loading Loading @@ -819,6 +820,7 @@ static void help(void) " --krb <level> Enable Kerberos with specified security level (F)", " --libcurl <file> Dump libcurl equivalent code of this command line", " --limit-rate <rate> Limit transfer speed to this rate", " -J/--remote-header-name Use the header-provided filename (H)", " -l/--list-only List only names of an FTP directory (F)", " --local-port <num>[-num] Force use of these local port numbers", " -L/--location Follow Location: hints (H)", Loading Loading @@ -1792,6 +1794,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"i", "include", FALSE}, {"I", "head", FALSE}, {"j", "junk-session-cookies", FALSE}, {"J", "remote-header-name", FALSE}, {"k", "insecure", FALSE}, {"K", "config", TRUE}, {"l", "list-only", FALSE}, Loading Loading @@ -2664,6 +2667,14 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ &config->httpreq)) return PARAM_BAD_USE; break; case 'J': /* --remote-header-name */ if (config->include_headers) { warnf(config, "--include and --remote-header-name cannot be combined.\n"); return PARAM_BAD_USE; } config->content_disposition = toggle; break; case 'k': /* allow insecure SSL connects */ config->insecure_ok = toggle; break; Loading Loading @@ -3314,24 +3325,41 @@ static void go_sleep(long ms) static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream) { int res; size_t rc; struct OutStruct *out=(struct OutStruct *)stream; struct Configurable *config = out->config; if(!out->stream) { /* open file for writing */ out->stream=fopen(out->filename, "wb"); if(!out->stream) { warnf(config, "Failed to create the file %s\n", out->filename); /* * Once that libcurl has called back my_fwrite() the returned value * is checked against the amount that was intended to be written, if * it does not match then it fails with CURLE_WRITE_ERROR. So at this * point returning a value different from sz*nmemb indicates failure. */ rc = (0 == (sz * nmemb)) ? 1 : 0; return rc; /* failure */ const size_t err_rc = (sz * nmemb) ? 0 : 1; if(!out->stream) { if (!out->filename) { warnf(config, "Remote filename has no length!\n"); return err_rc; /* Failure */ } if (config->content_disposition) { /* don't overwrite existing files */ FILE* f = fopen(out->filename, "r"); if (f) { fclose(f); warnf(config, "Refusing to overwrite %s: %s\n", out->filename, strerror(EEXIST)); return err_rc; /* Failure */ } } /* open file for writing */ out->stream=fopen(out->filename, "wb"); if(!out->stream) { warnf(config, "Failed to create the file %s: %s\n", out->filename, strerror(errno)); return err_rc; /* failure */ } } Loading @@ -3349,11 +3377,10 @@ static size_t my_fwrite(void *buffer, size_t sz, size_t nmemb, void *stream) if(config->nobuffer) { /* disable output buffering */ res = fflush(out->stream); int res = fflush(out->stream); if(res) { /* return a value that isn't the same as sz * nmemb */ rc = (0 == (sz * nmemb)) ? 1 : 0; return rc; /* failure */ return err_rc; /* failure */ } } Loading Loading @@ -4049,6 +4076,87 @@ static bool stdin_upload(const char *uploadfile) return curlx_strequal(uploadfile, "-") || curlx_strequal(uploadfile, "."); } static char* parse_filename(char *ptr, int len) { char* copy; char* p; char* q; char quote = 0; /* simple implementation of strndup() */ copy = malloc(len+1); if (!copy) return NULL; strncpy(copy, ptr, len); copy[len] = 0; p = copy; if (*p == '\'' || *p == '"') { /* store the starting quote */ quote = *p; p++; } /* if the filename contains a path, only use filename portion */ q = strrchr(copy, '/'); if (q) { p=q+1; if (!*p) { free(copy); return NULL; } } q = strrchr(p, quote); if (q) *q = 0; if (copy!=p) memmove(copy, p, strlen(p)+1); return copy; } static size_t header_callback(void *ptr, size_t size, size_t nmemb, void *stream) { struct OutStruct* outs = (struct OutStruct*)stream; const char* str = (char*)ptr; const size_t cb = size*nmemb; const char* end = (char*)ptr + cb; if (cb > 20 && curlx_strnequal(str, "Content-disposition:", 20)) { char *p = (char*)str + 20; /* look for the 'filename=' parameter (encoded filenames (*=) are not supported) */ while (1) { char *filename; while (p < end && !isalpha(*p)) p++; if (p > end-9) break; if (memcmp(p, "filename=", 9)) { /* no match, find next parameter */ while ((p < end) && (*p != ';')) p++; continue; } p+=9; filename = parse_filename(p, cb - (p - str)); if (filename) { outs->filename = filename; break; } } } return cb; } static int operate(struct Configurable *config, int argc, argv_item_t argv[]) { Loading Loading @@ -4431,7 +4539,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) pc++; outfile = *pc ? strdup(pc): NULL; } if(!outfile || !*outfile) { if((!outfile || !*outfile) && !config->content_disposition) { helpf(config->errors, "Remote file name has no length!\n"); res = CURLE_WRITE_ERROR; free(url); Loading Loading @@ -5046,6 +5154,12 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) if(config->ftp_pret) my_setopt(curl, CURLOPT_FTP_USE_PRET, TRUE); if ((urlnode->flags & GETOUT_USEREMOTE) && config->content_disposition) { my_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); my_setopt(curl, CURLOPT_HEADERDATA, &outs); } retry_numretries = config->req_retry; retrystart = cutil_tvnow(); Loading @@ -5057,6 +5171,9 @@ operate(struct Configurable *config, int argc, argv_item_t argv[]) break; } if (config->content_disposition && outs.stream && !config->mute) printf("curl: Saved to filename '%s'\n", outs.filename); /* if retry-max-time is non-zero, make sure we haven't exceeded the time */ if(retry_numretries && Loading