com.sun.jsftemplating.util.fileStreamer.ServletStreamerContext Maven / Gradle / Ivy
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://jsftemplating.dev.java.net/cddl1.html or
* jsftemplating/cddl1.txt.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at jsftemplating/cddl1.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.jsftemplating.util.fileStreamer;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* This class encapsulates servlet specific objects so that the
* {@link FileStreamer} class is not servlet-specific.
*
* This implementation will look for the following attributes
* ({@link BaseContext#setAttribute(String, Object)}):
*
* - {@link Context#CONTENT_TYPE} -- The "Content-type:" of the response.
* - {@link Context#CONTENT_DISPOSITION} -- Disposition of the streamed content.
* - {@link Context#CONTENT_FILENAME} -- Filename of the streamed content.
* - {@link Context#EXTENSION} -- The file extension of the response.
*
*/
public class ServletStreamerContext extends BaseContext {
/**
* Constructor.
*/
public ServletStreamerContext(HttpServletRequest request, HttpServletResponse resp, ServletConfig config) {
super();
setServletRequest(request);
setServletResponse(resp);
setServletConfig(config);
setAttribute(Context.FILE_PATH, request.getPathInfo());
// FIXME: initialize allowed / denied paths...
List paths = new ArrayList();
paths.add(""); // Add default value
ServletContext ctx = config.getServletContext();
setAllowedPaths(ctx, paths);
paths = new ArrayList();
paths.add("META-INF/");
paths.add("WEB-INF/");
setDeniedPaths(ctx, paths);
}
/**
* Accessor to get the {@link FileStreamer} instance.
*/
public FileStreamer getFileStreamer() {
return FileStreamer.getFileStreamer(getServletConfig().getServletContext());
}
/**
* This method locates the appropriate {@link ContentSource} for this
* {@link Context}. It uses the HttpServletRequest
to
* look for a HttpServletRequest parameter named
* {@link #CONTENT_SOURCE_ID}. This value is used as the key when
* looking up registered {@link ContentSource} implementations.
*/
public ContentSource getContentSource() {
// Check cache...
ContentSource src = (ContentSource) getAttribute("_contentSource");
if (src != null) {
return src;
}
// Get the ContentSource id
String id = getServletRequest().getParameter(CONTENT_SOURCE_ID);
if (id == null) {
id = getServletConfig().getInitParameter(CONTENT_SOURCE_ID);
if (id == null) {
id = Context.DEFAULT_CONTENT_SOURCE_ID;
}
}
// Get the ContentSource
src = getFileStreamer().getContentSource(id);
if (src == null) {
throw new RuntimeException("The ContentSource with id '" + id
+ "' is not registered!");
}
// Return the ContentSource
setAttribute("_contentSource", src); // cache result
return src;
}
/**
* This method allows the Context to restrict access to resources.
* It returns true
if the user is allowed to view the
* resource. It returns false
if the user should not
* be allowed access to the resource.
*/
public boolean hasPermission(ContentSource src) {
String filename = src.getResourcePath(this);
ServletContext srvCtx = getServletConfig().getServletContext();
List paths = getAllowedPaths(srvCtx);
boolean ok = false;
// Ensure it is in our list of OK paths...
for (String path : paths) {
if (filename.startsWith(path)) {
ok = true;
break;
}
}
// ...and ensure it is not in our blacklisted paths...
if (ok) {
// Only check if ok so far...
paths = getDeniedPaths(srvCtx);
for (String path : paths) {
if (filename.startsWith(path)) {
ok = false;
break;
}
}
}
return ok;
}
/**
* This methods sets the allowed paths for resources. Paths may be
* further restricted using the {@link #setDeniedPaths} method.
*/
public List getAllowedPaths(ServletContext ctx) {
return (List) ctx.getAttribute(ALLOWED_PATHS_KEY);
}
/**
* This methods sets the allowed paths for resources. Paths may be
* further restricted using the {@link #setDeniedPaths} method.
*/
public void setAllowedPaths(ServletContext ctx, List paths) {
ctx.setAttribute(ALLOWED_PATHS_KEY, paths);
}
/**
* This methods sets the list of paths in which resources should not
* be served.
*/
public void setDeniedPaths(ServletContext ctx, List paths) {
ctx.setAttribute(DENIED_PATHS_KEY, paths);
}
/**
* This methods sets the list of paths for resources.
*/
public List getDeniedPaths(ServletContext ctx) {
return (List) ctx.getAttribute(DENIED_PATHS_KEY);
}
/**
* This method is responsible for setting the response header
* information.
*/
public void writeHeader(ContentSource source) {
HttpServletResponse resp = getServletResponse();
// Set the "Last-Modified" Header
// First check context
long longTime = source.getLastModified(this);
if (longTime != -1) {
resp.setDateHeader("Last-Modified", longTime);
resp.setDateHeader("Expires",
new java.util.Date().getTime() + Context.EXPIRY_TIME);
}
// First check CONTENT_TYPE
String contentType = (String) getAttribute(CONTENT_TYPE);
if (contentType == null) {
// Not found yet, check EXTENSION
String ext = (String) getAttribute(EXTENSION);
if (ext != null) {
contentType = FileStreamer.getMimeType(ext);
}
if (contentType == null) {
// Default Content-type is: application/octet-stream
contentType = FileStreamer.getDefaultMimeType();
}
}
resp.setHeader("Content-type", contentType);
// Check disposition/filename to associate a name with the stream
String disposition = (String) getAttribute(CONTENT_DISPOSITION);
String filename = (String) getAttribute(CONTENT_FILENAME);
if (disposition == null) {
// No disposition set, see if we have a filename
if (filename != null) {
resp.setHeader("Content-Disposition", DEFAULT_DISPOSITION
+ ";filename=\"" + filename + "\"");
}
} else {
// Disposition set, see if we also have a filename
if (filename != null) {
disposition += ";filename=\"" + filename + "\"";
}
resp.setHeader("Content-Disposition", disposition);
}
}
/**
* This method is responsible for sending an error.
*/
public void sendError(int code, String msg) throws IOException {
HttpServletResponse resp = getServletResponse();
if (msg == null) {
resp.sendError(code);
} else {
resp.sendError(code, msg);
}
}
/**
* This method is returns a ServletOutputStream
for the
* Servlet
that is represented by this class.
*/
public OutputStream getOutputStream() throws IOException {
return getServletResponse().getOutputStream();
}
/**
* This returns the ServletConfig
. This is the same
* as calling:
*
* getAttribute(SERVLET_CONFIG)
*/
public ServletConfig getServletConfig() {
return (ServletConfig) getAttribute(SERVLET_CONFIG);
}
/**
* This sets the ServletConfig
. This is the same as
* calling:
*
* setAttribute(SERVLET_CONFIG, config)
*/
protected void setServletConfig(ServletConfig config) {
setAttribute(SERVLET_CONFIG, config);
}
/**
* This returns the HttpServletRequest
. This is the same
* as calling:
*
* getAttribute(SERVLET_REQUEST)
*/
public HttpServletRequest getServletRequest() {
return (HttpServletRequest) getAttribute(SERVLET_REQUEST);
}
/**
* This sets the HttpServletRequest
. This is the same as
* calling:
*
* setAttribute(SERVLET_REQUEST, request)
*/
protected void setServletRequest(HttpServletRequest request) {
setAttribute(SERVLET_REQUEST, request);
}
/**
* This returns the HttpServletResponse
. This is the same
* as calling:
*
* getAttribute(SERVLET_RESPONSE)
*/
public HttpServletResponse getServletResponse() {
return (HttpServletResponse) getAttribute(SERVLET_RESPONSE);
}
/**
* This sets the HttpServletResponse
. This is the same as
* calling:
*
* setAttribute(SERVLET_RESPONSE, response)
*/
protected void setServletResponse(HttpServletResponse response) {
setAttribute(SERVLET_RESPONSE, response);
}
/**
* The attribute value to access the ServletConfig. See
* {@link #getServletConfig()}.
*/
public static final String SERVLET_CONFIG = "servletConfig";
/**
* The attribute value to access the HttpServletRequest. See
* {@link #getServletRequest()}.
*/
public static final String SERVLET_REQUEST = "servletRequest";
/**
* The attribute value to access the
* HttpServletResponse
. See
* {@link #getServletResponse()}.
*/
public static final String SERVLET_RESPONSE = "servletResponse";
/**
* The default Content-Disposition. It is only used when a filename
* is provided, but a disposition is not. The default is
* "attachment". This will normally cause a browser to prompt the
* user to save the file. This is the default since setting a
* filename implies that the user may want to save this file. You
* must explicitly set the disposition for "inline" behavior with a
* filename.
*/
public static final String DEFAULT_DISPOSITION = "attachment";
}