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

com.netflix.zuul.message.http.HttpResponseMessageImpl Maven / Gradle / Ivy

There is a newer version: 2.5.13
Show newest version
/*
 * 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