libcurl Cookie 详解
libcurl关于Cookie的一些选项:
CURLOPT_COOKIE
用来指定一个Cookie,用来在之后的http请求中发送这个Cookie。
CURLOPT_COOKIEFILE
告诉libcurl激活cookie引擎,然后读取指定文件来初始化Cookie,只读。
CURLOPT_COOKIEJAR
告诉libcurl激活cookie引擎,当easy handle被关闭,保存所有已知的Cookie到cookie jar文件,只写。
CURLOPT_COOKIELIST
提供单个的Cookie加入内部的Cookie存储引擎。可以传递http头格式也可以传递netscape 格式。这个也可以用来刷新Cookies。
CURLINFO_COOKIELIST
将Cookie信息从内部Cookie存储里导出,导出格式为链表。
CURLOPT_COOKIE
这个函数可以给http请求设置Cookie 用法如下:
curl_easy_setopt(curl, CURLOPT_COOKIE, "tool=curl; fun=yes;");
这个选项显式对发出的http请求的Cookie进设置,如果由于身份验证,随后的重定向或类似的操作完成了多个请求,则他们都将传递此Cookie。这句话的意思是重定向类操作会继续传递此Cookie。
通过这个选项设置Cookie是与内部的Cookie存储引擎分开的,内部的Cookie存储引擎不会被此选项修改。假如你开启Cookie存储引擎你又导入一个同名的Cookie(或者服务器已经设置了这样一个Cookie),那么你设置的Cookie将不会影响引擎内部的Cookie。向服务器发出的请求会发送两个Cookie都发。想要替换引擎内部的Cookie可以使用CURLOPT_COOKIELIST这个选项。
多次调用这个选项只有最后一次调用会被使用。
这个选项不会开启Cookie Engine。你可以使用CURLOPT_COOKIEFILE或者CURLOPT_COOKIEJAR去开启Cookie引擎来达到自动分析和发送Cookie的功能。
CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); curl_easy_setopt(curl, CURLOPT_COOKIE, "tool=curl; fun=yes;"); curl_easy_perform(curl); }
CURLOPT_COOKIELIST
这个选项的参数可以为一行Netscape/Mozilkla格式或者http头(Set-Cookie:…)。他会打开Cookie引擎。也会将单个Cookie加入内部Cookie存储。
如果你使用这个选项并且有多个请求要发送的时候要谨慎。如果你使用Set-Cookie格式没有指定域名的话那这个Cookie将会发送给所有的请求(包括重定向),而且这个Cookie无法被服务器SetCookie更改。如果服务器SetCookie时已经有一个同名的Cookie时,这个Cookie不会被替换,他会将两者都传递给该服务器,这可能不是你想要的。要解决这个问题,请在Set-Cookie中设置一个域(这样做将包括子域)或使用Netscape格式。如示例所示。
/* 这个例子演示了如何将Netscape格式的COokie的内联导入, 您可以将cookie设置为HttpOnly,以防XSS攻击#HttpOnly_到主机名。 如果cookie稍后由浏览器导入会很有用*/ #define SEP "\t" /* Tab separates the fields */ char *my_cookie = "example.com" /* Hostname */ SEP "FALSE" /* Include subdomains */ SEP "/" /* Path */ SEP "FALSE" /* Secure */ SEP "0" /* Expiry in epoch time format. 0 == Session */ SEP "foo" /* Name */ SEP "bar"; /* Value */ /* my_cookie 通过 CURLOPT_COOKIELIST导入*/ curl_easy_setopt(curl, CURLOPT_COOKIELIST, my_cookie); /* 在cookie.txt里面的cookie将不会被导入直到在传输前正确。如果Cookie里面有相同的hostname,path或者在my_cookies里存在将会被跳过。因为libcurl已经通过my_cookie导入被称为”活着”的Cookie。活着的cookie不可以被通过读入文件的Cookie替换。。 */ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt"); /* import */ /* Cookie的导出是在curl_easy_cleanup被调用之后进行的。服务器可以增加、删除、修改Cookie。被跳过的的cookie不会被导入 */ curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt"); /* export */ curl_easy_perform(curl); /* cookies imported from cookies.txt */ curl_easy_cleanup(curl); /* cookies exported to cookies.txt */
CURLOPT_COOKIEJAR
这个选项的功能是将Cookie存储到一个文件。
如果设置了这个选项libcurl将会在curl_easy_cleanup被调用的时候将cookie与入文件。如果没有已经的cookie,会以-为文件名替换。他会还启用此会话的cookie。所以如果你follow a location,它将会发送对应的Cookie
libcurl不会从cookie jar文件中读取任何cookie。如果你想从 文件要读取cookie请使用CURLOPT_COOKIEFILE。
如果cookie jar在curl_wasy_clean调用时候不能被创建或写入,libcurl不会去报告这个错误。使用CURLOPT_VERBOSE或CURLOPT_DEBUGFUNCTION会有一个警告显示。
自己7.43.0 cookie被Set-Cookie 格式并且没有domain 时,将不会导出。
CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin"); /*当调用cleanup的时候导出cookie到文件*/ curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "/tmp/cookies.txt"); ret = curl_easy_perform(curl); /* 关闭curl, 写入cookie! */ curl_easy_cleanup(curl); }