/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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.queplix.core.modules.web.www;

import com.queplix.core.utils.www.AbstractFilter;
import com.queplix.core.utils.www.HSRWImpl;
import com.queplix.core.utils.www.ServletHelper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.GZIPOutputStream;

/**
 * <p>Gzip filter</p>
 *
 * @author [ALB] Baranov Andrey
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:31:04 $
 */

public class ZipFilter
        extends AbstractFilter {

    /**
     * Make filter process
     *
     * @param request  Servlet request
     * @param response Servlet response
     * @param chain    filter chain object
     * @throws IOException      General input/output exception
     * @throws ServletException General servlet exception
     */
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        boolean isGzip = isGZipSupported(req);
        boolean isDebugEnabled = logger.getLogger().isDebugEnabled();

        if(isDebugEnabled) {
            logger.DEBUG("ZipFilter");
            logger.DEBUG("  request from: " + req.getRequestURI());
            logger.DEBUG("  is gzip supported: " + isGzip);
        }

        if(isGzip) {
            res.setHeader("Content-Encoding", ServletHelper.CONTENT_TYPE_GZIP);
            GZIPOutputStream gzos = new GZIPOutputStream(res.getOutputStream(),
                    HSRWImpl.BUFFER_SIZE);

            HSRWImpl hsrw = new HSRWImpl(res, gzos);
            chain.doFilter(req, hsrw);

            hsrw.flush();
            gzos.close();

        } else {
            chain.doFilter(req, res);
        }
    }

    /**
     * Detect if request supports GZipping.
     *
     * @param req HttpServletRequest object
     * @return true of false
     */
    public static boolean isGZipSupported(HttpServletRequest req) {
        boolean isGzip = false;

        if(req.getProtocol().equalsIgnoreCase("HTTP/1.1") &&
                !req.getRemoteAddr().equals("127.0.0.1")) {
            Enumeration e = req.getHeaders("Accept-Encoding");
            if(e != null) {
                while(e.hasMoreElements()) {
                    String name = (String) e.nextElement();
                    if(name.indexOf("gzip") >= 0) {
                        isGzip = true;
                        break;
                    }
                }
            }
        }

        return isGzip;

    }
}
