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