Skip to content

Commit 2e160c9

Browse files
committed
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
1 parent 47a3e6e commit 2e160c9

32 files changed

+1562
-258
lines changed

docs/cmdline-opts/Makefile.inc

+1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ DPAGES = \
275275
use-ascii.d \
276276
user-agent.d \
277277
user.d \
278+
variable.d \
278279
verbose.d \
279280
version.d \
280281
write-out.d \

docs/cmdline-opts/config.d

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ if so, the colon or equals characters can be used as separators. If the option
2121
is specified with one or two dashes, there can be no colon or equals character
2222
between the option and its parameter.
2323

24-
If the parameter contains whitespace (or starts with : or =), the parameter
25-
must be enclosed within quotes. Within double quotes, the following escape
26-
sequences are available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash
27-
preceding any other letter is ignored.
24+
If the parameter contains whitespace or starts with a colon (:) or equals sign
25+
(=), it must be specified enclosed within double quotes (\&"). Within double
26+
quotes the following escape sequences are available: \\\\, \\", \\t, \\n, \\r
27+
and \\v. A backslash preceding any other letter is ignored.
2828

29-
If the first column of a config line is a '#' character, the rest of the line
29+
If the first non-blank column of a config line is a '#' character, that line
3030
will be treated as a comment.
3131

3232
Only write one option per physical line in the config file. A single line is

docs/cmdline-opts/page-header

+42
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,48 @@ that getting many files from the same server do not use multiple connects /
9797
handshakes. This improves speed. Connection re-use can only be done for URLs
9898
specified for a single command line invocation and cannot be performed between
9999
separate curl runs.
100+
.SH VARIABLES
101+
Starting in curl 8.3.0, curl supports command line variables. Set variables
102+
with --variable name=content or --variable name@file (where "file" can be
103+
stdin if set to a single dash (-)).
104+
105+
Variable contents can expanded in option parameters using "{{name}}" (without
106+
the quotes) if the option name is prefixed with "--expand-". This gets the
107+
contents of the variable "name" inserted, or a blank if the name does not
108+
exist as a variable. Insert "{{" verbatim in the string by prefixing it with a
109+
backslash, like "\\{{".
110+
111+
You an access and expand environment variables by first importing them. You
112+
can select to either require the environment variable to be set or you can
113+
provide a default value in case it is not already set. Plain --variable %name
114+
imports the variable called 'name' but exits with an error if that environment
115+
variable is not alreadty set. To provide a default value if it is not set, use
116+
--variable %name=content or --variable %name@content.
117+
118+
Example. Get the USER environment variable into the URL, fail if USER is not
119+
set:
120+
121+
--variable '%USER'
122+
--expand-url = "https://example.com/api/{{USER}}/method"
123+
124+
When expanding variables, curl supports a set of functions that can make the
125+
variable contents more convenient to use. It can trim leading and trailing
126+
white space with "trim", it can output the contents as a JSON quoted string
127+
with "json" and it can URL encode the string with "urlencode". You apply
128+
function to a variable expansion, add them colon separated to the right side
129+
of the variable. Variable content holding null bytes that are not encoded when
130+
expanded, will cause error.
131+
132+
Exmaple: get the contents of a file called $HOME/.secret into a variable
133+
called "fix". Make sure that the content is trimmed and percent-encoded sent
134+
as POST data:
135+
136+
--variable %HOME
137+
--expand-variable fix@{{HOME}}/.secret
138+
--expand-data "{{fix:trim:urlencode}}"
139+
https://example.com/
140+
141+
Command line variables and expansions were added in in 8.3.0.
100142
.SH OUTPUT
101143
If not told otherwise, curl writes the received data to stdout. It can be
102144
instructed to instead save that data into a local file, using the --output or

docs/cmdline-opts/variable.d

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
2+
SPDX-License-Identifier: curl
3+
Long: variable
4+
Arg: <[%]name=text/@file>
5+
Help: Set variable
6+
Category: curl
7+
Example: --variable name=smith $URL
8+
Added: 8.3.0
9+
See-also: config
10+
Multi: append
11+
---
12+
Set a variable with "name=content" or "name@file" (where "file" can be stdin
13+
if set to a single dash (-)). The name is a case sensitive identifier that
14+
must consist of no other letters than a-z, A-Z, 0-9 or underscore. The
15+
specified content is then associated with this identifier.
16+
17+
The name must be unique within a command line invoke, setting the same
18+
variable name again will be ignored.
19+
20+
The contents of a variable can be referenced in a later command line option
21+
when that option name is prefixed with "--expand-", and the name is used as
22+
"{{name}}" (without the quotes).
23+
24+
--variable can import environment variables into the name space. Opt to either
25+
require the environment variable to be set or provide a default value for the
26+
variable in case it is not already set.
27+
28+
--variable %name imports the variable called 'name' but exits with an error if
29+
that environment variable is not alreadty set. To provide a default value if
30+
the environment variable is not set, use --variable %name=content or
31+
--variable %name@content. Note that on some systems - but not all -
32+
environment variables are case insensitive.
33+
34+
When expanding variables, curl supports a set of functions that can make the
35+
variable contents more convenient to use. You apply a function to a variable
36+
expansion by adding a colon and then list the desired functions in a
37+
comma-separted list that is evaluated in a left-to-right order. Variable
38+
content holding null bytes that are not encoded when expanded, will cause
39+
error.
40+
41+
These are functions that can help you get the value inserted more
42+
conveniently.
43+
44+
"trim" removes all leading and trailing white space.
45+
46+
"json" outputs the content using JSON string quoting rules.
47+
48+
"url" shows the content URL (percent) encoded.
49+
50+
"b64" expands the variable base64 encoded

docs/options-in-versions

+1
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@
261261
--use-ascii (-B) 5.0
262262
--user (-u) 4.0
263263
--user-agent (-A) 4.5.1
264+
--variable 8.3.0
264265
--verbose (-v) 4.0
265266
--version (-V) 4.0
266267
--write-out (-w) 6.5

lib/base64.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232
!defined(CURL_DISABLE_POP3) || \
3333
!defined(CURL_DISABLE_IMAP) || \
3434
!defined(CURL_DISABLE_DOH) || defined(USE_SSL)
35-
36-
#include "urldata.h" /* for the Curl_easy definition */
35+
#include "curl/curl.h"
3736
#include "warnless.h"
3837
#include "curl_base64.h"
3938

4039
/* The last 2 #include files should be in this order */
40+
#ifdef BUILDING_LIBCURL
4141
#include "curl_memory.h"
42+
#endif
4243
#include "memdebug.h"
4344

4445
/* ---- Base64 Encoding/Decoding Table --- */

lib/curl_base64.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@
2424
*
2525
***************************************************************************/
2626

27+
#ifndef BUILDING_LIBCURL
28+
/* this renames functions so that the tool code can use the same code
29+
without getting symbol collisions */
30+
#define Curl_base64_encode(a,b,c,d) curlx_base64_encode(a,b,c,d)
31+
#define Curl_base64url_encode(a,b,c,d) curlx_base64url_encode(a,b,c,d)
32+
#define Curl_base64_decode(a,b,c) curlx_base64_decode(a,b,c)
33+
#endif
34+
2735
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
2836
char **outptr, size_t *outlen);
2937
CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize,
3038
char **outptr, size_t *outlen);
3139
CURLcode Curl_base64_decode(const char *src,
3240
unsigned char **outptr, size_t *outlen);
33-
3441
#endif /* HEADER_CURL_BASE64_H */

projects/generate.bat

+2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ rem
217217
call :element %1 lib "curl_multibyte.c" %3
218218
call :element %1 lib "version_win32.c" %3
219219
call :element %1 lib "dynbuf.c" %3
220+
call :element %1 lib "base64.c" %3
220221
) else if "!var!" == "CURL_SRC_X_H_FILES" (
221222
call :element %1 lib "config-win32.h" %3
222223
call :element %1 lib "curl_setup.h" %3
@@ -228,6 +229,7 @@ rem
228229
call :element %1 lib "curl_multibyte.h" %3
229230
call :element %1 lib "version_win32.h" %3
230231
call :element %1 lib "dynbuf.h" %3
232+
call :element %1 lib "curl_base64.h" %3
231233
) else if "!var!" == "CURL_LIB_C_FILES" (
232234
for /f "delims=" %%c in ('dir /b ..\lib\*.c') do call :element %1 lib "%%c" %3
233235
) else if "!var!" == "CURL_LIB_H_FILES" (

src/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ endif()
6363

6464
# CURL_CFILES, CURLX_CFILES, CURL_HFILES come from Makefile.inc
6565
if(BUILD_STATIC_CURL)
66-
set(CURLX_CFILES ../lib/dynbuf.c)
66+
set(CURLX_CFILES ../lib/dynbuf.c ../lib/base64.c)
6767
endif()
6868

6969
add_executable(

src/Makefile.inc

+9-6
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232
# libcurl has sources that provide functions named curlx_* that aren't part of
3333
# the official API, but we re-use the code here to avoid duplication.
3434
CURLX_CFILES = \
35+
../lib/base64.c \
36+
../lib/curl_multibyte.c \
37+
../lib/dynbuf.c \
38+
../lib/nonblock.c \
3539
../lib/strtoofft.c \
3640
../lib/timediff.c \
37-
../lib/nonblock.c \
38-
../lib/warnless.c \
39-
../lib/curl_multibyte.c \
4041
../lib/version_win32.c \
41-
../lib/dynbuf.c
42+
../lib/warnless.c
4243

4344
CURLX_HFILES = \
4445
../lib/curl_setup.h \
@@ -91,7 +92,8 @@ CURL_CFILES = \
9192
tool_vms.c \
9293
tool_writeout.c \
9394
tool_writeout_json.c \
94-
tool_xattr.c
95+
tool_xattr.c \
96+
var.c
9597

9698
CURL_HFILES = \
9799
slist_wc.h \
@@ -135,7 +137,8 @@ CURL_HFILES = \
135137
tool_vms.h \
136138
tool_writeout.h \
137139
tool_writeout_json.h \
138-
tool_xattr.h
140+
tool_xattr.h \
141+
var.h
139142

140143
CURL_RCFILES = curl.rc
141144

src/tool_cfgable.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "tool_setup.h"
2727
#include "tool_sdecls.h"
2828
#include "tool_urlglob.h"
29+
#include "var.h"
2930

3031
struct GlobalConfig;
3132

@@ -322,6 +323,7 @@ struct GlobalConfig {
322323
unsigned short parallel_max; /* MAX_PARALLEL is the maximum */
323324
bool parallel_connect;
324325
char *help_category; /* The help category, if set */
326+
struct var *variables;
325327
struct OperationConfig *first;
326328
struct OperationConfig *current;
327329
struct OperationConfig *last; /* Always last in the struct */

0 commit comments

Comments
 (0)