📄 lycookie.c
字号:
* used it as a cookie name. - FM */ known_attr = NO; } } else if (len == 7 && !strncasecomp(attr_start, "comment", 7)) { known_attr = YES; if (cur_cookie != NULL && value && /* * Don't process a repeat comment. - FM */ cur_cookie->comment == NULL) { StrAllocCopy(cur_cookie->comment, value); length += strlen(cur_cookie->comment); } } else if (len == 10 && !strncasecomp(attr_start, "commentURL", 10)) { known_attr = YES; if (cur_cookie != NULL && value && /* * Don't process a repeat commentURL. - FM */ cur_cookie->commentURL == NULL) { /* * We should get only absolute URLs as * values, but will resolve versus the * request's URL just in case. - FM */ cur_cookie->commentURL = HTParse(value, address, PARSE_ALL); /* * Accept only URLs for http or https servers. - FM */ if ((url_type = is_url(cur_cookie->commentURL)) && (url_type == HTTP_URL_TYPE || url_type == HTTPS_URL_TYPE)) { length += strlen(cur_cookie->commentURL); } else { if (TRACE) fprintf(stderr, "LYProcessSetCookies: Rejecting commentURL value '%s'\n", cur_cookie->commentURL); FREE(cur_cookie->commentURL); } } } else if (len == 6 && !strncasecomp(attr_start, "domain", 6)) { known_attr = YES; if (cur_cookie != NULL && value && /* * Don't process a repeat domain. - FM */ !(cur_cookie->flags & COOKIE_FLAG_DOMAIN_SET)) { length -= strlen(cur_cookie->domain); /* * If the value does not have a lead dot, * but does have an embedded dot, and is * not an exact match to the hostname, nor * is a numeric IP address, add a lead dot. * Otherwise, use the value as is. - FM */ if (value[0] != '.' && value[0] != '\0' && value[1] != '\0' && strcmp(value, hostname)) { char *ptr = strchr(value, '.'); if (ptr != NULL && ptr[1] != '\0') { ptr = value; while (*ptr == '.' || isdigit((unsigned char)*ptr)) ptr++; if (*ptr != '\0') { if (TRACE) { fprintf(stderr, "LYProcessSetCookies: Adding lead dot for domain value '%s'\n", value); } StrAllocCopy(cur_cookie->domain, "."); StrAllocCat(cur_cookie->domain, value); } else { StrAllocCopy(cur_cookie->domain, value); } } else { StrAllocCopy(cur_cookie->domain, value); } } else { StrAllocCopy(cur_cookie->domain, value); } length += strlen(cur_cookie->domain); cur_cookie->flags |= COOKIE_FLAG_DOMAIN_SET; } } else if (len == 4 && !strncasecomp(attr_start, "path", 4)) { known_attr = YES; if (cur_cookie != NULL && value && /* * Don't process a repeat path. - FM */ !(cur_cookie->flags & COOKIE_FLAG_PATH_SET)) { length -= strlen(cur_cookie->path); StrAllocCopy(cur_cookie->path, value); length += (cur_cookie->pathlen = strlen(cur_cookie->path)); cur_cookie->flags |= COOKIE_FLAG_PATH_SET; } } else if (len == 4 && !strncasecomp(attr_start, "port", 4)) { if (cur_cookie != NULL && value && /* * Don't process a repeat port. - FM */ cur_cookie->PortList == NULL) { char *cp = value; while ((*cp != '\0') && (isdigit((unsigned char)*cp) || *cp == ',' || *cp == ' ')) { cp++; } if (*cp == '\0') { StrAllocCopy(cur_cookie->PortList, value); length += strlen(cur_cookie->PortList); known_attr = YES; } else { known_attr = NO; } } else if (cur_cookie != NULL) { /* * Don't process a repeat port. - FM */ if (cur_cookie->PortList == NULL) { char temp[256]; sprintf(temp, "%d", port); StrAllocCopy(cur_cookie->PortList, temp); length += strlen(cur_cookie->PortList); } known_attr = YES; } } else if (len == 7 && !strncasecomp(attr_start, "version", 7)) { known_attr = YES; if (cur_cookie != NULL && value && /* * Don't process a repeat version. - FM */ cur_cookie->version < 1) { int temp = strtol(value, NULL, 10); if (errno != -ERANGE) { cur_cookie->version = temp; } } } else if (len == 7 && !strncasecomp(attr_start, "max-age", 7)) { known_attr = YES; if (cur_cookie != NULL && value && /* * Don't process a repeat max-age. - FM */ !MaxAgeAttrSet) { int temp = strtol(value, NULL, 10); cur_cookie->flags |= COOKIE_FLAG_EXPIRES_SET; if (errno == -ERANGE) { cur_cookie->expires = (time_t)0; } else { cur_cookie->expires = (time(NULL) + temp); if (TRACE) fprintf(stderr, "LYSetCookie: expires %ld, %s", (long) cur_cookie->expires, ctime(&cur_cookie->expires)); } MaxAgeAttrSet = TRUE; } } else if (len == 7 && !strncasecomp(attr_start, "expires", 7)) { /* * Convert an 'expires' attribute value if we haven't * received a 'max-age'. Note that 'expires' should not * be used in Version 1 cookies, but it might be used for * "backward compatibility", and, in turn, ill-informed * people surely would start using it instead of, rather * than in addition to, 'max-age'. - FM */ known_attr = YES; if ((cur_cookie != NULL && !MaxAgeAttrSet) && !(cur_cookie->flags & COOKIE_FLAG_EXPIRES_SET)) { known_attr = YES; if (value) { cur_cookie->flags |= COOKIE_FLAG_EXPIRES_SET; cur_cookie->expires = LYmktime(value, FALSE); if (cur_cookie->expires > 0) { if (TRACE) fprintf(stderr, "LYSetCookie: expires %ld, %s", (long) cur_cookie->expires, ctime(&cur_cookie->expires)); } } } } /* * If none of the above comparisons succeeded, and we have * a value, then we have an unknown pair of the form 'foo=bar', * which means it's time to create a new cookie. If we don't * have a non-zero-length value, assume it's an error or a * new, unknown attribute which doesn't take a value, and * ignore it. - FM */ if (!known_attr && value_end > value_start) { /* * If we've started a cookie, and it's not too big, * save it in the CombinedCookies list. - FM */ if (length <= 4096 && cur_cookie != NULL) { /* * Assume version 1 if not set to that or higher. - FM */ if (cur_cookie->version < 1) { cur_cookie->version = 1; } HTList_appendObject(CombinedCookies, cur_cookie); } else if (cur_cookie != NULL) { if (TRACE) { fprintf(stderr, "LYProcessSetCookies: Rejecting Set-Cookie2: %s=%s\n", (cur_cookie->name ? cur_cookie->name : "[no name]"), (cur_cookie->value ? cur_cookie->value : "[no value]")); fprintf(stderr, " due to excessive length!\n"); } freeCookie(cur_cookie); cur_cookie = NULL; } /* * Start a new cookie. - FM */ cur_cookie = newCookie(); length = 0; NumCookies++; MemAllocCopy(&(cur_cookie->name), attr_start, attr_end); length += strlen(cur_cookie->name); MemAllocCopy(&(cur_cookie->value), value_start, value_end); length += strlen(cur_cookie->value); StrAllocCopy(cur_cookie->domain, hostname); length += strlen(cur_cookie->domain); StrAllocCopy(cur_cookie->path, path); length += (cur_cookie->pathlen = strlen(cur_cookie->path)); cur_cookie->port = port; MaxAgeAttrSet = FALSE; cur_cookie->quoted = TRUE; } FREE(value); } } /* * Add any final SetCookie2 cookie to the CombinedCookie list * if we are within the length limit. - FM */ if (NumCookies <= 50 && length <= 4096 && cur_cookie != NULL) { if (cur_cookie->version < 1) { cur_cookie->version = 1; } HTList_appendObject(CombinedCookies, cur_cookie); } else if (cur_cookie != NULL) { if (TRACE) { fprintf(stderr, "LYProcessSetCookies: Rejecting Set-Cookie2: %s=%s\n", (cur_cookie->name ? cur_cookie->name : "[no name]"), (cur_cookie->value ? cur_cookie->value : "[no value]")); fprintf(stderr, " due to excessive %s%s%s\n", (length > 4096 ? "length" : ""), (length > 4096 && NumCookies > 50 ? " and " : ""), (NumCookies > 50 ? "number!\n" : "!\n")); } freeCookie(cur_cookie); cur_cookie = NULL; } /* * Process the Set-Cookie header, if no non-zero-length Set-Cookie2 * header was present. - FM */ length = 0; NumCookies = 0; cur_cookie = NULL; p = ((SetCookie && !(SetCookie2 && *SetCookie2)) ? SetCookie : ""); if (TRACE && SetCookie2 && *p) { fprintf(stderr, "LYProcessSetCookies: Using Set-Cookie 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. - 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++; Quoted = TRUE; } 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -