📄 lycookie.c
字号:
co = NULL; /* * Don't add the cookie if we're over the domain's limit. - FM */ } else if (HTList_count(cookie_list) > 50) { if (TRACE) fprintf(stderr, "store_cookie: Domain's cookie limit exceeded! Rejecting cookie.\n"); freeCookie(co); co = NULL; /* * Don't add the cookie if we're over the total cookie limit. - FM */ } else if (total_cookies > 500) { if (TRACE) fprintf(stderr, "store_cookie: Total cookie limit exceeded! Rejecting cookie.\n"); freeCookie(co); co = NULL; /* * If it's a replacement for a cookie that had not expired, * and never allow has not been set, add it again without * confirmation. - FM */ } else if ((Replacement == TRUE && de) && de->bv != REJECT_ALWAYS) { HTList_insertObjectAt(cookie_list, co, pos); total_cookies++; /* * Get confirmation if we need it, and add cookie * if confirmed or 'allow' is set to always. - FM */ } else if (HTConfirmCookie(de, hostname, co->domain, co->path, co->name, co->value)) { HTList_insertObjectAt(cookie_list, co, pos); total_cookies++; } else { freeCookie(co); co = NULL; }}/*** Scan a domain's cookie_list for any cookies we should** include in a Cookie: request header. - AK & FM*/PRIVATE char * scan_cookie_sublist ARGS6( CONST char *, hostname, CONST char *, path, int, port, HTList *, sublist, char *, header, BOOL, secure){ HTList *hl = sublist, *next = NULL; cookie *co; time_t now = time(NULL); int len = 0; char crlftab[8]; sprintf(crlftab, "%c%c%c", CR, LF, '\t'); while (hl) { co = (cookie *)hl->object; next = hl->next; if (TRACE && co) { fprintf(stderr, "Checking cookie %lx %s=%s\n", (long)hl, (co->name ? co->name : "(no name)"), (co->value ? co->value : "(no value)")); fprintf(stderr, "%s %s %d %s %s %d%s\n", hostname, (co->domain ? co->domain : "(no domain)"), host_matches(hostname, co->domain), path, co->path, ((co->pathlen > 0) ? strncmp(path, co->path, co->pathlen) : 0), ((co->flags & COOKIE_FLAG_SECURE) ? " secure" : "")); } /* * Check if this cookie has expired, and if so, delete it. */ if (((co) && (co->flags & COOKIE_FLAG_EXPIRES_SET)) && co->expires < now) { HTList_removeObject(sublist, co); freeCookie(co); co = NULL; total_cookies--; } /* * Check if we have a unexpired match, and handle if we do. */ if (((co != NULL) && host_matches(hostname, co->domain)) && (co->pathlen == 0 || !strncmp(path, co->path, co->pathlen))) { /* * Skip if the secure flag is set and we don't have * a secure connection. HTTP.c presently treats only * SSL connections as secure. - FM */ if ((co->flags & COOKIE_FLAG_SECURE) && secure == FALSE) { hl = next; continue; } /* * Skip if we have a port list and the * current port is not listed. - FM */ if (co->PortList && !port_matches(port, co->PortList)) { hl = next; continue; } /* * Start or append to the request header. */ if (header == NULL) { if (co->version > 0) { /* * For Version 1 (or greater) cookies, * the version number goes before the * first cookie. */ char version[16]; sprintf(version, "$Version=\"%d\"; ", co->version); StrAllocCopy(header, version); len += strlen(header); } } else { /* * There's already cookie data there, so add * a separator (always use a semi-colon for * "backward compatibility"). - FM */ StrAllocCat(header, "; "); /* * Check if we should fold the header. - FM */ if (len > 800) { StrAllocCat(header, crlftab); len = 0; } } /* * Include the cookie name=value pair. */ StrAllocCat(header, co->name); StrAllocCat(header, "="); if (co->quoted) { StrAllocCat(header, "\""); len++; } StrAllocCat(header, co->value); if (co->quoted) { StrAllocCat(header, "\""); len++; } len += (strlen(co->name) + strlen(co->value) + 1); /* * For Version 1 (or greater) cookies, add * $PATH, $PORT and/or $DOMAIN attributes for * the cookie if they were specified via a * server reply header. - FM */ if (co->version > 0) { if (co->path && (co->flags & COOKIE_FLAG_PATH_SET)) { /* * Append the path attribute. - FM */ StrAllocCat(header, "; $Path=\""); StrAllocCat(header, co->path); StrAllocCat(header, "\""); len += (strlen(co->path) + 10); } if (co->PortList && isdigit((unsigned char)*co->PortList)) { /* * Append the port attribute. - FM */ StrAllocCat(header, "; $Port=\""); StrAllocCat(header, co->PortList); StrAllocCat(header, "\""); len += (strlen(co->PortList) + 10); } if (co->domain && (co->flags & COOKIE_FLAG_DOMAIN_SET)) { /* * Append the domain attribute. - FM */ StrAllocCat(header, "; $Domain=\""); StrAllocCat(header, co->domain); StrAllocCat(header, "\""); len += (strlen(co->domain) + 12); } } } hl = next; } return(header);}/*** Process potentially concatenated Set-Cookie2 and/or Set-Cookie** headers. - FM*/PRIVATE void LYProcessSetCookies ARGS6( CONST char *, SetCookie, CONST char *, SetCookie2, CONST char *, address, char *, hostname, char *, path, int, port){ CONST char *p, *attr_start, *attr_end, *value_start, *value_end; HTList *CombinedCookies = NULL, *cl = NULL; cookie *cur_cookie = NULL, *co = NULL; int length = 0, url_type = 0; int NumCookies = 0; BOOL MaxAgeAttrSet = FALSE; BOOL Quoted = FALSE; if (!(SetCookie && *SetCookie) && !(SetCookie2 && *SetCookie2)) { /* * Yuk! Garbage in, so nothing out. - FM */ return; } /* * If we have both Set-Cookie and Set-Cookie2 headers. * process the Set-Cookie2 header. Otherwise, process * whichever of the two headers we do have. Note that * if more than one instance of a valued attribute for * the same cookie is encountered, the value for the * first instance is retained. We only accept up to 50 * cookies from the header, and only if a cookie's values * do not exceed the 4096 byte limit on overall size. - FM */ CombinedCookies = HTList_new(); /* * Process the Set-Cookie2 header, if present and not zero-length, * adding each cookie to the CombinedCookies list. - FM */ p = (SetCookie2 ? SetCookie2 : ""); if (TRACE && SetCookie && *p) { fprintf(stderr, "LYProcessSetCookies: Using Set-Cookie2 header.\n"); } while (NumCookies <= 50 && *p) { attr_start = attr_end = value_start = value_end = NULL; while (*p != '\0' && isspace((unsigned char)*p)) { p++; } /* * Get the attribute name. */ attr_start = p; while (*p != '\0' && !isspace((unsigned char)*p) && *p != '=' && *p != ';' && *p != ',') p++; attr_end = p; while (*p != '\0' && isspace((unsigned char)*p)) { p++; } /* * Check for an '=' delimiter, or an 'expires' name followed * by white, since Netscape's bogus parser doesn't require * an '=' delimiter, and 'expires' attributes are being * encountered without them. These shouldn't be in a * Set-Cookie2 header, but we'll assume it's an expires * attribute rather a cookie with that name, since the * attribute mistake rather than name mistake seems more * likely to be made by providers. - FM */ if (*p == '=' || !strncasecomp(attr_start, "Expires", 7)) { /* * Get the value string. */ if (*p == '=') { p++; } while (*p != '\0' && isspace((unsigned char)*p)) { p++; } /* * Hack alert! We must handle Netscape-style cookies with * "Expires=Mon, 01-Jan-96 13:45:35 GMT" or * "Expires=Mon, 1 Jan 1996 13:45:35 GMT". * No quotes, but there are spaces. Argh... * Anyway, we know it will have at least 3 space separators * within it, and two dashes or two more spaces, so this code * looks for a space after the 5th space separator or dash to * mark the end of the value. - FM */ if ((attr_end - attr_start) == 7 && !strncasecomp(attr_start, "Expires", 7)) { int spaces = 6; value_start = p; if (isdigit((unsigned char)*p)) { /* * No alphabetic day field. - FM */ spaces--; } else { /* * Skip the alphabetic day field. - FM */ while (*p != '\0' && isalpha((unsigned char)*p)) { p++; } while (*p == ',' || isspace((unsigned char)*p)) { p++; } spaces--; } while (*p != '\0' && *p != ';' && *p != ',' && spaces) { p++; if (isspace((unsigned char)*p)) { while (isspace((unsigned char)*(p + 1))) p++; spaces--; } else if (*p == '-') { spaces--; } } value_end = p; /* * Hack Alert! The port attribute can take a * comma separated list of numbers as a value, * and such values should be quoted, but if * not, make sure we don't treat a number in * the list as the start of a new cookie. - FM */ } else if ((attr_end - attr_start) == 4 && !strncasecomp(attr_start, "port", 4) && isdigit((unsigned char)*p)) { /* * The value starts as an unquoted number. */ CONST char *cp, *cp1; value_start = p; while (1) { while (isdigit((unsigned char)*p)) p++; value_end = p; while (isspace((unsigned char)*p)) p++; if (*p == '\0' || *p == ';') break; if (*p == ',') { cp = (p + 1); while (*cp != '\0' && isspace((unsigned char)*cp)) cp++; if (*cp != '\0' && isdigit((unsigned char)*cp)) { cp1 = cp; while (isdigit((unsigned char)*cp1)) cp1++; while (*cp != '\0' && isspace((unsigned char)*cp)) cp1++; if (*cp1 == '\0' || *cp1 == ',' || *cp1 == ';') { p = cp; continue; } } } while (*p != '\0' && *p != ';' && *p != ',') p++; value_end = p; /* * Trim trailing spaces. */ if ((value_end > value_start) && isspace((unsigned char)*(value_end - 1))) { value_end--; while ((value_end > (value_start + 1)) && isspace((unsigned char)*value_end) && isspace((unsigned char)*(value_end - 1))) { value_end--; } } break; } } else if (*p == '"') { /* * It's a quoted string. */ p++; value_start = p; while (*p != '\0' && *p != '"') p++; value_end = p; if (*p == '"') p++; } else { /* * Otherwise, it's an unquoted string. */ value_start = p; while (*p != '\0' && *p != ';' && *p != ',') p++; value_end = p; /* * Trim trailing spaces. */ if ((value_end > value_start) && isspace((unsigned char)*(value_end - 1))) { value_end--; while ((value_end > (value_start + 1)) && isspace((unsigned char)*value_end) && isspace((unsigned char)*(value_end - 1))) { value_end--; } } } } /* * Check for a separator character, and skip it. */ if (*p == ';' || *p == ',') p++; /* * Now, we can handle this attribute/value pair. */ if (attr_end > attr_start) { int len = (attr_end - attr_start); BOOLEAN known_attr = NO; char *value = NULL; if (value_end > value_start) { int value_len = (value_end - value_start); if (value_len > 4096) { value_len = 4096; } value = (char *)calloc(1, value_len + 1); if (value == NULL) outofmem(__FILE__, "LYProcessSetCookies"); LYstrncpy(value, value_start, value_len); } if (len == 6 && !strncasecomp(attr_start, "secure", 6)) { if (value == NULL) { known_attr = YES; if (cur_cookie != NULL) { cur_cookie->flags |= COOKIE_FLAG_SECURE; } } else { /* * If secure has a value, assume someone * misused it as cookie name. - FM */ known_attr = NO; } } else if (len == 7 && !strncasecomp(attr_start, "discard", 7)) { if (value == NULL) { known_attr = YES; if (cur_cookie != NULL) { cur_cookie->flags |= COOKIE_FLAG_DISCARD; } } else { /* * If discard has a value, assume someone
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -