
net.dongliu.cute.http.Headers Maven / Gradle / Ivy
The newest version!
package net.dongliu.cute.http;
import net.dongliu.commons.Lazy;
import net.dongliu.commons.Optionals;
import net.dongliu.commons.collection.Lists;
import net.dongliu.commons.collection.Maps;
import java.net.HttpCookie;
import java.net.http.HttpHeaders;
import java.time.Instant;
import java.util.*;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toUnmodifiableList;
/**
* The http headers.
* This class is thread-safe.
*
* @author Liu Dong
*/
public class Headers {
private final Map> map;
private final Lazy cookies;
private final Lazy> contentType;
/**
* Create a new Headers.
*
* @param map the headers map
*/
private Headers(Map> map) {
this.map = requireNonNull(map);
this.cookies = Lazy.of(this::parseCookies);
this.contentType = Lazy.of(() -> getHeader(HeaderNames.CONTENT_TYPE).flatMap(ContentType::safeParse));
}
/**
* Construct a headers, from immutable jdk http client headers.
*
* @param httpHeaders the http headers
* @return Headers
*/
public static Headers ofHttpHeaders(HttpHeaders httpHeaders) {
return new Headers(httpHeaders.map());
}
/**
* Construct headers from a Collection of header.
*
* @param headers the header collection
* @return Headers
*/
public static Headers of(Collection extends Header> headers) {
var map = Maps.>newCaseInsensitiveMap();
for (var header : headers) {
map.computeIfAbsent(header.name(), name -> new ArrayList<>(2)).add(header.value());
}
return new Headers(copyImmutable(map));
}
// copy map to a new immutable, case-insensitive map
private static Map> copyImmutable(Map> map) {
var newMap = Maps.>newCaseInsensitiveMap();
for (var entry : map.entrySet()) {
newMap.put(entry.getKey(), List.copyOf(entry.getValue()));
}
return unmodifiableMap(newMap);
}
private Cookies parseCookies() {
var cookieValues = getHeaders(HeaderNames.SET_COOKIE);
// hope timestamp do not diff too much
var createTime = Instant.now();
var cookieList = cookieValues.stream()
.flatMap(v -> HttpCookie.parse(v).stream())
.map(c -> ofHttpCookie(createTime, c))
.collect(toUnmodifiableList());
return new Cookies(cookieList);
}
private static Cookie ofHttpCookie(Instant createTime, HttpCookie httpCookie) {
return new Cookie(httpCookie.getName(), httpCookie.getValue(), httpCookie.getDomain(), httpCookie.getPath(),
httpCookie.getMaxAge() < 0 ? OptionalLong.empty() : OptionalLong.of(httpCookie.getMaxAge()),
httpCookie.getSecure(), httpCookie.isHttpOnly(), createTime);
}
/**
* Get headers by name. If not exists, return empty list
*/
public List getHeaders(String name) {
requireNonNull(name);
return map.getOrDefault(name, List.of());
}
/**
* Get the first header value matched name.
*/
public Optional getHeader(String name) {
requireNonNull(name);
return Lists.first(getHeaders(name));
}
/**
* Get header value as long.
*/
public OptionalLong getLongHeader(String name) {
var header = getHeader(name);
return Optionals.mapToLong(header, Long::parseLong);
}
/**
* Get all header as Map
*
* @return immutable map of headers. return empty map if do not has any header.
*/
public Map> allHeaders() {
return map;
}
/**
* Get content type set in http header.
* If do not set Content-Type header, or parse header error, return empty Optional.
*
* @return the charset
*/
public Optional contentType() {
return contentType.get();
}
/**
* Get cookies in this header.
*
* @return a immutable list of cookies
*/
public Cookies cookies() {
return cookies.get();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy