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

com.turbospaces.resteasy.DefaultHttpClientResponsePrinter Maven / Gradle / Ivy

The newest version!
package com.turbospaces.resteasy;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker;

import com.github.robtimus.obfuscation.Obfuscator;
import com.github.robtimus.obfuscation.http.HeaderObfuscator;
import com.google.common.net.HttpHeaders;
import com.turbospaces.annotations.ApiEndpoint;
import com.turbospaces.cfg.ApplicationProperties;
import com.turbospaces.http.HttpProto;

import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientResponseContext;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.ext.RuntimeDelegate;
import jakarta.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DefaultHttpClientResponsePrinter implements HttpClientResponsePrinter {
    private static HeaderDelegate COOKIE_PRINTER = RuntimeDelegate.getInstance().createHeaderDelegate(Cookie.class);

    protected final ApplicationProperties props;
    protected final StringWriter writer = new StringWriter();
    protected final BufferedWriter buffer = new BufferedWriter(writer);

    public DefaultHttpClientResponsePrinter(ApplicationProperties props) {
        this.props = Objects.requireNonNull(props);
    }
    @Override
    public void writeStart(ClientRequestContext req, ClientResponseContext resp) throws IOException {
        buffer.write("Response:");
        buffer.newLine();
    }
    @Override
    public void writeUri(ClientRequestContext context, ClientResponseContext resp) throws IOException {
        URIBuilder builder = (URIBuilder) context.getProperty(HttpProto.toCtxName(HttpProto.CONTEXT_URI));

        buffer.write(context.getMethod() + ": " + builder);
        buffer.newLine();
    }
    @Override
    public void writeStatus(ClientRequestContext req, ClientResponseContext resp) throws IOException {
        buffer.write("Status: " + resp.getStatus());
        buffer.newLine();

        if (resp.getLength() > 0) {
            buffer.write("Length: " + resp.getLength());
            buffer.newLine();
        }
    }
    @Override
    public void writeHeaders(ClientRequestContext req, ClientResponseContext resp) throws IOException {
        MultivaluedMap headers = resp.getHeaders();

        HeaderObfuscator.Builder b = HeaderObfuscator.builder();

        List l = props.HTTP_HEADERS_TO_MASK.get();
        if (CollectionUtils.isNotEmpty(l)) {
            for (String it : l) {
                b.withHeader(it, Obfuscator.all());
            }
        }

        HeaderObfuscator obfuscator = b.build();
        if (BooleanUtils.isFalse(headers.isEmpty())) {
            for (Entry> next : headers.entrySet()) {
                String name = next.getKey();
                boolean isNotCookie = BooleanUtils.isFalse(StringUtils.equalsIgnoreCase(name, HttpHeaders.SET_COOKIE));

                if (isNotCookie) {
                    if (CollectionUtils.isNotEmpty(next.getValue())) {
                        for (String value : next.getValue()) {
                            buffer.write(String.format("Header: %s = %s", name, obfuscator.obfuscateHeader(name, value)));
                            buffer.newLine();
                        }
                    }
                }
            }
        }
    }
    @Override
    public void writeCookies(ClientRequestContext req, ClientResponseContext resp) throws IOException {
        Map cookies = resp.getCookies();

        if (BooleanUtils.isFalse(cookies.isEmpty())) {
            for (Entry next : cookies.entrySet()) {
                NewCookie cookie = next.getValue();
                if (cookie.isHttpOnly()) {
                    String cookieValue = StringUtils.isNotEmpty(cookie.getValue()) ? cookie.getValue() : StringUtils.EMPTY;
                    buffer.write(
                            String.format("Cookie: %s=%s Domain: %s, Path: %s, MaxAge: %s, Expire: %s, HttpOnly: %s, Secure: %s",
                                    cookie.getName(),
                                    cookie.isHttpOnly() ? Obfuscator.all().obfuscateText(cookieValue) : cookieValue,
                                    cookie.getDomain(),
                                    cookie.getPath(),
                                    cookie.getMaxAge(),
                                    cookie.getExpiry(),
                                    cookie.isHttpOnly(), cookie.isSecure()));
                } else {
                    buffer.write(String.format("Cookie: %s", COOKIE_PRINTER.toString(cookie)));
                }
                buffer.newLine();
            }
        }
    }
    @Override
    public void writeBody(ClientRequestContext req, ClientResponseContext resp) throws IOException {
        if (resp.hasEntity()) {
            ClientInvoker invoker = clientInvoker(req);
            Class resource = invoker.getDeclaring();
            Method method = invoker.getMethod();
            boolean doNotPrintBody = false;

            if (Objects.nonNull(resource.getAnnotation(ApiEndpoint.class))) {
                ApiEndpoint api = resource.getAnnotation(ApiEndpoint.class);
                doNotPrintBody = api.doNotPrintResponseBody();
            }
            if (Objects.nonNull(method.getAnnotation(ApiEndpoint.class))) {
                ApiEndpoint api = method.getAnnotation(ApiEndpoint.class);
                doNotPrintBody = api.doNotPrintResponseBody();
            }

            if (doNotPrintBody) {
                buffer.write("Body: Hidden{*}");
            } else {
                InputStream io = resp.getEntityStream();

                if (Objects.nonNull(io)) {
                    byte[] bytes = IOUtils.toByteArray(io);
                    resp.setEntityStream(new ByteArrayInputStream(bytes));

                    Charset charset = StandardCharsets.UTF_8;
                    MediaType mediaType = resp.getMediaType();
                    if (Objects.nonNull(mediaType)) {
                        String charsetName = mediaType.getParameters().get("charset");
                        if (Objects.nonNull(charsetName)) {
                            try {
                                charset = Charset.forName(charsetName);
                            } catch (Exception err) {
                                log.trace(err.getMessage(), err);
                            }
                        }
                    }

                    buffer.write("Body: " + new String(bytes, charset));
                }
            }
        }
    }
    @Override
    public void doOutPut(ClientRequestContext req, ClientResponseContext resp) {
        try {
            writeStart(req, resp);
            writeUri(req, resp);
            writeStatus(req, resp);
            writeHeaders(req, resp);
            writeCookies(req, resp);
            writeBody(req, resp);
            buffer.flush();

            LOGGING_FILTER_LOGGER.debug(writer.toString());

            buffer.close();
            writer.close();
        } catch (IOException err) {
            log.error(err.getMessage(), err);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy