📄 cookies.c
字号:
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;}/* * Function: add_cookie_to_cache * * Description: Adds the cookie to the WSPMachine cookie cache. */static void add_cookie_to_cache(const WSPMachine *sm, Cookie *value){ gw_assert(sm != NULL); gw_assert(sm -> cookies != NULL); gw_assert(value != NULL); list_append(sm -> cookies, value); return;}/* * Function: have_cookie * * Description: Checks to see if the cookie is present in the list. */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 < list_len(cookies)) { value = list_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); list_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;}/* * Function: expire_cookies * * Description: Walks thru the cookie list and checking for expired cookies. */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 (list_len(cookies) > 0) { debug("wap.wsp.http", 0, "expire_cookies: Cookies in cache"); for (pos = 0; pos < list_len(cookies); pos++) { value = list_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); list_delete(cookies, pos, 1); } } } } else debug("wap.wsp.http", 0, "expire_cookies: No cookies in cache"); return;}static void cookie_destroy(void *p){ Cookie *cookie; if (p == NULL) return; cookie = p; octstr_destroy(cookie->name); octstr_destroy(cookie->value); octstr_destroy(cookie->version); octstr_destroy(cookie->domain); octstr_destroy(cookie->path); gw_free(cookie); debug("wap.wsp.http", 0, "cookie_destroy: Destroyed cookie"); return;}/* * Function: parse_http_date * * Description: Parses an HTTP date format as used by the Expires: header. See RFC 2616 * section 3.3.1 for more information. * HTTP applications have historically allowed three different formats * for the representation of date/time stamps: * * Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 * Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 * Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format * * The first format is preferred as an Internet standard and represents * a fixed-length subset of that defined by RFC 1123 [8] (an update to * RFC 822 [9]). The second format is in common use, but is based on the * obsolete RFC 850 [12] date format and lacks a four-digit year. * HTTP/1.1 clients and servers that parse the date value MUST accept * all three formats (for compatibility with HTTP/1.0), though they MUST * only generate the RFC 1123 format for representing HTTP-date values * in header fields. * * Returns: -1 on success, max-age sematic value on success. */static const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};static int month_index(const char *s){ const char **p = &months[0]; int i = 0; while (*p != NULL) { if (strcmp(s, *p) == 0) return i; p++, i++; } return -1;}static int parse_http_date(const char *expires){ struct tm ti; char *p = NULL; char *date = NULL; char month[MAX_HTTP_DATE_LENGTH]; time_t rv; time_t now; memset(&ti, 0, sizeof(struct tm)); /* Break up the Expires: header */ if (!(date = strchr(expires, '='))) { error(0, "parse_http_date: Bogus expires type=value header (%s)", expires); return -1; } else { date++; while (isspace((int)*date)) ++date; } /* Onto the date value */ if (!(p = strchr (date,' '))) { error(0, "parse_http_date: Bogus date string (%s)", date); return -1; } else while (isspace((int)*p)) ++p; if (MAX_HTTP_DATE_LENGTH < strlen(p)) { error(0, "parse_http_date: %s blows length limit (%d)", date, MAX_HTTP_DATE_LENGTH); return -1; } if (isalpha((int)*p)) { /* ctime */ sscanf(p, (strstr(p, "DST") ? "%s %d %d:%d:%d %*s %d" : "%s %d %d:%d:%d %d"), month, &ti.tm_mday, &ti.tm_hour, &ti.tm_min, &ti.tm_sec, &ti.tm_year); ti.tm_year -= 1900; } else if (p[2] == '-') { /* RFC 850 (normal HTTP) */ char buf[MAX_HTTP_DATE_LENGTH]; sscanf(p, "%s %d:%d:%d", buf, &ti.tm_hour, &ti.tm_min, &ti.tm_sec); buf[2] = '\0'; ti.tm_mday = atoi(buf); buf[6] = '\0'; strcpy(month, &buf[3]); ti.tm_year = atoi(&buf[7]); /* Prevent wraparound from ambiguity */ if (ti.tm_year < 70) { ti.tm_year += 100; } else if (ti.tm_year > 1900) { ti.tm_year -= 1900; } } else { /* RFC 822 */ sscanf(p,"%d %s %d %d:%d:%d",&ti.tm_mday, month, &ti.tm_year, &ti.tm_hour, &ti.tm_min, &ti.tm_sec); /* * since tm_year is years since 1900 and the year we parsed * is absolute, we need to subtract 1900 years from it */ ti.tm_year -= 1900; } ti.tm_mon = month_index(month); if (ti.tm_mon == -1) { error(0, "parse_http_date () failed on bad month value (%s)", month); return -1; } ti.tm_isdst = -1; rv = gw_mktime(&ti); if (ti.tm_isdst) rv -= 3600; if (rv == -1) { error(0, "parse_http_date(): mktime() was unable to resolve date/time: %s", asctime (&ti)); return -1; } debug("parse_http_date", 0, "Parsed date (%s) as: %s", date, asctime(&ti)); /* * If rv is valid, it should be some time in the (near) future. Normalise this to * a max-age semantic so we can use the same expiry mechanism */ now = time(NULL); if (rv - now < 0) { /* This is bad - set the delta to 0 so we expire next time around */ error(0, "parse_http_date () Expiry time (%s) (delta=%ld) is in the past !", asctime (&ti), rv-now); return 0; } return rv - now;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -