General Computing
linux curl
Updated Sat, 17 Sep 2022 00:35:51 GMT

How to curl case-insensitive


If I use this link to install docker-compose, I get Not Found error:

[root@hostname ~]# curl -L "https://github.com/docker/compose/releases/download/2.9.0/docker-compose-$(uname -s)-$(uname -m)" -o here
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100     9  100     9    0     0     37      0 --:--:-- --:--:-- --:--:--    37
[root@hostname ~]# cat here
Not Found

That's because the actual file is docker-compose-linux-x86_64 with small l, while:

[root@hostname ~]# echo $(uname -s)-$(uname -m)
Linux-x86_64

It returns capital L.

I saw man curl but did not see any entry for checking case-insensitive link.




Solution

It's not curl that decides case-insensitivity at all link "checking" is the server's decision.

(In other words, HTTP clients do not have the opportunity to see the list of all possible URLs and choose a matching one. The only thing an HTTP client can do is give the exact URL to the server and let the server decide how to respond. Some servers are case-insensitive, some are not.)

But if you already know that you need a lowercase 'linux', you can just transform the uname output before giving it to curl, e.g. by piping it through tr A-Z a-z to change all uppercase letters to lowercase:

docker-$(uname -s | tr A-Z a-z)

or by using Bash's ${var,,} expansion to return a lowercase version of $var:

os=$(uname -s); arch=$(uname -m)
docker-${os,,}-${arch}

Finally, since there's only a small set of accepted values, and because the accepted values aren't guaranteed to be "uname but lowercase" in general, you could indirectly assign each possible value (using if or case blocks), for example:

case $(uname -s) in
    Darwin)    docker_os='darwin';;
    Linux)     docker_os='linux';;
    Cygwin)    docker_os='windows';;
    Microsoft) docker_os='windows';;
    *)         echo "Docker is not supported on this OS!" >&2; exit 1;;
esac

(Note: The 'windows' examples are completely made up. )





Comments (5)

  • +1 – Technically, case-ness is not a server's decision. It is more like unfortunate implementation reality. As per RFC3986 6.2.2.1 (and references from there taking you further down the rabbit hole) the URI path part is defined to be case-sensitive. HTTPd, for example, conforms with that. IIS does not because whole Windows are case-insensitive... so even simple static file serving would become a huge pain. — Aug 03, 2022 at 06:43  
  • +9 – @Fiisch: It's the server's decision because nothing in the spec would forbid servers from serving the same resource at both /FOO and /foo if they wish. The path is only required to be "case-sensitive" from a client's perspective, i.e. so that a weird client (or proxy) wouldn't try to unnecessarily casefold paths before sending them to the server (thus practically requiring servers to become case-insensitive to deal with that), like how some clients already downcase the domain name. — Aug 03, 2022 at 07:12  
  • +1 – I am not sure about that. The part of RFC3986 (which is for generic URI syntax) reads The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3). And I could not find anything in the HTTP scheme definition which would override that statement. — Aug 03, 2022 at 07:26  
  • +6 – It doesn't have to override that statement, because what content the server actually serves at any URL is already outside the scope of the scheme definition. It only means the actual URLs with paths /FOO and /foo must not be considered "the same URL", but they can still have the same content available. — Aug 03, 2022 at 07:28  
  • +1 – Yes, that is true - and that is a decision of the server; if there was an explicit alias configured in the server config, it would effectively be the same. I was trying to say that - canonically by RFC - URI paths differring only in their case-ness point to (canonically) differrent resources. — Aug 03, 2022 at 08:49