CaravanHttpResponse.java
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2014 wcm.io
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.wcm.caravan.io.http.response;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.osgi.annotation.versioning.ProviderType;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import io.wcm.caravan.io.http.impl.CaravanHttpHelper;
/**
* An immutable response to an http invocation which only returns string content.
*/
@ProviderType
public final class CaravanHttpResponse {
private final int status;
private final String reason;
private final Multimap<String, String> headers;
private final Body body;
CaravanHttpResponse(int status, String reason, Multimap<String, String> headers, Body body) {
checkState(status >= 200, "Invalid status code: %s", status);
this.status = status;
this.reason = checkNotNull(reason, "reason");
Multimap<String, String> copyOf = LinkedHashMultimap.create(checkNotNull(headers, "headers"));
this.headers = ImmutableMultimap.copyOf(copyOf);
this.body = body; // nullable
}
/**
* status code. ex {@code 200} See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" >rfc2616</a>
* @return HTTP status code
*/
public int status() {
return status;
}
/**
* @return HTTP status reason
*/
public String reason() {
return reason;
}
/**
* @return HTTP headers
*/
public Multimap<String, String> headers() {
return headers;
}
/**
* Collects all "Cache-Control" directives from the response headers into a single map. The keys in the map are the
* directive names (e.g. "max-age", "no-cache"), and everything after the "=" is taken as value. For directives that
* don't have a value "true" is used as a value instead.
* @return the map of Cache-Control directice
*/
public Map<String, String> getCacheControl() {
// http headers are case-insensitive, and even if we write all our headers in upper-case,
// any proxy in-between can turn them into lower-case variants.
// We need to make sure that we don't miss the lower-case variants here
List<String> cacheControlHeaders = new LinkedList<>();
cacheControlHeaders.addAll(headers.get("Cache-Control"));
cacheControlHeaders.addAll(headers.get("cache-control"));
return CaravanHttpHelper.convertMultiValueHeaderToMap(cacheControlHeaders);
}
/**
* if present, the response had a body
* @return HTTP body
*/
public Body body() {
return body;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("HTTP/1.1 ").append(status).append(' ').append(reason).append('\n');
for (String field : headers.keySet()) {
builder.append(field).append(": ").append(Joiner.on(", ").join(headers.get(field))).append('\n');
}
if (body != null) {
builder.append('\n').append(body);
}
return builder.toString();
}
}