You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/05/02 01:23:48 UTC
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/core Context.java
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;