use of org.apache.catalina.mapper.MappingData in project tomcat by apache.
the class ApplicationContext method getContext.
@Override
public ServletContext getContext(String uri) {
// Validate the format of the specified argument
if (uri == null || !uri.startsWith("/")) {
return null;
}
Context child = null;
try {
// Look for an exact match
Container host = context.getParent();
child = (Context) host.findChild(uri);
// Non-running contexts should be ignored.
if (child != null && !child.getState().isAvailable()) {
child = null;
}
// Remove any version information and use the mapper
if (child == null) {
int i = uri.indexOf("##");
if (i > -1) {
uri = uri.substring(0, i);
}
// Note: This could be more efficient with a dedicated Mapper
// method but such an implementation would require some
// refactoring of the Mapper to avoid copy/paste of
// existing code.
MessageBytes hostMB = MessageBytes.newInstance();
hostMB.setString(host.getName());
MessageBytes pathMB = MessageBytes.newInstance();
pathMB.setString(uri);
MappingData mappingData = new MappingData();
service.getMapper().map(hostMB, pathMB, null, mappingData);
child = mappingData.context;
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
return null;
}
if (child == null) {
return null;
}
if (context.getCrossContext()) {
// If crossContext is enabled, can always return the context
return child.getServletContext();
} else if (child == context) {
// Can still return the current context
return context.getServletContext();
} else {
// Nothing to return
return null;
}
}
use of org.apache.catalina.mapper.MappingData in project tomcat by apache.
the class ApplicationContext method getRequestDispatcher.
@Override
public RequestDispatcher getRequestDispatcher(final String path) {
// Validate the path argument
if (path == null) {
return null;
}
if (!path.startsWith("/")) {
throw new IllegalArgumentException(sm.getString("applicationContext.requestDispatcher.iae", path));
}
// Same processing order as InputBuffer / CoyoteAdapter
// First remove query string
String uri;
String queryString;
int pos = path.indexOf('?');
if (pos >= 0) {
uri = path.substring(0, pos);
queryString = path.substring(pos + 1);
} else {
uri = path;
queryString = null;
}
// Remove path parameters
String uriNoParams = stripPathParams(uri);
// Then normalize
String normalizedUri = RequestUtil.normalize(uriNoParams);
if (normalizedUri == null) {
return null;
}
if (getContext().getDispatchersUseEncodedPaths()) {
// Decode
String decodedUri = UDecoder.URLDecode(normalizedUri, StandardCharsets.UTF_8);
// Security check to catch attempts to encode /../ sequences
normalizedUri = RequestUtil.normalize(decodedUri);
if (!decodedUri.equals(normalizedUri)) {
getContext().getLogger().warn(sm.getString("applicationContext.illegalDispatchPath", path), new IllegalArgumentException());
return null;
}
// URI needs to include the context path
uri = URLEncoder.DEFAULT.encode(getContextPath(), StandardCharsets.UTF_8) + uri;
} else {
// uri is passed to the constructor for ApplicationDispatcher and is
// ultimately used as the value for getRequestURI() which returns
// encoded values. Therefore, since the value passed in for path
// was decoded, encode uri here.
uri = URLEncoder.DEFAULT.encode(getContextPath() + uri, StandardCharsets.UTF_8);
}
// Use the thread local URI and mapping data
DispatchData dd = dispatchData.get();
if (dd == null) {
dd = new DispatchData();
dispatchData.set(dd);
}
// Use the thread local mapping data
MessageBytes uriMB = dd.uriMB;
MappingData mappingData = dd.mappingData;
try {
// Map the URI
CharChunk uriCC = uriMB.getCharChunk();
try {
uriCC.append(context.getPath());
uriCC.append(normalizedUri);
service.getMapper().map(context, uriMB, mappingData);
if (mappingData.wrapper == null) {
return null;
}
} catch (Exception e) {
// Should never happen
log(sm.getString("applicationContext.mapping.error"), e);
return null;
}
Wrapper wrapper = mappingData.wrapper;
String wrapperPath = mappingData.wrapperPath.toString();
String pathInfo = mappingData.pathInfo.toString();
HttpServletMapping mapping = new ApplicationMapping(mappingData).getHttpServletMapping();
// Construct a RequestDispatcher to process this request
return new ApplicationDispatcher(wrapper, uri, wrapperPath, pathInfo, queryString, mapping, null);
} finally {
// Recycle thread local data at the end of the request so references
// are not held to a completed request as there is potential for
// that to trigger a memory leak if a context is unloaded. Not
// strictly necessary here for uriMB but it needs to be recycled at
// some point so do it here for consistency with mappingData which
// must be recycled here.
uriMB.recycle();
mappingData.recycle();
}
}
Aggregations