CURLOPT_ALTSVC(3)

✨ CURLOPT_ALTSVC ✨

okay so this is the CURLOPT_ALTSVC page from the curl library functions manual, and honestly it's kind of a gem πŸ’– β€” it's all about alt-svc cache filename, which sounds scary but bestie it's literally just "where do we keep the little notes file". let's get into it 🫢


🌸 SYNOPSIS 🌸

#include <curl/curl.h>

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ALTSVC, char *filename);

πŸ’… DESCRIPTION πŸ’…

so you pass in a pointer to a filename and that tells libcurl "hey, use THIS file as the Alt-Svc cache" β€” meaning it reads the existing cache contents from it, and possibly also writes back to it after a transfer. ✨

the one exception? if CURLALTSVC_READONLYFILE is set in CURLOPT_ALTSVC_CTRL(3). then it's read-only, no writing back, respect the boundary 😌

if you pass a blank filename ("") then libcurl just... doesn't load from a file at all. bye file, we don't know her πŸ’€

good news: the application does not have to keep the string around after setting this option. libcurl's got it, you can let go πŸ¦‹

and if you set this option multiple times? the last set string wins, it overrides the previous ones. main character energy only πŸ‘‘ set it to NULL to disable its use again.


πŸ”₯ SECURITY CONCERNS πŸ”₯

no cap, this part matters so listen up:

libcurl cannot fully protect against attacks where an attacker has write access to the same directory where it is directed to save files. and it's particularly sensitive if you save files using elevated privileges. 😭 like, be careful bestie.

also β€” libcurl creates the file to store the alt-svc cache in using default file permissions. meaning that on *nix systems you may need to restrict your umask to prevent other users on the same system from accessing the file. πŸ™ˆ

fr fr, check your umask. this is not a drill.

πŸŽ€ DEFAULT πŸŽ€

NULL. the alt-svc cache is not read nor written to file. a whole lot of nothing, iconic πŸ’…

🌈 PROTOCOLS 🌈

this functionality affects http only. that's it, that's the whole section πŸ“


⭐ EXAMPLE ⭐

int main(void)
{
  CURL *curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, CURLALTSVC_H1);
    curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt");
    curl_easy_perform(curl);
  }
}

look at that. clean. no notes. 🧚


πŸ¦‹ HISTORY πŸ¦‹

okay tiny lore drop: the CURLALTSVC_* macros became long types in 8.16.0. prior to this version a long cast was necessary when passed to curl_easy_setopt(3). so if you're on ancient curl, cast it. slay πŸ’œ


πŸ” FILE FORMAT πŸ”

it's a text based file, one line per alt-svc entry, and each line consists of nine space-separated fields. nine!! count 'em πŸ‘‘

an example line could look like

h2 www.example.com 8443 h3 second.example.com 443 "20190808 06:18:37" 1 0

the fields of that line are:

  • h2 β€” ALPN id for the source origin
  • www.example.comp β€” Hostname for the source origin
  • 8443 β€” Port number for the source origin
  • h3 β€” ALPN id for the destination host
  • second.example.com β€” Hostname for the destination host
  • 443 β€” Port number for the destination host
  • 2019* β€” Expiration date and time of this entry within double quotes. the date format is "YYYYMMDD HH:MM:SS" and the time zone is GMT.
  • 1 β€” Boolean (1 or 0) if "persist" was set for this entry
  • 0 β€” Integer priority value (not currently used)
no I did not typo www.example.comp, that's literally what the page says, we keep the facts exactly as they are πŸ’–

πŸ’– AVAILABILITY πŸ’–

added in curl 7.64.1 🌸

🫢 RETURN VALUE 🫢

curl_easy_setopt(3) returns a CURLcode indicating success or error.

CURLE_OK (0) means everything was OK, non-zero means an error occurred, see libcurl-errors(3). simple as that ✨

πŸ‘‘ SEE ALSO πŸ‘‘


and that's the whole page bestie!! mwah πŸ’‹ this was libcurl, dated 2026-10-12 β€” go forth and cache your alt-svcs responsibly πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from