[PATCH] Add --header option to pass additional raw HTTP headers
Sergey Ponomarev
stokito at gmail.com
Sun Jan 26 20:27:50 EST 2020
Signed-off-by: Sergey Ponomarev <stokito at 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 <stokito at 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 at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list