A second round of fixes to simplify the web application setup code and provide for a connection context accessible by the application when handling web requests.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
package com.foundation.web;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.util.IHashMap;
|
||||
import com.common.util.LiteHashMap;
|
||||
import com.foundation.web.WebApplication.PathSubstitution;
|
||||
import com.foundation.web.interfaces.IConnectionContext;
|
||||
import com.foundation.web.interfaces.IRequest;
|
||||
import com.foundation.web.interfaces.IResponse;
|
||||
|
||||
public class DefaultResourceRequestHandler extends ResourceRequestHandler {
|
||||
private IHashMap nameSubstitutionMap = new LiteHashMap(10);
|
||||
private IHashMap pathSubstitutionMap = new LiteHashMap(10);
|
||||
public DefaultResourceRequestHandler() {
|
||||
|
||||
}//DefaultResourceRequestHandler()//
|
||||
/**
|
||||
* Adds a resource name subtitution mapping where the old resource name will be replaced by the new resource name automatically prior to the request being processed.
|
||||
* @param oldName The old resource name.
|
||||
* @param newName The new resource name.
|
||||
*/
|
||||
public void addResourceNameSubstitution(String oldName, String newName) {
|
||||
nameSubstitutionMap.put(oldName, newName);
|
||||
}//addResourceNameSubstitution()//
|
||||
/**
|
||||
* Adds a path subtitution mapping where the old path will be replaced by the new path automatically prior to the request being processed.
|
||||
* @param oldPath The old resource name. eg: "/"
|
||||
* @param newPath The new resource name. eg: "/subdir/index.html"
|
||||
* @param forward Whether the substitution should constitute a forward (where the client is told of the new path) versus a redirect.
|
||||
*/
|
||||
public void addPathSubstitution(String oldPath, String newPath, boolean forward) {
|
||||
pathSubstitutionMap.put(oldPath, new PathSubstitution(newPath, forward));
|
||||
}//addPathSubstitution()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.ResourceRequestHandler#performPathSubstitution(java.lang.String, com.foundation.web.interfaces.IRequest, com.foundation.web.interfaces.IResponse)
|
||||
*/
|
||||
protected String performPathSubstitution(String path, IRequest request, IResponse response) {
|
||||
PathSubstitution substitutePath = (PathSubstitution) pathSubstitutionMap.get(path);
|
||||
|
||||
//First attempt to find a substitute path, then check to see if there is a substitute resource.//
|
||||
if(substitutePath != null) {
|
||||
if(substitutePath.forward()) {
|
||||
//Update the Browser's URL if a substitute is found so that additional requests that are relative to the primary resource's path don't fail spectacularly.//
|
||||
response.setForwardUri(substitutePath.getPath() + (request.getParameterString() == null ? "" : request.getParameterString()));
|
||||
path = null;
|
||||
}//if//
|
||||
else {
|
||||
path = substitutePath.getPath();
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
int lastForwardSlash = path.lastIndexOf('/');
|
||||
int lastBackSlash = path.lastIndexOf('\\');
|
||||
int lastSlash = Math.max(lastForwardSlash, lastBackSlash);
|
||||
//boolean hasDot = path.indexOf('.', lastSlash) != -1; //Note: This requires all accessed resources to have a dot in the name! Is this desired? Without this we can't tell if this is supposed to use the default resource in the directory though.
|
||||
//String resourceName = hasDot && lastSlash + 2 != path.length() ? path.substring(lastSlash + 1) : "";
|
||||
String resourceName = path.substring(lastSlash + 1);
|
||||
String newResourceName = (String) nameSubstitutionMap.get(resourceName);
|
||||
|
||||
if(newResourceName != null) {
|
||||
if(resourceName.length() > 0) {
|
||||
path = path.substring(0, lastSlash + 1) + newResourceName;
|
||||
}//if//
|
||||
else {
|
||||
path += newResourceName;
|
||||
}//else//
|
||||
}//if//
|
||||
}//else//
|
||||
|
||||
return path;
|
||||
}//performPathSubstitution()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.ResourceRequestHandler#getMaxMessageSize(com.foundation.web.interfaces.IRequest, com.foundation.web.SessionData, com.foundation.web.SecureSessionData)
|
||||
*/
|
||||
public int getMaxMessageSize(IRequest request, SessionData sessionData, SecureSessionData secureSessionData) {
|
||||
return 0;
|
||||
}//getMaxMessageSize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.ResourceRequestHandler#processRequest(java.lang.String, com.foundation.web.interfaces.IRequest, com.foundation.web.interfaces.IResponse, com.foundation.web.SessionData, com.foundation.web.SecureSessionData, boolean, com.foundation.web.interfaces.IConnectionContext)
|
||||
*/
|
||||
public void processRequest(String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext) {
|
||||
try {
|
||||
int extensionDecimal = requestPath.lastIndexOf('.');
|
||||
boolean cacheIndefinately = false;
|
||||
|
||||
//Set images to cache indefinately.//
|
||||
if(extensionDecimal != -1) {
|
||||
String extension = requestPath.substring(extensionDecimal + 1).toLowerCase();
|
||||
|
||||
if(extension.equals("gif") || extension.equals("png") || extension.equals("jpg") || extension.equals("jpeg")) {
|
||||
cacheIndefinately = true;
|
||||
}//if//
|
||||
}//if//
|
||||
|
||||
FileContent.setContentResource(response, requestPath, request, request.getCacheDate(), null, cacheIndefinately);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
}//processRequest()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.ResourceRequestHandler#processRequest(com.foundation.web.IWebRequestHandler, java.lang.String, com.foundation.web.interfaces.IRequest, com.foundation.web.interfaces.IResponse, com.foundation.web.SessionData, com.foundation.web.SecureSessionData, boolean, com.foundation.web.interfaces.IConnectionContext)
|
||||
*/
|
||||
public void processRequest(IWebRequestHandler handler, String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext) {
|
||||
try {
|
||||
handler.processRequest(request, response, sessionData, secureSessionData);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
}//processRequest()//
|
||||
}//DefaultResourceRequestHandler//
|
||||
@@ -18,9 +18,9 @@ import com.foundation.web.interfaces.IResponse;
|
||||
public final class FrameworkController extends WebRequestController {
|
||||
private static final Integer INVALID_CLIENT_ID = new Integer(0);
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.IWebRequestHandler#processRequest(com.foundation.web.interfaces.IRequest, com.foundation.web.interfaces.IResponse, com.foundation.web.SessionData, com.foundation.web.SecureSessionData, com.foundation.web.interfaces.IConnectionContext)
|
||||
* @see com.foundation.web.IWebRequestHandler#processRequest(com.foundation.web.interfaces.IRequest, com.foundation.web.interfaces.IResponse, com.foundation.web.SessionData, com.foundation.web.SecureSessionData)
|
||||
*/
|
||||
public void processRequest(IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, IConnectionContext connectionContext) {
|
||||
public void processRequest(IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData) {
|
||||
String result = null;
|
||||
|
||||
//Note that all calls to this method within the context of a single session are single threaded - the session's request handler is used by the web application to thread the requests on the session's thread.//
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package com.foundation.web;
|
||||
|
||||
import com.foundation.web.interfaces.IConnectionContext;
|
||||
import com.foundation.web.interfaces.IRequest;
|
||||
import com.foundation.web.interfaces.IResponse;
|
||||
import com.foundation.web.interfaces.ISession;
|
||||
import com.foundation.web.SessionData;
|
||||
import com.foundation.web.SecureSessionData;
|
||||
|
||||
|
||||
/**
|
||||
* Allows the application to specify special handling for access to static resources.
|
||||
*/
|
||||
public interface IResourceRequestHandler {
|
||||
/**
|
||||
* Gets a resource from the file system. The implementor can validate that the user has the rights to access the resource and can ensure that there is an SSL connection if needed.
|
||||
* <p>A simple implementation will simply call: <code>response.setContentResource(requestPath, request.getCacheDate());</code>, a more complex implementation will test for an SSL connection for secure resources, and will ensure the user is logged in and has rights to access the resource for rights oriented resources.</p>
|
||||
* @param requestPath The path to the requested resource. This is the request's URI already mapped to an actual resource (same as calling request.getUri()).
|
||||
* @param request The request metadata.
|
||||
* @param response The response metadata.
|
||||
* @param sessionData The non-secure session data.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public void processRequest(String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext);
|
||||
/**
|
||||
* Calls a handler to access the requested resource. The implementor can validate that the user has the rights to access the resource and can ensure that there is an SSL connection if needed.
|
||||
* <p>A simple implementation will simply call: <code>response.setContentResource(requestPath, request.getCacheDate());</code>, a more complex implementation will test for an SSL connection for secure resources, and will ensure the user is logged in and has rights to access the resource for rights oriented resources.</p>
|
||||
* @param handler The handler which will process the request.
|
||||
* @param requestPath The path to the requested resource. This is the path from the application's default package name to the handler class using slashes instead of dots as separators.
|
||||
* @param request The request metadata.
|
||||
* @param response The response metadata.
|
||||
* @param sessionData The non-secure session data.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public void processRequest(IWebRequestHandler handler, String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext);
|
||||
/**
|
||||
* Gets the maximum size of message allowed by the application beyond the header (for upload only).
|
||||
* @param request The request whose header has been read, but whose body has not yet been read.
|
||||
* @param sessionData The sessionData for the session that the request exists within. This may be null only if the application does not assign a session, or a session for this connection has not yet been assigned.
|
||||
* @param secureSessionData The secure session data for the session. This may be null if a session has not or will not be assigned, or if the connection to the client is not secure.
|
||||
* @return The maximum message size in bytes, or -1 if the message may be infinately large. This should be restricted unless the user is trusted to prevent malicious users from hogging network and system resources.
|
||||
*/
|
||||
public int getMaxMessageSize(IRequest request, SessionData sessionData, SecureSessionData secureSessionData);
|
||||
}//IResourceRequestHandler//
|
||||
@@ -26,5 +26,5 @@ public interface IWebRequestHandler {
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
* @param secureSessionData The application specific data object associated with this user's session if the user made the request over a secure connection and used the correct secure session identifier, otherwise null.
|
||||
*/
|
||||
public void processRequest(IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, IConnectionContext connectionContext);
|
||||
public void processRequest(IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData);
|
||||
}//IWebRequestHandler//
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.foundation.web;
|
||||
|
||||
import com.foundation.web.interfaces.IConnectionContext;
|
||||
import com.foundation.web.interfaces.IRequest;
|
||||
import com.foundation.web.interfaces.IResponse;
|
||||
import com.foundation.web.interfaces.ISession;
|
||||
|
||||
/**
|
||||
* Allows the application's default handling of webdav requests to be preempted.
|
||||
*/
|
||||
public interface IWebdavRequestHandler {
|
||||
/**
|
||||
* Processes the incoming web dav request.
|
||||
* @param requestPath The path to the requested resource. This is the request's URI already mapped to an actual resource (same as calling request.getUri()).
|
||||
* @param request The request metadata.
|
||||
* @param response The response metadata.
|
||||
* @param sessionData The non-secure session data.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public void processRequest(String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext);
|
||||
}//IWebdavRequestHandler//
|
||||
@@ -0,0 +1,221 @@
|
||||
package com.foundation.web;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
||||
import com.common.debug.Debug;
|
||||
import com.common.io.StreamSupport;
|
||||
import com.common.thread.IRunnable;
|
||||
import com.common.util.IHashMap;
|
||||
import com.common.util.LiteHashMap;
|
||||
import com.foundation.web.WebApplication.PathSubstitution;
|
||||
import com.foundation.web.interfaces.IConnectionContext;
|
||||
import com.foundation.web.interfaces.IRequest;
|
||||
import com.foundation.web.interfaces.IResponse;
|
||||
import com.foundation.web.interfaces.ISession;
|
||||
import com.foundation.web.interfaces.IWebApplication;
|
||||
import com.foundation.web.SessionData;
|
||||
import com.foundation.web.SecureSessionData;
|
||||
|
||||
|
||||
/**
|
||||
* Allows the application to specify special handling for access to static resources.
|
||||
*/
|
||||
public abstract class ResourceRequestHandler {
|
||||
/** The framework.js source. */
|
||||
private String frameworkJavascript;
|
||||
/**
|
||||
* ResourceRequestHandler constructor.
|
||||
*/
|
||||
public ResourceRequestHandler() {
|
||||
try {
|
||||
InputStream in = getClass().getClassLoader().getResourceAsStream("framework.js");
|
||||
|
||||
try {
|
||||
frameworkJavascript = StreamSupport.readText(in, "UTF8");
|
||||
}//try//
|
||||
finally {
|
||||
try {in.close();} catch(Throwable e) {}
|
||||
}//finally//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log("Failed to read the framework.js file from the framework jar.", e);
|
||||
}//catch//
|
||||
}//ResourceRequestHandler()//
|
||||
/**
|
||||
* Allows the handler to substitute one path for another.
|
||||
* @param path The path that was provided by the client.
|
||||
* @param request The request object.
|
||||
* @param response The response object.
|
||||
* @return The path to be used when locating the resource. May be <code>null</code> if no furthor processing of the request should be performed.
|
||||
*/
|
||||
protected String performPathSubstitution(String path, IRequest request, IResponse response) {
|
||||
return path;
|
||||
}//performPathSubstitution()//
|
||||
/**
|
||||
* Gets a resource from the file system. The implementor can validate that the user has the rights to access the resource and can ensure that there is an SSL connection if needed.
|
||||
* <p>A simple implementation will simply call: <code>response.setContentResource(requestPath, request.getCacheDate());</code>, a more complex implementation will test for an SSL connection for secure resources, and will ensure the user is logged in and has rights to access the resource for rights oriented resources.</p>
|
||||
* <p><em>WARNING</em>: The caller of this method synchronizes on the internal web server session for the client. Because of this, all code handling the request that requires session access *MUST* ensure this thread exits the method AFTER all worker threads that might be created or used. This is also important because the Response object should never be modified outside the scope of this method call.</p>
|
||||
* @param requestPath The path to the requested resource. This is the request's URI already mapped to an actual resource (same as calling request.getUri()).
|
||||
* @param request The request object.
|
||||
* @param response The response object.
|
||||
* @param sessionData The non-secure session data or null if there is none for the application.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public void processRequest(final IRequest request, final IResponse response, final SessionData sessionData, final SecureSessionData secureSessionData, final boolean isSecure, final IConnectionContext connectionContext) {
|
||||
int requestType = request.getRequestType();
|
||||
boolean isGetPostOrHead = requestType == IRequest.TYPE_GET || requestType == IRequest.TYPE_POST || requestType == IRequest.TYPE_HEAD;
|
||||
boolean isWebdav = requestType == IRequest.TYPE_WEBDAV_COPY || requestType == IRequest.TYPE_WEBDAV_LOCK || requestType == IRequest.TYPE_WEBDAV_MKCOL || requestType == IRequest.TYPE_WEBDAV_MOVE || requestType == IRequest.TYPE_WEBDAV_PROPFIND || requestType == IRequest.TYPE_WEBDAV_PROPPATCH || requestType == IRequest.TYPE_WEBDAV_UNLOCK;
|
||||
String path = request.getUri();
|
||||
IWebApplication webApplication = request.getWebApplication();
|
||||
|
||||
while(path != null) {
|
||||
path = performPathSubstitution(path, request, response);
|
||||
|
||||
if(path != null) {
|
||||
boolean isFrameworkController = path.equals("/Framework") || path.equals("/Framework.java") || path.equals("/FrameworkController") || path.equals("/FrameworkController.java");
|
||||
boolean isFrameworkJavascript = path.equals("/framework.js");
|
||||
|
||||
//Verification of rights to access the resource are handled by the IResourceRequestHandler setup by the application. If an IResourceRequestHandler is provided then it can perform any validation it sees fit prior to allowing access to the requested resource.//
|
||||
if((path.endsWith(".java") || isFrameworkController) && isGetPostOrHead) {
|
||||
try {
|
||||
final IWebRequestHandler handler;
|
||||
Object instance = null;
|
||||
|
||||
if(isFrameworkController) {
|
||||
instance = new FrameworkController();
|
||||
}//if//
|
||||
else {
|
||||
String clsName = path.replace('/', '.').substring(0, path.length() - 5);
|
||||
Class cls = null;
|
||||
|
||||
if(clsName.startsWith(".")) {
|
||||
clsName = clsName.substring(1);
|
||||
}//if//
|
||||
|
||||
cls = Class.forName(webApplication.getDefaultPackageName() + clsName);
|
||||
instance = cls.newInstance();
|
||||
}//else//
|
||||
|
||||
if(instance instanceof IWebRequestHandler) {
|
||||
handler = (IWebRequestHandler) instance;
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("Unexpected class called by the client: " + instance.getClass().getName()));
|
||||
handler = null;
|
||||
}//else//
|
||||
|
||||
if(handler != null) {
|
||||
final String requestPath = path;
|
||||
IRunnable runnable = new IRunnable() {
|
||||
public Object run() {
|
||||
processRequest(handler, requestPath, request, response, sessionData, secureSessionData, isSecure, connectionContext);
|
||||
|
||||
return null;
|
||||
}//run()//
|
||||
};
|
||||
|
||||
//Ensure the request is processed on the correct thread.//
|
||||
if(sessionData != null && sessionData.getRequestHandler() != null) {
|
||||
//Note: This is a synchronous call, so no need to increment/decrement the activity counter on the web application container.//
|
||||
sessionData.getRequestHandler().execute(runnable, true);
|
||||
}//if//
|
||||
else {
|
||||
runnable.run();
|
||||
}//else//
|
||||
}//if//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
response.setError(response.ERROR_TYPE_RESOURCE_NOT_FOUND);
|
||||
}//catch//
|
||||
}//if//
|
||||
else if(isGetPostOrHead) {
|
||||
if(isFrameworkJavascript) {
|
||||
JavascriptContent content = new JavascriptContent(frameworkJavascript);
|
||||
|
||||
//Attempt to tell the client not to cache.//
|
||||
content.setCacheLength(content.CACHE_LENGTH_NEVER_CACHE);
|
||||
content.setExpiresDirective(null);
|
||||
response.setContent(content);
|
||||
}//if//
|
||||
else {
|
||||
processRequest(path, request, response, sessionData, secureSessionData, isSecure, connectionContext);
|
||||
}//else//
|
||||
}//else if//
|
||||
else if(isWebdav) {
|
||||
processWebDavRequest(path, request, response, sessionData, secureSessionData, isSecure, connectionContext);
|
||||
}//else if//
|
||||
else { //The request type is PUT or OPTIONS.//
|
||||
//TODO: Provide a way for applications to provide support for these requests.
|
||||
response.setError(IResponse.ERROR_TYPE_INVALID_ACCESS);
|
||||
}//else//
|
||||
|
||||
if(response.getRedirectUri() != null) {
|
||||
try {
|
||||
path = new URI(path).resolve(new URI(response.getRedirectUri())).getPath();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
//TODO: Use a better error - internal error.
|
||||
response.setError(IResponse.ERROR_TYPE_RESOURCE_NOT_FOUND);
|
||||
path = null;
|
||||
}//catch//
|
||||
|
||||
response.setRedirectUri(null);
|
||||
}//if//
|
||||
else {
|
||||
path = null;
|
||||
}//else//
|
||||
}//if//
|
||||
}//while//
|
||||
}//processRequest()//
|
||||
/**
|
||||
* Gets a resource from the file system. The implementor can validate that the user has the rights to access the resource and can ensure that there is an SSL connection if needed.
|
||||
* <p>A simple implementation will simply call: <code>response.setContentResource(requestPath, request.getCacheDate());</code>, a more complex implementation will test for an SSL connection for secure resources, and will ensure the user is logged in and has rights to access the resource for rights oriented resources.</p>
|
||||
* @param requestPath The path to the requested resource. This is the request's URI already mapped to an actual resource (same as calling request.getUri()).
|
||||
* @param request The request object.
|
||||
* @param response The response object.
|
||||
* @param sessionData The non-secure session data.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public abstract void processRequest(String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext);
|
||||
/**
|
||||
* Handles a WebDav request.
|
||||
* @param requestPath The path to the requested resource. This is the request's URI already mapped to an actual resource (same as calling request.getUri()).
|
||||
* @param request The request object.
|
||||
* @param response The response object.
|
||||
* @param sessionData The non-secure session data.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public void processWebDavRequest(String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext) {
|
||||
//Does nothing.//
|
||||
}//processWebDavRequest()//
|
||||
/**
|
||||
* Calls a handler to access the requested resource. The implementor can validate that the user has the rights to access the resource and can ensure that there is an SSL connection if needed.
|
||||
* <p>A simple implementation will simply call: <code>response.setContentResource(requestPath, request.getCacheDate());</code>, a more complex implementation will test for an SSL connection for secure resources, and will ensure the user is logged in and has rights to access the resource for rights oriented resources.</p>
|
||||
* @param handler The handler which will process the request.
|
||||
* @param requestPath The path to the requested resource. This is the path from the application's default package name to the handler class using slashes instead of dots as separators.
|
||||
* @param request The request object.
|
||||
* @param response The response object.
|
||||
* @param sessionData The non-secure session data.
|
||||
* @param secureSessionData The secure session data, or null if the request was made over an insecure connection or no secure session data exists.
|
||||
* @param isSecure Whether the request was made over a secure connection and provided the correct secure id.
|
||||
* @param connectionContext The context object for the connection (socket) between the client (web browser) and server (web server).
|
||||
*/
|
||||
public abstract void processRequest(IWebRequestHandler handler, String requestPath, IRequest request, IResponse response, SessionData sessionData, SecureSessionData secureSessionData, boolean isSecure, IConnectionContext connectionContext);
|
||||
/**
|
||||
* Gets the maximum size of message allowed by the application beyond the header (for upload only).
|
||||
* @param request The request whose header has been read, but whose body has not yet been read.
|
||||
* @param sessionData The sessionData for the session that the request exists within. This may be null only if the application does not assign a session, or a session for this connection has not yet been assigned.
|
||||
* @param secureSessionData The secure session data for the session. This may be null if a session has not or will not be assigned, or if the connection to the client is not secure.
|
||||
* @return The maximum message size in bytes, or -1 if the message may be infinately large. This should be restricted unless the user is trusted to prevent malicious users from hogging network and system resources.
|
||||
*/
|
||||
public abstract int getMaxMessageSize(IRequest request, SessionData sessionData, SecureSessionData secureSessionData);
|
||||
}//IResourceRequestHandler//
|
||||
@@ -94,10 +94,6 @@ public class WebApplication implements IWebApplication, IWebServerApplicationDef
|
||||
private File externalBaseDirectory = null;
|
||||
/** An optional directory where cache files are stored. These cache files are not part of the webapp's general distribution and must be fully re-creatable. */
|
||||
private File cacheBaseDirectory = null;
|
||||
/** The mapping of replacement resource names indexed by requested resource names. This should contain at least the default resource mapping (a resource indexed by an empty string). */
|
||||
private IHashMap nameSubstitutionMap = null;
|
||||
/** The mapping of replacement paths indexed by requested paths. This should contain at least the default resource mapping (a resource indexed by an empty string). */
|
||||
private IHashMap pathSubstitutionMap = null;
|
||||
/** The package name to prepend to a call to a java resource. */
|
||||
private String defaultPackageName = "";
|
||||
/** The application's session handler which creates sessions, restores sessions, and provides the tools necessary for the web application to send restoration data to a client. */
|
||||
@@ -116,18 +112,14 @@ public class WebApplication implements IWebApplication, IWebServerApplicationDef
|
||||
private long sessionTimeout;
|
||||
/** The optional handler for processing requests that contain a stale session identifier. */
|
||||
private IBadSessionHandler badSessionHandler = null;
|
||||
/** Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation. */
|
||||
private IResourceRequestHandler resourceRequestHandler = null;
|
||||
/** Replaces the default web dav handling of requests. */
|
||||
private IWebdavRequestHandler webdavRequestHandler = null;
|
||||
/** Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation. This value will never be null (defaults to an instance of DefaultResourceRequestHandler). */
|
||||
private ResourceRequestHandler resourceRequestHandler = null;
|
||||
/** The mime type provider used by the server. */
|
||||
private MimeTypeProvider mimeTypeProvider = new MimeTypeProvider();
|
||||
/** The maximum size of resource to be cachable. */
|
||||
private long cacheCutoffSize = 10000; //10kb//
|
||||
/** The map of resource values (image bytes and such) by the uri they are referenced by. Note that the value is weakly referenced, not the key. */
|
||||
private SoftHashMap staticResourceMap = new SoftHashMap(100);
|
||||
/** The framework.js source. */
|
||||
private String frameworkJavascript;
|
||||
/** The handler passed to the web session when deserializing. Allows the application to manage class name changes without damaging the ability to restore sessions. */
|
||||
private IClassReplacementHandler classReplacementHandler = null;
|
||||
/** Whether responses should be compressed by default when possible. Certain resources that compress poorly will of course ignore this directive. */
|
||||
@@ -397,22 +389,6 @@ public WebApplication(String name, WebOptions options, Application application)
|
||||
this.name = name;
|
||||
this.application = application;
|
||||
|
||||
if(options.getNameSubstitutionMap() == null) {
|
||||
this.nameSubstitutionMap = new LiteHashMap(10);
|
||||
}//if//
|
||||
else {
|
||||
//Copy the map so that the caller cannot change it after the fact without going through the application class.//
|
||||
this.nameSubstitutionMap = new LiteHashMap(options.getNameSubstitutionMap());
|
||||
}//else//
|
||||
|
||||
if(options.getPathSubstitutionMap() == null) {
|
||||
this.pathSubstitutionMap = new LiteHashMap(10);
|
||||
}//if//
|
||||
else {
|
||||
//Copy the map so that the caller cannot change it after the fact without going through the application class.//
|
||||
this.pathSubstitutionMap = new LiteHashMap(options.getPathSubstitutionMap());
|
||||
}//else//
|
||||
|
||||
//This is not good code - it forces a resource name to always be provided which isn't always desireable.//
|
||||
// if(!nameSubstitutionMap.containsKey("")) {
|
||||
// nameSubstitutionMap.put("", "index.htm");
|
||||
@@ -439,7 +415,11 @@ public WebApplication(String name, WebOptions options, Application application)
|
||||
this.sessionRepositoryTimeout = sessionUpdateInterval * 3;
|
||||
this.badSessionHandler = options.getBadSessionHandler();
|
||||
this.resourceRequestHandler = options.getResourceRequestHandler();
|
||||
this.webdavRequestHandler = options.getWebdavRequestHandler();
|
||||
|
||||
if(this.resourceRequestHandler == null) {
|
||||
this.resourceRequestHandler = new DefaultResourceRequestHandler();
|
||||
}//if//
|
||||
|
||||
this.compressResponses = options.getCompressResponses();
|
||||
this.retainRequestBufferHandler = options.getRetainRequestBufferHandler();
|
||||
setCacheCuttoffSize(options.getCacheCutoffSize());
|
||||
@@ -468,20 +448,6 @@ public WebApplication(String name, WebOptions options, Application application)
|
||||
throw new RuntimeException("Cache base directory (" + (cacheBaseDirectory != null ? cacheBaseDirectory.getAbsolutePath() : "null") + ") not readable, does not exist, or is not a directory.");
|
||||
}//if//
|
||||
|
||||
try {
|
||||
InputStream in = getClass().getClassLoader().getResourceAsStream("framework.js");
|
||||
|
||||
try {
|
||||
frameworkJavascript = StreamSupport.readText(in, "UTF8");
|
||||
}//try//
|
||||
finally {
|
||||
try {in.close();} catch(Throwable e) {}
|
||||
}//finally//
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log("Failed to read the framework.js file from the framework jar.", e);
|
||||
}//catch//
|
||||
|
||||
//Setup the task to check for stale sessions.//
|
||||
Scheduler.addTask(options.getSessionCheckInterval(), new Scheduler.Task() {
|
||||
public void evaluate() {
|
||||
@@ -705,21 +671,10 @@ public String getErrorHeader(int errorCode) {
|
||||
|
||||
return result;
|
||||
}//getErrorHeader()//
|
||||
/**
|
||||
* Allows substitutions for a given resource name.
|
||||
* @param resourceName The name of the resource to be substituted.
|
||||
* @return The substituted name or null.
|
||||
*/
|
||||
protected String processResourceName(String resourceName) {
|
||||
return (String) nameSubstitutionMap.get(resourceName);
|
||||
}//processResourceName()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.web.interfaces.IWebApplication#processRequest(com.foundation.web.interfaces.IRequest, com.foundation.web.interfaces.IResponse, com.foundation.web.interfaces.ISession, boolean, boolean, com.foundation.web.interfaces.IConnectionContext)
|
||||
*/
|
||||
public void processRequest(final IRequest request, final IResponse response, final ISession session, final boolean isSecure, final boolean clientHadBadSession, final IConnectionContext connectionContext) {
|
||||
int requestType = request.getRequestType();
|
||||
boolean isGetPostOrHead = requestType == IRequest.TYPE_GET || requestType == IRequest.TYPE_POST || requestType == IRequest.TYPE_HEAD;
|
||||
boolean isWebdav = requestType == IRequest.TYPE_WEBDAV_COPY || requestType == IRequest.TYPE_WEBDAV_LOCK || requestType == IRequest.TYPE_WEBDAV_MKCOL || requestType == IRequest.TYPE_WEBDAV_MOVE || requestType == IRequest.TYPE_WEBDAV_PROPFIND || requestType == IRequest.TYPE_WEBDAV_PROPPATCH || requestType == IRequest.TYPE_WEBDAV_UNLOCK;
|
||||
boolean ignoreRequest = false;
|
||||
|
||||
if(badSessionHandler != null && clientHadBadSession) {
|
||||
@@ -727,175 +682,11 @@ public void processRequest(final IRequest request, final IResponse response, fin
|
||||
}//if//
|
||||
|
||||
if(!ignoreRequest) {
|
||||
String path = request.getUri();
|
||||
|
||||
while(path != null) {
|
||||
PathSubstitution substitutePath = (PathSubstitution) pathSubstitutionMap.get(path);
|
||||
|
||||
//First attempt to find a substitute path, then check to see if there is a substitute resource.//
|
||||
if(substitutePath != null) {
|
||||
if(substitutePath.forward()) {
|
||||
//Update the Browser's URL if a substitute is found so that additional requests that are relative to the primary resource's path don't fail spectacularly.//
|
||||
response.setForwardUri(substitutePath.getPath() + (request.getParameterString() == null ? "" : request.getParameterString()));
|
||||
path = null;
|
||||
}//if//
|
||||
else {
|
||||
path = substitutePath.getPath();
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
int lastForwardSlash = path.lastIndexOf('/');
|
||||
int lastBackSlash = path.lastIndexOf('\\');
|
||||
int lastSlash = Math.max(lastForwardSlash, lastBackSlash);
|
||||
//boolean hasDot = path.indexOf('.', lastSlash) != -1; //Note: This requires all accessed resources to have a dot in the name! Is this desired? Without this we can't tell if this is supposed to use the default resource in the directory though.
|
||||
//String resourceName = hasDot && lastSlash + 2 != path.length() ? path.substring(lastSlash + 1) : "";
|
||||
String resourceName = path.substring(lastSlash + 1);
|
||||
String newResourceName = (String) nameSubstitutionMap.get(resourceName);
|
||||
|
||||
if(newResourceName != null) {
|
||||
if(resourceName.length() > 0) {
|
||||
path = path.substring(0, lastSlash + 1) + newResourceName;
|
||||
}//if//
|
||||
else {
|
||||
path += newResourceName;
|
||||
}//else//
|
||||
}//if//
|
||||
}//else//
|
||||
|
||||
if(path != null) {
|
||||
boolean isFrameworkController = path.equals("/Framework") || path.equals("/Framework.java") || path.equals("/FrameworkController") || path.equals("/FrameworkController.java");
|
||||
boolean isFrameworkJavascript = path.equals("/framework.js");
|
||||
|
||||
//Verification of rights to access the resource are handled by the IResourceRequestHandler setup by the application. If an IResourceRequestHandler is provided then it can perform any validation it sees fit prior to allowing access to the requested resource.//
|
||||
if((path.endsWith(".java") || isFrameworkController) && isGetPostOrHead) {
|
||||
if(session != null) {
|
||||
//Synchronize on the session such that two threads cannot mess with the same session at the same time. Static resources being requested don't need to synchronize (they also won't update the session).//
|
||||
synchronized(session) {
|
||||
try {
|
||||
final IWebRequestHandler handler;
|
||||
Object instance = null;
|
||||
|
||||
if(isFrameworkController) {
|
||||
instance = new FrameworkController();
|
||||
}//if//
|
||||
else {
|
||||
String clsName = path.replace('/', '.').substring(0, path.length() - 5);
|
||||
Class cls = null;
|
||||
|
||||
if(clsName.startsWith(".")) {
|
||||
clsName = clsName.substring(1);
|
||||
}//if//
|
||||
|
||||
cls = Class.forName(getDefaultPackageName() + clsName);
|
||||
instance = cls.newInstance();
|
||||
}//else//
|
||||
|
||||
if(instance instanceof IWebRequestHandler) {
|
||||
handler = (IWebRequestHandler) instance;
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("Unexpected class called by the client: " + instance.getClass().getName()));
|
||||
handler = null;
|
||||
}//else//
|
||||
|
||||
if(handler != null) {
|
||||
WebSession webSession = (WebSession) session;
|
||||
final String requestPath = path;
|
||||
IRunnable runnable = new IRunnable() {
|
||||
public Object run() {
|
||||
if(resourceRequestHandler != null) {
|
||||
resourceRequestHandler.processRequest(handler, requestPath, request, response, (SessionData) session.getApplicationData(), (SecureSessionData) (isSecure ? session.getApplicationSecureData() : null), isSecure, connectionContext);
|
||||
}//if//
|
||||
else {
|
||||
try {
|
||||
//Note: Synchronization on the session is not necessary now that we single thread all requests for a given session.//
|
||||
handler.processRequest(request, response, (SessionData) session.getApplicationData(), isSecure ? (SecureSessionData) session.getApplicationSecureData() : null, connectionContext);
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
throw new RuntimeException();
|
||||
}//catch//
|
||||
}//else//
|
||||
|
||||
return null;
|
||||
}//run()//
|
||||
};
|
||||
|
||||
//Ensure the request is processed on the correct thread.//
|
||||
if(session != null && webSession.getApplicationData() != null && ((SessionData) webSession.getApplicationData()).getRequestHandler() != null) {
|
||||
//Note: This is a synchronous call, so no need to increment/decrement the activity counter on the web application container.//
|
||||
((SessionData) webSession.getApplicationData()).getRequestHandler().execute(runnable, true);
|
||||
}//if//
|
||||
else {
|
||||
runnable.run();
|
||||
}//else//
|
||||
}//if//
|
||||
|
||||
//Update the repository with the session changes as necessary.//
|
||||
((WebSession) session).updateRepository();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
response.setError(response.ERROR_TYPE_RESOURCE_NOT_FOUND);
|
||||
}//catch//
|
||||
}//synchronized//
|
||||
}//if//
|
||||
else {
|
||||
Debug.log(new RuntimeException("No session!"));
|
||||
}//else//
|
||||
}//if//
|
||||
else if(isGetPostOrHead) {
|
||||
if(isFrameworkJavascript) {
|
||||
JavascriptContent content = new JavascriptContent(frameworkJavascript);
|
||||
|
||||
//Attempt to tell the client not to cache.//
|
||||
content.setCacheLength(content.CACHE_LENGTH_NEVER_CACHE);
|
||||
content.setExpiresDirective(null);
|
||||
response.setContent(content);
|
||||
}//if//
|
||||
else if(resourceRequestHandler == null) {
|
||||
FileContent.setContentResource(response, path, request.getCacheDate());
|
||||
}//else if//
|
||||
else {
|
||||
//TODO: Should we synchronize on the session here? The app code could interact with the session and cause problems otherwise.
|
||||
resourceRequestHandler.processRequest(path, request, response, (SessionData) session.getApplicationData(), (SecureSessionData) (isSecure ? session.getApplicationSecureData() : null), isSecure, connectionContext);
|
||||
}//else//
|
||||
}//else if//
|
||||
else if(isWebdav) {
|
||||
if(webdavRequestHandler == null) {
|
||||
response.setError(IResponse.ERROR_TYPE_INVALID_ACCESS);
|
||||
}//if//
|
||||
else {
|
||||
synchronized(session) {
|
||||
webdavRequestHandler.processRequest(path, request, response, (SessionData) session.getApplicationData(), (SecureSessionData) (isSecure ? session.getApplicationSecureData() : null), isSecure, connectionContext);
|
||||
//Update the repository with the session changes as necessary.//
|
||||
((WebSession) session).updateRepository();
|
||||
}//synchronized//
|
||||
}//else//
|
||||
}//else if//
|
||||
else { //The request type is PUT or OPTIONS.//
|
||||
//TODO: Provide a way for applications to provide support for these requests.
|
||||
response.setError(IResponse.ERROR_TYPE_INVALID_ACCESS);
|
||||
}//else//
|
||||
|
||||
if(response.getRedirectUri() != null) {
|
||||
try {
|
||||
path = new URI(path).resolve(new URI(response.getRedirectUri())).getPath();
|
||||
}//try//
|
||||
catch(Throwable e) {
|
||||
Debug.log(e);
|
||||
//TODO: Use a better error - internal error.
|
||||
response.setError(IResponse.ERROR_TYPE_RESOURCE_NOT_FOUND);
|
||||
path = null;
|
||||
}//catch//
|
||||
|
||||
response.setRedirectUri(null);
|
||||
}//if//
|
||||
else {
|
||||
path = null;
|
||||
}//else//
|
||||
}//if//
|
||||
}//while//
|
||||
synchronized(session) {
|
||||
resourceRequestHandler.processRequest(request, response, session == null ? null : (SessionData) session.getApplicationData(), session == null ? null : (SecureSessionData) (isSecure ? session.getApplicationSecureData() : null), isSecure, connectionContext);
|
||||
//Update the repository with the session changes as necessary.//
|
||||
((WebSession) session).updateRepository();
|
||||
}//synchronized//
|
||||
}//if//
|
||||
}//processRequest()//
|
||||
/* (non-Javadoc)
|
||||
@@ -1244,6 +1035,8 @@ public String initiateOpenIdAuth(String userId) {
|
||||
if(connection != null) {
|
||||
String type = connection.getContentType();
|
||||
Object content = connection.getContent();
|
||||
|
||||
//TODO: Finish?
|
||||
}//if//
|
||||
}//try//
|
||||
catch(MalformedURLException e) {
|
||||
@@ -1253,7 +1046,6 @@ public String initiateOpenIdAuth(String userId) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
|
||||
|
||||
return null;
|
||||
}//initiateOpenIdAuth()//
|
||||
private static class Endpoint {
|
||||
@@ -1380,6 +1172,10 @@ private static Endpoint getOpenIdEndpoint(String urlText) {
|
||||
|
||||
return result;
|
||||
}//getGoogleOpenIdEndpoint()//
|
||||
/**
|
||||
* Test code for google's open id implementation.
|
||||
* @param endpoint
|
||||
*/
|
||||
public static void getGoogleOpenIdX(Endpoint endpoint) {
|
||||
try {
|
||||
URL url = new URL(endpoint.url);
|
||||
@@ -1445,6 +1241,11 @@ public static void getGoogleOpenIdX(Endpoint endpoint) {
|
||||
Debug.log(e);
|
||||
}//catch//
|
||||
}//getGoogleOpenIdX()//
|
||||
/**
|
||||
* Test code for open id.
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public static String initiateOpenIdAuthX(String userId) {
|
||||
Endpoint endpoint = getGoogleOpenIdEndpoint();
|
||||
|
||||
|
||||
@@ -33,16 +33,12 @@ public class WebOptions {
|
||||
private File externalBaseDirectory = null;
|
||||
/** An optional directory where cache files are stored. These files are not part of the webapp's general distribution and are fully re-creatable. */
|
||||
private File cacheBaseDirectory = null;
|
||||
private IHashMap nameSubstitutionMap = new LiteHashMap(10);
|
||||
private IHashMap pathSubstitutionMap = new LiteHashMap(10);
|
||||
private String defaultPackageName = null;
|
||||
private long sessionTimeout = 3600000;
|
||||
private long sessionCheckInterval = 3600000;
|
||||
private IBadSessionHandler badSessionHandler = null;
|
||||
/** Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation. */
|
||||
private IResourceRequestHandler resourceRequestHandler = null;
|
||||
/** Replaces the default handling of web dav requests. */
|
||||
private IWebdavRequestHandler webdavRequestHandler = null;
|
||||
private ResourceRequestHandler resourceRequestHandler = null;
|
||||
/** Sets the cutoff size for caching a file in memory. This may be zero to stop caching resources alltogether. Defaults to 10KB. */
|
||||
private long cacheCutoffSize = 10000;
|
||||
/** Whether responses should be compressed by default when possible. Certain resources that compress poorly will of course ignore this directive. */
|
||||
@@ -187,32 +183,6 @@ public boolean getCompressResponses() {
|
||||
public void setCompressResponses(boolean compressResponses) {
|
||||
this.compressResponses = compressResponses;
|
||||
}//setCompressResponses()//
|
||||
public IHashMap getNameSubstitutionMap() {
|
||||
return nameSubstitutionMap;
|
||||
}//getNameSubstitutionMap()//
|
||||
/**
|
||||
* Sets the mapping between old resource names and new ones.
|
||||
* This is used to substitute just the ending name for another ending name.
|
||||
* It is not recommended to use this.
|
||||
* <p>TODO: Replace this with something that uses a regular expression like language.</p>
|
||||
* @param nameSubstitutionMap
|
||||
*/
|
||||
public void setNameSubstitutionMap(LiteHashMap nameSubstitutionMap) {
|
||||
this.nameSubstitutionMap = nameSubstitutionMap;
|
||||
}//setNameSubstitutionMap()//
|
||||
public IHashMap getPathSubstitutionMap() {
|
||||
return pathSubstitutionMap;
|
||||
}//getPathSubstitutionMap()//
|
||||
/**
|
||||
* Sets the mapping between old resource request paths and new ones.
|
||||
* This is used to substitute a *full* resource requested by the client with another *full* resource request.
|
||||
* For example: "/" -> "/index.html" will only alter http://mydomain.com/ to become http://mydomain.com/index.html, but won't modify http://mydomain.com/path/ at all.
|
||||
* <p>TODO: Replace this with something that uses a regular expression like language.</p>
|
||||
* @param pathSubstitutionMap
|
||||
*/
|
||||
public void setPathSubstitutionMap(LiteHashMap pathSubstitutionMap) {
|
||||
this.pathSubstitutionMap = pathSubstitutionMap == null ? new LiteHashMap(10) : pathSubstitutionMap;
|
||||
}//setPathSubstitutionMap()//
|
||||
public String getDefaultPackageName() {
|
||||
return defaultPackageName;
|
||||
}//getDefaultPackageName()//
|
||||
@@ -255,51 +225,20 @@ public IBadSessionHandler getBadSessionHandler() {
|
||||
public void setBadSessionHandler(IBadSessionHandler badSessionHandler) {
|
||||
this.badSessionHandler = badSessionHandler;
|
||||
}//setBadSessionHandler()//
|
||||
/**
|
||||
* Adds a resource name subtitution mapping where the old resource name will be replaced by the new resource name automatically prior to the request being processed.
|
||||
* @param oldName The old resource name.
|
||||
* @param newName The new resource name.
|
||||
*/
|
||||
public void addResourceNameSubstitution(String oldName, String newName) {
|
||||
nameSubstitutionMap.put(oldName, newName);
|
||||
}//addResourceNameSubstitution()//
|
||||
/**
|
||||
* Adds a path subtitution mapping where the old path will be replaced by the new path automatically prior to the request being processed.
|
||||
* @param oldPath The old resource name. eg: "/"
|
||||
* @param newPath The new resource name. eg: "/subdir/index.html"
|
||||
* @param forward Whether the substitution should constitute a forward (where the client is told of the new path) versus a redirect.
|
||||
*/
|
||||
public void addPathSubstitution(String oldPath, String newPath, boolean forward) {
|
||||
pathSubstitutionMap.put(oldPath, new PathSubstitution(newPath, forward));
|
||||
}//addPathSubstitution()//
|
||||
/**
|
||||
* Gets the resource request handler which allows the application control over how users access static resources via the web server.
|
||||
* @return Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation.
|
||||
*/
|
||||
public IResourceRequestHandler getResourceRequestHandler() {
|
||||
public ResourceRequestHandler getResourceRequestHandler() {
|
||||
return resourceRequestHandler;
|
||||
}//getResourceRequestHandler()//
|
||||
/**
|
||||
* Sets the resource request handler which allows the application control over how users access static resources via the web server.
|
||||
* @param resourceRequestHandler Replaces the default handling of a user's access to static (file system based) resources. Allows for permission validation.
|
||||
*/
|
||||
public void setResourceRequestHandler(IResourceRequestHandler resourceRequestHandler) {
|
||||
public void setResourceRequestHandler(ResourceRequestHandler resourceRequestHandler) {
|
||||
this.resourceRequestHandler = resourceRequestHandler;
|
||||
}//setResourceRequestHandler()//
|
||||
/**
|
||||
* Gets the web dav request handler.
|
||||
* @return Replaces the default handling of web dav commands.
|
||||
*/
|
||||
public IWebdavRequestHandler getWebdavRequestHandler() {
|
||||
return webdavRequestHandler;
|
||||
}//getWebdavRequestHandler()//
|
||||
/**
|
||||
* Sets the web dav request handler.
|
||||
* @param webdavRequestHandler Replaces the default handling of web dav commands.
|
||||
*/
|
||||
public void setWebdavRequestHandler(IWebdavRequestHandler webdavRequestHandler) {
|
||||
this.webdavRequestHandler = webdavRequestHandler;
|
||||
}//setWebdavRequestHandler()//
|
||||
public long getCacheCutoffSize() {
|
||||
return cacheCutoffSize;
|
||||
}//getCacheCutoffSize()//
|
||||
|
||||
Reference in New Issue
Block a user