summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Ponomarev2022-05-09 21:09:09 +0000
committerFelix Fietkau2026-02-13 07:38:05 +0000
commit0392dfc8e8c445fc51a83674b18cc6a2f1700689 (patch)
treebe514857a660f31a8684748ba282961ea6572b30
parent8df3120639a4b4e4779c600742a8ebc4ba6eceb1 (diff)
downloaduclient-0392dfc8e8c445fc51a83674b18cc6a2f1700689.tar.gz
uclient-fetch: Support of --method, --body-data and --body-file
The --method allows executing PUT, DELETE, OPTIONS, HEAD e.g.: wget -O - -q \ --method=PUT \ --body-data='{"id": 42}' \ --header='Content-Type: application/json' \ http://api.example.com/ To avoid clashes with the --post-data/file options, the separate --body-data/file must be used. They are stored to the same post_data and post_file vars. Mutual usage of the options is not allowed, same as in GNU wget. Signed-off-by: Sergey Ponomarev <stokito@gmail.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--tests/cram/test-san_uclient-fetch.t3
-rw-r--r--tests/cram/test_uclient-fetch.t3
-rw-r--r--uclient-fetch.c54
3 files changed, 53 insertions, 7 deletions
diff --git a/tests/cram/test-san_uclient-fetch.t b/tests/cram/test-san_uclient-fetch.t
index dc5fcb4..f37149a 100644
--- a/tests/cram/test-san_uclient-fetch.t
+++ b/tests/cram/test-san_uclient-fetch.t
@@ -18,6 +18,9 @@ check uclient-fetch usage:
\t--user-agent | -U <str>\t\tSet HTTP user agent (esc)
\t--post-data=STRING\t\tuse the POST method; send STRING as the data (esc)
\t--post-file=FILE\t\tuse the POST method; send FILE as the data (esc)
+ \t--method=METHOD\t\tuse the HTTP method e.g. PUT (esc)
+ \t--body-data=STRING\t\twith --method send the STRING in body (esc)
+ \t--body-file=FILE\t\twith --method send the FILE content in body (esc)
\t--spider | -s\t\t\tSpider mode - only check file existence (esc)
\t--timeout=N | -T N\t\tSet connect/request timeout to N seconds (esc)
\t--proxy=on | -Y on\t\tEnable interpretation of proxy env vars (default) (esc)
diff --git a/tests/cram/test_uclient-fetch.t b/tests/cram/test_uclient-fetch.t
index 77fc7ae..c6cf1a3 100644
--- a/tests/cram/test_uclient-fetch.t
+++ b/tests/cram/test_uclient-fetch.t
@@ -18,6 +18,9 @@ check uclient-fetch usage:
\t--user-agent | -U <str>\t\tSet HTTP user agent (esc)
\t--post-data=STRING\t\tuse the POST method; send STRING as the data (esc)
\t--post-file=FILE\t\tuse the POST method; send FILE as the data (esc)
+ \t--method=METHOD\t\tuse the HTTP method e.g. PUT (esc)
+ \t--body-data=STRING\t\twith --method send the STRING in body (esc)
+ \t--body-file=FILE\t\twith --method send the FILE content in body (esc)
\t--spider | -s\t\t\tSpider mode - only check file existence (esc)
\t--timeout=N | -T N\t\tSet connect/request timeout to N seconds (esc)
\t--proxy=on | -Y on\t\tEnable interpretation of proxy env vars (default) (esc)
diff --git a/uclient-fetch.c b/uclient-fetch.c
index 26269f5..43f7d9d 100644
--- a/uclient-fetch.c
+++ b/uclient-fetch.c
@@ -50,7 +50,7 @@ static const char *user_agent = "uclient-fetch";
static const char *method = NULL;
static const char *post_data;
static const char *post_file;
-static char opt_post = 0; /* 1 when --post-data/file is used */
+static char opt_post = 0; /* 1 when --post-data/file is used, 2 when --body-data/file is used */
static struct ustream_ssl_ctx *ssl_ctx;
static const struct ustream_ssl_ops *ssl_ops;
static int quiet = false;
@@ -529,6 +529,9 @@ static void usage(const char *progname)
" --user-agent | -U <str> Set HTTP user agent\n"
" --post-data=STRING use the POST method; send STRING as the data\n"
" --post-file=FILE use the POST method; send FILE as the data\n"
+ " --method=METHOD use the HTTP method e.g. PUT\n"
+ " --body-data=STRING with --method send the STRING in body\n"
+ " --body-file=FILE with --method send the FILE content in body\n"
" --spider | -s Spider mode - only check file existence\n"
" --timeout=N | -T N Set connect/request timeout to N seconds\n"
" --proxy=on | -Y on Enable interpretation of proxy env vars (default)\n"
@@ -595,6 +598,9 @@ enum {
L_USER_AGENT,
L_POST_DATA,
L_POST_FILE,
+ L_METHOD,
+ L_BODY_DATA,
+ L_BODY_FILE,
L_SPIDER,
L_TIMEOUT,
L_CONTINUE,
@@ -614,6 +620,9 @@ static const struct option longopts[] = {
[L_USER_AGENT] = { "user-agent", required_argument, NULL, 0 },
[L_POST_DATA] = { "post-data", required_argument, NULL, 0 },
[L_POST_FILE] = { "post-file", required_argument, NULL, 0 },
+ [L_METHOD] = { "method", required_argument, NULL, 0 },
+ [L_BODY_DATA] = { "body-data", required_argument, NULL, 0 },
+ [L_BODY_FILE] = { "body-file", required_argument, NULL, 0 },
[L_SPIDER] = { "spider", no_argument, NULL, 0 },
[L_TIMEOUT] = { "timeout", required_argument, NULL, 0 },
[L_CONTINUE] = { "continue", no_argument, NULL, 0 },
@@ -700,6 +709,25 @@ int main(int argc, char **argv)
opt_post = 1;
post_file = optarg;
break;
+ case L_METHOD:
+ method = optarg;
+ break;
+ case L_BODY_DATA:
+ if (opt_post) {
+ usage(progname);
+ goto out;
+ }
+ opt_post = 2;
+ post_data = optarg;
+ break;
+ case L_BODY_FILE:
+ if (opt_post) {
+ usage(progname);
+ goto out;
+ }
+ opt_post = 2;
+ post_file = optarg;
+ break;
case L_SPIDER:
no_output = true;
break;
@@ -796,13 +824,25 @@ int main(int argc, char **argv)
}
}
- if (opt_post == 1) {
- method = "POST";
- } else if (no_output) {
- /* Note: GNU wget --spider sends a HEAD and if it failed repeats with a GET */
- method = "HEAD";
+ if (method) {
+ if (opt_post == 1 || no_output) {
+ /* --post-data/file or --spider can't be used with --method */
+ usage(progname);
+ goto out;
+ }
} else {
- method = "GET";
+ if (opt_post == 1) {
+ method = "POST";
+ } else if (opt_post == 2) {
+ /* --body-data/file specified but no --method */
+ usage(progname);
+ goto out;
+ } else if (no_output) {
+ /* Note: GNU wget --spider sends a HEAD and if it failed repeats with a GET */
+ method = "HEAD";
+ } else {
+ method = "GET";
+ }
}
argv += optind;