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/core Context.java
Date Mon, 01 May 2000 23:23:48 GMT
costin      00/05/01 16:23:48

  Modified:    src/share/org/apache/tomcat/core Context.java
  Log:
  - added absPath - that remove multiple redundant ( and expensive ) computations
  of the absolute context path.
  
  - added more docs
  
  - clean up getResources and getRealPath. The old code was based on a wrong
  assumption - the spec doesn't allow getResource or getRealPath to cross
  web app boundaries, so the code is much simpler and faster.
  XXX We still need to abstract that - maybe using a callback - in order to
  support non-file-based contexts.
  
  Revision  Changes    Path
  1.83      +88 -88    jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v
  retrieving revision 1.82
  retrieving revision 1.83
  diff -u -r1.82 -r1.83
  --- Context.java	2000/04/26 22:49:49	1.82
  +++ Context.java	2000/05/01 23:23:47	1.83
  @@ -102,6 +102,9 @@
       private String path = "";
       private String docBase;
   
  +    // Absolute path to docBase if file-system based
  +    private String absPath; 
  +
       // internal state / related objects
       private ContextManager contextM;
       private ServletContextFacade contextFacade;
  @@ -222,6 +225,23 @@
   	return docBase;
       }
   
  +    /** Return the absolute path for the docBase, if we are file-system
  +     *  based, null otherwise.
  +    */
  +    public String getAbsolutePath() {
  +	if( absPath!=null) return absPath;
  +
  +	if (FileUtil.isAbsolute( docBase ) )
  +	    absPath=docBase;
  +	else
  +	    absPath = contextM.getHome() + File.separator + docBase;
  +	try {
  +	    absPath = new File(absPath).getCanonicalPath();
  +	} catch (IOException npe) {
  +	}
  +	return absPath;
  +    }
  +
       // -------------------- Tomcat specific properties
       // workaround for XmlMapper unable to set anything but strings
       public void setReloadable( String s ) {
  @@ -496,6 +516,16 @@
   	containers.put( path, map );
       }
   
  +    /** Will add a new security constraint:
  +	For all paths:
  +	if( match(path) && match(method) && match( transport ) )
  +	then require("roles")
  +
  +	This is equivalent with adding a Container with the path,
  +	method and transport. If the container will be matched,
  +	the request will have to pass the security constraints.
  +	
  +    */
       public void addSecurityConstraint( String path[], String methods[],
   				       String roles[], String transport)
   	throws TomcatException
  @@ -696,68 +726,49 @@
   	return rD;
       }
   
  -    /** Implements getResource() - use a sub-request to let interceptors do the job.
  -     */
  -    public URL getResource(String rpath) throws MalformedURLException {
  -        URL url = null;
   
  -	String absPath=getDocBase();
  +    Context getContext(String path) {
  +	if (! path.startsWith("/")) {
  +	    return null; // according to spec, null is returned
  +	    // if we can't  return a servlet, so it's more probable
  +	    // servlets will check for null than IllegalArgument
  +	}
  +	// absolute path
  +	Request lr=contextM.createRequest( path );
  +	if( vhost != null ) lr.setServerName( vhost );
  +	getContextManager().processRequest(lr);
  +        return lr.getContext();
  +    }
   
  -	if (FileUtil.isAbsolute( docBase ) )
  -	    absPath=docBase;
  -	else
  -	    absPath = contextM.getHome() + File.separator + docBase;
  +    /** Implements getResource()
  +     *  See getRealPath(), it have to be local to the current Context -
  +     *  and can't go to a sub-context. That means we don't need any overhead.
  +     */
  +    public URL getResource(String rpath) throws MalformedURLException {
  +        if (rpath == null) return null;
   
  -	try {
  -	    absPath = new File(absPath).getCanonicalPath();
  -	} catch (IOException npe) {
  -	}
  +        URL url = null;
  +	String absPath=getAbsolutePath();
   
   	if ("".equals(rpath))
   	    return new URL( "file", null, 0, absPath );
   
  -        if (rpath == null)
  -	    return null;
   
   	if ( ! rpath.startsWith("/")) {
   	    rpath="/" + rpath;
   	}
  -
  -	// Create a Sub-Request, do the request processing stage
  -	// that will take care of aliasing and set the paths
  -	Request lr=contextM.createRequest( this, rpath );
  -	getContextManager().processRequest(lr);
  -
  -	String mappedPath = lr.getMappedPath();
  -
  -	// XXX workaround for mapper bugs
  -	if( mappedPath == null ) {
  -	    mappedPath=lr.getPathInfo();
  -	}
  -	if(mappedPath == null ) {
  -	    String pI=lr.getPathInfo();
  -	    if( pI == null ) 
  -		mappedPath=lr.getServletPath();
  -	    else
  -		mappedPath=lr.getServletPath() + pI;
  -	}
  -
   
  +	String realPath=absPath + rpath;
   	try {
  -	    String contextHome=new File( docBase ).getCanonicalPath();
  -	    String realPath=contextHome + mappedPath;
  -
  -	    //   System.out.println("XXX " + realPath + " " + new File(realPath).getCanonicalPath()
+ " "  + contextHome );
  -	    if( ! new File(realPath).getCanonicalPath().startsWith(contextHome) ) {
  +	    if( ! new File(realPath).getCanonicalPath().startsWith(absPath) ) {
   		// no access to files in a different context.
   		// XXX needs a better design - it should be in an interceptor,
   		// in order to support non-file based repositories.
   		return null;
   	    }
  -            url=new URL("file", null,
  -                        0,
  -                        absPath + mappedPath);
  -	    if( debug>9) log( "getResourceURL=" + url + " request=" + lr );
  +	    
  +            url=new URL("file", null, 0,realPath );
  +	    if( debug>9) log( "getResourceURL=" + url + " request=" + rpath );
   	    return url;
   	} catch( IOException ex ) {
   	    ex.printStackTrace();
  @@ -765,59 +776,48 @@
   	}
       }
   
  -
  -    Context getContext(String path) {
  -	if (! path.startsWith("/")) {
  -	    return null; // according to spec, null is returned
  -	    // if we can't  return a servlet, so it's more probable
  -	    // servlets will check for null than IllegalArgument
  -	}
  -	// absolute path
  -	Request lr=contextM.createRequest( path );
  -	if( vhost != null ) lr.setServerName( vhost );
  -	getContextManager().processRequest(lr);
  -        return lr.getContext();
  -    }
   
  -    /**
  -     *
  +    /**   According to Servlet 2.2 the real path is interpreted as
  +     *    relative to the current web app and _cannot_ go outside the 
  +     *    box. If your intention is different or want the "other" behavior 
  +     *    you'll have to first call getContext(path) and call getRealPath()
  +     *    on the result context ( if any - the server may disable that from
  +     *    security reasons !).
  +     *    XXX find out how can we find the context path in order to remove it
  +     *    from the path - that's the only way a user can do that unless he have
  +     *    prior knowledge of the mappings !
        */
       String getRealPath( String path) {
  -	//	Real Path is the same as PathTranslated for a new request
  -	String normP=FileUtil.normPath(path);
  -
  -	Request req=contextM.createRequest( this , normP );
  -	contextM.processRequest(req);
  +	// No need for a sub-request, that's a great simplification
  +	// in servlet space.
   
  -	String mappedPath = req.getMappedPath();
  +	// Important: that's different from what some people might
  +	// expect and how other server APIs work, but that's how it's
  +	// specified in 2.2. From a security point of view that's very
  +	// good, it keeps inter-webapp communication under control.
   
  -	// XXX workaround - need to fix mapper to return mapped path
  -	if( mappedPath == null )
  -	    mappedPath=req.getPathInfo();
  -	if(mappedPath == null ) {
  -	    String pI=req.getPathInfo();
  -	    if( pI == null ) 
  -		mappedPath=req.getServletPath();
  -	    else
  -		mappedPath=req.getServletPath() + pI;
  -	}
  -	
  -	// All paths have to be relative to the context - it's not so
  -	// logical ( IMHO - costin ), but that's the spec.
  -	// 
  -	// Strip off URI path that brought us to this context.
  -	//  	if (0 == mappedPath.indexOf(this.getPath())) {
  -	// 	    mappedPath = mappedPath.substring(this.getPath().length());
  -	// 	}
  -
  -	Context targetContext=req.getContext();
  -	String realPath= targetContext.getDocBase() + mappedPath;
  +	// XXX Everything can/should be abstracted out as soon as we
  +	// are ready to support non-file-based servers.
  +	String normP=FileUtil.normPath(path);
   
  -	if (!FileUtil.isAbsolute(realPath))
  -	    realPath = contextM.getHome() + "/" + realPath;
  +	String absPath=getAbsolutePath();
  +	String realPath= absPath + normP;
   
   	// Probably not needed - it will be used on the local FS
   	realPath = FileUtil.patch(realPath);
  +
  +	// extra-extra safety check, ( but slow )
  +	try {
  +	    if( ! new File(realPath).getCanonicalPath().startsWith(absPath) ) {
  +		// no access to files in a different context.
  +		// XXX needs a better design - it should be in an interceptor,
  +		// in order to support non-file based repositories.
  +		return null;
  +	    }
  +	} catch( IOException ex ) {
  +	    ex.printStackTrace();
  +	    return null;
  +	}
   
   	if( debug>5) log("Get real path " + path + " " + realPath + " " + normP );
   	return realPath;
  
  
  

Mime
View raw message