You can add a custom HTTP header(s) to request: wget --header='Authorization: Bearer TOKEN' \ --header='If-Modified-Since: Wed, 9 May 2021 12:16:00 GMT' \ https://example.com/
Some headers like Authorization or User-Agent may be already set by --password or --user-agent. We may override them but it's a protection from user itself. To keep code concise the logic omitted. Signed-off-by: Sergey Ponomarev <stok...@gmail.com> --- tests/cram/test-san_uclient-fetch.t | 1 + tests/cram/test_uclient-fetch.t | 1 + uclient-fetch.c | 16 +++++++++++++++ uclient-http.c | 31 +++++++++++++++++++++++++++++ uclient.h | 1 + 5 files changed, 50 insertions(+) diff --git a/tests/cram/test-san_uclient-fetch.t b/tests/cram/test-san_uclient-fetch.t index 435659b..047749a 100644 --- a/tests/cram/test-san_uclient-fetch.t +++ b/tests/cram/test-san_uclient-fetch.t @@ -15,6 +15,7 @@ check uclient-fetch usage: \t--user=<user>\t\t\tHTTP authentication username (esc) \t--password=<password>\t\tHTTP authentication password (esc) \t--user-agent | -U <str>\t\tSet HTTP user agent (esc) + \t--header='Header: value'\t\tAdd HTTP header. Multiple allowed (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--spider | -s\t\t\tSpider mode - only check file existence (esc) diff --git a/tests/cram/test_uclient-fetch.t b/tests/cram/test_uclient-fetch.t index e22aa40..cb70271 100644 --- a/tests/cram/test_uclient-fetch.t +++ b/tests/cram/test_uclient-fetch.t @@ -15,6 +15,7 @@ check uclient-fetch usage: \t--user=<user>\t\t\tHTTP authentication username (esc) \t--password=<password>\t\tHTTP authentication password (esc) \t--user-agent | -U <str>\t\tSet HTTP user agent (esc) + \t--header='Header: value'\t\tAdd HTTP header. Multiple allowed (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--spider | -s\t\t\tSpider mode - only check file existence (esc) diff --git a/uclient-fetch.c b/uclient-fetch.c index 282092e..4efc917 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -44,6 +44,7 @@ static const char *user_agent = "uclient-fetch"; static const char *post_data; static const char *post_file; +static const char **raw_headers = NULL; static struct ustream_ssl_ctx *ssl_ctx; static const struct ustream_ssl_ops *ssl_ops; static int quiet = false; @@ -342,6 +343,7 @@ static int init_request(struct uclient *cl) uclient_http_reset_headers(cl); uclient_http_set_header(cl, "User-Agent", user_agent); + uclient_http_set_raw_headers(cl, raw_headers); if (cur_resume) check_resume_offset(cl); @@ -481,6 +483,7 @@ static int usage(const char *progname) " --continue | -c Continue a partially-downloaded file\n" " --user=<user> HTTP authentication username\n" " --password=<password> HTTP authentication password\n" + " --header='Header: value' Add HTTP header. Multiple allowed\n" " --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" @@ -542,6 +545,7 @@ enum { L_USER, L_PASSWORD, L_USER_AGENT, + L_HEADER, L_POST_DATA, L_POST_FILE, L_SPIDER, @@ -559,6 +563,7 @@ static const struct option longopts[] = { [L_USER] = { "user", required_argument, NULL, 0 }, [L_PASSWORD] = { "password", required_argument, NULL, 0 }, [L_USER_AGENT] = { "user-agent", required_argument, NULL, 0 }, + [L_HEADER] = { "header", required_argument, NULL, 0 }, [L_POST_DATA] = { "post-data", required_argument, NULL, 0 }, [L_POST_FILE] = { "post-file", required_argument, NULL, 0 }, [L_SPIDER] = { "spider", no_argument, NULL, 0 }, @@ -578,6 +583,7 @@ int main(int argc, char **argv) const char *proxy_url; char *username = NULL; char *password = NULL; + int raw_headers_count = 0; struct uclient *cl; int longopt_idx = 0; bool has_cert = false; @@ -626,6 +632,16 @@ int main(int argc, char **argv) case L_USER_AGENT: user_agent = optarg; break; + case L_HEADER: + if (!raw_headers) { + /* Max possible count of headers is the count of args (argc) - 2 + Since the first arg is program and last is a URL. + But user may forget the URL and raw_headers is null terminated so allocate argc */ + raw_headers = calloc(argc, sizeof(char *)); + } + raw_headers[raw_headers_count] = optarg; + raw_headers_count++; + break; case L_POST_DATA: post_data = optarg; break; diff --git a/uclient-http.c b/uclient-http.c index c2bba6b..3d59de8 100644 --- a/uclient-http.c +++ b/uclient-http.c @@ -96,6 +96,7 @@ struct uclient_http { uint32_t nc; + const char **raw_headers; struct blob_buf headers; struct blob_buf meta; }; @@ -587,6 +588,20 @@ uclient_http_add_auth_header(struct uclient_http *uh) return 0; } +static void +uclient_http_send_raw_headers(const struct uclient_http *uh) { + if (!uh->raw_headers) { + return; + } + const char **raw_headers = uh->raw_headers; + const char *raw_header = *raw_headers; + while (raw_header != NULL) { + ustream_printf(uh->us, "%s\r\n", raw_header); + raw_headers++; + raw_header = *raw_headers; + } +} + static int uclient_http_send_headers(struct uclient_http *uh) { @@ -625,6 +640,7 @@ uclient_http_send_headers(struct uclient_http *uh) if (err) return err; + uclient_http_send_raw_headers(uh); ustream_printf(uh->us, "\r\n"); uh->state = HTTP_STATE_HEADERS_SENT; @@ -1026,6 +1042,21 @@ uclient_http_set_header(struct uclient *cl, const char *name, const char *value) return 0; } +int +uclient_http_set_raw_headers(struct uclient *cl, const char **raw_headers) +{ + struct uclient_http *uh = container_of(cl, struct uclient_http, uc); + + if (cl->backend != &uclient_backend_http) + return -1; + + if (uh->state > HTTP_STATE_INIT) + return -1; + + uh->raw_headers = raw_headers; + return 0; +} + static int uclient_http_send_data(struct uclient *cl, const char *buf, unsigned int len) { diff --git a/uclient.h b/uclient.h index 4f37364..f1977bc 100644 --- a/uclient.h +++ b/uclient.h @@ -121,6 +121,7 @@ extern const struct uclient_backend uclient_backend_http; int uclient_http_reset_headers(struct uclient *cl); int uclient_http_set_header(struct uclient *cl, const char *name, const char *value); +int uclient_http_set_raw_headers(struct uclient *cl, const char **raw_headers); int uclient_http_set_request_type(struct uclient *cl, const char *type); int uclient_http_redirect(struct uclient *cl); -- 2.34.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel