com.netflix.zuul.message.http.HttpResponseMessageImpl Maven / Gradle / Ivy
/*
* Copyright 2018 Netflix, Inc.
*
* 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.
*/
package com.netflix.zuul.message.http;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.zuul.context.SessionContext;
import com.netflix.zuul.filters.ZuulFilter;
import com.netflix.zuul.message.Header;
import com.netflix.zuul.message.Headers;
import com.netflix.zuul.message.ZuulMessage;
import com.netflix.zuul.message.ZuulMessageImpl;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* User: michaels
* Date: 2/24/15
* Time: 10:54 AM
*/
public class HttpResponseMessageImpl implements HttpResponseMessage {
private static final DynamicIntProperty MAX_BODY_SIZE_PROP = DynamicPropertyFactory.getInstance()
.getIntProperty("zuul.HttpResponseMessage.body.max.size", 25 * 1000 * 1024);
private static final Logger LOG = LoggerFactory.getLogger(HttpResponseMessageImpl.class);
private ZuulMessage message;
private HttpRequestMessage outboundRequest;
private int status;
private HttpResponseInfo inboundResponse = null;
public HttpResponseMessageImpl(SessionContext context, HttpRequestMessage request, int status) {
this(context, new Headers(), request, status);
}
public HttpResponseMessageImpl(SessionContext context, Headers headers, HttpRequestMessage request, int status) {
this.message = new ZuulMessageImpl(context, headers);
this.outboundRequest = request;
if (this.outboundRequest.getInboundRequest() == null) {
LOG.warn(
"HttpResponseMessage created with a request that does not have a stored inboundRequest! Probably a bug in the filter that is creating this response.",
new RuntimeException("Invalid HttpRequestMessage"));
}
this.status = status;
}
public static HttpResponseMessage defaultErrorResponse(HttpRequestMessage request) {
final HttpResponseMessage resp = new HttpResponseMessageImpl(request.getContext(), request, 500);
resp.finishBufferedBodyIfIncomplete();
return resp;
}
@Override
public Headers getHeaders() {
return message.getHeaders();
}
@Override
public SessionContext getContext() {
return message.getContext();
}
@Override
public void setHeaders(Headers newHeaders) {
message.setHeaders(newHeaders);
}
@Override
public void setHasBody(boolean hasBody) {
message.setHasBody(hasBody);
}
@Override
public boolean hasBody() {
return message.hasBody();
}
@Override
public void bufferBodyContents(HttpContent chunk) {
message.bufferBodyContents(chunk);
}
@Override
public void setBodyAsText(String bodyText) {
message.setBodyAsText(bodyText);
}
@Override
public void setBody(byte[] body) {
message.setBody(body);
}
@Override
public String getBodyAsText() {
return message.getBodyAsText();
}
@Override
public byte[] getBody() {
return message.getBody();
}
@Override
public int getBodyLength() {
return message.getBodyLength();
}
@Override
public boolean hasCompleteBody() {
return message.hasCompleteBody();
}
@Override
public boolean finishBufferedBodyIfIncomplete() {
return message.finishBufferedBodyIfIncomplete();
}
@Override
public Iterable getBodyContents() {
return message.getBodyContents();
}
@Override
public void resetBodyReader() {
message.resetBodyReader();
}
@Override
public void runBufferedBodyContentThroughFilter(ZuulFilter filter) {
message.runBufferedBodyContentThroughFilter(filter);
}
@Override
public void disposeBufferedBody() {
message.disposeBufferedBody();
}
@Override
public HttpRequestInfo getInboundRequest() {
return outboundRequest.getInboundRequest();
}
@Override
public HttpRequestMessage getOutboundRequest() {
return outboundRequest;
}
@Override
public int getStatus() {
return status;
}
@Override
public void setStatus(int status) {
this.status = status;
}
@Override
public int getMaxBodySize() {
return MAX_BODY_SIZE_PROP.get();
}
@Override
public Cookies parseSetCookieHeader(String setCookieValue) {
Cookies cookies = new Cookies();
cookies.add(ClientCookieDecoder.STRICT.decode(setCookieValue));
return cookies;
}
@Override
public boolean hasSetCookieWithName(String cookieName) {
for (String setCookieValue : getHeaders().getAll(HttpHeaderNames.SET_COOKIE)) {
Cookie cookie = ClientCookieDecoder.STRICT.decode(setCookieValue);
if (cookie.name().equalsIgnoreCase(cookieName)) {
return true;
}
}
return false;
}
@Override
public boolean removeExistingSetCookie(String cookieName) {
String cookieNamePrefix = cookieName + "=";
boolean dirty = false;
Headers filtered = new Headers();
for (Header hdr : getHeaders().entries()) {
if (HttpHeaderNames.SET_COOKIE.equals(hdr.getName())) {
String value = hdr.getValue();
// Strip out this set-cookie as requested.
if (value.startsWith(cookieNamePrefix)) {
// Don't copy it.
dirty = true;
} else {
// Copy all other headers.
filtered.add(hdr.getName(), hdr.getValue());
}
} else {
// Copy all other headers.
filtered.add(hdr.getName(), hdr.getValue());
}
}
if (dirty) {
setHeaders(filtered);
}
return dirty;
}
@Override
public void addSetCookie(Cookie cookie) {
getHeaders().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.LAX.encode(cookie));
}
@Override
public void setSetCookie(Cookie cookie) {
getHeaders().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.LAX.encode(cookie));
}
@Override
public ZuulMessage clone() {
// TODO - not sure if should be cloning the outbound request object here or not....
HttpResponseMessageImpl clone = new HttpResponseMessageImpl(
getContext().clone(), Headers.copyOf(getHeaders()), getOutboundRequest(), getStatus());
if (getInboundResponse() != null) {
clone.inboundResponse = (HttpResponseInfo) getInboundResponse().clone();
}
return clone;
}
protected HttpResponseInfo copyResponseInfo() {
HttpResponseMessageImpl response = new HttpResponseMessageImpl(
getContext(), Headers.copyOf(getHeaders()), getOutboundRequest(), getStatus());
response.setHasBody(hasBody());
return response;
}
@Override
public String toString() {
return "HttpResponseMessageImpl{" + "message="
+ message + ", outboundRequest="
+ outboundRequest + ", status="
+ status + ", inboundResponse="
+ inboundResponse + '}';
}
@Override
public void storeInboundResponse() {
inboundResponse = copyResponseInfo();
}
@Override
public HttpResponseInfo getInboundResponse() {
return inboundResponse;
}
@Override
public String getInfoForLogging() {
HttpRequestInfo req = getInboundRequest() == null ? getOutboundRequest() : getInboundRequest();
StringBuilder sb = new StringBuilder()
.append(req.getInfoForLogging())
.append(",proxy-status=")
.append(getStatus());
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy