io.helidon.common.http.SetCookie Maven / Gradle / Ivy
/*
* Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.common.http;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Objects;
/**
* Represents {@code 'Set-Cookie'} header value specified by RFC6265.
*
* It is mutable and fluent builder.
*/
public class SetCookie {
private static final String PARAM_SEPARATOR = "; ";
private final String name;
private final String value;
private final ZonedDateTime expires;
private final Duration maxAge;
private final String domain;
private final String path;
private final Boolean secure;
private final Boolean httpOnly;
private SetCookie(Builder builder) {
this.name = builder.name;
this.value = builder.value;
this.expires = builder.expires;
this.maxAge = builder.maxAge;
this.domain = builder.domain;
this.path = builder.path;
this.secure = builder.secure;
this.httpOnly = builder.httpOnly;
}
/**
* Creates a new fluent API builder.
*
* @param name a cookie name.
* @param value a cookie value.
* @return a new fluent API builder
*/
public static Builder builder(String name, String value) {
return new Builder(name, value);
}
/**
* Creates new instance.
*
* @param name a cookie name.
* @param value a cookie value.
* @return a new instance with just the name and value configured
*/
public static SetCookie create(String name, String value) {
return builder(name, value)
.build();
}
/**
* Returns content of this instance as a 'Set-Cookie:' header value specified
* by RFC6265.
*
* @return a 'Set-Cookie:' header value.
*/
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append(name).append('=').append(value);
if (expires != null) {
result.append(PARAM_SEPARATOR);
result.append("Expires=");
result.append(expires.format(Http.DateTime.RFC_1123_DATE_TIME));
}
if ((maxAge != null) && !maxAge.isNegative() && !maxAge.isZero()) {
result.append(PARAM_SEPARATOR);
result.append("Max-Age=");
result.append(maxAge.getSeconds());
}
if (domain != null) {
result.append(PARAM_SEPARATOR);
result.append("Domain=");
result.append(domain);
}
if (path != null) {
result.append(PARAM_SEPARATOR);
result.append("Path=");
result.append(path);
}
if (secure != null) {
result.append(PARAM_SEPARATOR);
result.append("Secure");
}
if (httpOnly != null) {
result.append(PARAM_SEPARATOR);
result.append("HttpOnly");
}
return result.toString();
}
/**
* A fluent API builder for {@link SetCookie}.
*/
public static final class Builder implements io.helidon.common.Builder {
private final String name;
private final String value;
private ZonedDateTime expires;
private Duration maxAge;
private String domain;
private String path;
private Boolean secure;
private Boolean httpOnly;
private Builder(String name, String value) {
Objects.requireNonNull(name, "Parameter 'name' is null!");
//todo validate accepted characters
this.name = name;
this.value = value;
}
@Override
public SetCookie build() {
return new SetCookie(this);
}
/**
* Sets {@code Expires} parameter.
*
* @param expires an {@code Expires} parameter.
* @return Updated instance.
*/
public Builder expires(ZonedDateTime expires) {
this.expires = expires;
return this;
}
/**
* Sets {@code Expires} parameter.
*
* @param expires an {@code Expires} parameter.
* @return Updated instance.
*/
public Builder expires(Instant expires) {
if (expires == null) {
this.expires = null;
} else {
this.expires = ZonedDateTime.ofInstant(expires, ZoneId.systemDefault());
}
return this;
}
/**
* Sets {@code Max-Age} parameter.
*
* @param maxAge an {@code Max-Age} parameter.
* @return Updated instance.
*/
public Builder maxAge(Duration maxAge) {
this.maxAge = maxAge;
return this;
}
/**
* Sets {@code Domain} parameter.
*
* @param domain an {@code Domain} parameter.
* @return Updated instance.
*/
public Builder domain(String domain) {
this.domain = domain;
return this;
}
/**
* Sets {@code Path} parameter.
*
* @param path an {@code Path} parameter.
* @return Updated instance.
*/
public Builder path(String path) {
this.path = path;
return this;
}
/**
* Sets {@code Domain} and {@code Path} parameters.
*
* @param domainAndPath an URI to specify {@code Domain} and {@code Path} parameters.
* @return Updated instance.
*/
public Builder domainAndPath(URI domainAndPath) {
if (domainAndPath == null) {
this.domain = null;
this.path = null;
} else {
this.domain = domainAndPath.getHost();
this.path = domainAndPath.getPath();
}
return this;
}
/**
* Sets {@code Secure} parameter.
*
* @param secure an {@code Secure} parameter.
* @return Updated instance.
*/
public Builder secure(boolean secure) {
this.secure = secure;
return this;
}
/**
* Sets {@code HttpOnly} parameter.
*
* @param httpOnly an {@code HttpOnly} parameter.
* @return Updated instance.
*/
public Builder httpOnly(boolean httpOnly) {
this.httpOnly = httpOnly;
return this;
}
}
}