Using cURL with HTTP/2 on Mac OS X

cURL is one of the most powerful tool for testing HTTP requests and responses. Most developers use curl to interact with HTTP APIs or to test a website.

Starting from version 7.43.0 cURL (and libcurl) supports HTTP/2. You can perform a request using the HTTP/2 protocol passing the --http2 flag:

➜  curl -I --http2 https://www.cloudflare.com/
HTTP/2.0 200
server:cloudflare-nginx
date:Sun, 24 Jan 2016 21:53:48 GMT
content-type:text/html
set-cookie:__cfduid=d73309ac5d32f18d2ca9efb414cc0fd111453672428; expires=Mon, 23-Jan-17 21:53:48 GMT; path=/; domain=.cloudflare.com; HttpOnly
last-modified:Thu, 21 Jan 2016 18:44:44 GMT
etag:W/"56a1271c-3342"
strict-transport-security:max-age=31536000
x-content-type-options:nosniff
x-frame-options:SAMEORIGIN
content-security-policy-report-only:default-src 'self' https://*; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*; img-src 'self' https://* data:; style-src 'self' 'unsafe-inline' https://*; font-src 'self' https://* data:; frame-src https://*; connect-src 'self' https://*; report-uri https://www.cloudflare.com/csp-report
cf-cache-status:HIT
expires:Mon, 25 Jan 2016 01:53:48 GMT
cache-control:public, max-age=14400
cf-ray:269ef92389950e12-MXP

However, in order to support HTTP/2, cURL must be linked to nghttp and the default cURL version shipped with Mac OS X does not. As a result, if you try to pass the --http2 flag you'll receive the following error:

➜  curl -I --http2 https://www.cloudflare.com/
curl: (1) Unsupported protocol

To solve the issue and use cURL with HTTP/2 in Mac OS X your need to recompile cURL. This is a very easy task if you use Homebrew. Thanks to this PR you can reinstall cURL via Homebrew and pass the --with-nghttp2 flag to add the HTTP/2 support along with the necessary dependencies.

➜  brew install curl --with-nghttp2

Almost done. By default, Homebrew will not replace the curl binary shipped with Mac OS X, therefore you need to explicitly "link" it if you want to use the new version without specifying the entire path to the binary (which by the way is /usr/local/Cellar/curl/7.46.0/bin/curl):

➜  brew link curl
Warning: curl is keg-only and must be linked with --force
Note that doing so can interfere with building software.
➜  brew link curl --force
Linking /usr/local/Cellar/curl/7.46.0... 348 symlinks created

Close/reopen the shell and the curl location should now be:

➜  which curl
/usr/local/bin/curl

You can also confirm the version and the custom flag using the command brew info curl:

➜  brew info curl
curl: stable 7.46.0 (bottled) [keg-only]
Get a file from an HTTP, HTTPS or FTP server
http://curl.haxx.se/
/usr/local/Cellar/curl/7.46.0 (359 files, 2.5M) *
  Built from source with: --with-nghttp2

If it's still /usr/bin/curl then make sure cURL was properly installed via Homebrew and you restarted your shell.

Instructions

To recap, here's the list of commands to compile and install cURL with HTTP/2 support in Mac OS X using Homebrew:

# install cURL with nghttp2 support
➜  brew install curl --with-nghttp2

# link the formula to replace the system cURL
➜  brew link curl --force

# now reload the shell

# test an HTTP/2 request passing the --http2 flag
➜  curl -I --http2 https://www.cloudflare.com/

A special thanks to Daniel Stenberg for cURL, and to @felixbuenemann for the Homebrew patch that made it possible to install cURL with HTTP/2 with zero effort.