diff options
Diffstat (limited to 'container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java')
-rw-r--r-- | container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java b/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java new file mode 100644 index 00000000000..f7138ba0e2b --- /dev/null +++ b/container-core/src/main/java/com/yahoo/jdisc/http/HttpResponse.java @@ -0,0 +1,125 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.http; + +import com.yahoo.jdisc.HeaderFields; +import com.yahoo.jdisc.Request; +import com.yahoo.jdisc.Response; +import com.yahoo.jdisc.handler.CompletionHandler; +import com.yahoo.jdisc.handler.ContentChannel; +import com.yahoo.jdisc.handler.ResponseHandler; +import com.yahoo.jdisc.http.servlet.ServletOrJdiscHttpResponse; + +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * A HTTP response. + * + * @author Einar M R Rosenvinge + */ +public class HttpResponse extends Response implements ServletOrJdiscHttpResponse { + + private final HeaderFields trailers = new HeaderFields(); + private boolean chunkedEncodingEnabled = true; + private String message; + + public interface Status extends Response.Status { + int REQUEST_ENTITY_TOO_LARGE = REQUEST_TOO_LONG; + int REQUEST_RANGE_NOT_SATISFIABLE = REQUESTED_RANGE_NOT_SATISFIABLE; + } + + protected HttpResponse(Request request, int status, String message, Throwable error) { + super(status, error); + this.message = message; + } + + public boolean isChunkedEncodingEnabled() { + if (headers().contains(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED)) { + return true; + } + if (headers().containsKey(HttpHeaders.Names.CONTENT_LENGTH)) { + return false; + } + return chunkedEncodingEnabled; + } + + public void setChunkedEncodingEnabled(boolean chunkedEncodingEnabled) { + this.chunkedEncodingEnabled = chunkedEncodingEnabled; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + @Override + public void copyHeaders(HeaderFields target) { + target.addAll(headers()); + } + + public List<Cookie> decodeSetCookieHeader() { + List<String> cookies = headers().get(HttpHeaders.Names.SET_COOKIE); + if (cookies == null) { + return Collections.emptyList(); + } + List<Cookie> ret = new LinkedList<>(); + for (String cookie : cookies) { + ret.add(Cookie.fromSetCookieHeader(cookie)); + } + return ret; + } + + public void encodeSetCookieHeader(List<Cookie> cookies) { + headers().remove(HttpHeaders.Names.SET_COOKIE); + for (Cookie cookie : cookies) { + headers().add(HttpHeaders.Names.SET_COOKIE, Cookie.toSetCookieHeaders(Arrays.asList(cookie))); + } + } + + /** + * <p>Returns the set of trailer header fields of this HttpResponse. These are typically meta-data that should have + * been part of {@link #headers()}, but were not available prior to calling {@link + * ResponseHandler#handleResponse(Response)}. You must NOT WRITE to these headers AFTER calling {@link + * ContentChannel#close(CompletionHandler)}, and you must NOT READ from these headers BEFORE {@link + * ContentChannel#close(CompletionHandler)} has been called.</p> + * + * <p><b>NOTE:</b> These headers are NOT thread-safe. You need to explicitly synchronized on the returned object to + * prevent concurrency issues such as ConcurrentModificationExceptions.</p> + * + * @return The trailer headers of this HttpRequest. + */ + public HeaderFields trailers() { + return trailers; + } + + public static boolean isServerError(Response response) { + return (response.getStatus() >= 500) && (response.getStatus() < 600); + } + + public static HttpResponse newInstance(int status) { + return new HttpResponse(null, status, null, null); + } + + public static HttpResponse newInstance(int status, String message) { + return new HttpResponse(null, status, message, null); + } + + public static HttpResponse newError(Request request, int status, Throwable error) { + return new HttpResponse(request, status, formatMessage(error), error); + } + + public static HttpResponse newInternalServerError(Request request, Throwable error) { + return new HttpResponse(request, Status.INTERNAL_SERVER_ERROR, formatMessage(error), error); + } + + private static String formatMessage(Throwable t) { + String msg = t.getMessage(); + return msg != null ? msg : t.toString(); + } + +} |