001: /*
002: * Copyright 2005 jWic Group (http://www.jwic.de)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: * de.jwic.web.ClasspathResourceServlet
017: * Created on 14.04.2005
018: * $Id: ClasspathResourceServlet.java,v 1.3 2006/08/14 09:34:59 lordsam Exp $
019: */
020: package de.jwic.web;
021:
022: import java.io.IOException;
023: import java.io.InputStream;
024:
025: import javax.servlet.ServletException;
026: import javax.servlet.ServletOutputStream;
027: import javax.servlet.http.HttpServlet;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033:
034: /**
035: * Returns a file resource from the classpath. The servlet must be
036: * mapped to the path /cp/ to function properly.
037: * @author Florian Lippisch
038: * @version $Revision: 1.3 $
039: */
040: public class ClasspathResourceServlet extends HttpServlet {
041:
042: private static final long serialVersionUID = 1L;
043:
044: protected final Log log = LogFactory.getLog(getClass());
045:
046: private String[] allowedTypes = { ".gif", ".jpeg", ".js", ".css",
047: ".png" };
048: private String servletId = "/cp/";
049: private long startup = 0;
050:
051: /**
052: * Default constructor.
053: *
054: */
055: public ClasspathResourceServlet() {
056: startup = System.currentTimeMillis();
057: }
058:
059: protected long getLastModified(HttpServletRequest arg0) {
060: return startup;
061:
062: }
063:
064: /* (non-Javadoc)
065: * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
066: */
067: protected void doGet(HttpServletRequest req, HttpServletResponse res)
068: throws ServletException, IOException {
069:
070: String fileLocation = getFileLocation(req);
071: String fileName;
072: if (fileLocation != null) {
073: fileName = getFileName(fileLocation);
074: } else {
075: fileName = null;
076: }
077:
078: if (fileName == null) {
079: res.sendError(HttpServletResponse.SC_BAD_REQUEST);
080: return;
081: }
082:
083: if (!isAllowedType(fileName)) {
084: res.sendError(HttpServletResponse.SC_FORBIDDEN);
085: return;
086: }
087:
088: // prepare the dowload
089: InputStream in = null;
090: try {
091:
092: // get the file data as an InputStream
093: in = getClass().getClassLoader().getResourceAsStream(
094: fileLocation);
095:
096: } catch (Exception e) {
097: in = null;
098: log.error("Error reading resource " + fileLocation, e);
099: res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
100: e.toString());
101: return;
102: }
103:
104: if (in == null) {
105: res.sendError(HttpServletResponse.SC_NOT_FOUND);
106: return;
107: }
108:
109: String mimeType = getServletContext().getMimeType(fileName);
110: if (mimeType == null) {
111: mimeType = "application/x-msdownload";
112: }
113: // set the response header
114:
115: res.setContentType(mimeType);
116: res.setHeader("Content-Disposition", "filename=" + fileName
117: + ";");
118: res.setHeader("Cache-Control", "max-age=" + (60 * 60 * 24)); // 24 hours
119: res.setContentLength(in != null ? in.available() : 0);
120:
121: ServletOutputStream out = res.getOutputStream();
122:
123: //send the file as a stream of bytes
124: int transfered = 0;
125: try {
126: byte[] buf = new byte[1024];
127: int length = 0;
128:
129: while ((in != null) && ((length = in.read(buf)) != -1)) {
130: try {
131: out.write(buf, 0, length);
132: } catch (Exception e1) {
133: // error with client
134: log.error("Error sending data to client", e1);
135: return;
136: }
137: transfered += length;
138: // for debugging !!!
139: //long start = System.currentTimeMillis();
140: //while (System.currentTimeMillis()-start<1000) {}
141: }
142: } catch (Exception e2) {
143: // error with server
144: log.error("Error reading data", e2);
145: return;
146: } finally {
147: in.close();
148: out.flush();
149: out.close();
150: }
151:
152: log.debug("Access to ClasspathResource '" + fileLocation + "'");
153:
154: }
155:
156: /**
157: * @param fileName
158: * @return
159: */
160: private boolean isAllowedType(String fileName) {
161:
162: int pos = fileName.lastIndexOf('.');
163: String suffix = ".";
164: if (pos != -1) {
165: suffix = fileName.substring(pos);
166: }
167:
168: for (int i = 0; i < allowedTypes.length; i++) {
169: if (allowedTypes[i].equals(suffix)) {
170: return true;
171: }
172: }
173:
174: return false;
175: }
176:
177: /**
178: * @param req
179: * @return
180: */
181: private String getFileLocation(HttpServletRequest req) {
182:
183: String uri = req.getRequestURI();
184: int i = uri.indexOf(servletId);
185: if (i != -1) {
186: return uri.substring(i + servletId.length());
187: }
188: return null;
189:
190: }
191:
192: /**
193: * Returns the filename in the filePath.
194: * @param filePath
195: * @return
196: */
197: private String getFileName(String filePath) {
198:
199: int i = filePath.lastIndexOf('/');
200: if (i != -1) {
201: return filePath.substring(i + 1);
202: }
203: return null;
204: }
205:
206: }
|