enable curl cookie engine

Enabling Curl cookie engine brings advantage:
* handle cookies during a redirection: when a srv redirects including
  cookies, curl sends back the cookies correctly during the next request
This commit is contained in:
Pierre Tachoire
2025-08-13 16:51:14 +02:00
parent 6a29d6711c
commit b2f645a5ce
2 changed files with 30 additions and 12 deletions

View File

@@ -603,6 +603,22 @@ pub const Transfer = struct {
const header = buffer[0 .. buf_len - 2]; const header = buffer[0 .. buf_len - 2];
if (transfer.response_header == null) { if (transfer.response_header == null) {
if (transfer._redirecting and buf_len == 2) {
// retrieve cookies from the redirect's response.
var i: usize = 0;
while (true) {
const ct = getResponseHeader(easy, "set-cookie", i);
if (ct == null) break;
transfer.req.cookie_jar.populateFromResponse(&transfer.uri, ct.?.value) catch |err| {
log.err(.http, "set cookie", .{ .err = err, .req = transfer });
};
i += 1;
if (i >= ct.?.amount) break;
}
return buf_len;
}
if (buf_len < 13 or std.mem.startsWith(u8, header, "HTTP/") == false) { if (buf_len < 13 or std.mem.startsWith(u8, header, "HTTP/") == false) {
if (transfer._redirecting) { if (transfer._redirecting) {
return buf_len; return buf_len;
@@ -641,18 +657,6 @@ pub const Transfer = struct {
return buf_len; return buf_len;
} }
{
const SET_COOKIE_LEN = "set-cookie:".len;
if (header.len > SET_COOKIE_LEN) {
if (std.ascii.eqlIgnoreCase(header[0..SET_COOKIE_LEN], "set-cookie:")) {
const value = std.mem.trimLeft(u8, header[SET_COOKIE_LEN..], " ");
transfer.req.cookie_jar.populateFromResponse(&transfer.uri, value) catch |err| {
log.err(.http, "set cookie", .{ .err = err, .req = transfer });
};
}
}
}
if (buf_len == 2) { if (buf_len == 2) {
if (getResponseHeader(easy, "content-type", 0)) |ct| { if (getResponseHeader(easy, "content-type", 0)) |ct| {
var hdr = &transfer.response_header.?; var hdr = &transfer.response_header.?;
@@ -662,6 +666,17 @@ pub const Transfer = struct {
@memcpy(hdr._content_type[0..len], value[0..len]); @memcpy(hdr._content_type[0..len], value[0..len]);
} }
var i: usize = 0;
while (true) {
const ct = getResponseHeader(easy, "set-cookie", i);
if (ct == null) break;
transfer.req.cookie_jar.populateFromResponse(&transfer.uri, ct.?.value) catch |err| {
log.err(.http, "set cookie", .{ .err = err, .req = transfer });
};
i += 1;
if (i >= ct.?.amount) break;
}
transfer.req.header_done_callback(transfer) catch |err| { transfer.req.header_done_callback(transfer) catch |err| {
log.err(.http, "header_done_callback", .{ .err = err, .req = transfer }); log.err(.http, "header_done_callback", .{ .err = err, .req = transfer });
// returning < buf_len terminates the request // returning < buf_len terminates the request

View File

@@ -110,6 +110,9 @@ pub const Connection = struct {
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_FOLLOWLOCATION, @as(c_long, 2))); try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_FOLLOWLOCATION, @as(c_long, 2)));
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_REDIR_PROTOCOLS_STR, "HTTP,HTTPS")); // remove FTP and FTPS from the default try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_REDIR_PROTOCOLS_STR, "HTTP,HTTPS")); // remove FTP and FTPS from the default
// enable cookie engine for redirections handled directly by Curl.
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_COOKIEFILE, ""));
// proxy // proxy
if (opts.http_proxy) |proxy| { if (opts.http_proxy) |proxy| {
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_PROXY, proxy.ptr)); try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_PROXY, proxy.ptr));