tool: add "variable" support

Add support for command line variables. Set variables with --variable
name=content or --variable name@file (where "file" can be stdin if set
to a single dash (-)).

Variable content is expanded in option parameters using "{{name}}"
(without the quotes) if the option name is prefixed with
"--expand-". This gets the contents of the variable "name" inserted, or
a blank if the name does not exist as a variable. Insert "{{" verbatim
in the string by prefixing it with a backslash, like "\\{{".

Import an environment variable with --variable %name. It makes curl exit
with an error if the environment variable is not set. It can also rather
get a default value if the variable does not exist, using =content or
@file like shown above.

Example: get the USER environment variable into the URL:

 --variable %USER
 --expand-url = "https://example.com/api/{{USER}}/method"

When expanding variables, curl supports a set of functions that can make
the variable contents more convenient to use. It can trim leading and
trailing white space with "trim", output the contents as a JSON quoted
string with "json", URL encode it with "url" and base 64 encode it with
"b64". To apply functions to a variable expansion, add them colon
separated to the right side of the variable. They are then performed in
a left to right order.

Example: get the contents of a file called $HOME/.secret into a variable
called "fix". Make sure that the content is trimmed and percent-encoded
sent as POST data:

  --variable %HOME=/home/default
  --expand-variable fix@{{HOME}}/.secret
  --expand-data "{{fix:trim:url}}"
  https://example.com/

Documented. Many new test cases.

Co-brainstormed-by: Emanuele Torre
Assisted-by: Jat Satiro
Closes #11346
This commit is contained in:
Daniel Stenberg 2023-07-31 11:50:28 +02:00
parent 47a3e6e577
commit 2e160c9c65
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
32 changed files with 1562 additions and 258 deletions

View file

@ -275,6 +275,7 @@ DPAGES = \
use-ascii.d \
user-agent.d \
user.d \
variable.d \
verbose.d \
version.d \
write-out.d \

View file

@ -21,12 +21,12 @@ if so, the colon or equals characters can be used as separators. If the option
is specified with one or two dashes, there can be no colon or equals character
between the option and its parameter.
If the parameter contains whitespace (or starts with : or =), the parameter
must be enclosed within quotes. Within double quotes, the following escape
sequences are available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash
preceding any other letter is ignored.
If the parameter contains whitespace or starts with a colon (:) or equals sign
(=), it must be specified enclosed within double quotes (\&"). Within double
quotes the following escape sequences are available: \\\\, \\", \\t, \\n, \\r
and \\v. A backslash preceding any other letter is ignored.
If the first column of a config line is a '#' character, the rest of the line
If the first non-blank column of a config line is a '#' character, that line
will be treated as a comment.
Only write one option per physical line in the config file. A single line is

View file

@ -97,6 +97,48 @@ that getting many files from the same server do not use multiple connects /
handshakes. This improves speed. Connection re-use can only be done for URLs
specified for a single command line invocation and cannot be performed between
separate curl runs.
.SH VARIABLES
Starting in curl 8.3.0, curl supports command line variables. Set variables
with --variable name=content or --variable name@file (where "file" can be
stdin if set to a single dash (-)).
Variable contents can expanded in option parameters using "{{name}}" (without
the quotes) if the option name is prefixed with "--expand-". This gets the
contents of the variable "name" inserted, or a blank if the name does not
exist as a variable. Insert "{{" verbatim in the string by prefixing it with a
backslash, like "\\{{".
You an access and expand environment variables by first importing them. You
can select to either require the environment variable to be set or you can
provide a default value in case it is not already set. Plain --variable %name
imports the variable called 'name' but exits with an error if that environment
variable is not alreadty set. To provide a default value if it is not set, use
--variable %name=content or --variable %name@content.
Example. Get the USER environment variable into the URL, fail if USER is not
set:
--variable '%USER'
--expand-url = "https://example.com/api/{{USER}}/method"
When expanding variables, curl supports a set of functions that can make the
variable contents more convenient to use. It can trim leading and trailing
white space with "trim", it can output the contents as a JSON quoted string
with "json" and it can URL encode the string with "urlencode". You apply
function to a variable expansion, add them colon separated to the right side
of the variable. Variable content holding null bytes that are not encoded when
expanded, will cause error.
Exmaple: get the contents of a file called $HOME/.secret into a variable
called "fix". Make sure that the content is trimmed and percent-encoded sent
as POST data:
--variable %HOME
--expand-variable fix@{{HOME}}/.secret
--expand-data "{{fix:trim:urlencode}}"
https://example.com/
Command line variables and expansions were added in in 8.3.0.
.SH OUTPUT
If not told otherwise, curl writes the received data to stdout. It can be
instructed to instead save that data into a local file, using the --output or

View file

@ -0,0 +1,50 @@
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
SPDX-License-Identifier: curl
Long: variable
Arg: <[%]name=text/@file>
Help: Set variable
Category: curl
Example: --variable name=smith $URL
Added: 8.3.0
See-also: config
Multi: append
---
Set a variable with "name=content" or "name@file" (where "file" can be stdin
if set to a single dash (-)). The name is a case sensitive identifier that
must consist of no other letters than a-z, A-Z, 0-9 or underscore. The
specified content is then associated with this identifier.
The name must be unique within a command line invoke, setting the same
variable name again will be ignored.
The contents of a variable can be referenced in a later command line option
when that option name is prefixed with "--expand-", and the name is used as
"{{name}}" (without the quotes).
--variable can import environment variables into the name space. Opt to either
require the environment variable to be set or provide a default value for the
variable in case it is not already set.
--variable %name imports the variable called 'name' but exits with an error if
that environment variable is not alreadty set. To provide a default value if
the environment variable is not set, use --variable %name=content or
--variable %name@content. Note that on some systems - but not all -
environment variables are case insensitive.
When expanding variables, curl supports a set of functions that can make the
variable contents more convenient to use. You apply a function to a variable
expansion by adding a colon and then list the desired functions in a
comma-separted list that is evaluated in a left-to-right order. Variable
content holding null bytes that are not encoded when expanded, will cause
error.
These are functions that can help you get the value inserted more
conveniently.
"trim" removes all leading and trailing white space.
"json" outputs the content using JSON string quoting rules.
"url" shows the content URL (percent) encoded.
"b64" expands the variable base64 encoded

View file

@ -261,6 +261,7 @@
--use-ascii (-B) 5.0
--user (-u) 4.0
--user-agent (-A) 4.5.1
--variable 8.3.0
--verbose (-v) 4.0
--version (-V) 4.0
--write-out (-w) 6.5