mirror of
https://github.com/curl/curl.git
synced 2026-05-16 19:16:22 +03:00
curl: named globs in output file name for upload glob references
Use parts of text from the upload filename field when that uses globbing
by giving it a name the same way we do it for URL globs. For example, if
you upload three files to a HTTP URL and want to save the corresponding
responses in separate files:
curl -T 'file{<num>1,2,3}' https://upload.example/ -o 'response-#<num>'
Verified by test 2014
Closes #21407
This commit is contained in:
parent
89f38c168c
commit
2238f0921c
7 changed files with 145 additions and 22 deletions
|
|
@ -23,10 +23,10 @@ Example:
|
|||
|
||||
# `--output`
|
||||
|
||||
Write output to the given file instead of stdout. If you are using globbing to
|
||||
fetch multiple documents, you should quote the URL and you can use `#`
|
||||
followed by a number in the filename. That variable is then replaced with the
|
||||
current string for the URL being fetched. Like in:
|
||||
Write output to the given file instead of stdout. If you are using globbing in
|
||||
the URL to fetch multiple documents, you should quote the URL and you can use
|
||||
`#` followed by a number in the filename. That variable gets replaced with the
|
||||
current glob text. Like in:
|
||||
|
||||
curl "http://{one,two}.example.com" -o "file_#1.txt"
|
||||
|
||||
|
|
@ -70,9 +70,9 @@ override curl's internal binary output in terminal prevention:
|
|||
Note that the binary output may be caused by the response being compressed, in
|
||||
which case you may want to use the --compressed option.
|
||||
|
||||
Starting in curl 8.21.0, the separate globbing parts can be named and
|
||||
referenced by their names. The case sensitive alphanumeric name is set
|
||||
enclosed within angle brackets after the opening character. Examples:
|
||||
Since curl 8.21.0, the separate globbing parts can be named and referenced by
|
||||
their names. The case sensitive alphanumeric name is set enclosed within angle
|
||||
brackets after the opening character. Examples:
|
||||
|
||||
curl "https://fun.example/{<num>one,two}.jpg" -o "save-#<num>"
|
||||
|
||||
|
|
@ -80,3 +80,11 @@ enclosed within angle brackets after the opening character. Examples:
|
|||
-o "save-#<range>.txt"
|
||||
|
||||
Referencing a named glob that is not set, causes an error.
|
||||
|
||||
Since curl 8.21.0, you can use parts of the upload filename when it uses
|
||||
globbing by setting a glob name and referencing it the same way you reference
|
||||
named URL globs. For example, if you upload three files to a single fixed HTTP
|
||||
URL and want to save the corresponding responses in separate files:
|
||||
|
||||
curl -T 'file{<num>1,2,3}' \
|
||||
https://upload.example/ -o 'response-#<num>'
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ Upload the specified local file to the remote URL.
|
|||
|
||||
If there is no file part in the specified URL, curl appends the local file
|
||||
name to the end of the URL before the operation starts. You must use a
|
||||
trailing slash (/) on the last directory to prove to curl that there is no
|
||||
trailing slash (`/`) on the last directory to prove to curl that there is no
|
||||
filename or curl thinks that your last directory name is the remote filename
|
||||
to use.
|
||||
|
||||
When putting the local filename at the end of the URL, curl ignores what is on
|
||||
the left side of any slash (/) or backslash (\\) used in the filename and only
|
||||
appends what is on the right side of the rightmost such character.
|
||||
the left side of any slash (`/`) or backslash (`\\`) used in the filename and
|
||||
only appends what is on the right side of the rightmost such character.
|
||||
|
||||
Use the filename `-` (a single dash) to use stdin instead of a given file.
|
||||
Alternately, the filename `.` (a single period) may be specified instead of
|
||||
|
|
@ -45,9 +45,19 @@ You can specify one --upload-file for each URL on the command line. Each
|
|||
--upload-file + URL pair specifies what to upload and to where. curl also
|
||||
supports globbing of the --upload-file argument, meaning that you can upload
|
||||
multiple files to a single URL by using the same URL globbing style supported
|
||||
in the URL.
|
||||
in the URL. Example:
|
||||
|
||||
When uploading to an SMTP server: the uploaded data is assumed to be RFC 5322
|
||||
formatted. It has to feature the necessary set of headers and mail body
|
||||
formatted correctly by the user as curl does not transcode nor encode it
|
||||
further in any way.
|
||||
curl --upload-file 'file{1,2,3}' ftp://ftp.example/
|
||||
|
||||
Since curl 8.21.0, you can use parts of the upload filename when it uses
|
||||
globbing by setting a glob name and referencing that in the same way you
|
||||
reference named URL globs. For example, if you upload three files to a single
|
||||
fixed HTTP URL and want to save the corresponding responses in separate files:
|
||||
|
||||
curl -T 'file{<num>1,2,3}' \
|
||||
https://upload.example/ -o 'response-#<num>'
|
||||
|
||||
When uploading to an SMTP server (aka "sending email"): the uploaded data is
|
||||
assumed to be RFC 5322 formatted. It has to feature the necessary set of
|
||||
headers and mail body formatted correctly by the user as curl does not
|
||||
transcode nor encode it further in any way.
|
||||
|
|
|
|||
|
|
@ -1052,11 +1052,13 @@ static CURLcode setup_outfile(struct OperationConfig *config,
|
|||
return result;
|
||||
}
|
||||
}
|
||||
else if(glob_inuse(&state->urlglob)) {
|
||||
/* fill '#1' ... '#9' terms from URL pattern */
|
||||
else if(glob_inuse(&state->urlglob) || glob_inuse(&state->inglob)) {
|
||||
/* expand '#1' ... '#9' references from URL pattern and named references
|
||||
from the upload file glob */
|
||||
SANITIZEcode sc;
|
||||
CURLcode result =
|
||||
glob_match_url(&per->outfile, u->outfile, &state->urlglob, &sc);
|
||||
glob_match_url(&per->outfile, u->outfile, &state->urlglob,
|
||||
glob_inuse(&state->inglob) ? &state->inglob : NULL, &sc);
|
||||
|
||||
if(sc) {
|
||||
if(sc == SANITIZE_ERR_OUT_OF_MEMORY)
|
||||
|
|
|
|||
|
|
@ -703,7 +703,8 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob)
|
|||
#define MAX_OUTPUT_GLOB_LENGTH (1024 * 1024)
|
||||
|
||||
CURLcode glob_match_url(char **output, const char *filename,
|
||||
struct URLGlob *glob, SANITIZEcode *sc)
|
||||
struct URLGlob *glob, struct URLGlob *glob2,
|
||||
SANITIZEcode *sc)
|
||||
{
|
||||
struct dynbuf dyn;
|
||||
const char *ifilename = filename;
|
||||
|
|
@ -741,7 +742,11 @@ CURLcode glob_match_url(char **output, const char *filename,
|
|||
if(!curlx_str_until(&filename, &name, MAX_GLOBNAME_LEN, '>') &&
|
||||
!curlx_str_single(&filename, '>')) {
|
||||
/* find the correct glob entry */
|
||||
pat = glob_find_name(glob, &name);
|
||||
if(glob_inuse(glob))
|
||||
pat = glob_find_name(glob, &name);
|
||||
if(!pat && glob2 && glob_inuse(glob2))
|
||||
/* scan the second glob list if there is one */
|
||||
pat = glob_find_name(glob2, &name);
|
||||
if(!pat) {
|
||||
/* when the name is given correctly, it needs to be an existing glob
|
||||
name, which makes this an error */
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@ CURLcode glob_url(struct URLGlob *glob, const char *url, curl_off_t *urlnum,
|
|||
FILE *error);
|
||||
CURLcode glob_next_url(char **globbed, struct URLGlob *glob);
|
||||
CURLcode glob_match_url(char **output, const char *filename,
|
||||
struct URLGlob *glob, SANITIZEcode *sc);
|
||||
struct URLGlob *glob, struct URLGlob *glob2,
|
||||
SANITIZEcode *sc);
|
||||
void glob_cleanup(struct URLGlob *glob);
|
||||
bool glob_inuse(struct URLGlob *glob);
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 \
|
|||
test1978 test1979 test1980 test1981 test1982 test1983 test1984 \
|
||||
\
|
||||
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
||||
test2008 test2009 test2010 test2011 test2012 test2013 \
|
||||
test2008 test2009 test2010 test2011 test2012 test2013 test2014 \
|
||||
\
|
||||
test2023 \
|
||||
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
|
||||
|
|
|
|||
97
tests/data/test2014
Normal file
97
tests/data/test2014
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP PUT
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<data crlf="headers" nocheck="yes">
|
||||
HTTP/1.1 200 OK swsbounce
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Accept-Ranges: bytes
|
||||
Content-Length: 6
|
||||
Content-Type: text/html
|
||||
|
||||
-foo-
|
||||
</data>
|
||||
<data1 crlf="headers" nocheck="yes">
|
||||
HTTP/1.1 200 OK
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 20
|
||||
Content-Type: text/html
|
||||
|
||||
the second response
|
||||
</data1>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
upload with glob, output name based on upload glob
|
||||
</name>
|
||||
<command option="no-output">
|
||||
-T '%LOGDIR/upload{%LThej%GT1,2}' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --silent '--output=%LOGDIR/out-#%LThej%GT'
|
||||
</command>
|
||||
|
||||
<file name="%LOGDIR/upload1">
|
||||
first!
|
||||
</file>
|
||||
|
||||
<file2 name="%LOGDIR/upload2">
|
||||
second
|
||||
</file2>
|
||||
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol crlf="headers">
|
||||
PUT /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
Content-Length: 7
|
||||
|
||||
first!
|
||||
PUT /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
Content-Length: 7
|
||||
|
||||
second
|
||||
</protocol>
|
||||
<stdout>
|
||||
%EMPTY
|
||||
</stdout>
|
||||
|
||||
<file name="%LOGDIR/out-1" crlf="headers">
|
||||
HTTP/1.1 200 OK swsbounce
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Accept-Ranges: bytes
|
||||
Content-Length: 6
|
||||
Content-Type: text/html
|
||||
|
||||
-foo-
|
||||
</file>
|
||||
|
||||
<file2 name="%LOGDIR/out-2" crlf="headers">
|
||||
HTTP/1.1 200 OK
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Content-Length: 20
|
||||
Content-Type: text/html
|
||||
|
||||
the second response
|
||||
</file2>
|
||||
|
||||
</verify>
|
||||
</testcase>
|
||||
Loading…
Add table
Add a link
Reference in a new issue