<div dir="ltr"><div>Hi,</div><div><br></div><div>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.<br></div><div>I'm pretty sure that there is thousands of other reasons to pass a custom header like `Accept: application/json` etc.</div><div>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.</div><div>uclient-fetch --header="H1: VAL1" --header="H2: VAL2" -O - <a href="http://192.168.1.1/">http://192.168.1.1/</a></div><div>I tested with Wireshark and all works fine.<br></div><div><br></div><div>Index: uclient-fetch.c<br><+>UTF-8<br>===================================================================<br>--- uclient-fetch.c (revision fef6d3d311ac45c662c01e0ebd9cb0f6c8d7145c)<br>+++ uclient-fetch.c        (revision 8a9562d89891ec886192d7693e60065d0985fedd)<br>@@ -43,6 +43,7 @@<br> <br> static const char *user_agent = "uclient-fetch";<br> static const char *post_data;<br>+static const char **raw_headers = NULL;<br> static struct ustream_ssl_ctx *ssl_ctx;<br> static const struct ustream_ssl_ops *ssl_ops;<br> static int quiet = false;<br>@@ -340,6 +341,7 @@<br> <br>        uclient_http_reset_headers(cl);<br>      uclient_http_set_header(cl, "User-Agent", user_agent);<br>+     uclient_http_set_raw_headers(cl, raw_headers);<br>       if (cur_resume)<br>              check_resume_offset(cl);<br> <br>@@ -458,6 +460,7 @@<br>            "  -P <dir>                  Set directory for output files\n"<br>               "  --user=<user>                     HTTP authentication username\n"<br>                 "  --password=<password>             HTTP authentication password\n"<br>+         "  --header=<header>         Add HTTP header\n"<br>              "  --user-agent|-U <str>             Set HTTP user agent\n"<br>          "  --post-data=STRING              use the POST method; send STRING as the data\n"<br>                 "  --spider|-s                     Spider mode - only check file existence\n"<br>@@ -512,6 +515,7 @@<br>         L_CA_CERTIFICATE,<br>    L_USER,<br>      L_PASSWORD,<br>+  L_HEADER,<br>    L_USER_AGENT,<br>        L_POST_DATA,<br>         L_SPIDER,<br>@@ -527,6 +531,7 @@<br>       [L_CA_CERTIFICATE] = { "ca-certificate", required_argument },<br>      [L_USER] = { "user", required_argument },<br>  [L_PASSWORD] = { "password", required_argument },<br>+  [L_HEADER] = { "header", required_argument },<br>      [L_USER_AGENT] = { "user-agent", required_argument },<br>      [L_POST_DATA] = { "post-data", required_argument },<br>        [L_SPIDER] = { "spider", no_argument },<br>@@ -546,6 +551,7 @@<br>       const char *proxy_url;<br>       char *username = NULL;<br>       char *password = NULL;<br>+       int raw_headers_count = 0;<br>   struct uclient *cl;<br>  int longopt_idx = 0;<br>         bool has_cert = false;<br>@@ -579,6 +585,16 @@<br>                                         break;<br>                               password = strdup(optarg);<br>                           memset(optarg, '*', strlen(optarg));<br>+                         break;<br>+                       case L_HEADER:<br>+                               if (!raw_headers) {<br>+                                  // Max possible count of headers is the count of args (argc) - 2<br>+                                     // because the first arg is program and last is a URL.<br>+                                       // But user may forget the URL and raw_headers is null terminated so max raw_headers can be argc<br>+                                     raw_headers = calloc(argc, sizeof(char *));<br>+                          }<br>+                            raw_headers[raw_headers_count] = optarg;<br>+                             raw_headers_count++;<br>                                 break;<br>                       case L_USER_AGENT:<br>                           user_agent = optarg;<br>Index: uclient-http.c<br><+>UTF-8<br>===================================================================<br>--- uclient-http.c    (revision fef6d3d311ac45c662c01e0ebd9cb0f6c8d7145c)<br>+++ uclient-http.c (revision 8a9562d89891ec886192d7693e60065d0985fedd)<br>@@ -96,6 +96,7 @@<br> <br>   uint32_t nc;<br> <br>+     const char **raw_headers;<br>    struct blob_buf headers;<br>     struct blob_buf meta;<br> };<br>@@ -589,6 +590,17 @@<br>    return 0;<br> }<br> <br>+static void<br>+uclient_http_send_raw_headers(const struct uclient_http *uh) {<br>+    const char **raw_headers = uh->raw_headers;<br>+       const char *raw_header = *raw_headers;<br>+       while (raw_header != NULL) {<br>+         ustream_printf(uh->us, "%s\r\n", raw_header);<br>+           raw_headers++;<br>+               raw_header = *raw_headers;<br>+   }<br>+}<br>+<br> static int<br> uclient_http_send_headers(struct uclient_http *uh)<br> {<br>@@ -626,6 +638,7 @@<br>       if (err)<br>             return err;<br> <br>+      uclient_http_send_raw_headers(uh);<br>   ustream_printf(uh->us, "\r\n");<br> <br>     uh->state = HTTP_STATE_HEADERS_SENT;<br>@@ -1025,6 +1038,21 @@<br>      blobmsg_add_string(&uh->headers, name, value);<br>        return 0;<br> }<br>+<br>+int<br>+uclient_http_set_raw_headers(struct uclient *cl, const char **raw_headers)<br>+{<br>+     struct uclient_http *uh = container_of(cl, struct uclient_http, uc);<br>+<br>+      if (cl->backend != &uclient_backend_http)<br>+             return -1;<br>+<br>+        if (uh->state > HTTP_STATE_INIT)<br>+               return -1;<br>+<br>+        uh->raw_headers = raw_headers;<br>+    return 0;<br>+}<br> <br> static int<br> uclient_http_send_data(struct uclient *cl, const char *buf, unsigned int len)<br>Index: uclient.h<br><+>UTF-8<br>===================================================================<br>--- uclient.h  (revision fef6d3d311ac45c662c01e0ebd9cb0f6c8d7145c)<br>+++ uclient.h      (revision 8a9562d89891ec886192d7693e60065d0985fedd)<br>@@ -121,6 +121,7 @@<br> <br> int uclient_http_reset_headers(struct uclient *cl);<br> int uclient_http_set_header(struct uclient *cl, const char *name, const char *value);<br>+int uclient_http_set_raw_headers(struct uclient *cl, const char **raw_headers);<br> int uclient_http_set_request_type(struct uclient *cl, const char *type);<br> int uclient_http_redirect(struct uclient *cl);<br> </div></div>