CURLOPT_HSTSWRITEFUNCTION(3)
π CURLOPT_HSTSWRITEFUNCTION(3) β¨
okay so bestie, welcome to the CURLOPT_HSTSWRITEFUNCTION page from the Library Functions Manual β yes, the libcurl one, and no, you can't skip it, this is the good stuff π
πΈ NAME πΈ
CURLOPT_HSTSWRITEFUNCTION β the write callback for HSTS hosts, aka the little function that lets you save the HSTS cache before libcurl yeets it into the void π
β¨ SYNOPSIS β¨
#include <curl/curl.h>
struct curl_hstsentry {
char *name;
size_t namelen;
unsigned int includeSubDomains:1;
char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */
};
struct curl_index {
size_t index; /* the provided entry's "index" or count */
size_t total; /* total number of entries to save */
};
CURLSTScode hstswrite(CURL *easy, struct curl_hstsentry *sts,
struct curl_index *count, void *clientp);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTSWRITEFUNCTION, hstswrite);
π¦ DESCRIPTION π¦
Pass a pointer to your callback function, exactly like the prototype up there shows β¬οΈ. That's the whole assignment, no cap.
This callback gets called by libcurl repeatedly β like, over and over β so your app can store the in-memory HSTS cache when libcurl is about to discard it ποΈ. It's giving "last chance to save your work" energy fr fr.
Set the clientp argument with the CURLOPT_HSTSWRITEDATA(3) option, or just let it be NULL, whatever works π«Ά. When the callback is invoked, the sts pointer points to a populated struct, so here's the tea:
- Read the hostname from
nameβ it isnamelenbytes long and null terminated π - The
includeSubDomainsfield is non-zero if the entry matches subdomains π - The
expirestring is a date stamp, null-terminated, using the syntaxYYYYMMDD HH:MM:SSβ°
Your callback should return CURLSTS_OK if it succeeded and is prepared to be called again (for another host), or CURLSTS_DONE if there is nothing more to do π. It can also return CURLSTS_FAIL to signal error π.
heads up bestie!! π¨ This option does not enable HSTS. You need to use CURLOPT_HSTS_CTRL(3) to do that. Don't come for me, I'm just the messenger π
π DEFAULT π
NULL β no callback. literally nothing happens, it's a vibe, it's fine π
πΈ PROTOCOLS πΈ
This functionality affects http only π§
β EXAMPLE β
struct priv {
void *custom;
};
static CURLSTScode hswr_cb(CURL *easy, struct curl_hstsentry *sts,
struct curl_index *count, void *clientp)
{
/* save the passed in HSTS data somewhere */
return CURLSTS_OK;
}
int main(void)
{
CURL *curl = curl_easy_init();
if(curl) {
struct priv my_stuff;
CURLcode result;
/* set HSTS read callback */
curl_easy_setopt(curl, CURLOPT_HSTSWRITEFUNCTION, hswr_cb);
/* pass in suitable argument to the callback */
curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &my_stuff);
result = curl_easy_perform(curl);
}
}
(and yes, the comment in the example really does say "set HSTS read callback" even though this is the write callback β we love a chaotic comment, iykyk π keep it exactly as is)
π₯ AVAILABILITY π₯
Added in curl 7.74.0 β so if your curl is older than that, this option simply doesn't exist, bestie π°οΈ
π RETURN VALUE π
This returns CURLE_OK β¨
π SEE ALSO π
(and yes, this page links to itself in SEE ALSO β iconic self-referential main character energy, don't question it π )
and that's the whole page, bestie!! π this came to you from the libcurl manual, dated 2026-10-12, version line libcurl β so go forth and write that HSTS callback, slay, periodt π¦π
π¦ where this page comes from
- fedora 44: libcurl-devel 8.18.0-14.fc44 Β· curl
- fedora 44: libcurl-devel 8.18.0-14.fc44 Β· curl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms