/*
* Copyright 2017-2020 original authors
*
* 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
*
* https://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.micronaut.http;
import io.micronaut.core.convert.ConversionContext;
import io.micronaut.core.type.Headers;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
Constants for common HTTP headers. See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
Author: Graeme Rocher Since: 1.0
/**
* Constants for common HTTP headers. See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
*
* @author Graeme Rocher
* @since 1.0
*/
public interface HttpHeaders extends Headers {
"Accept"
. /**
* {@code "Accept"}.
*/
String ACCEPT = "Accept";
"Accept-CH"
. /**
* {@code "Accept-CH"}.
*/
String ACCEPT_CH = "Accept-CH";
"Accept-CH"
. /**
* {@code "Accept-CH"}.
*/
String ACCEPT_CH_LIFETIME = "Accept-CH-Lifetime";
"Accept-Charset"
. /**
* {@code "Accept-Charset"}.
*/
String ACCEPT_CHARSET = "Accept-Charset";
"Accept-Encoding"
. /**
* {@code "Accept-Encoding"}.
*/
String ACCEPT_ENCODING = "Accept-Encoding";
"Accept-Language"
. /**
* {@code "Accept-Language"}.
*/
String ACCEPT_LANGUAGE = "Accept-Language";
"Accept-Ranges"
. /**
* {@code "Accept-Ranges"}.
*/
String ACCEPT_RANGES = "Accept-Ranges";
"Accept-Patch"
. /**
* {@code "Accept-Patch"}.
*/
String ACCEPT_PATCH = "Accept-Patch";
"Access-Control-Allow-Credentials"
. /**
* {@code "Access-Control-Allow-Credentials"}.
*/
String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
"Access-Control-Allow-Headers"
. /**
* {@code "Access-Control-Allow-Headers"}.
*/
String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
"Access-Control-Allow-Methods"
. /**
* {@code "Access-Control-Allow-Methods"}.
*/
String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
"Access-Control-Allow-Origin"
. /**
* {@code "Access-Control-Allow-Origin"}.
*/
String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
"Access-Control-Expose-Headers"
. /**
* {@code "Access-Control-Expose-Headers"}.
*/
String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
"Access-Control-Max-Age"
. /**
* {@code "Access-Control-Max-Age"}.
*/
String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
"Access-Control-Request-Headers"
. /**
* {@code "Access-Control-Request-Headers"}.
*/
String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
"Access-Control-Request-Method"
. /**
* {@code "Access-Control-Request-Method"}.
*/
String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
"Age"
. /**
* {@code "Age"}.
*/
String AGE = "Age";
"Allow"
. /**
* {@code "Allow"}.
*/
String ALLOW = "Allow";
"Authorization"
. /**
* {@code "Authorization"}.
*/
String AUTHORIZATION = "Authorization";
"Authorization"
. /**
* {@code "Authorization"}.
*/
String AUTHORIZATION_INFO = "Authorization-Info";
"Cache-Control"
. /**
* {@code "Cache-Control"}.
*/
String CACHE_CONTROL = "Cache-Control";
"Connection"
. /**
* {@code "Connection"}.
*/
String CONNECTION = "Connection";
"Content-Base"
. /**
* {@code "Content-Base"}.
*/
String CONTENT_BASE = "Content-Base";
"Content-Disposition"
. /**
* {@code "Content-Disposition"}.
*/
String CONTENT_DISPOSITION = "Content-Disposition";
"Content-DPR"
. /**
* {@code "Content-DPR"}.
*/
String CONTENT_DPR = "Content-DPR";
"Content-Encoding"
. /**
* {@code "Content-Encoding"}.
*/
String CONTENT_ENCODING = "Content-Encoding";
"Content-Language"
. /**
* {@code "Content-Language"}.
*/
String CONTENT_LANGUAGE = "Content-Language";
"Content-Length"
. /**
* {@code "Content-Length"}.
*/
String CONTENT_LENGTH = "Content-Length";
"Content-Location"
. /**
* {@code "Content-Location"}.
*/
String CONTENT_LOCATION = "Content-Location";
"Content-Transfer-Encoding"
. /**
* {@code "Content-Transfer-Encoding"}.
*/
String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
"Content-MD5"
. /**
* {@code "Content-MD5"}.
*/
String CONTENT_MD5 = "Content-MD5";
"Content-Range"
. /**
* {@code "Content-Range"}.
*/
String CONTENT_RANGE = "Content-Range";
"Content-Type"
. /**
* {@code "Content-Type"}.
*/
String CONTENT_TYPE = "Content-Type";
"Cookie"
. /**
* {@code "Cookie"}.
*/
String COOKIE = "Cookie";
"Cross-Origin-Resource-Policy"
. /**
* {@code "Cross-Origin-Resource-Policy"}.
*/
String CROSS_ORIGIN_RESOURCE_POLICY = "Cross-Origin-Resource-Policy";
"Date"
. /**
* {@code "Date"}.
*/
String DATE = "Date";
"Device-Memory"
. /**
* {@code "Device-Memory"}.
*/
String DEVICE_MEMORY = "Device-Memory";
"Downlink"
. /**
* {@code "Downlink"}.
*/
String DOWNLINK = "Downlink";
"DPR"
. /**
* {@code "DPR"}.
*/
String DPR = "DPR";
"ECT"
. /**
* {@code "ECT"}.
*/
String ECT = "ECT";
"ETag"
. /**
* {@code "ETag"}.
*/
String ETAG = "ETag";
"Expect"
. /**
* {@code "Expect"}.
*/
String EXPECT = "Expect";
"Expires"
. /**
* {@code "Expires"}.
*/
String EXPIRES = "Expires";
"Feature-Policy"
. /**
* {@code "Feature-Policy"}.
*/
String FEATURE_POLICY = "Feature-Policy";
"Forwarded"
. /**
* {@code "Forwarded"}.
*/
String FORWARDED = "Forwarded";
"From"
. /**
* {@code "From"}.
*/
String FROM = "From";
"Host"
. /**
* {@code "Host"}.
*/
String HOST = "Host";
"If-Match"
. /**
* {@code "If-Match"}.
*/
String IF_MATCH = "If-Match";
"If-Modified-Since"
. /**
* {@code "If-Modified-Since"}.
*/
String IF_MODIFIED_SINCE = "If-Modified-Since";
"If-None-Match"
. /**
* {@code "If-None-Match"}.
*/
String IF_NONE_MATCH = "If-None-Match";
"If-Range"
. /**
* {@code "If-Range"}.
*/
String IF_RANGE = "If-Range";
"If-Unmodified-Since"
. /**
* {@code "If-Unmodified-Since"}.
*/
String IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
"Last-Modified"
. /**
* {@code "Last-Modified"}.
*/
String LAST_MODIFIED = "Last-Modified";
"Link"
. /**
* {@code "Link"}.
*/
String LINK = "Link";
"Location"
. /**
* {@code "Location"}.
*/
String LOCATION = "Location";
"Max-Forwards"
. /**
* {@code "Max-Forwards"}.
*/
String MAX_FORWARDS = "Max-Forwards";
"Origin"
. /**
* {@code "Origin"}.
*/
String ORIGIN = "Origin";
"Pragma"
. /**
* {@code "Pragma"}.
*/
String PRAGMA = "Pragma";
"Proxy-Authenticate"
. /**
* {@code "Proxy-Authenticate"}.
*/
String PROXY_AUTHENTICATE = "Proxy-Authenticate";
"Proxy-Authorization"
. /**
* {@code "Proxy-Authorization"}.
*/
String PROXY_AUTHORIZATION = "Proxy-Authorization";
"Range"
. /**
* {@code "Range"}.
*/
String RANGE = "Range";
"Referer"
. /**
* {@code "Referer"}.
*/
String REFERER = "Referer";
"Referrer-Policy"
. /**
* {@code "Referrer-Policy"}.
*/
String REFERRER_POLICY = "Referrer-Policy";
"Retry-After"
. /**
* {@code "Retry-After"}.
*/
String RETRY_AFTER = "Retry-After";
"RTT"
. /**
* {@code "RTT"}.
*/
String RTT = "RTT";
"Save-Data"
. /**
* {@code "Save-Data"}.
*/
String SAVE_DATA = "Save-Data";
"Sec-WebSocket-Key1"
. /**
* {@code "Sec-WebSocket-Key1"}.
*/
String SEC_WEBSOCKET_KEY1 = "Sec-WebSocket-Key1";
"Sec-WebSocket-Key2"
. /**
* {@code "Sec-WebSocket-Key2"}.
*/
String SEC_WEBSOCKET_KEY2 = "Sec-WebSocket-Key2";
"Sec-WebSocket-Location"
. /**
* {@code "Sec-WebSocket-Location"}.
*/
String SEC_WEBSOCKET_LOCATION = "Sec-WebSocket-Location";
"Sec-WebSocket-Origin"
. /**
* {@code "Sec-WebSocket-Origin"}.
*/
String SEC_WEBSOCKET_ORIGIN = "Sec-WebSocket-Origin";
"Sec-WebSocket-Protocol"
. /**
* {@code "Sec-WebSocket-Protocol"}.
*/
String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol";
"Sec-WebSocket-Version"
. /**
* {@code "Sec-WebSocket-Version"}.
*/
String SEC_WEBSOCKET_VERSION = "Sec-WebSocket-Version";
"Sec-WebSocket-Key"
. /**
* {@code "Sec-WebSocket-Key"}.
*/
String SEC_WEBSOCKET_KEY = "Sec-WebSocket-Key";
"Sec-WebSocket-Accept"
. /**
* {@code "Sec-WebSocket-Accept"}.
*/
String SEC_WEBSOCKET_ACCEPT = "Sec-WebSocket-Accept";
"Server"
. /**
* {@code "Server"}.
*/
String SERVER = "Server";
"Set-Cookie"
. /**
* {@code "Set-Cookie"}.
*/
String SET_COOKIE = "Set-Cookie";
"Set-Cookie2"
. /**
* {@code "Set-Cookie2"}.
*/
String SET_COOKIE2 = "Set-Cookie2";
"Source-Map"
. /**
* {@code "Source-Map"}.
*/
String SOURCE_MAP = "SourceMap";
"TE"
. /**
* {@code "TE"}.
*/
String TE = "TE";
"Trailer"
. /**
* {@code "Trailer"}.
*/
String TRAILER = "Trailer";
"Transfer-Encoding"
. /**
* {@code "Transfer-Encoding"}.
*/
String TRANSFER_ENCODING = "Transfer-Encoding";
"Upgrade"
. /**
* {@code "Upgrade"}.
*/
String UPGRADE = "Upgrade";
"User-Agent"
. /**
* {@code "User-Agent"}.
*/
String USER_AGENT = "User-Agent";
"Vary"
. /**
* {@code "Vary"}.
*/
String VARY = "Vary";
"Via"
. /**
* {@code "Via"}.
*/
String VIA = "Via";
"Viewport-Width"
. /**
* {@code "Viewport-Width"}.
*/
String VIEWPORT_WIDTH = "Viewport-Width";
"Warning"
. /**
* {@code "Warning"}.
*/
String WARNING = "Warning";
"WebSocket-Location"
. /**
* {@code "WebSocket-Location"}.
*/
String WEBSOCKET_LOCATION = "WebSocket-Location";
"WebSocket-Origin"
. /**
* {@code "WebSocket-Origin"}.
*/
String WEBSOCKET_ORIGIN = "WebSocket-Origin";
"WebSocket-Protocol"
. /**
* {@code "WebSocket-Protocol"}.
*/
String WEBSOCKET_PROTOCOL = "WebSocket-Protocol";
"Width"
. /**
* {@code "Width"}.
*/
String WIDTH = "Width";
"WWW-Authenticate"
. /**
* {@code "WWW-Authenticate"}.
*/
String WWW_AUTHENTICATE = "WWW-Authenticate";
"X-Auth-Token"
. /**
* {@code "X-Auth-Token"}.
*/
String X_AUTH_TOKEN = "X-Auth-Token";
Obtain the date header.
Params: - name – The header name
Returns: The date header as a ZonedDateTime
otherwise if it is not present or cannot be parsed Optional.empty()
/**
* Obtain the date header.
*
* @param name The header name
* @return The date header as a {@link ZonedDateTime} otherwise if it is not present or cannot be parsed
* {@link Optional#empty()}
*/
default Optional<ZonedDateTime> findDate(CharSequence name) {
try {
return findFirst(name).map(str -> {
LocalDateTime localDateTime = LocalDateTime.parse(str, DateTimeFormatter.RFC_1123_DATE_TIME);
return ZonedDateTime.of(localDateTime, ZoneId.of("GMT"));
}
);
} catch (DateTimeParseException e) {
return Optional.empty();
}
}
Obtain the date header.
Params: - name – The header name
Returns: The date header as a ZonedDateTime
otherwise if it is not present or cannot be parsed null
/**
* Obtain the date header.
*
* @param name The header name
* @return The date header as a {@link ZonedDateTime} otherwise if it is not present or cannot be parsed null
*/
default ZonedDateTime getDate(CharSequence name) {
return findDate(name).orElse(null);
}
Obtain an integer header.
Params: - name – The header name
Returns: The date header as a ZonedDateTime
otherwise if it is not present or cannot be parsed null
/**
* Obtain an integer header.
*
* @param name The header name
* @return The date header as a {@link ZonedDateTime} otherwise if it is not present or cannot be parsed null
*/
default Integer getInt(CharSequence name) {
return findInt(name).orElse(null);
}
Find an integer header.
Params: - name – The name of the header
Returns: An Optional
of Integer
/**
* Find an integer header.
*
* @param name The name of the header
* @return An {@link Optional} of {@link Integer}
*/
default Optional<Integer> findInt(CharSequence name) {
return get(name, ConversionContext.INT);
}
Get the first value of the given header.
Params: - name – The header name
Returns: The first value or null if it is present
/**
* Get the first value of the given header.
*
* @param name The header name
* @return The first value or null if it is present
*/
default Optional<String> findFirst(CharSequence name) {
return getFirst(name, ConversionContext.STRING);
}
The request or response content type.
Returns: The content type
/**
* The request or response content type.
*
* @return The content type
*/
default Optional<MediaType> contentType() {
return getFirst(HttpHeaders.CONTENT_TYPE, MediaType.CONVERSION_CONTEXT);
}
The request or response content type.
Returns: The content type
/**
* The request or response content type.
*
* @return The content type
*/
default OptionalLong contentLength() {
final Long aLong = getFirst(HttpHeaders.CONTENT_LENGTH, ConversionContext.LONG).orElse(null);
if (aLong != null) {
return OptionalLong.of(aLong);
} else {
return OptionalLong.empty();
}
}
A list of accepted MediaType
instances. Returns: A list of zero or many MediaType
instances
/**
* A list of accepted {@link MediaType} instances.
*
* @return A list of zero or many {@link MediaType} instances
*/
default List<MediaType> accept() {
final List<String> values = getAll(HttpHeaders.ACCEPT);
if (!values.isEmpty()) {
List<MediaType> mediaTypes = new ArrayList<>(10);
for (String value : values) {
final String[] tokens = value.split(",");
for (String token : tokens) {
try {
mediaTypes.add(new MediaType(token));
} catch (IllegalArgumentException e) {
// ignore
}
}
}
return mediaTypes;
} else {
return Collections.emptyList();
}
}
Returns: Whether the CONNECTION
header is set to Keep-Alive
/**
* @return Whether the {@link HttpHeaders#CONNECTION} header is set to Keep-Alive
*/
default boolean isKeepAlive() {
return getFirst(CONNECTION, ConversionContext.STRING)
.map(val -> val.equalsIgnoreCase(HttpHeaderValues.CONNECTION_KEEP_ALIVE)).orElse(false);
}
Returns: The ORIGIN
header
/**
* @return The {@link #ORIGIN} header
*/
default Optional<String> getOrigin() {
return findFirst(ORIGIN);
}
Returns: The AUTHORIZATION
header
/**
* @return The {@link #AUTHORIZATION} header
*/
default Optional<String> getAuthorization() {
return findFirst(AUTHORIZATION);
}
Returns: The CONTENT_TYPE
header
/**
* @return The {@link #CONTENT_TYPE} header
*/
default Optional<String> getContentType() {
return findFirst(CONTENT_TYPE);
}
}