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

com.yahoo.jdisc.http.Cookie Maven / Gradle / Ivy

There is a newer version: 8.499.20
Show newest version
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.http;

import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.server.CookieCutter;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static java.util.stream.Collectors.toList;

/**
 * A RFC 6265 compliant cookie.
 *
 * Note: RFC 2109 and RFC 2965 is no longer supported. All fields that are not part of RFC 6265 are deprecated.
 *
 * @author Einar M R Rosenvinge
 * @author bjorncs
 */
public class Cookie {

    private final Set ports = new HashSet<>();
    private String name;
    private String value;
    private String domain;
    private String path;
    private SameSite sameSite;
    private long maxAgeSeconds = Integer.MIN_VALUE;
    private boolean secure;
    private boolean httpOnly;
    private boolean discard;

    public Cookie() {
    }

    public Cookie(Cookie cookie) {
        ports.addAll(cookie.ports);
        name = cookie.name;
        value = cookie.value;
        domain = cookie.domain;
        path = cookie.path;
        sameSite = cookie.sameSite;
        maxAgeSeconds = cookie.maxAgeSeconds;
        secure = cookie.secure;
        httpOnly = cookie.httpOnly;
        discard = cookie.discard;
    }

    public Cookie(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public Cookie setName(String name) {
        this.name = name;
        return this;
    }

    public String getValue() {
        return value;
    }

    public Cookie setValue(String value) {
        this.value = value;
        return this;
    }

    public String getDomain() {
        return domain;
    }

    public Cookie setDomain(String domain) {
        this.domain = domain;
        return this;
    }

    public String getPath() {
        return path;
    }

    public Cookie setPath(String path) {
        this.path = path;
        return this;
    }

    public SameSite getSameSite() {
        return sameSite;
    }

    public Cookie setSameSite(SameSite sameSite) {
        this.sameSite = sameSite;
        return this;
    }

    public int getMaxAge(TimeUnit unit) {
        return (int)unit.convert(maxAgeSeconds, TimeUnit.SECONDS);
    }

    public Cookie setMaxAge(int maxAge, TimeUnit unit) {
        this.maxAgeSeconds = maxAge >= 0 ? unit.toSeconds(maxAge) : Integer.MIN_VALUE;
        return this;
    }

    public boolean isSecure() {
        return secure;
    }

    public Cookie setSecure(boolean secure) {
        this.secure = secure;
        return this;
    }

    public boolean isHttpOnly() {
        return httpOnly;
    }

    public Cookie setHttpOnly(boolean httpOnly) {
        this.httpOnly = httpOnly;
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Cookie cookie = (Cookie) o;
        return maxAgeSeconds == cookie.maxAgeSeconds &&
                secure == cookie.secure &&
                httpOnly == cookie.httpOnly &&
                discard == cookie.discard &&
                sameSite == cookie.sameSite &&
                Objects.equals(ports, cookie.ports) &&
                Objects.equals(name, cookie.name) &&
                Objects.equals(value, cookie.value) &&
                Objects.equals(domain, cookie.domain) &&
                Objects.equals(path, cookie.path);
    }

    @Override
    public int hashCode() {
        return Objects.hash(ports, name, value, domain, path, sameSite, maxAgeSeconds, secure, httpOnly, discard);
    }

    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        ret.append(name).append("=").append(value);
        return ret.toString();
    }
    // NOTE cookie encoding and decoding:
    //      The implementation uses Jetty for server-side (encoding of Set-Cookie and decoding of Cookie header),
    //      and java.net.HttpCookie for client-side (encoding of Cookie and decoding of Set-Cookie header).
    //
    // Implementation is RFC-6265 compliant.

    public static String toCookieHeader(Iterable cookies) {
        return StreamSupport.stream(cookies.spliterator(), false)
                .map(cookie -> {
                    java.net.HttpCookie httpCookie = new java.net.HttpCookie(cookie.getName(), cookie.getValue());
                    httpCookie.setDomain(cookie.getDomain());
                    httpCookie.setHttpOnly(cookie.isHttpOnly());
                    httpCookie.setMaxAge(cookie.getMaxAge(TimeUnit.SECONDS));
                    httpCookie.setPath(cookie.getPath());
                    httpCookie.setSecure(cookie.isSecure());
                    httpCookie.setVersion(0);
                    return httpCookie.toString();
                })
                .collect(Collectors.joining(";"));
    }

    public static List fromCookieHeader(String headerVal) {
        CookieCutter cookieCutter = new CookieCutter();
        cookieCutter.addCookieField(headerVal);
        return Arrays.stream(cookieCutter.getCookies())
                .map(servletCookie -> {
                    Cookie cookie = new Cookie();
                    cookie.setName(servletCookie.getName());
                    cookie.setValue(servletCookie.getValue());
                    cookie.setPath(servletCookie.getPath());
                    cookie.setDomain(servletCookie.getDomain());
                    cookie.setMaxAge(servletCookie.getMaxAge(), TimeUnit.SECONDS);
                    cookie.setSecure(servletCookie.getSecure());
                    cookie.setHttpOnly(servletCookie.isHttpOnly());
                    return cookie;
                })
                .collect(toList());
    }

    public static List toSetCookieHeaders(Iterable cookies) {
        return StreamSupport.stream(cookies.spliterator(), false)
                .map(cookie ->
                             new org.eclipse.jetty.http.HttpCookie(
                                     cookie.getName(),
                                     cookie.getValue(),
                                     cookie.getDomain(),
                                     cookie.getPath(),
                                     cookie.getMaxAge(TimeUnit.SECONDS),
                                     cookie.isHttpOnly(),
                                     cookie.isSecure(),
                                     null, /* comment */
                                     0, /* version */
                                     Optional.ofNullable(cookie.getSameSite()).map(SameSite::jettySameSite).orElse(null)
                             ).getRFC6265SetCookie())
                .collect(toList());
    }

    @Deprecated // TODO Vespa 8 Remove
    public static List toSetCookieHeaderAll(Iterable cookies) {
        return toSetCookieHeaders(cookies);
    }

    public static Cookie fromSetCookieHeader(String headerVal) {
        return java.net.HttpCookie.parse(headerVal).stream()
                .map(httpCookie -> {
                    Cookie cookie = new Cookie();
                    cookie.setName(httpCookie.getName());
                    cookie.setValue(httpCookie.getValue());
                    cookie.setDomain(httpCookie.getDomain());
                    cookie.setHttpOnly(httpCookie.isHttpOnly());
                    cookie.setMaxAge((int) httpCookie.getMaxAge(), TimeUnit.SECONDS);
                    cookie.setPath(httpCookie.getPath());
                    cookie.setSecure(httpCookie.getSecure());
                    return cookie;
                })
                .findFirst().get();
    }

    public enum SameSite {
        NONE, STRICT, LAX;

        HttpCookie.SameSite jettySameSite() {
            return HttpCookie.SameSite.valueOf(name());
        }

        static SameSite fromJettySameSite(HttpCookie.SameSite jettySameSite) {
            return valueOf(jettySameSite.name());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy