001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.access.common.servlet;
015
016import java.io.IOException;
017import java.net.InetAddress;
018import java.net.UnknownHostException;
019import java.util.ArrayList;
020import java.util.List;
021
022import ch.qos.logback.access.common.AccessConstants;
023import jakarta.servlet.Filter;
024import jakarta.servlet.FilterChain;
025import jakarta.servlet.FilterConfig;
026import jakarta.servlet.ServletException;
027import jakarta.servlet.ServletRequest;
028import jakarta.servlet.ServletResponse;
029import jakarta.servlet.http.HttpServletRequest;
030import jakarta.servlet.http.HttpServletResponse;
031
032public class TeeFilter implements Filter {
033
034    boolean active;
035
036    @Override
037    public void destroy() {
038        // NOP
039    }
040
041    @Override
042    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
043            throws IOException, ServletException {
044
045        if (active && request instanceof HttpServletRequest) {
046            try {
047                TeeHttpServletRequest teeRequest = new TeeHttpServletRequest((HttpServletRequest) request);
048                TeeHttpServletResponse teeResponse = new TeeHttpServletResponse((HttpServletResponse) response);
049
050                // System.out.println("BEFORE TeeFilter. filterChain.doFilter()");
051                filterChain.doFilter(teeRequest, teeResponse);
052                // System.out.println("AFTER TeeFilter. filterChain.doFilter()");
053
054                teeResponse.finish();
055                // let the output contents be available for later use by
056                // logback-access-logging
057                teeRequest.setAttribute(AccessConstants.LB_OUTPUT_BUFFER, teeResponse.getOutputBuffer());
058            } catch (IOException e) {
059                e.printStackTrace();
060                throw e;
061            } catch (ServletException e) {
062                e.printStackTrace();
063                throw e;
064            }
065        } else {
066            filterChain.doFilter(request, response);
067        }
068
069    }
070
071    @Override
072    public void init(FilterConfig filterConfig) throws ServletException {
073        String includeListAsStr = filterConfig.getInitParameter(AccessConstants.TEE_FILTER_INCLUDES_PARAM);
074        String excludeListAsStr = filterConfig.getInitParameter(AccessConstants.TEE_FILTER_EXCLUDES_PARAM);
075        String localhostName = getLocalhostName();
076
077        active = computeActivation(localhostName, includeListAsStr, excludeListAsStr);
078        if (active)
079            System.out.println("TeeFilter will be ACTIVE on this host [" + localhostName + "]");
080        else
081            System.out.println("TeeFilter will be DISABLED on this host [" + localhostName + "]");
082
083    }
084
085    public static List<String> extractNameList(String nameListAsStr) {
086        List<String> nameList = new ArrayList<String>();
087        if (nameListAsStr == null) {
088            return nameList;
089        }
090
091        nameListAsStr = nameListAsStr.trim();
092        if (nameListAsStr.length() == 0) {
093            return nameList;
094        }
095
096        String[] nameArray = nameListAsStr.split("[,;]");
097        for (String n : nameArray) {
098            n = n.trim();
099            nameList.add(n);
100        }
101        return nameList;
102    }
103
104    static String getLocalhostName() {
105        String hostname = "127.0.0.1";
106
107        try {
108            hostname = InetAddress.getLocalHost().getHostName();
109        } catch (UnknownHostException uhe) {
110            uhe.printStackTrace();
111        }
112        return hostname;
113    }
114
115    public static boolean computeActivation(String hostname, String includeListAsStr, String excludeListAsStr) {
116        List<String> includeList = extractNameList(includeListAsStr);
117        List<String> excludeList = extractNameList(excludeListAsStr);
118        boolean inIncludesList = mathesIncludesList(hostname, includeList);
119        boolean inExcludesList = mathesExcludesList(hostname, excludeList);
120        return inIncludesList && (!inExcludesList);
121    }
122
123    static boolean mathesIncludesList(String hostname, List<String> includeList) {
124        if (includeList.isEmpty())
125            return true;
126        return includeList.contains(hostname);
127    }
128
129    static boolean mathesExcludesList(String hostname, List<String> excludesList) {
130        if (excludesList.isEmpty())
131            return false;
132        return excludesList.contains(hostname);
133    }
134
135}