From b2f645a5cef592a8ee48d07814199c57c63ab99f Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 13 Aug 2025 16:51:14 +0200 Subject: [PATCH] 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 --- src/http/Client.zig | 39 +++++++++++++++++++++++++++------------ src/http/Http.zig | 3 +++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/http/Client.zig b/src/http/Client.zig index 8b308c3b..27298126 100644 --- a/src/http/Client.zig +++ b/src/http/Client.zig @@ -603,6 +603,22 @@ pub const Transfer = struct { const header = buffer[0 .. buf_len - 2]; 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 (transfer._redirecting) { return buf_len; @@ -641,18 +657,6 @@ pub const Transfer = struct { 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 (getResponseHeader(easy, "content-type", 0)) |ct| { var hdr = &transfer.response_header.?; @@ -662,6 +666,17 @@ pub const Transfer = struct { @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| { log.err(.http, "header_done_callback", .{ .err = err, .req = transfer }); // returning < buf_len terminates the request diff --git a/src/http/Http.zig b/src/http/Http.zig index 3195a24c..f1453263 100644 --- a/src/http/Http.zig +++ b/src/http/Http.zig @@ -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_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 if (opts.http_proxy) |proxy| { try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_PROXY, proxy.ptr));