org.xbib.helianthus.common.http.DefaultHttpHeaders Maven / Gradle / Ivy
package org.xbib.helianthus.common.http;
import static io.netty.util.AsciiString.isUpperCase;
import static java.util.Objects.requireNonNull;
import io.netty.handler.codec.DefaultHeaders;
import io.netty.util.AsciiString;
import org.xbib.helianthus.internal.http.HelianthusHttpUtil;
import java.util.List;
/**
* Default {@link HttpHeaders} implementation.
*/
public final class DefaultHttpHeaders
extends DefaultHeaders implements HttpHeaders {
private static final NameValidator HTTP2_NAME_VALIDATOR = name -> {
if (name == null) {
throw new NullPointerException("header name");
}
final int index;
try {
index = name.forEachByte(value -> !isUpperCase(value));
} catch (Exception e) {
throw new IllegalArgumentException("invalid header name: " + name, e);
}
if (index != -1) {
throw new IllegalArgumentException("invalid header name: " + name);
}
};
private final boolean endOfStream;
private HttpMethod method;
private HttpStatus status;
public DefaultHttpHeaders() {
this(true);
}
public DefaultHttpHeaders(boolean validate) {
this(validate, 16);
}
/**
* Creates a new instance.
*
* @param validate whether to validate the header names and values
* @param initialCapacity the initial capacity of the internal data structure
*/
public DefaultHttpHeaders(boolean validate, int initialCapacity) {
this(validate, initialCapacity, false);
}
/**
* Creates a new instance.
*
* @param validate whether to validate the header names and values
* @param initialCapacity the initial capacity of the internal data structure
* @param endOfStream whether the stream should be closed after writing these headers
*/
@SuppressWarnings("unchecked")
public DefaultHttpHeaders(boolean validate, int initialCapacity, boolean endOfStream) {
super(HelianthusHttpUtil.HTTP2_HEADER_NAME_HASHER,
StringValueConverter.INSTANCE,
validate ? HTTP2_NAME_VALIDATOR : NameValidator.NOT_NULL, initialCapacity);
this.endOfStream = endOfStream;
}
@Override
public HttpHeaders method(HttpMethod method) {
requireNonNull(method, "method");
this.method = method;
set(HttpHeaderNames.METHOD, method.name());
return this;
}
@Override
public HttpHeaders scheme(String scheme) {
requireNonNull(scheme, "scheme");
set(HttpHeaderNames.SCHEME, scheme);
return this;
}
@Override
public HttpHeaders authority(String authority) {
requireNonNull(authority, "authority");
set(HttpHeaderNames.AUTHORITY, authority);
return this;
}
@Override
public HttpHeaders path(String path) {
requireNonNull(path, "path");
set(HttpHeaderNames.PATH, path);
return this;
}
@Override
public HttpHeaders status(int statusCode) {
final HttpStatus status = this.status = HttpStatus.valueOf(statusCode);
set(HttpHeaderNames.STATUS, status.codeAsText());
return this;
}
@Override
public HttpHeaders status(HttpStatus status) {
requireNonNull(status, "status");
return status(status.code());
}
@Override
public HttpMethod method() {
HttpMethod method = this.method;
if (method != null) {
return method;
}
final String methodStr = get(HttpHeaderNames.METHOD);
if (methodStr == null) {
return null;
}
try {
return this.method = HttpMethod.valueOf(methodStr);
} catch (IllegalArgumentException ignored) {
throw new IllegalStateException("unknown method: " + methodStr);
}
}
@Override
public String scheme() {
return get(HttpHeaderNames.SCHEME);
}
@Override
public String authority() {
return get(HttpHeaderNames.AUTHORITY);
}
@Override
public String path() {
return get(HttpHeaderNames.PATH);
}
@Override
public HttpStatus status() {
HttpStatus status = this.status;
if (status != null) {
return status;
}
final String statusStr = get(HttpHeaderNames.STATUS);
if (statusStr == null) {
return null;
}
try {
return this.status = HttpStatus.valueOf(Integer.parseInt(statusStr));
} catch (NumberFormatException ignored) {
throw new IllegalStateException("invalid status: " + statusStr);
}
}
@Override
public boolean isEndOfStream() {
return endOfStream;
}
@Override
public String toString() {
final int size = size();
if (size == 0) {
return "[]";
}
final StringBuilder buf = new StringBuilder(size() * 16).append('[');
String separator = "";
for (AsciiString name : names()) {
List values = getAll(name);
for (String value : values) {
buf.append(separator);
buf.append(name).append('=').append(value);
}
separator = ", ";
}
return buf.append(']').toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy