[OpenWrt-Devel] uclient-fetch add ability to pass custom http headers

Sergey Ponomarev stokito at gmail.com
Sun Jan 26 20:46:49 EST 2020


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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20200127/ce3a08f7/attachment.htm>
-------------- next part --------------
_______________________________________________
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