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

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