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

org.wings.session.SmartURLsFilter Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2000,2005 wingS development team.
 *
 * This file is part of wingS (http://wingsframework.org).
 *
 * wingS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * Please see COPYING for the complete licence.
 */
package org.wings.session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author hengels
 */
public class SmartURLsFilter
        implements Filter {
    private final transient static Logger log = LoggerFactory.getLogger(SmartURLsFilter.class);
    private String parameterSeparator = ";";
    private String nameValueSeparator = ",";
    private Pattern encodePattern;
    private Pattern decodePattern;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        if (filterConfig.getInitParameter("wings.servlet.smarturls.parameterSeparator") != null)
            parameterSeparator = filterConfig.getInitParameter("wings.servlet.smarturls.parameterSeparator");

        if (filterConfig.getInitParameter("wings.servlet.smarturls.nameValueSeparator") != null)
            nameValueSeparator = filterConfig.getInitParameter("wings.servlet.smarturls.nameValueSeparator");

        log.info("wings.servlet.smarturls.parameterSeparator " + parameterSeparator);
        log.info("wings.servlet.smarturls.nameValueSeparator " + nameValueSeparator);

        encodePattern = Pattern.compile('(' + "\\?|&" + ")([a-zA-Z0-9%+.-[*]_]*)" +
                '(' + '=' + ")([a-zA-Z0-9%+.-[*]_=/:]*)");
        decodePattern = Pattern.compile('(' + parameterSeparator + ")([a-zA-Z0-9%+.-[*]_]*)" +
                '(' + nameValueSeparator + ")([a-zA-Z0-9%+.-[*]_=/:]*)");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        ServletRequest request = servletRequest;
        ServletResponse response = servletResponse;

        if (servletRequest instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

            MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(httpServletRequest);
            if (requestWrapper.getPathInfo() == null || requestWrapper.getPathInfo().indexOf('.') == -1) {
                response = new MyHttpServletResponseWrapper(servletResponse);

                if ("get".equalsIgnoreCase(httpServletRequest.getMethod()))
                    request = requestWrapper;

                log.debug("wrap " + requestWrapper.getPathInfo());
            } else
                log.debug("don't wrap " + requestWrapper.getPathInfo());
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

    public static final String replace(String s,
                                       String toFind, String replace) {

        int indexOf = s.indexOf(toFind);
        if (indexOf == -1) return s;
        int lastindex = 0;
        StringBuilder erg = new StringBuilder();
        while (indexOf != -1) {
            erg.append(s.substring(lastindex, indexOf)).append(replace);
            lastindex = indexOf + toFind.length();
            indexOf = s.indexOf(toFind, lastindex);
        }

        erg.append(s.substring(lastindex));

        return erg.toString();
    }

    private class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
        private Map parameterMap;
        private String pathInfo;
        private String queryString;

        public MyHttpServletRequestWrapper(HttpServletRequest httpServletRequest) {
            super(httpServletRequest);

            pathInfo = httpServletRequest.getPathInfo();
            queryString = httpServletRequest.getQueryString();
            parameterMap = httpServletRequest.getParameterMap();
            log.debug("pathInfo = " + pathInfo);
            log.debug("queryString = " + queryString);
            log.debug("parameterMap = " + parameterMap);

            if (pathInfo == null)
                return;

            int pos = pathInfo.indexOf(parameterSeparator);
            if (pos != -1) {
                queryString = pathInfo.substring(pos);
                pathInfo = pathInfo.substring(0, pos);

                parameterMap = new HashMap();
                StringBuffer buffer = new StringBuffer(queryString.length());
                Matcher matcher = decodePattern.matcher(queryString);
                while (matcher.find()) {
                    String param = matcher.group();
                    pos = param.indexOf(nameValueSeparator);
                    parameterMap.put(param.substring(1, pos), param.substring(pos + 1));
                    matcher.appendReplacement(buffer, "&$2=$4");
                }
                queryString = buffer.substring(1);
                log.debug("modified pathInfo = " + pathInfo);
                log.debug("modified queryString = " + queryString);
                log.debug("modified parameterMap = " + parameterMap);
            }
        }

        @Override
        public String getRequestURI() {
            return super.getRequestURI();
        }

        @Override
        public Map getParameterMap() {
            return parameterMap;
        }

        @Override
        public String getPathInfo() {
            return pathInfo;
        }

        @Override
        public String getQueryString() {
            return queryString;
        }

        @Override
        public String getParameter(String string) {
            Object value = parameterMap.get(string);
            if (value instanceof String)
                return (String) value;
            else
                return ((String[]) value)[0];
        }

        @Override
        public Enumeration getParameterNames() {
            return Collections.enumeration(parameterMap.keySet());
        }

        @Override
        public String[] getParameterValues(String string) {
            Object value = parameterMap.get(string);
            if (value instanceof String)
                return new String[]{(String) value};
            else
                return (String[]) value;
        }
    }

    private static class MyHttpServletResponseWrapper extends HttpServletResponseWrapper {
        public MyHttpServletResponseWrapper(ServletResponse servletResponse) {
            super((HttpServletResponse) servletResponse);
        }

        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            final ServletOutputStream superOut = super.getOutputStream();
            return new MyServletOutputStream(superOut);
        }

        private static class MyServletOutputStream extends ServletOutputStream {
            private final ServletOutputStream superOut;
            ByteArrayOutputStream bytes;

            public MyServletOutputStream(ServletOutputStream superOut) {
                this.superOut = superOut;
                bytes = new ByteArrayOutputStream(1000);
            }

            @Override
            public void write(int b) throws IOException {
                bytes.write(b);
            }

            @Override
            public void close() throws IOException {
                encode(bytes, superOut);
                superOut.close();
            }
        }
    }


    private static void encode(ByteArrayOutputStream bytes, ServletOutputStream out) throws IOException {

        SmartURLsFilter smartURLsFilter = new SmartURLsFilter();
        String replacement =
                smartURLsFilter.parameterSeparator + "$2" +
                smartURLsFilter.nameValueSeparator + "$4";

        smartURLsFilter.encodePattern = Pattern.compile('(' + "\\?|&" + ")([a-zA-Z0-9%+.-[*]_]*)" +
                '(' + '=' + ")([a-zA-Z0-9%+.-[*]_=/]*)");

        CharBuffer chars = CharBuffer.wrap(bytes.toString());
        String regex = "(href|src|action) *= *\"([^\"]*)\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(chars);
        int pos = 0;
        while (matcher.find()) {
            out.print(chars.subSequence(pos, matcher.start()).toString());
            pos = matcher.end();
            Matcher matcher2 = smartURLsFilter.encodePattern.matcher(matcher.group(2));
            String group2 = matcher2.replaceAll(replacement);

            out.print(matcher.group(1) + "=\"" + group2 + '"');
        }
        out.print(chars.subSequence(pos, bytes.size()).toString());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy