Message ID | CADR0UcUXJS4DkSSR_0-ZKhdEOaOwUn09WpJDpG9NMRYNsjQ8Sw@mail.gmail.com |
---|---|
State | Needs Review / ACK |
Headers | show |
Series | [OpenWrt-Devel] uclient-fetch add ability to pass custom http headers | expand |
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 <stokito@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 <stokito@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);
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);