I can’t make curl
to work with "request_header
" array in bash
.
When I pass an "${request_header[@]}
" array into curl command line, it will not work as expected.
But if I hard code the "-H
" one by one in the curl
command line, it works!
Here is the code for testing:
#!/bin/bash
send_example_by_array() {
local -a request_header=()
request_header[0]="-H"
request_header[1]=""Accept: */*""
request_header[2]="-H"
request_header[3]=""Accept-Language: en-US,en;q=0.5""
curl "${request_header[@]}" --verbose --silent --location "https://www.example.com"
}
send_example_by_array
send_example_by_hard_code_headers_in_command_line_one_by_one() {
curl -H "Accept: */*" -H "Accept-Language: en-US,en;q=0.5" --verbose --silent --location "https://www.example.com"
}
send_example_by_hard_code_headers_in_command_line_one_by_one
Here is the output of send_example_by_array
:
As you can see, the "–verbose" print the "double" accept: / headers and output will not return the HTML page content at all.
> Host: www.example.com
> user-agent: curl/7.81.0
> accept: */*
> "accept: */*"
> "accept-language: en-US,en;q=0.5"
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
* stopped the pause stream!
* Connection #0 to host www.example.com left intact
Here is the output of send_example_by_hard_code_headers_in_command_line_one_by_one
:
As you can see, the "–verbose" print the only one "accept: /" header in this case, and it will return the correct HTML page.
> GET / HTTP/2
> Host: www.example.com
> user-agent: curl/7.81.0
> accept: */*
> accept-language: en-US,en;q=0.5
>
...
< content-length: 1256
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
...
</body>
</html>
The problem is, the request_header
is dynamic and it may grow dynamically and it can’t be hard coded one by one.
What’s problem when passing "${request_header[@]}
" to curl
command line? Why not working? and How to fix?
2
Answers
It’s simple! instead of keeping the
-H
flag and header value separate, store them as one string element in the request_header array, each element will have the flag and value together,so when you pass${request_header[@]}
to the curl command, it will treat each element as a separate argument, including the flag and value together!"Accept: ..."
is not a valid HTML header. Get rid of the double quotes surrounding it: