Hi again, I need to discuss some changes before working on it so please take a look on https://forum.openwrt.org/t/uclient-fetch-add-more-options-from-wget-and-create-uclient-curl-clone-of-curl/54060
I created the patch from CLion and it doesn't contains signoff so just to be sure that it will be processed correctly I regenerated it with git format-patch: >From 8a9562d89891ec886192d7693e60065d0985fedd Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev <stok...@gmail.com> Date: Mon, 27 Jan 2020 03:27:50 +0200 Subject: [PATCH] Add --header option to pass additional raw HTTP headers Signed-off-by: Sergey Ponomarev <stok...@gmail.com> --- uclient-fetch.c | 16 ++++++++++++++++ uclient-http.c | 28 ++++++++++++++++++++++++++++ uclient.h | 1 + 3 files changed, 45 insertions(+) diff --git a/uclient-fetch.c b/uclient-fetch.c index 38c9c53..34cbfd5 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -43,6 +43,7 @@ static const char *user_agent = "uclient-fetch"; static const char *post_data; +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; @@ -340,6 +341,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); @@ -458,6 +460,7 @@ static int usage(const char *progname) " -P <dir> Set directory for output files\n" " --user=<user> HTTP authentication username\n" " --password=<password> HTTP authentication password\n" + " --header=<header> Add HTTP header\n" " --user-agent|-U <str> Set HTTP user agent\n" " --post-data=STRING use the POST method; send STRING as the data\n" " --spider|-s Spider mode - only check file existence\n" @@ -512,6 +515,7 @@ enum { L_CA_CERTIFICATE, L_USER, L_PASSWORD, + L_HEADER, L_USER_AGENT, L_POST_DATA, L_SPIDER, @@ -527,6 +531,7 @@ static const struct option longopts[] = { [L_CA_CERTIFICATE] = { "ca-certificate", required_argument }, [L_USER] = { "user", required_argument }, [L_PASSWORD] = { "password", required_argument }, + [L_HEADER] = { "header", required_argument }, [L_USER_AGENT] = { "user-agent", required_argument }, [L_POST_DATA] = { "post-data", required_argument }, [L_SPIDER] = { "spider", no_argument }, @@ -546,6 +551,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; @@ -580,6 +586,16 @@ int main(int argc, char **argv) password = strdup(optarg); memset(optarg, '*', strlen(optarg)); break; + case L_HEADER: + if (!raw_headers) { + // Max possible count of headers is the count of args (argc) - 2 + // because the first arg is program and last is a URL. + // But user may forget the URL and raw_headers is null terminated so max raw_headers can be argc + raw_headers = calloc(argc, sizeof(char *)); + } + raw_headers[raw_headers_count] = optarg; + raw_headers_count++; + break; case L_USER_AGENT: user_agent = optarg; break; diff --git a/uclient-http.c b/uclient-http.c index c1f7228..a70d445 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; }; @@ -589,6 +590,17 @@ uclient_http_add_auth_header(struct uclient_http *uh) return 0; } +static void +uclient_http_send_raw_headers(const struct uclient_http *uh) { + 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) { @@ -626,6 +638,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 +1039,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.20.1 On Mon, 27 Jan 2020 at 03:46, Sergey Ponomarev <stok...@gmail.com> wrote: > > Hi, > > I making a package that internally will perform a HTTP call to OAuth service > and I need to pass `Authorization: Barer token` as a header. The wget clone > uclient-fetch doesn't have such functionality to pass an additional header > while original wget have it. I can use curl but it uses too much space: > uclient-fetch~ 28Kb while curl ~280kb. > I'm pretty sure that there is thousands of other reasons to pass a custom > header like `Accept: application/json` etc. > So here I made a small patch that adds such functionality to uclient-fetch. > You can specify multiple headers so they all will be stored to raw_headers > list. > uclient-fetch --header="H1: VAL1" --header="H2: VAL2" -O - http://192.168.1.1/ > I tested with Wireshark and all works fine. > > Index: uclient-fetch.c > <+>UTF-8 > =================================================================== > --- uclient-fetch.c (revision fef6d3d311ac45c662c01e0ebd9cb0f6c8d7145c) > +++ uclient-fetch.c (revision 8a9562d89891ec886192d7693e60065d0985fedd) > @@ -43,6 +43,7 @@ > > static const char *user_agent = "uclient-fetch"; > static const char *post_data; > +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; > @@ -340,6 +341,7 @@ > > 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); > > @@ -458,6 +460,7 @@ > " -P <dir> Set directory for output files\n" > " --user=<user> HTTP authentication username\n" > " --password=<password> HTTP authentication password\n" > + " --header=<header> Add HTTP header\n" > " --user-agent|-U <str> Set HTTP user agent\n" > " --post-data=STRING use the POST method; send STRING as the data\n" > " --spider|-s Spider mode - only check file existence\n" > @@ -512,6 +515,7 @@ > L_CA_CERTIFICATE, > L_USER, > L_PASSWORD, > + L_HEADER, > L_USER_AGENT, > L_POST_DATA, > L_SPIDER, > @@ -527,6 +531,7 @@ > [L_CA_CERTIFICATE] = { "ca-certificate", required_argument }, > [L_USER] = { "user", required_argument }, > [L_PASSWORD] = { "password", required_argument }, > + [L_HEADER] = { "header", required_argument }, > [L_USER_AGENT] = { "user-agent", required_argument }, > [L_POST_DATA] = { "post-data", required_argument }, > [L_SPIDER] = { "spider", no_argument }, > @@ -546,6 +551,7 @@ > 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; > @@ -579,6 +585,16 @@ > break; > password = strdup(optarg); > memset(optarg, '*', strlen(optarg)); > + break; > + case L_HEADER: > + if (!raw_headers) { > + // Max possible count of headers is the count of args (argc) - 2 > + // because the first arg is program and last is a URL. > + // But user may forget the URL and raw_headers is null terminated so max > raw_headers can be argc > + raw_headers = calloc(argc, sizeof(char *)); > + } > + raw_headers[raw_headers_count] = optarg; > + raw_headers_count++; > break; > case L_USER_AGENT: > user_agent = optarg; > Index: uclient-http.c > <+>UTF-8 > =================================================================== > --- uclient-http.c (revision fef6d3d311ac45c662c01e0ebd9cb0f6c8d7145c) > +++ uclient-http.c (revision 8a9562d89891ec886192d7693e60065d0985fedd) > @@ -96,6 +96,7 @@ > > uint32_t nc; > > + const char **raw_headers; > struct blob_buf headers; > struct blob_buf meta; > }; > @@ -589,6 +590,17 @@ > return 0; > } > > +static void > +uclient_http_send_raw_headers(const struct uclient_http *uh) { > + 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) > { > @@ -626,6 +638,7 @@ > if (err) > return err; > > + uclient_http_send_raw_headers(uh); > ustream_printf(uh->us, "\r\n"); > > uh->state = HTTP_STATE_HEADERS_SENT; > @@ -1025,6 +1038,21 @@ > blobmsg_add_string(&uh->headers, name, 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) > Index: uclient.h > <+>UTF-8 > =================================================================== > --- uclient.h (revision fef6d3d311ac45c662c01e0ebd9cb0f6c8d7145c) > +++ uclient.h (revision 8a9562d89891ec886192d7693e60065d0985fedd) > @@ -121,6 +121,7 @@ > > 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); > -- Sergey Ponomarev, skype:stokito _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel