tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@locus.apache.org
Subject cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/servlets InvokerServlet.java
Date Wed, 19 Apr 2000 17:40:27 GMT
costin      00/04/19 10:40:27

  Modified:    src/share/org/apache/tomcat/core ServletWrapper.java
               src/share/org/apache/tomcat/request SimpleMapper.java
               src/share/org/apache/tomcat/servlets InvokerServlet.java
  Log:
  - Cleaned-up ( a bit) the InvokerServlet. Removed some duplicated code
  ( string.length(), lookups for the same element, etc).
  Most important difference - invoker will notify the context of a new
  map, so next time the servlet will be called we'll no longer call 2
  servlets instead of one.
  This alters the old logic a bit - you can no longer test if a request
  is "Invoker-based" by comparing the servlet with invoker servlet. That
  test was bad anyway - there is no guarantee that a particular invoker
  will be used.
  
  - Added logic to get the source of a servlet definition - it can be web.xml,
  the admin interface, a dynamic mapping like invoker - and hopefully soon
  jsp can take advantage of this.
  
  - Added counters to ServletWrapper - to be used in tomcat performance tuning
  ( the overhead is very small, and the information may be very usefull even
  at run-time. The web interface later )
  
  Please test and review the new Invoker.
  
  ( during this review it showed up that exact matching is broken, and it also
  look like suffix mapping with PathInfo will not work even if you declare the
  JSP page.  )
  
  Revision  Changes    Path
  1.42      +61 -3     jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java
  
  Index: ServletWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- ServletWrapper.java	2000/04/18 23:16:13	1.41
  +++ ServletWrapper.java	2000/04/19 17:40:24	1.42
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v
1.41 2000/04/18 23:16:13 costin Exp $
  - * $Revision: 1.41 $
  - * $Date: 2000/04/18 23:16:13 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v
1.42 2000/04/19 17:40:24 costin Exp $
  + * $Revision: 1.42 $
  + * $Date: 2000/04/19 17:40:24 $
    *
    * ====================================================================
    *
  @@ -114,7 +114,27 @@
   
       Hashtable initArgs=null;
       Hashtable securityRoleRefs=new Hashtable();
  +
  +    /** The servlet was declared in web.xml
  +     */
  +    public static final int ORIGIN_WEB_XML=0;
  +    public static final int ORIGIN_INVOKER=1;
  +    public static final int ORIGIN_JSP=2;
  +    /** any tomcat-specific component that can
  +	register mappings that are "re-generable",
  +	i.e. can be recreated - the mapping can
  +	safely be removed. Jsp and invoker are particular
  +	cases
  +    */
  +    public static final int ORIGIN_DYNAMIC=3;
  +    /** The servlet was added by the admin, it should be safed
  +	preferably in web.xml
  +    */
  +    public static final int ORIGIN_ADMIN=4;
       
  +    // who creates the servlet definition
  +    int origin;
  +
       public ServletWrapper() {
           config = new ServletConfigImpl();
       }
  @@ -522,6 +542,44 @@
   	if( servlet!=null ) toS=toS+ "S:" + servlet.getClass().getName();
   	else  toS= toS + servletClassName;
   	return toS + ")";
  +    }
  +
  +    /** Who created this servlet definition - default is 0, i.e. the
  +	web.xml mapping. It can also be the Invoker, the admin ( by using a
  +	web interface), JSP engine or something else.
  +
  +	Tomcat can do special actions - for example remove non-used
  +	mappings if the source is the invoker or a similar component
  +    */
  +    public void setOrigin( int origin ) {
  +	this.origin=origin;
  +    }
  +
  +    public int getOrigin() {
  +	return origin;
  +    }
  +
  +    /** ServletWrapper counts. The accounting desing is not
  +	final, but all this is needed to tune up tomcat
  +	( and to understand and be able to implement a good
  +	solution )
  +    */
  +    public static final int ACC_LAST_ACCESSED=0;
  +    public static final int ACC_INVOCATION_COUNT=1;
  +    public static final int ACC_SERVICE_TIME=2;
  +    public static final int ACC_ERRORS=3;
  +    public static final int ACC_OVERHEAD=4;
  +    public static final int ACC_IN_INCLUDE=5;
  +    
  +    public static final int ACCOUNTS=6;
  +    long accTable[]=new long[ACCOUNTS];
  +
  +    public void setAccount( int pos, long value ) {
  +	accTable[pos]=value;
  +    }
  +
  +    public long getAccount( int pos ) {
  +	return accTable[pos];
       }
   
   }
  
  
  
  1.19      +3 -1      jakarta-tomcat/src/share/org/apache/tomcat/request/SimpleMapper.java
  
  Index: SimpleMapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/SimpleMapper.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- SimpleMapper.java	2000/04/14 06:53:51	1.18
  +++ SimpleMapper.java	2000/04/19 17:40:26	1.19
  @@ -293,7 +293,9 @@
   	Hashtable mtable=securityConstraints;
   	if( ct.getHandler() != null )
   	    mtable=contextPaths;
  -	//	System.out.println("XXX " + path + " " + ctx.getDebug() + " " + ctxP + " " + ct.getHandler()
+ " " + ct.getRoles());
  +
  +	if(debug>0) ctx.log("Add mapping/container " + path + " " + ctx.getDebug() + " " +
ctxP + " " +
  +			    ct.getHandler() + " " + ct.getRoles());
   	
   	Mappings m=(Mappings)mtable.get(ctxP);
   	if( m==null ) {
  
  
  
  1.9       +104 -155  jakarta-tomcat/src/share/org/apache/tomcat/servlets/InvokerServlet.java
  
  Index: InvokerServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/servlets/InvokerServlet.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- InvokerServlet.java	2000/04/18 23:16:14	1.8
  +++ InvokerServlet.java	2000/04/19 17:40:27	1.9
  @@ -90,197 +90,146 @@
       public void service(HttpServletRequest request,HttpServletResponse response)
   	throws ServletException, IOException
       {
  -        String requestPath = request.getRequestURI();
  -	String pathInfo = (String)request.getAttribute(
  -            Constants.ATTRIBUTE_PathInfo);
  -
  -	if (pathInfo == null) {
  +        String requestURI = request.getRequestURI();
  +	String includedRequestURI = (String)request.getAttribute("javax.servlet.include.request_uri");
  +	boolean inInclude = (includedRequestURI != null);
  +
  +	// it's possible to have include.pathInfo==null and getPathInfo()!= null
  +	String pathInfo;
  +	if( inInclude)
  +	    pathInfo = (String)request.getAttribute("javax.servlet.include.path_info");
  +	else
   	    pathInfo = request.getPathInfo();
  -	}
   
  -	String includedRequestURI = (String)request.getAttribute(
  -	    Constants.ATTRIBUTE_RequestURI);
  -	boolean inInclude = false;
  -
  -	// XXX XXX XXX in the new model we are _never_ inInclude
  -	if (includedRequestURI != null) {
  -	    inInclude = true;
  -	} else {
  -	    inInclude = false;
  +	String servletPath;
  +	if( inInclude )
  +	    servletPath=(String)request.getAttribute("javax.servlet.include.servlet_path");
  +	else
  +	    servletPath=request.getServletPath();
  +	
  +        if (pathInfo == null || !pathInfo.startsWith("/") ||  pathInfo.length() < 3)
{
  +	    // theres not enough information here to invoke a servlet
  +	    response.sendError(404, "Not enough information " + request.getRequestURI() + " "
+ pathInfo);
  +            return;
   	}
  -
  -        String servletName = "";
  -        String newServletPath = "";
  -        String newPathInfo = "";
  -
  +	
           // XXX
           // yet another example of substring overkill -- we can do
           // this better....
  +	int piLen=pathInfo.length();
  +	String servletName = pathInfo.substring(1, piLen );
   
  -        if (pathInfo != null &&
  -            pathInfo.startsWith("/") &&
  -	    pathInfo.length() > 2) {
  -            servletName = pathInfo.substring(1, pathInfo.length());
  -
  -            if (servletName.indexOf("/") > -1) {
  -                servletName =
  -		    servletName.substring(0, servletName.indexOf("/"));
  -            }
  -
  -	    if (! inInclude) {
  -		newServletPath = request.getServletPath() +
  -		    "/" + servletName;
  -	    } else {
  -		newServletPath = (String)request.getAttribute
  -		    (Constants.ATTRIBUTE_ServletPath)  + "/" +
  -                    servletName;
  -	    }
  +	if (servletName.indexOf("/") > -1) {
  +	    servletName = servletName.substring(0, servletName.indexOf("/"));
  +	}
  +	
  +	String newServletPath = servletPath + "/" + servletName;
  +	
  +	String newPathInfo;
  +	int sNLen=servletName.length();
  +	if( piLen > sNLen +1 )
  +	    newPathInfo= pathInfo.substring(sNLen + 1 );
  +	else
  +	    newPathInfo=null;
  +
  +	/*
  +	  String newPathInfo = "";
  +	  // XXX XXX I think it's wrong inInclude..
  +	  if (inInclude) {
  +	  newPathInfo = includedRequestURI.substring(
  +	  newServletPath.length(),
  +	  includedRequestURI.length());
  +	  } else {
  +	  newPathInfo = requestURI.substring(
  +	  context.getPath().length() +
  +	  newServletPath.length(),
  +	  requestURI.length());
  +	  }
  +	*/
   	    
  -            // XXX
  -            // oh, very sloppy here just catching the exception... Do
  -            // this for real...
  -
  -            try {
  -		if (inInclude) {
  -		    newPathInfo = includedRequestURI.substring(
  -			newServletPath.length(),
  -			includedRequestURI.length());
  -		} else {
  -		    newPathInfo = requestPath.substring(
  -			context.getPath().length() +
  -			    newServletPath.length(),
  -			requestPath.length());
  -		}
  -		
  -		int i = newPathInfo.indexOf("?");
  -
  -		if (i > -1) {
  -		    newPathInfo = newPathInfo.substring(0, i);
  -		}
  -
  -		if (newPathInfo.length() < 1) {
  -		    newPathInfo = null;
  -		}
  -            } catch (Exception e) {
  -                newPathInfo = null;
  -            }
  -	} else {
  -            // theres not enough information here to invoke a servlet
  -            doError(response,"Not enough information " + request.getRequestURI() + " "
+ pathInfo);
  -
  -            return;
  -        }
  +	// RequestURI doesn't include QUERY - no need for that
  +	/* int i = newPathInfo.indexOf("?");
  +	   if (i > -1) {
  +	   newPathInfo = newPathInfo.substring(0, i);
  +	   }
  +	*/
   
           // try the easy one -- lookup by name
           ServletWrapper wrapper = context.getServletByName(servletName);
  -	//	System.out.println("Invoker: getServletByName " + servletName + "=" + wrapper);
   
           if (wrapper == null) {
  -	    // Moved loadServlet here //loadServlet(servletName);
  -	    wrapper = new ServletWrapper();
  -	    wrapper.setContext(context);
  -	    wrapper.setServletClass(servletName);
  -	    wrapper.setServletName(servletName); // XXX it can create a conflict !
  -
  +	    // XXX Check if the wrapper is valid -
  +	    
  +	    
  +	    // even if the server doesn't supports dynamic mappings,
  +	    // we'll avoid the interceptor for include() and
  +	    // it's a much cleaner way to construct the servlet and
  +	    // make sure all interceptors are up to date.
   	    try {
  -		context.addServlet( wrapper );
  -	    } catch(TomcatException ex ) {
  +		context.addServletMapping( newServletPath , servletName );
  +		wrapper = context.getServletByName( servletName);
  +		wrapper.setOrigin( ServletWrapper.ORIGIN_INVOKER );
  +	    } catch( TomcatException ex ) {
   		ex.printStackTrace();
  +		response.sendError(505, "Error getting the servlet " + ex);
  +		return;
   	    }
   
  -	    // XXX add mapping - if the engine supports dynamic changes in mappings,
  -	    // we'll avoid the extra parsing in Invoker !!!
  -
  -	    // XXX Invoker can be avoided easily - it's a special mapping, easy to
  -	    // support
  +	    /* Original code - rollback if anything is broken ( it shouldn't )
  +	       // Moved loadServlet here //loadServlet(servletName);
  +	       wrapper = new ServletWrapper();
  +	       wrapper.setContext(context);
  +	       wrapper.setServletClass(servletName);
  +	       wrapper.setServletName(servletName); // XXX it can create a conflict !
  +	       
  +	       try {
  +	       context.addServlet( wrapper );
  +	       } catch(TomcatException ex ) {
  +	       ex.printStackTrace();
  +	       }
  +	    */
           }
  -
  -	// System.out.println("CL: " + context.getServletLoader().getClassLoader() +
  -	//	   " wrapper: " + wrapper);
  -	
   
  -	// Can't be null - loadServlet creates a new wrapper .
  -	//         if (wrapper == null) {
  -	//             // we are out of luck
  -	//             doError(response, "Wrapper is null - " + servletName);
  -	//             return;
  -	//         }
  -
  -        HttpServletRequestFacade requestfacade =
  -	    (HttpServletRequestFacade)request;
  -        HttpServletResponseFacade responsefacade =
  -	    (HttpServletResponseFacade)response;
  +	if( context.getDebug() > 3 ) context.log( "Invoker-based execution " + newServletPath
+ " " + newPathInfo );
  +        HttpServletRequestFacade requestfacade = (HttpServletRequestFacade)request;
  +        HttpServletResponseFacade responsefacade = (HttpServletResponseFacade)response;
   	Request realRequest = requestfacade.getRealRequest();
   	Response realResponse = realRequest.getResponse();
   
  -	// The saved servlet path, path info are for cases in which a
  -	// request dispatcher forwards through the invoker. This is
  -	// some seriously sick code here that needs to be done
  -	// better, but this will do the trick for now.
  -	String savedServletPath=null;
  -	String savedPathInfo =null;
  -
  -
  -	// XXX XXX XXX need to be removed after the include hacks are out
  -	if( ! inInclude )  {
  -	    savedPathInfo=realRequest.getPathInfo();
  -	    savedServletPath=realRequest.getServletPath();
  -	} else {
  -	    savedServletPath = (String)realRequest.getAttribute(
  -			       Constants.ATTRIBUTE_ServletPath);
  -	    savedPathInfo = (String)realRequest.getAttribute(
  -			       Constants.ATTRIBUTE_PathInfo);
  -	}
  -	
   	if (! inInclude) {
   	    realRequest.setServletPath(newServletPath);
   	    realRequest.setPathInfo(newPathInfo);
   	} else {
  -	    if (newServletPath != null) {
  -		realRequest.setAttribute(
  -                    Constants.ATTRIBUTE_ServletPath, newServletPath);
  -	    }
  -
  +	    realRequest.setAttribute("javax.servlet.include.servlet_path",
  +				     newServletPath);
   	    if (newPathInfo != null) {
  -		realRequest.setAttribute(
  -                    Constants.ATTRIBUTE_PathInfo, newPathInfo);
  -	    }
  -
  -	    if (newPathInfo == null) {
  -		// Can't store a null, so remove for same effect
  -
  -		realRequest.removeAttribute(
  -                    Constants.ATTRIBUTE_PathInfo);
  +		realRequest.setAttribute("javax.servlet.include.path_info",
  +					 newPathInfo);
  +	    } else {
  +		realRequest.removeAttribute("javax.servlet.include.path_info");
   	    }
   	}
   
           wrapper.handleRequest(realRequest, realResponse);
  -	
  +
  +	// restore servletPath and pathInfo.
  +	// Usefull because we may include with the same request multiple times.
  +	// 
   	if (!inInclude) {
  -	    realRequest.setServletPath( savedServletPath);
  -	    realRequest.setPathInfo(savedPathInfo);
  +	    realRequest.setServletPath( servletPath);
  +	    realRequest.setPathInfo( pathInfo);
   	} else {
  -	    if (savedServletPath != null) {
  -		realRequest.setAttribute(
  -                    Constants.ATTRIBUTE_ServletPath, savedServletPath);
  -	    } else {
  -		realRequest.removeAttribute(
  -                    Constants.ATTRIBUTE_ServletPath);
  -	    }
  -
  -	    if (savedPathInfo != null) {
  -		realRequest.setAttribute(
  -                    Constants.ATTRIBUTE_PathInfo, savedPathInfo);
  +	    realRequest.setAttribute("javax.servlet.include.servlet_path",
  +				     servletPath);
  +	    
  +	    if (pathInfo != null) {
  +		realRequest.setAttribute("javax.servlet.include.path_info",
  +					 pathInfo);
   	    } else {
  -		realRequest.removeAttribute(
  -                    Constants.ATTRIBUTE_PathInfo);
  +		realRequest.removeAttribute("javax.servlet.include.path_info");
   	    }
   	}
       }
   
  -    public void doError(HttpServletResponse response, String msg)
  -	throws ServletException, IOException
  -    {
  -	response.sendError(404, msg);
  -    }    
  +    
   }
  
  
  

Mime
View raw message