private static List parseSetCookie1()

in api_dev/src/main/java/com/google/appengine/tools/util/ClientCookie.java [355:480]


  private static List<ClientCookie> parseSetCookie1(String setCookie1Header,
                                                    URL url)
      throws HttpHeaderParseException {
    final HttpHeaderParser parser = new HttpHeaderParser(setCookie1Header);
    final ArrayList<ClientCookie> results = new ArrayList<ClientCookie>();
    parser.eatLWS();
    while (true) {
      // read name=value
      final ClientCookie cookie = new ClientCookie();
      cookie.effectiveVersion_ = 1;
      cookie.name_ = parser.eatToken();
      parser.eatLWS();
      parser.eatChar('=');
      parser.eatLWS();
      cookie.value_ = parser.eatTokenOrQuotedString();
      parser.eatLWS();

      // read cookie attributes
      while (parser.peek() == ';') {
        parser.eatChar(';');
        parser.eatLWS();
        final String name = parser.eatToken().toLowerCase();
        parser.eatLWS();
        if (name.equals("secure")) {
          cookie.secure_ = true;
        } else if (name.equals("httponly")) {
          cookie.httponly_ = true;
        } else {
          parser.eatChar('=');
          parser.eatLWS();
          final String value = parser.eatTokenOrQuotedString();
          if (name.equals("comment")) {
            cookie.comment_ = value;
          } else if (name.equals("domain")) {
            cookie.domain_ = value.toLowerCase();
          } else if (name.equals("max-age")) {
            final int maxAge;
            try {
              maxAge = Integer.parseInt(value);
              if (maxAge < 0) {
                throw new NumberFormatException(value);
              }
            } catch (NumberFormatException e) {
              throw new HttpHeaderParseException("invalid max-age: " +
                setCookie1Header);
            }
            cookie.expires_ = System.currentTimeMillis() + 1000 * maxAge;
          } else if (name.equals("path")) {
            cookie.path_ = value;
          } else if (name.equals("version")) {
            try {
              cookie.version_ = Integer.parseInt(value);
              if (cookie.version_ <= 0) {
                throw new NumberFormatException(value);
              }
            } catch (NumberFormatException e) {
              throw new HttpHeaderParseException("invalid version: " +
                setCookie1Header);
            }
          } else if (name.equals("expires")) {
            throw new HttpHeaderParseException("this is a v0 cookie");
          } else {
            logger.info("unrecognized v1 cookie attribute: " +
              name + "=" + value);
          }
        }
        parser.eatLWS();
      }

      // validate the cookie - see RFC 2109 sec. 4.3.1, 4.3.2
      boolean valid = true;
      final String requestHost = url.getHost().toLowerCase();
      final String requestPath = url.getPath();
      if (cookie.domain_ == null) {
        cookie.effectiveDomain_ = requestHost;
      } else {
        if (!cookie.domain_.startsWith(".") ||
            cookie.domain_.substring(1, cookie.domain_.length() - 1)
                  .indexOf('.') < 0) {
          logger.info("rejecting v1 cookie [bad domain - no periods]: " +
            setCookie1Header);
          valid = false;
        } else if (!requestHost.endsWith(cookie.domain_)) {
          logger.info("rejecting v1 cookie [bad domain - no match]: " +
            setCookie1Header);
          valid = false;
        } else if (requestHost
                   .substring(0, requestHost.length() - cookie.domain_.length())
                   .indexOf('.') >= 0) {
          logger.info("rejecting v1 cookie [bad domain - extra periods]: " +
            setCookie1Header);
          valid = false;
        } else {
          cookie.effectiveDomain_ = cookie.domain_;
        }
      }
      if (cookie.path_ == null) {
        int index = requestPath.lastIndexOf('/');
        if (index < 0) {
          cookie.effectivePath_ = requestPath;
        } else {
          // trailing slash not included
          cookie.effectivePath_ = requestPath.substring(0, index);
        }
      } else {
        if (!requestPath.startsWith(cookie.path_)) {
          logger.info("rejecting v1 cookie [bad path]: " +
            setCookie1Header);
          valid = false;
        } else {
          cookie.effectivePath_ = cookie.path_;
        }
      }
      if (valid) {
        results.add(cookie);
      }

      // on to next cookie
      if (!parser.isEnd()) {
        parser.eatChar(',');
      } else {
        break;
      }
    }
    return results;
  }