Hello everybody,

If you read all the mails, you must know all the problems
I've encouter with the mod_rewrite module.

Remember... the following rules didn't work:

------

#Don't know if it is useful ?!?
#RewriteRule  ^(/.*;jsessionid=.*)$  $1 [T=jserv-servlet]

RewriteCond %{REQUEST_URI} ^/servlet* [NC]
RewriteRule ^/servlet/(.*) /lol/$1 [PT]

RewriteCond %{REQUEST_URI} !^/lol* [NC]
RewriteCond %{REQUEST_URI} !^/Image* [NC]
RewriteCond %{REQUEST_URI} !^/Elemtech* [NC]
RewriteCond %{REQUEST_URI} !^/Erreur* [NC]
RewriteCond %{REQUEST_URI} ^/.*/.*
RewriteRule ^/(.*) /lol/AdFront?access=/$1 [PT,QSA]

------

After many investigations, I decided to make my own Mapper
starting with SimpleMapper1 (look in server.xml).

So here is the code I added (line starting with a '#' are original!):

--------------------------
START --------------------------------------------------
package com.fivia.adfront;
#
#import org.apache.tomcat.core.*;
#import org.apache.tomcat.core.Constants;
#import org.apache.tomcat.util.*;
#import java.util.*;
import java.io.*;
import org.apache.oro.text.GlobCompiler;
import org.apache.oro.text.awk.AwkCompiler;
import org.apache.oro.text.awk.AwkMatcher;
import org.apache.oro.text.regex.*;
import javax.servlet.http.*;
#
#/**
# *  This class will set up the data structures used by a simple patern
matching
# *  alghoritm and use it to extract the path components from the request
URI.
# *
# *  The interceptor will be called in standalone case, for "integrated"
mode
# *  we should have all the data from the web server - that means the
# * performance of this code is not relevant for production mode if a web
# * server is used.
# *
# *  This particular implementation does the following:
# *  - extract the information that is relevant to matching from the Request
# *   object. The current implementation deals with the Host header and the
# *   request URI.
# *  - Use an external mapper to find the best match.
# *  - Adjust the request paths
# *
# *  The execution time is proportional with the number of hosts, number of
# *  context, number of mappings and with the length of the request.
# *
# *  Security mappings are more complex ( method, transport are also part of
the
# *  matching ). We can share the same mapping alghoritm or even the
mapper -
# *  but until security code will be stable it's better to keep it
separated.
# *
# */
public class AdFrontMapper extends  BaseInterceptor
#{

...

#               if(debug>0)
#                       log( "Remove mapping " + mapping );
#    }
#
#
#    /* -------------------- Request mapping -------------------- */

        private boolean checkConditions(String path, String[] sa, boolean
caseSensitiv )
        {
                org.apache.oro.text.regex.Pattern pattern;
        PatternCompiler compiler = new Perl5Compiler();
            PatternMatcher matcher = new Perl5Matcher();
            boolean notPresent, result;
                int i;
                for(i=0;i<sa.length;i++)
                {
                        log("Condition "+(i+1)+": "+sa[i]);

                        notPresent = (sa[i].charAt(0)=='!');

                        if( notPresent )
                                sa[i] = sa[i].substring(1);

                        try
            {
                    pattern =
compiler.compile(sa[i],(caseSensitiv?Perl5Compiler.DEFAULT_MASK:Perl5Compile
r.CASE_INSENSITIVE_MASK)); // Condition
                }
                catch(MalformedPatternException malformedpatternexception)
                {
                log("\nMalformed Regular Expression:\n" +
malformedpatternexception.getMessage());
                return false;
                }

                        result = matcher.contains(new PatternMatcherInput(path), 
pattern);

                        if( notPresent )
                                result = !result;

                        if( !result )
                        {
                                log("Condition: "+(notPresent?"!":"")+sa[i]+" => 
not-matched");
                                return false;
                        }
                        else
                                log("Condition: "+(notPresent?"!":"")+sa[i]+" => 
matched");
                }

                return true;
        }

        private String applyRule(Request req, String path, String rule, String
substitution, String[] conditions, boolean conditionsCaseSensitivity )
        {
                String orgPath = path;
                boolean matched = true;

                org.apache.oro.text.regex.Pattern pattern;
                PatternCompiler compiler = new Perl5Compiler();
                PatternMatcher matcher = new Perl5Matcher();

                log("Applying rule: "+rule+" on "+path);

                try
        {
            pattern = compiler.compile(rule); // Rule
        }
        catch(MalformedPatternException malformedpatternexception)
        {
            log("\nMalformed Regular Expression:\n" +
malformedpatternexception.getMessage());
            return null;
        }

        MatchResult matchresult;
        int i=0, j, j1;
                PatternMatcherInput patternmatcherinput;

        for(patternmatcherinput = new PatternMatcherInput(path);
matcher.contains(patternmatcherinput, pattern);)
        {
            matchresult = matcher.getMatch();
            i++;
            log("Match " + i + ": " + matchresult.group(0) );
            j1 = matchresult.groups();
            if(j1 > 1)
            {
                if( checkConditions(path,conditions,
conditionsCaseSensitivity) )
                {
                        log("    Subgroups:");
                        for(j = j1-1; j > 0; j--)
                    {
                        if( substitution.indexOf("$"+j) != -1 )
                                                        substitution =
replaceString(substitution,"$"+j,matchresult.group(j));
                    }

                        path = substitution;
                }
                else
                {
                                        matched = false;
                        break;
                }
            }
            else
            {
                matched = false;
                break;
            }
        }

                if( i==0 )
                        matched = false;

                if( matched )
                {
                        int pos;
                        String queryParameters = null;
                        if( (pos = path.indexOf("?")) != -1 )
                        {
                                queryParameters = path.substring(pos+1);
                                path = path.substring(0,pos);
                                req.setQueryString(queryParameters);
                        }

                        req.setRequestURI(path);

                log("rewrite "+orgPath+" -> "+(queryParameters==null?path:"split
uri="+substitution+" -> uri="+path+",
                      args="+queryParameters+"\nlocal path result: "+path));
                }
                else
                        log("pass through "+orgPath);

        return path;
        }

        private String replaceString(String string, String oldString, String
newString)
        {
                if((string==null)    || (string.length()==0)    ||
                   (oldString==null) || (oldString.length()==0) ||
                   (newString==null))
                        return string;

                StringBuffer sb = new StringBuffer(string);
                int count=0;
                int index=-1;
                int nlen = newString.length();
                int olen = oldString.length();

                while(true)
                {
                        index = string.indexOf(oldString,count);
                        if(index<0)
                                break;

                        sb.replace(index,index+olen,newString);
                        string = sb.toString();
                        count  = index + nlen;
                }

                return sb.toString();
        }

private void info(Request request)
{

        log("##################################################################");
        log("Server Name: " + request.getServerName());
        log("Server Port: " + request.getServerPort());
        log("Remote Addr: " + request.getRemoteAddr());
        log("Remote Host: " + request.getRemoteHost());
        log("Character Encoding: " + request.getCharacterEncoding());
        log("Content Type: "+ request.getContentType());
        log("");
        log("Request Is Secure: " + request.isSecure());
        log("Auth Type: " + request.getAuthType());
        log("HTTP Method: " + request.getMethod());
        log("Request URI: " + request.getRequestURI());
        log("Servlet Path: " + request.getServletPath());
        log("Path Info: " + request.getPathInfo());
                log("Path Trans: " + request.getPathTranslated());
        log("Query String: " + request.getQueryString());
        log("");
        log("Headers in this request:");
        Enumeration e = request.getHeaderNames();
        while (e.hasMoreElements()) {
            String key = (String)e.nextElement();
            String value = request.getHeader(key);
            log("   " + key + ": " + value);
        }
        log("");
        log("Parameter names in this request:");
        e = request.getParameterNames();
        while (e.hasMoreElements()) {
            String key = (String)e.nextElement();
            String[] values = request.getParameterValues(key);
            String s = "   " + key + " = ";
            for(int i = 0; i < values.length; i++) {
                s += values[i] + " ";
            }
            log(s+"\n");
        }
}

#    /** First step of request porcessing is finding the Context.
#     */
#    public int contextMap( Request req )
#    {
                //info(req);

                log("contextMap( "+req.toString()+" )");

#               String path = req.getRequestURI();
#
#               if( path==null)
#               throw new RuntimeException("ASSERT: null path in request URI");

                path = applyRule(req, path,"^/servlet/(.*)","/lol/$1",new
tring[]{ "^/servlet*" },false);

                path = applyRule(req, path,"^/(.*)","/lol/AdFront?access=/$1",new
String[]{ "!^/lol*", "!^/Image*", "!^/Elemtech*", "!^/Erreur*",
"^/.*/.*" },false);

                if( path == null )
                        return 404;

#               if( path.indexOf("?") >=0 )
#               throw new RuntimeException("ASSERT: ? in requestURI");
#
#               try
#               {
#               String host=req.getServerName();
#               if(debug>0)
#                       cm.log("Host = " + host);
#
#               Container container =(Container)map.getLongestPrefixMatch( host,
path );
#
#               if( container == null )
#                               return 404;
#
#               if(debug>0)
#                               cm.log("SM: Prefix match " + path + " -> " + 
container.getPath() + " "
+ container.getHandler() + " " + container.getRoles());

...

----------------------------------------------------------------------------
---------------
-----------------------------------
END ---------------------------------------------------
----------------------------------------------------------------------------
---------------

I use the jakarta package ORO 2.0.4:

http://jakarta.apache.org/builds/jakarta-oro/release/v2.0.4/jakarta-oro-2.0.
4.tar.gz

I then compile to create the mapper.jar package, put it in %TOMCAT_HOME%/lib
and replace in server.xml:

        <RequestInterceptor
            className="org.apache.tomcat.request.SimpleMapper1"
            debug="1" />

BY

        <RequestInterceptor
            className="com.fivia.adfront.AdFrontMapper"
            debug="1" />


Please send me any comment.


Lo�c Lef�vre

Reply via email to