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

org.xbib.helianthus.common.http.HttpResponseWriter Maven / Gradle / Ivy

package org.xbib.helianthus.common.http;

import org.xbib.helianthus.common.stream.StreamWriter;

import static org.xbib.helianthus.internal.http.HelianthusHttpUtil.isContentAlwaysEmpty;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

import static java.util.Objects.requireNonNull;

/**
 * A {@link StreamWriter} of an {@link HttpResponse}.
 */
public interface HttpResponseWriter extends StreamWriter {

    /**
     * Writes the HTTP response of the specified {@code statusCode} and closes the stream if the
     * {@link HttpStatusClass} is not {@linkplain HttpStatusClass#INFORMATIONAL informational} (1xx).
     */
    default void respond(int statusCode) {
        respond(HttpStatus.valueOf(statusCode));
    }

    default void respond(HttpStatus status) {
        requireNonNull(status, "status");
        if (status.codeClass() == HttpStatusClass.INFORMATIONAL) {
            write(HttpHeaders.of(status));
        } else if (isContentAlwaysEmpty(status)) {
            write(HttpHeaders.of(status));
            close();
        } else {
            respond(status, "text/plain", status.toHttpData());
        }
    }

    default void respond(HttpStatus status, String mediaType, String content) {
        requireNonNull(status, "status");
        requireNonNull(content, "content");
        requireNonNull(mediaType, "mediaType");
        respond(status,
                mediaType, content.getBytes(StandardCharsets.UTF_8));
    }

    default void respond(HttpStatus status, String mediaType, String format, Object... args) {
        requireNonNull(status, "status");
        requireNonNull(mediaType, "mediaType");
        requireNonNull(format, "format");
        requireNonNull(args, "args");
        respond(status,
                mediaType,
                String.format(Locale.ENGLISH, format, args).getBytes(StandardCharsets.UTF_8));
    }

    default void respond(HttpStatus status, String mediaType, byte[] content) {
        requireNonNull(content, "content");
        respond(status, mediaType, HttpData.of(content));
    }

    default void respond(HttpStatus status, String mediaType, byte[] content, int offset, int length) {
        requireNonNull(content, "content");
        respond(status, mediaType, HttpData.of(content, offset, length));
    }

    default void respond(HttpStatus status, String mediaType, HttpData content) {
        requireNonNull(status, "status");
        requireNonNull(content, "content");
        requireNonNull(mediaType, "mediaType");

        final int length = content.length();
        final HttpHeaders headers =
                HttpHeaders.of(status)
                        .set(HttpHeaderNames.CONTENT_TYPE, mediaType)
                        .setInt(HttpHeaderNames.CONTENT_LENGTH, length);

        if (isContentAlwaysEmpty(status)) {
            if (length != 0) {
                throw new IllegalArgumentException(
                        "A " + status + " response must have empty content: " + length + " byte(s)");
            }
            write(headers);
        } else {
            write(headers);
            write(content);
        }

        close();
    }

    default void respond(AggregatedHttpMessage res) {
        final HttpHeaders headers = res.headers();
        write(headers);

        final HttpData content = res.content();
        if (isContentAlwaysEmpty(headers.status())) {
            if (!content.isEmpty()) {
                throw new IllegalArgumentException(
                        "A " + headers.status() + " response must have empty content: " +
                                content.length() + " byte(s)");
            }

            if (!res.trailingHeaders().isEmpty()) {
                throw new IllegalArgumentException(
                        "A " + headers.status() + " response must not have trailing headers: " +
                                res.trailingHeaders());
            }

            close();
            return;
        }

        // Add content if not empty.
        if (!content.isEmpty()) {
            write(content);
        }

        // Add trailing headers if not empty.
        final HttpHeaders trailingHeaders = res.trailingHeaders();
        if (!trailingHeaders.isEmpty()) {
            write(trailingHeaders);
        }

        close();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy