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