cookie: overhaul and cleanup

- split the huge Curl_cookie_add() into several smaller static functions

- switch to using the common llist instead of custom linked list

- use less memory for *getlist()

- use bitfields for flags in the Cookie struct

- avoid the copy for date parsing

- more consistent variable naming

Closes #15247
This commit is contained in:
Daniel Stenberg 2024-10-10 10:08:15 +02:00
parent 91d451b488
commit be39ed19a5
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 719 additions and 774 deletions

File diff suppressed because it is too large Load Diff

View File

@ -27,20 +27,24 @@
#include <curl/curl.h>
#include "llist.h"
struct Cookie {
struct Cookie *next; /* next in the chain */
struct Curl_llist_node node; /* for the main cookie list */
struct Curl_llist_node getnode; /* for getlist */
char *name; /* <this> = value */
char *value; /* name = <this> */
char *path; /* path = <this> which is in Set-Cookie: */
char *spath; /* sanitized cookie path */
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
bool tailmatch; /* whether we do tail-matching of the domain name */
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
int creationtime; /* time when the cookie was written */
unsigned char prefix; /* bitmap fields indicating which prefix are set */
BIT(tailmatch); /* tail-match the domain name */
BIT(secure); /* the 'secure' keyword was used */
BIT(livecookie); /* updated from a server, not a stored file */
BIT(httponly); /* the httponly directive is present */
BIT(prefix_secure); /* secure prefix is set */
BIT(prefix_host); /* host prefix is set */
};
/*
@ -53,8 +57,8 @@ struct Cookie {
#define COOKIE_HASH_SIZE 63
struct CookieInfo {
/* linked list of cookies we know of */
struct Cookie *cookies[COOKIE_HASH_SIZE];
/* linked lists of cookies we know of */
struct Curl_llist cookielist[COOKIE_HASH_SIZE];
curl_off_t next_expiration; /* the next time at which expiration happens */
int numcookies; /* number of cookies in the "jar" */
int lastct; /* last creation-time used in the jar */
@ -112,10 +116,10 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
const char *domain, const char *path,
bool secure);
struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
int Curl_cookie_getlist(struct Curl_easy *data,
struct CookieInfo *c, const char *host,
const char *path, bool secure);
void Curl_cookie_freelist(struct Cookie *cookies);
const char *path, bool secure,
struct Curl_llist *list);
void Curl_cookie_clearall(struct CookieInfo *cookies);
void Curl_cookie_clearsess(struct CookieInfo *cookies);

View File

@ -2248,8 +2248,9 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
addcookies = data->set.str[STRING_COOKIE];
if(data->cookies || addcookies) {
struct Cookie *co = NULL; /* no cookies from start */
struct Curl_llist list;
int count = 0;
int rc = 1;
if(data->cookies && data->state.cookie_engine) {
const char *host = data->state.aptr.cookiehost ?
@ -2260,15 +2261,17 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
!strcmp(host, "127.0.0.1") ||
!strcmp(host, "::1") ? TRUE : FALSE;
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
co = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path,
secure_context);
rc = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path,
secure_context, &list);
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
if(co) {
struct Cookie *store = co;
if(!rc) {
struct Curl_llist_node *n;
size_t clen = 8; /* hold the size of the generated Cookie: header */
/* now loop through all cookies that matched */
while(co) {
/* loop through all cookies that matched */
for(n = Curl_llist_head(&list); n; n = Curl_node_next(n)) {
struct Cookie *co = Curl_node_elem(n);
if(co->value) {
size_t add;
if(!count) {
@ -2290,9 +2293,8 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
clen += add + (count ? 2 : 0);
count++;
}
co = co->next; /* next cookie please */
}
Curl_cookie_freelist(store);
Curl_llist_destroy(&list, NULL);
}
if(addcookies && !result && !linecap) {
if(!count)