📄 ssiservletexternalresolver.java
字号:
// If this is an error page, get the original URI
retVal = (String) req.getAttribute(
"javax.servlet.forward.request_uri");
if (retVal == null) retVal=req.getRequestURI();
}
} else if (nameParts[0].equals("SCRIPT")) {
String scriptName = req.getServletPath();
if (nameParts[1].equals("FILENAME")) {
retVal = context.getRealPath(scriptName);
}
else if (nameParts[1].equals("NAME")) {
retVal = scriptName;
}
} else if (nameParts[0].equals("SERVER")) {
if (nameParts[1].equals("ADDR")) {
retVal = req.getLocalAddr();
}
if (nameParts[1].equals("NAME")) {
retVal = req.getServerName();
} else if (nameParts[1].equals("PORT")) {
retVal = Integer.toString(req.getServerPort());
} else if (nameParts[1].equals("PROTOCOL")) {
retVal = req.getProtocol();
} else if (nameParts[1].equals("SOFTWARE")) {
StringBuffer rv = new StringBuffer(context.getServerInfo());
rv.append(" ");
rv.append(System.getProperty("java.vm.name"));
rv.append("/");
rv.append(System.getProperty("java.vm.version"));
rv.append(" ");
rv.append(System.getProperty("os.name"));
retVal = rv.toString();
}
} else if (name.equalsIgnoreCase("UNIQUE_ID")) {
retVal = req.getRequestedSessionId();
}
if (requiredParts != nameParts.length) return null;
return retVal;
}
public Date getCurrentDate() {
return new Date();
}
protected String nullToEmptyString(String string) {
String retVal = string;
if (retVal == null) {
retVal = "";
}
return retVal;
}
protected String getPathWithoutFileName(String servletPath) {
String retVal = null;
int lastSlash = servletPath.lastIndexOf('/');
if (lastSlash >= 0) {
//cut off file namee
retVal = servletPath.substring(0, lastSlash + 1);
}
return retVal;
}
protected String getPathWithoutContext(String servletPath) {
String retVal = null;
int secondSlash = servletPath.indexOf('/', 1);
if (secondSlash >= 0) {
//cut off context
retVal = servletPath.substring(secondSlash);
}
return retVal;
}
protected String getAbsolutePath(String path) throws IOException {
String pathWithoutContext = SSIServletRequestUtil.getRelativePath(req);
String prefix = getPathWithoutFileName(pathWithoutContext);
if (prefix == null) {
throw new IOException("Couldn't remove filename from path: "
+ pathWithoutContext);
}
String fullPath = prefix + path;
String retVal = SSIServletRequestUtil.normalize(fullPath);
if (retVal == null) {
throw new IOException("Normalization yielded null on path: "
+ fullPath);
}
return retVal;
}
protected ServletContextAndPath getServletContextAndPathFromNonVirtualPath(
String nonVirtualPath) throws IOException {
if (nonVirtualPath.startsWith("/") || nonVirtualPath.startsWith("\\")) {
throw new IOException("A non-virtual path can't be absolute: "
+ nonVirtualPath);
}
if (nonVirtualPath.indexOf("../") >= 0) {
throw new IOException("A non-virtual path can't contain '../' : "
+ nonVirtualPath);
}
String path = getAbsolutePath(nonVirtualPath);
ServletContextAndPath csAndP = new ServletContextAndPath(
context, path);
return csAndP;
}
protected ServletContextAndPath getServletContextAndPathFromVirtualPath(
String virtualPath) throws IOException {
if (!virtualPath.startsWith("/") && !virtualPath.startsWith("\\")) {
return new ServletContextAndPath(context,
getAbsolutePath(virtualPath));
} else {
String normalized = SSIServletRequestUtil.normalize(virtualPath);
if (isVirtualWebappRelative) {
return new ServletContextAndPath(context, normalized);
} else {
ServletContext normContext = context.getContext(normalized);
if (normContext == null) {
throw new IOException("Couldn't get context for path: "
+ normalized);
}
//If it's the root context, then there is no context element
// to remove,
// ie:
// '/file1.shtml' vs '/appName1/file1.shtml'
if (!isRootContext(normContext)) {
String noContext = getPathWithoutContext(normalized);
if (noContext == null) {
throw new IOException(
"Couldn't remove context from path: "
+ normalized);
}
return new ServletContextAndPath(normContext, noContext);
} else {
return new ServletContextAndPath(normContext, normalized);
}
}
}
}
//Assumes servletContext is not-null
//Assumes that identity comparison will be true for the same context
//Assuming the above, getContext("/") will be non-null as long as the root
// context is
// accessible.
//If it isn't, then servletContext can't be the root context anyway, hence
// they will
// not match.
protected boolean isRootContext(ServletContext servletContext) {
return servletContext == servletContext.getContext("/");
}
protected ServletContextAndPath getServletContextAndPath(
String originalPath, boolean virtual) throws IOException {
ServletContextAndPath csAndP = null;
if (debug > 0) {
log("SSIServletExternalResolver.getServletContextAndPath( "
+ originalPath + ", " + virtual + ")", null);
}
if (virtual) {
csAndP = getServletContextAndPathFromVirtualPath(originalPath);
} else {
csAndP = getServletContextAndPathFromNonVirtualPath(originalPath);
}
return csAndP;
}
protected URLConnection getURLConnection(String originalPath,
boolean virtual) throws IOException {
ServletContextAndPath csAndP = getServletContextAndPath(originalPath,
virtual);
ServletContext context = csAndP.getServletContext();
String path = csAndP.getPath();
URL url = context.getResource(path);
if (url == null) {
throw new IOException("Context did not contain resource: " + path);
}
URLConnection urlConnection = url.openConnection();
return urlConnection;
}
public long getFileLastModified(String path, boolean virtual)
throws IOException {
long lastModified = 0;
try {
URLConnection urlConnection = getURLConnection(path, virtual);
lastModified = urlConnection.getLastModified();
} catch (IOException e) {
// Ignore this. It will always fail for non-file based includes
}
return lastModified;
}
public long getFileSize(String path, boolean virtual) throws IOException {
long fileSize = -1;
try {
URLConnection urlConnection = getURLConnection(path, virtual);
fileSize = urlConnection.getContentLength();
} catch (IOException e) {
// Ignore this. It will always fail for non-file based includes
}
return fileSize;
}
//We are making lots of unnecessary copies of the included data here. If
//someone ever complains that this is slow, we should connect the included
// stream to the print writer that SSICommand uses.
public String getFileText(String originalPath, boolean virtual)
throws IOException {
try {
ServletContextAndPath csAndP = getServletContextAndPath(
originalPath, virtual);
ServletContext context = csAndP.getServletContext();
String path = csAndP.getPath();
RequestDispatcher rd = context.getRequestDispatcher(path);
if (rd == null) {
throw new IOException(
"Couldn't get request dispatcher for path: " + path);
}
ByteArrayServletOutputStream basos =
new ByteArrayServletOutputStream();
ResponseIncludeWrapper responseIncludeWrapper =
new ResponseIncludeWrapper(context, req, res, basos);
rd.include(req, responseIncludeWrapper);
//We can't assume the included servlet flushed its output
responseIncludeWrapper.flushOutputStreamOrWriter();
byte[] bytes = basos.toByteArray();
//Assume platform default encoding unless otherwise specified
String retVal;
if (inputEncoding == null) {
retVal = new String( bytes );
} else {
retVal = new String (bytes, inputEncoding);
}
//make an assumption that an empty response is a failure. This is
// a problem
// if a truly empty file
//were included, but not sure how else to tell.
if (retVal.equals("") && !req.getMethod().equalsIgnoreCase(
org.apache.coyote.http11.Constants.HEAD)) {
throw new IOException("Couldn't find file: " + path);
}
return retVal;
} catch (ServletException e) {
throw new IOException("Couldn't include file: " + originalPath
+ " because of ServletException: " + e.getMessage());
}
}
protected class ServletContextAndPath {
protected ServletContext servletContext;
protected String path;
public ServletContextAndPath(ServletContext servletContext,
String path) {
this.servletContext = servletContext;
this.path = path;
}
public ServletContext getServletContext() {
return servletContext;
}
public String getPath() {
return path;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -