⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cookies.c

📁 基于minigui的浏览器. 这是最新版本.
💻 C
📖 第 1 页 / 共 3 页
字号:
{   int i;   for (i = 1; i <= 12; i++) {      if (!g_strncasecmp(months[i], month_name, 3))         return i;   }   return 0;}/* * Return a local timestamp from a GMT date string * Accept: RFC-1123 | RFC-850 | ANSI asctime | Old Netscape format. * *   Wdy, DD-Mon-YY HH:MM:SS GMT *   Wdy, DD-Mon-YYYY HH:MM:SS GMT *   Weekday, DD-Mon-YY HH:MM:SS GMT *   Weekday, DD-Mon-YYYY HH:MM:SS GMT *   Tue May 21 13:46:22 1991\n *   Tue May 21 13:46:22 1991 * * (return 0 on malformed date string syntax) */static time_t Cookies_create_timestamp(const char *expires){   time_t ret;   int day, month, year, hour, minutes, seconds;   gchar *cp;   gchar *E_msg =      "Expire date is malformed!\n"      " (should be RFC-1123 | RFC-850 | ANSI asctime)\n"      " Ignoring cookie: ";   cp = strchr(expires, ',');   if (!cp && (strlen(expires) == 24 || strlen(expires) == 25)) {      /* Looks like ANSI asctime format... */      cp = (gchar *)expires;      day = strtol(cp + 8, NULL, 10);       /* day */      month = Cookies_get_month(cp + 4);    /* month */      year = strtol(cp + 20, NULL, 10);     /* year */      hour = strtol(cp + 11, NULL, 10);     /* hour */      minutes = strtol(cp + 14, NULL, 10);  /* minutes */      seconds = strtol(cp + 17, NULL, 10);  /* seconds */   } else if (cp && (cp - expires == 3 || cp - expires > 5) &&                    (strlen(cp) == 24 || strlen(cp) == 26)) {      /* RFC-1123 | RFC-850 format | Old Netscape format */      day = strtol(cp + 2, NULL, 10);      month = Cookies_get_month(cp + 5);      year = strtol(cp + 9, &cp, 10);      /* todo: tricky, because two digits for year IS ambiguous! */      year += (year < 70) ? 2000 : ((year < 100) ? 1900 : 0);      hour = strtol(cp + 1, NULL, 10);      minutes = strtol(cp + 4, NULL, 10);      seconds = strtol(cp + 7, NULL, 10);   } else {      MSG("%s%s\n", E_msg, expires);      return (time_t) 0;   }   /* Error checks  --this may be overkill */   if (!(day > 0 && day < 32 && month > 0 && month < 13 && year > 1970 &&         hour >= 0 && hour < 24 && minutes >= 0 && minutes < 60 &&         seconds >= 0 && seconds < 60)) {      MSG("%s%s\n", E_msg, expires);      return (time_t) 0;   }   /* Calculate local timestamp.    * [stolen from Lynx... (http://lynx.browser.org)] */   month -= 3;   if (month < 0) {      month += 12;      year--;   }   day += (year - 1968) * 1461 / 4;   day += ((((month * 153) + 2) / 5) - 672);   ret = (time_t)((day * 60 * 60 * 24) +                  (hour * 60 * 60) +                  (minutes * 60) +                  seconds);   MSG("Expires in %ld seconds, at %s",       (long)ret - time(NULL), ctime(&ret));   return ret;}/* * Parse a string containing a list of port numbers. */static void Cookies_parse_ports(gint url_port, CookieData_t *cookie,                                const char *port_str){   if ((!port_str || !port_str[0]) && url_port != 0) {      /* There was no list, so only the calling urls port should be allowed. */      cookie->ports = g_list_append(cookie->ports,                                    GINT_TO_POINTER(url_port));   } else if (port_str[0] == '"' && port_str[1] != '"') {      char **tokens, **i;      int port;      tokens = g_strsplit(port_str + 1, ",", -1);      for (i = tokens; *i; ++i) {         port = strtol(*i, NULL, 10);         if (port > 0) {            cookie->ports = g_list_append(cookie->ports,                                          GINT_TO_POINTER(port));         }      }      g_strfreev(tokens);   }}/* * Build a string of the ports in 'cookie'. */static char *Cookies_build_ports_str(CookieData_t *cookie){   GString *gstr;   GList *list;   char *ret;   gstr = g_string_new("\"");   for (list = cookie->ports; list; list = g_list_next(list))      g_string_sprintfa(gstr, "%d,", GPOINTER_TO_INT(list->data));   /* Remove any trailing comma */   if (gstr->len > 1)      g_string_erase(gstr, gstr->len - 1, 1);   g_string_append(gstr, "\"");   ret = gstr->str;   g_string_free(gstr, FALSE);   return ret;}/* * Used by g_list_insert_sorted() to sort the cookies by most specific path */static gint Cookies_compare(gconstpointer a, gconstpointer b){   const CookieData_t *ca = a, *cb = b;   return strcmp(ca->path, cb->path);}static void Cookies_add_cookie(CookieData_t *cookie){   GList *domain_cookies, *tmp;   char *domain_str;   /* Don't add an expired cookie */   if (!cookie->session_only && cookie->expires_at < time(NULL)) {      Cookies_free_cookie(cookie);      return;   }   domain_cookies = g_hash_table_lookup(cookies, cookie->domain);   if (domain_cookies) {      /* Respect the limit of 20 cookies per domain */      if (g_list_length(domain_cookies) > 20) {         MSG("There are too many cookies for this domain (%s)\n",             cookie->domain);         Cookies_free_cookie(cookie);         return;      }      /* Remove any cookies with the same name and path */      while ((tmp = g_list_find_custom(domain_cookies, cookie,                                       Cookies_equals))) {         Cookies_remove_cookie(tmp->data);         domain_cookies = g_hash_table_lookup(cookies, cookie->domain);      }   }   /* Allocate string key when no domain_cookies are left    * (because remove_cookie has then killed the key, when it was there) */   domain_str = domain_cookies ? cookie->domain : g_strdup(cookie->domain);   domain_cookies = g_list_insert_sorted(domain_cookies, cookie,                                         Cookies_compare);   g_hash_table_insert(cookies, domain_str, domain_cookies);}/* * Remove the cookie from the domain list. * If the domain list is empty, free the hash table entry. * Free the cookie. */static void Cookies_remove_cookie(CookieData_t *cookie){   GList *list;   gpointer orig_key;   gpointer orig_val;   if (g_hash_table_lookup_extended(cookies, cookie->domain,                                    &orig_key, &orig_val)) {      list = g_list_remove(orig_val, cookie);      if (list) {         /* Make sure that we have the correct start of the list stored */         g_hash_table_insert(cookies, cookie->domain, list);      } else {         g_hash_table_remove(cookies, cookie->domain);         g_free(orig_key);      }   } else {      MSG("Attempting to remove a cookie that doesn't exist!\n");   }   Cookies_free_cookie(cookie);}/* * Return the attribute that is present at *cookie_str. This function * will also attempt to advance cookie_str past any equal-sign. */static char *Cookies_parse_attr(char **cookie_str){   char *str = *cookie_str;   guint i, end = 0;   gboolean got_attr = FALSE;   for (i = 0; ; i++) {      switch (str[i]) {      case ' ':      case '\t':      case '=':      case ';':         got_attr = TRUE;         if (end == 0)            end = i;         break;      case ',':         *cookie_str = str + i;         return g_strndup(str, i);         break;      case '\0':         if (!got_attr) {            end = i;            got_attr = TRUE;         }         /* fall through! */      default:         if (got_attr) {            *cookie_str = str + i;            return g_strndup(str, end);         }         break;      }   }   return NULL;}/* * Get the value starting at *cookie_str. * broken_syntax: watch out for stupid syntax (comma in unquoted string...) */static char *Cookies_parse_value(char **cookie_str,                                 gboolean broken_syntax,                                 gboolean keep_quotes){   guint i, end;   char *str = *cookie_str;   for (i = end = 0; !end; ++i) {      switch (str[i]) {      case ' ':      case '\t':         if (!broken_syntax && str[0] != '\'' && str[0] != '"') {            *cookie_str = str + i + 1;            end = 1;         }         break;      case '\'':      case '"':         if (i != 0 && str[i] == str[0]) {            char *tmp = str + i;            while (*tmp != '\0' && *tmp != ';' && *tmp != ',')               tmp++;            *cookie_str = (*tmp == ';') ? tmp + 1 : tmp;            if (keep_quotes)               i++;            end = 1;         }         break;      case '\0':         *cookie_str = str + i;         end = 1;         break;      case ',':         if (str[0] != '\'' && str[0] != '"' && !broken_syntax) {            /* A new cookie starts here! */            *cookie_str = str + i;            end = 1;         }         break;      case ';':         if (str[0] != '\'' && str[0] != '"') {            *cookie_str = str + i + 1;            end = 1;         }         break;      default:         break;      }   }   /* keep i as an index to the last char */   --i;   if ((str[0] == '\'' || str[0] == '"') && !keep_quotes) {      return i > 1 ? g_strndup(str + 1, i - 1) : NULL;   } else {      return g_strndup(str, i);   }}/* * Parse one cookie... */static CookieData_t *Cookies_parse_one(gint url_port, char **cookie_str){   CookieData_t *cookie;   char *str = *cookie_str;   char *attr;   char *value;   int num_attr = 0;   gboolean max_age = FALSE;   gboolean discard = FALSE;   cookie = g_new0(CookieData_t, 1);   cookie->session_only = TRUE;   /* Iterate until there is nothing left of the string OR we come    * across a comma representing the start of another cookie */   while (*str != '\0' && *str != ',') {      /* Skip whitespace */      while (isspace(*str))         str++;      /* Get attribute */      attr = Cookies_parse_attr(&str);      if (!attr) {         MSG("Failed to parse cookie attribute!\n");         Cookies_free_cookie(cookie);         return NULL;      }      /* Get the value for the attribute and store it */      if (num_attr == 0) {         /* The first attr, which always is the user supplied attr, may          * have the same name as an ordinary attr. Hence this workaround. */         cookie->name = g_strdup(attr);         cookie->value = Cookies_parse_value(&str, FALSE, TRUE);      } else if (g_strcasecmp(attr, "Path") == 0) {         value = Cookies_parse_value(&str, FALSE, FALSE);         cookie->path = value;      } else if (g_strcasecmp(attr, "Domain") == 0) {         value = Cookies_parse_value(&str, FALSE, FALSE);         cookie->domain = value;      } else if (g_strcasecmp(attr, "Discard") == 0) {         cookie->session_only = TRUE;         discard = TRUE;      } else if (g_strcasecmp(attr, "Max-Age") == 0) {         if (!discard) {            value = Cookies_parse_value(&str, FALSE, FALSE);            if (value) {               cookie->expires_at = time(NULL) + strtol(value, NULL, 10);               cookie->session_only = FALSE;               max_age = TRUE;               g_free(value);            } else {               MSG("Failed to parse cookie value!\n");               Cookies_free_cookie(cookie);               return NULL;            }         }      } else if (g_strcasecmp(attr, "Expires") == 0) {         if (!max_age && !discard) {            MSG("Old netscape-style cookie...\n");            value = Cookies_parse_value(&str, TRUE, FALSE);            if (value) {               cookie->expires_at = Cookies_create_timestamp(value);               cookie->session_only = FALSE;               g_free(value);            } else {               MSG("Failed to parse cookie value!\n");               Cookies_free_cookie(cookie);               return NULL;            }         }      } else if (g_strcasecmp(attr, "Port") == 0) {         value = Cookies_parse_value(&str, FALSE, TRUE);         Cookies_parse_ports(url_port, cookie, value);         g_free(value);      } else if (g_strcasecmp(attr, "Comment") == 0) {         value = Cookies_parse_value(&str, FALSE, FALSE);         cookie->comment = value;      } else if (g_strcasecmp(attr, "CommentURL") == 0) {         value = Cookies_parse_value(&str, FALSE, FALSE);         cookie->comment_url = value;      } else if (g_strcasecmp(attr, "Version") == 0) {         value = Cookies_parse_value(&str, FALSE, FALSE);         if (value) {            cookie->version = strtol(value, NULL, 10);            g_free(value);         } else {            MSG("Failed to parse cookie value!\n");            Cookies_free_cookie(cookie);            return NULL;         }      } else if (g_strcasecmp(attr, "Secure") == 0) {         cookie->secure = TRUE;      } else {         /* Oops! this can't be good... */         g_free(attr);         Cookies_free_cookie(cookie);         MSG("Cookie contains illegal attribute!\n");         return NULL;      }      g_free(attr);      num_attr++;   }   *cookie_str = (*str == ',') ? str + 1 : str;   if (cookie->name && cookie->value) {      return cookie;   } else {      MSG("Cookie missing name and/or value!\n");      Cookies_free_cookie(cookie);      return NULL;   }}/* * Iterate the cookie string until we catch all cookies. * Return Value: a list with all the cookies! (or NULL upon error) */static GSList *Cookies_parse_string(gint url_port, char *cookie_string){   CookieData_t *cookie;   GSList *ret = NULL;   char *str = cookie_string;   /* The string may contain several cookies separated by comma.    * We'll iterate until we've catched them all */   while (*str) {      cookie = Cookies_parse_one(url_port, &str);      if (cookie) {         ret = g_slist_append(ret, cookie);      } else {         MSG("Malformed cookie field, ignoring cookie: %s\n", cookie_string);         return NULL;      }   }   return ret;}/* * Compare cookies by name and path (return 0 if equal) */static gint Cookies_equals(gconstpointer a, gconstpointer b){   const CookieData_t *ca = a, *cb = b;   return (strcmp(ca->name, cb->name) || strcmp(ca->path, cb->path));}/* * Validate cookies domain against some security checks. */static gboolean Cookies_validate_domain(CookieData_t *cookie, gchar *host,                                         gchar *url_path){   int dots, diff, i;   gboolean is_ip;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -