All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.jfunc.http.cookie.Cookie Maven / Gradle / Ivy

// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

package top.jfunc.http.cookie;

import top.jfunc.http.base.HttpHeaders;
import top.jfunc.common.utils.StrUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * from jodd
 * Cookie object. Simple cookie data holder, cookie header parser and generator.
 * @author xiongshiyan
 */
public class Cookie {
	public static final String MAX_AGE   = "Max-Age";
	public static final String COMMENT   = "Comment";
	public static final String DOMAIN    = "Domain";
	public static final String PATH      = "Path";
	public static final String SECURE    = "Secure";
	public static final String VERSION   = "Version";
	public static final String HTTP_ONLY = "HttpOnly";
	public static final String EXPIRES   = "Expires";

    /**
     * cookie key
     */
	private String name;
    /**
     * cookie value
     * name=value
     */
	private String value;

	/// attributes encoded in the header's cookie fields

    /**
     * ;Comment=VALUE ... describes cookie's use ; Discard ... implied by maxAge < 0
     */
    private String comment;
    /**
     * ;Domain=VALUE ... domain that sees cookie
     */
    private String domain;
    /**
     * ;Max-Age=VALUE ... cookies auto-expire
     */
    private Integer maxAge;
    /**
     * ;Path=VALUE ... URLs that see the cookie
     */
    private String path;
    /**
     * ;Expires= ... expires values
     */
    private String expires;
    /**
     * ;Secure ... e.g. use SSL
     */
    private boolean secure;
    /**
     * ;Version=1 ... means RFC 2109++ style
     */
    private Integer version;
    /**
     * ;HttpOnly
     */
    private boolean httpOnly;


	/**
	 * Creates cookie with specified name and value.
	 * 

* The name must conform to RFC 2109. That means it can contain * only ASCII alphanumeric characters and cannot contain commas, * semicolons, or white space or begin with a $ character. *

* The value can be anything the server chooses to send. */ public Cookie(final String name, final String value) { setName(name); setValue(value); } /** * 形如:oschina_new_user=false; path=/; expires=Fri, 02 Nov 2040 09:11:02 -0000 * Parses cookie data from given user-agent string. */ public Cookie(String cookieString) { int from = 0; int ndx = 0; cookieString = cookieString.trim(); while (ndx < cookieString.length()) { ndx = cookieString.indexOf(StrUtil.SEMICOLON, from); if (ndx == -1) { // last chunk ndx = cookieString.length(); } int ndx2 = cookieString.indexOf(StrUtil.EQUALS, from); String name; String value; if (ndx2 != -1 && ndx2 < ndx) { name = cookieString.substring(from, ndx2).trim(); value = cookieString.substring(ndx2 + 1, ndx).trim(); } else { if (from == ndx) { ndx++; continue; } name = cookieString.substring(from, ndx).trim(); value = null; } if (value != null && MAX_AGE.equalsIgnoreCase(name)) { setMaxAge(Integer.parseInt(value)); } else if (COMMENT.equalsIgnoreCase(name)) { setComment(value); } else if (DOMAIN.equalsIgnoreCase(name)) { setDomain(value); } else if (PATH.equalsIgnoreCase(name)) { setPath(value); } else if (SECURE.equalsIgnoreCase(name)) { setSecure(true); } else if (value != null && VERSION.equalsIgnoreCase(name)) { setVersion(Integer.parseInt(value)); } else if (HTTP_ONLY.equalsIgnoreCase(name)) { setHttpOnly(true); } else if (EXPIRES.equalsIgnoreCase(name)) { setExpires(value); } else if (this.name == null && !StrUtil.isBlank(name)) { setName(name); setValue(value); } // continue from = ndx + 1; } } /** * Sets the cookie name and checks for validity. */ private void setName(final String name) { if (name.contains(StrUtil.SEMICOLON) || name.contains(StrUtil.COMMA) || name.startsWith("$")) { throw new IllegalArgumentException("Invalid cookie name:" + name); } for (int n = 0; n < name.length(); n++) { char c = name.charAt(n); if (c <= 0x20 || c >= 0x7f) { throw new IllegalArgumentException("Invalid cookie name:" + name); } } this.name = name; } /** * Returns the comment describing the purpose of this cookie, or * null if the cookie has no comment. */ public String getComment() { return comment; } /** * Specifies a comment that describes a cookie's purpose. * The comment is useful if the browser presents the cookie * to the user. */ public Cookie setComment(final String purpose) { comment = purpose; return this; } /** * Returns the domain name set for this cookie. The form of * the domain name is set by RFC 2109. */ public String getDomain() { return domain; } /** * Specifies the domain within which this cookie should be presented. *

* The form of the domain name is specified by RFC 2109. A domain * name begins with a dot (.foo.com) and means that * the cookie is visible to servers in a specified Domain Name System * (DNS) zone (for example, www.foo.com, but not * a.b.foo.com). By default, cookies are only returned * to the server that sent them. */ public Cookie setDomain(final String pattern) { // IE allegedly needs this domain = pattern.toLowerCase(); return this; } /** * Returns the maximum age of the cookie, specified in seconds, * By default, -1 indicating the cookie will persist * until browser shutdown. */ public Integer getMaxAge() { return maxAge; } /** * Sets the maximum age of the cookie in seconds. *

* A positive value indicates that the cookie will expire * after that many seconds have passed. Note that the value is * the maximum age when the cookie will expire, not the cookie's * current age. *

* A negative value means * that the cookie is not stored persistently and will be deleted * when the Web browser exits. A zero value causes the cookie * to be deleted. */ public Cookie setMaxAge(final int expiry) { maxAge = expiry; return this; } /** * Returns the path on the server * to which the browser returns this cookie. The * cookie is visible to all subpaths on the server. */ public String getPath() { return path; } /** * Specifies a path for the cookie * to which the client should return the cookie. *

* The cookie is visible to all the pages in the directory * you specify, and all the pages in that directory's subdirectories. * A cookie's path must include the servlet that set the cookie, * for example, /catalog, which makes the cookie * visible to all directories on the server under /catalog. * *

Consult RFC 2109 (available on the Internet) for more * information on setting path names for cookies. */ public Cookie setPath(final String uri) { path = uri; return this; } /** * Returns true if the browser is sending cookies * only over a secure protocol, or false if the * browser can send cookies using any protocol. */ public boolean isSecure() { return secure; } /** * Indicates to the browser whether the cookie should only be sent * using a secure protocol, such as HTTPS or SSL. */ public Cookie setSecure(final boolean flag) { secure = flag; return this; } /** * Returns the name of the cookie. The name cannot be changed after * creation. */ public String getName() { return name; } /** * Returns the value of the cookie. */ public String getValue() { return value; } /** * Assigns a new value to a cookie after the cookie is created. * If you use a binary value, you may want to use BASE64 encoding. */ public Cookie setValue(final String newValue) { value = newValue; return this; } /** * Returns the version of the protocol this cookie complies * with. Version 1 complies with RFC 2109, * and version 0 complies with the original * cookie specification drafted by Netscape. Cookies provided * by a browser use and identify the browser's cookie version. */ public Integer getVersion() { return version; } /** * Sets the version of the cookie protocol this cookie complies * with. Version 0 complies with the original Netscape cookie * specification. Version 1 complies with RFC 2109. */ public Cookie setVersion(final int version) { this.version = version; return this; } public boolean isHttpOnly() { return httpOnly; } public Cookie setHttpOnly(final boolean httpOnly) { this.httpOnly = httpOnly; return this; } public String getExpires() { return expires; } public Cookie setExpires(final String expires) { this.expires = expires; return this; } @Override public String toString() { StringBuilder cookie = new StringBuilder(); cookie.append(name).append('=').append(value); if (maxAge != null) { cookie.append("; Max-Age=").append(maxAge); } if (expires != null) { cookie.append("; Expires=").append(expires); } if (comment != null) { cookie.append("; Comment=").append(comment); } if (domain != null) { cookie.append("; Domain=").append(domain); } if (path != null) { cookie.append("; Path=").append(path); } if (secure) { cookie.append("; Secure"); } if (version != null) { cookie.append("; Version=").append(version); } if (httpOnly) { cookie.append("; HttpOnly"); } return cookie.toString(); } /** * 形成key1=value1;key2=value2用于请求Cookie:key1=value1;key2=value2 * @param cookies 多个cookie * @return cookie字符串 */ public static String buildCookieString(List cookies){ StringBuilder cookieString = new StringBuilder(); boolean first = true; for (Cookie cookie : cookies) { Integer maxAge = cookie.getMaxAge(); if (maxAge != null && maxAge == 0) { continue; } if (!first) { cookieString.append("; "); } first = false; cookieString.append(cookie.getName()); cookieString.append(StrUtil.EQUALS); cookieString.append(cookie.getValue()); } return cookieString.toString(); } /** * 从响应中的{@link HttpHeaders#SET_COOKIE}|{@link HttpHeaders#SET_COOKIE2}字段获取cookie解析成一个个的cookie * @param newCookies 多个{@link HttpHeaders#SET_COOKIE}|{@link HttpHeaders#SET_COOKIE2}的值 * @return 多个cookie */ public static List parseCookies(List newCookies){ List cookieList = new ArrayList<>(newCookies.size()); for (String cookieValue : newCookies) { try { cookieList.add(new Cookie(cookieValue)); }catch (Exception e) { // ignore } } return cookieList; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy