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.servlet;
015
016import java.io.IOException;
017import java.net.InetAddress;
018import java.net.UnknownHostException;
019import java.util.ArrayList;
020import java.util.List;
021
022import javax.servlet.Filter;
023import javax.servlet.FilterChain;
024import javax.servlet.FilterConfig;
025import javax.servlet.ServletException;
026import javax.servlet.ServletRequest;
027import javax.servlet.ServletResponse;
028import javax.servlet.http.HttpServletRequest;
029import javax.servlet.http.HttpServletResponse;
030
031import static ch.qos.logback.access.AccessConstants.LB_OUTPUT_BUFFER;
032import static ch.qos.logback.access.AccessConstants.TEE_FILTER_INCLUDES_PARAM;
033import static ch.qos.logback.access.AccessConstants.TEE_FILTER_EXCLUDES_PARAM;
034
035public class TeeFilter implements Filter {
036
037    boolean active;
038
039    @Override
040    public void destroy() {
041        // NOP
042    }
043
044    @Override
045    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
046            throws IOException, ServletException {
047
048        if (active && request instanceof HttpServletRequest) {
049            try {
050                TeeHttpServletRequest teeRequest = new TeeHttpServletRequest((HttpServletRequest) request);
051                TeeHttpServletResponse teeResponse = new TeeHttpServletResponse((HttpServletResponse) response);
052
053                // System.out.println("BEFORE TeeFilter. filterChain.doFilter()");
054                filterChain.doFilter(teeRequest, teeResponse);
055                // System.out.println("AFTER TeeFilter. filterChain.doFilter()");
056
057                teeResponse.finish();
058                // let the output contents be available for later use by
059                // logback-access-logging
060                teeRequest.setAttribute(LB_OUTPUT_BUFFER, teeResponse.getOutputBuffer());
061            } catch (IOException e) {
062                e.printStackTrace();
063                throw e;
064            } catch (ServletException e) {
065                e.printStackTrace();
066                throw e;
067            }
068        } else {
069            filterChain.doFilter(request, response);
070        }
071
072    }
073
074    @Override
075    public void init(FilterConfig filterConfig) throws ServletException {
076        String includeListAsStr = filterConfig.getInitParameter(TEE_FILTER_INCLUDES_PARAM);
077        String excludeListAsStr = filterConfig.getInitParameter(TEE_FILTER_EXCLUDES_PARAM);
078        String localhostName = getLocalhostName();
079
080        active = computeActivation(localhostName, includeListAsStr, excludeListAsStr);
081        if (active)
082            System.out.println("TeeFilter will be ACTIVE on this host [" + localhostName + "]");
083        else
084            System.out.println("TeeFilter will be DISABLED on this host [" + localhostName + "]");
085
086    }
087
088    static List<String> extractNameList(String nameListAsStr) {
089        List<String> nameList = new ArrayList<String>();
090        if (nameListAsStr == null) {
091            return nameList;
092        }
093
094        nameListAsStr = nameListAsStr.trim();
095        if (nameListAsStr.length() == 0) {
096            return nameList;
097        }
098
099        String[] nameArray = nameListAsStr.split("[,;]");
100        for (String n : nameArray) {
101            n = n.trim();
102            nameList.add(n);
103        }
104        return nameList;
105    }
106
107    static String getLocalhostName() {
108        String hostname = "127.0.0.1";
109
110        try {
111            hostname = InetAddress.getLocalHost().getHostName();
112        } catch (UnknownHostException uhe) {
113            uhe.printStackTrace();
114        }
115        return hostname;
116    }
117
118    static boolean computeActivation(String hostname, String includeListAsStr, String excludeListAsStr) {
119        List<String> includeList = extractNameList(includeListAsStr);
120        List<String> excludeList = extractNameList(excludeListAsStr);
121        boolean inIncludesList = mathesIncludesList(hostname, includeList);
122        boolean inExcludesList = mathesExcludesList(hostname, excludeList);
123        return inIncludesList && (!inExcludesList);
124    }
125
126    static boolean mathesIncludesList(String hostname, List<String> includeList) {
127        if (includeList.isEmpty())
128            return true;
129        return includeList.contains(hostname);
130    }
131
132    static boolean mathesExcludesList(String hostname, List<String> excludesList) {
133        if (excludesList.isEmpty())
134            return false;
135        return excludesList.contains(hostname);
136    }
137
138}