static http_cookie_t *cookie_parse(const char *value, const char *host, const char *path) { http_cookie_t *cookie = calloc( 1, sizeof( http_cookie_t ) ); if ( unlikely( !cookie ) ) return NULL; char *content = cookie_get_content(value); if ( !content ) { cookie_destroy( cookie ); return NULL; } const char *eq = strchr( content, '=' ); if ( eq ) { cookie->psz_name = strndup( content, eq-content ); cookie->psz_value = strdup( eq + 1 ); } else { cookie->psz_name = strdup( content ); cookie->psz_value = NULL; } cookie->psz_domain = cookie_get_domain(value); if ( !cookie->psz_domain || strlen(cookie->psz_domain) == 0 ) { free(cookie->psz_domain); cookie->psz_domain = strdup(host); cookie->b_host_only = true; } else cookie->b_host_only = false; cookie->psz_path = cookie_get_attribute_value(value, "path" ); if ( !cookie->psz_path || strlen(cookie->psz_path) == 0 ) { free(cookie->psz_path); cookie->psz_path = cookie_default_path(path); } cookie->b_secure = cookie_has_attribute(value, "secure" ); FREENULL( content ); if ( !cookie->psz_domain || !cookie->psz_path || !cookie->psz_name ) { cookie_destroy( cookie ); return NULL; } return cookie; }
static void expire_cookies(List *cookies) { Cookie *value = NULL; time_t now = 0; long pos = 0; if (cookies == NULL) { error(0, "expire_cookies: Null argument(s) - no Cookie list"); return; } /* Walk through the cookie cache */ time(&now); if (gwlist_len(cookies) > 0) { debug("wap.wsp.http", 0, "expire_cookies: Cookies in cache"); for (pos = 0; pos < gwlist_len(cookies); pos++) { value = gwlist_get(cookies, pos); gw_assert(value != NULL); if (value->max_age != -1) { /* Interesting value */ if (value->max_age + value->birth < now) { debug("wap.wsp.http", 0, "expire_cookies: Expired cookie (%s)", octstr_get_cstr(value->name)); cookie_destroy(value); gwlist_delete(cookies, pos, 1); } } } } else debug("wap.wsp.http", 0, "expire_cookies: No cookies in cache"); return; }
bool vlc_http_cookies_store(vlc_http_cookie_jar_t *p_jar, const char *cookies, bool secure, const char *host, const char *path) { assert(host != NULL); assert(path != NULL); int i; http_cookie_t *cookie = cookie_parse(cookies, host, path); if (cookie == NULL) return false; if (!cookie_is_valid(cookie, secure, host, path)) { cookie_destroy(cookie); return false; } vlc_mutex_lock( &p_jar->lock ); for( i = 0; i < vlc_array_count( &p_jar->cookies ); i++ ) { http_cookie_t *iter = vlc_array_item_at_index( &p_jar->cookies, i ); assert( iter->psz_name ); assert( iter->psz_domain ); assert( iter->psz_path ); bool domains_match = vlc_ascii_strcasecmp( cookie->psz_domain, iter->psz_domain ) == 0; bool paths_match = strcmp( cookie->psz_path, iter->psz_path ) == 0; bool names_match = strcmp( cookie->psz_name, iter->psz_name ) == 0; if( domains_match && paths_match && names_match ) { /* Remove previous value for this cookie */ vlc_array_remove( &p_jar->cookies, i ); cookie_destroy(iter); break; } } vlc_array_append( &p_jar->cookies, cookie ); vlc_mutex_unlock( &p_jar->lock ); return true; }
static int have_cookie(List *cookies, Cookie *cookie) { Cookie *value = NULL; long pos = 0; if (cookies == NULL || cookie == NULL) { error(0, "have_cookie: Null argument(s) - no Cookie list, Cookie or both"); return 0; } /* Walk through the cookie cache, comparing cookie */ while (pos < gwlist_len(cookies)) { value = gwlist_get(cookies, pos); /* octstr_compare() now only returns 0 on an exact match or if both args are 0 */ debug ("wap.wsp.http", 0, "have_cookie: Comparing name (%s:%s), path (%s:%s), domain (%s:%s)", octstr_get_cstr(cookie->name), octstr_get_cstr(value->name), octstr_get_cstr(cookie->path), octstr_get_cstr(value->path), octstr_get_cstr(cookie->domain), octstr_get_cstr(value->domain)); /* Match on no value or value and value equality for name, path and domain */ if ( (value->name == NULL || ((value->name != NULL && cookie->name != NULL) && octstr_compare(value->name, cookie->name) == 0)) && (value->path == NULL || ((value->path != NULL && cookie->path != NULL) && octstr_compare(value->path, cookie->path) == 0)) && (value->domain == NULL || ((value->domain != NULL && cookie->domain != NULL) && octstr_compare(value->domain, cookie->domain) == 0)) ) { /* We have a match according to 4.3.3 - discard the old one */ cookie_destroy(value); gwlist_delete(cookies, pos, 1); /* Discard the new cookie also if max-age is 0 - set if expiry date is up */ if (cookie->max_age == 0) { debug("wap.wsp.http", 0, "have_cookie: Discarding expired cookie (%s)", octstr_get_cstr(cookie->name)); return 1; } debug("wap.wsp.http", 0, "have_cookie: Updating cached cookie (%s)", octstr_get_cstr (cookie->name)); break; } else { pos++; } } return 0; }
void vlc_http_cookies_destroy( vlc_http_cookie_jar_t * p_jar ) { if ( !p_jar ) return; int i; for( i = 0; i < vlc_array_count( &p_jar->cookies ); i++ ) cookie_destroy( vlc_array_item_at_index( &p_jar->cookies, i ) ); vlc_array_clear( &p_jar->cookies ); vlc_mutex_destroy( &p_jar->lock ); free( p_jar ); }
int get_cookies(List *headers, const WSPMachine *sm) { Octstr *header = NULL; Octstr *value = NULL; Cookie *cookie = NULL; long pos = 0; /* * This can happen if the user aborts while the HTTP request is pending from the server. * In that case, the session machine is destroyed and is not available to this function * for cookie caching. */ if (sm == NULL) { info (0, "No session machine for cookie retrieval"); return 0; } for (pos = 0; pos < gwlist_len(headers); pos++) { header = gwlist_get(headers, pos); /* debug ("wap.wsp.http", 0, "get_cookies: Examining header (%s)", octstr_get_cstr (header)); */ if (strncasecmp ("set-cookie", octstr_get_cstr (header),10) == 0) { debug ("wap.wsp.http", 0, "Caching cookie (%s)", octstr_get_cstr (header)); if ((value = get_header_value (header)) == NULL) { error (0, "get_cookies: No value in (%s)", octstr_get_cstr(header)); continue; } /* Parse the received cookie */ if ((cookie = parse_cookie(value)) != NULL) { /* Check to see if this cookie is already present */ if (have_cookie(sm->cookies, cookie) == 1) { debug("wap.wsp.http", 0, "parse_cookie: Cookie present"); cookie_destroy(cookie); continue; } else { add_cookie_to_cache(sm, cookie); debug("wap.wsp.http", 0, "get_cookies: Added (%s)", octstr_get_cstr(cookie -> name)); } } } } debug("wap.wsp.http", 0, "get_cookies: End"); return 0; }
static Cookie *parse_cookie(Octstr *cookiestr) { char *v = NULL; char *p = NULL; int delta = 0; Cookie *c = NULL; Octstr **f = NULL; if (cookiestr == NULL) { error(0, "parse_cookie: NULL argument"); return NULL; } v = gw_strdup(octstr_get_cstr (cookiestr)); p = strtok(v, ";"); c = cookie_create(); /* Never returns NULL */ while (p != NULL) { while (isspace((int)*p)) p++; /* Skip leading whitespace */ if (strncasecmp("version", p, 7) == 0) f = &c -> version; else if (strncasecmp("path", p, 4) == 0) f = &c -> path; else if (strncasecmp("domain", p, 6) == 0) f = &c -> domain; /* XXX DAVI: Shouldn't we check if domain is similar * to real domain, and to set domain to * real domain if not set by header ??? */ else if (strncasecmp("max-age", p, 7) == 0) { c -> max_age = atol(strrchr (p, '=') + 1); p = strtok(NULL, ";"); continue; } else if (strncasecmp("expires", p, 7) == 0) { delta = parse_http_date(p); if (delta != -1) c->max_age = delta; p = strtok(NULL, ";"); continue; } else if (strncasecmp("comment", p, 7) == 0 ) { /* Ignore comments */ p = strtok(NULL, ";"); continue; } else if (strncasecmp("secure", p, 6) == 0 ) { /* XXX DAVI: this should processed */ p = strtok(NULL, ";"); continue; } else { /* Name value pair - this should be first */ char *equals = NULL; if ((equals = strchr(p, '=')) != NULL) { *equals = '\0'; c->name = octstr_create(p); c->value = octstr_create(equals + 1); } else { error(0, "parse_cookie: Bad name=value cookie component (%s)", p); cookie_destroy(c); return NULL; } p = strtok(NULL, ";"); continue; } if (*f != NULL) { /* Undefined behaviour - 4.2.2 */ error(0, "parse_cookie: Duplicate cookie field (%s), discarding", p); p = strtok(NULL, ";"); continue; } *f = octstr_create("$"); octstr_append_cstr(*f, p); p = strtok(NULL, ";"); } /* Process version - 4.3.4 * XXX DAVI: Altough it seems to be "MUST" in RFC, no one sends a Version * tag when it's value is "0" if (c->version == NULL) { c->version = octstr_create(""); octstr_append_cstr(c->version, "$Version=\"0\";"); } */ gw_free (v); return c; }