KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > cofax > cds > FileServlet


1 /*
2  * FileServlet is part of the Cofax content management system library.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Please see http://www.cofax.org for contact information and other related informaion.
19  *
20  * $Header: /cvsroot/cofax/cofax/src/org/cofax/cds/FileServlet.java,v 1.4.2.1 2006/12/11 16:19:29 fxrobin Exp $
21  */

22
23 package org.cofax.cds;
24
25 import java.io.*;
26 import java.util.*;
27 import java.text.*;
28 import javax.servlet.*;
29 import javax.servlet.http.*;
30
31 /**
32  * A simple servlet for dynamically returning static files.
33  *
34  * @author kmartino
35  * @created April 22, 2002
36  */

37 public class FileServlet extends HttpServlet {
38
39     /**
40      * Returns a string containing information about the author, version, and
41      * copyright of the servlet.
42      *
43      * @return The servletInfo value
44      */

45     public String JavaDoc getServletInfo() {
46         return "servlet similar to a standard httpd";
47     }
48
49     /**
50      * Services a single request from the client.
51      *
52      * @param req
53      * the servlet request
54      * @param res
55      * Description of the Parameter
56      * @exception ServletException
57      * when an exception has occurred
58      * @exception IOException
59      * Description of the Exception
60      */

61     public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
62
63         boolean headOnly;
64
65         if (req.getMethod().equalsIgnoreCase("get")) {
66             headOnly = false;
67         } else if (!req.getMethod().equalsIgnoreCase("head")) {
68             headOnly = true;
69         } else {
70             res.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
71             return;
72         }
73
74         // FX : to change file name delivery
75
// 29/03/2006
76

77         String JavaDoc path = req.getRequestURI();
78         String JavaDoc pathInfo = req.getPathInfo();
79
80         String JavaDoc aliasPattern = "/_alias_/";
81
82         if (path != null && path.indexOf(aliasPattern) > 0) {
83
84             CDSServlet.cofaxLog("this is an alias file : " + path);
85             path = path.replaceAll(aliasPattern, "/");
86             String JavaDoc reste = path;
87
88             CDSServlet.cofaxLog("removing alias part : " + reste);
89
90             int i = reste.lastIndexOf("/");
91             String JavaDoc filename = reste.substring(i + 1);
92             reste = reste.substring(0, i);
93
94             CDSServlet.cofaxLog("got the filename : " + filename + " - rest : " + reste);
95
96             /*
97              * i = reste.lastIndexOf("/"); String extension =
98              * reste.substring(i+1); reste = reste.substring(0,i);
99              *
100              *
101              * CDSServlet.cofaxLog("got the extension : "+ extension + " - rest : " +
102              * reste);
103              */

104
105             i = reste.lastIndexOf("/");
106             String JavaDoc fileOnDisk = reste.substring(i + 1);
107             reste = reste.substring(0, i);
108
109             CDSServlet.cofaxLog("got the file on disk : " + fileOnDisk + " - rest : " + reste);
110
111             path = reste + "/" + fileOnDisk;
112
113             CDSServlet.cofaxLog("real file : " + path);
114
115             res.setHeader("Content-Disposition", "attachment; filename=" + filename + ";");
116         }
117
118         // For security disallow any path's with dots in them.
119
if (path == null || path.charAt(0) != '/') {
120             res.sendError(HttpServletResponse.SC_BAD_REQUEST);
121             return;
122         }
123         if (path.indexOf("/../") != -1 || path.endsWith("/..")) {
124             res.sendError(HttpServletResponse.SC_FORBIDDEN);
125             return;
126         }
127
128         // we need to strip the context path from the BEGINNING
129
// of the path to continue
130
String JavaDoc stripMe = req.getContextPath();
131         int stripMeLen = stripMe.length();
132         path = path.substring(stripMeLen);
133
134         // Make a version without the leading /.
135
String JavaDoc pathname = path.substring(1);
136         if (pathname.length() == 0) {
137             pathname = "./";
138         }
139         dispatchPathname(req, res, headOnly, path, pathname);
140
141     }
142
143     /**
144      * Description of the Method
145      *
146      * @param req
147      * Description of the Parameter
148      * @param res
149      * Description of the Parameter
150      * @param headOnly
151      * Description of the Parameter
152      * @param path
153      * Description of the Parameter
154      * @param pathname
155      * Description of the Parameter
156      * @exception IOException
157      * Description of the Exception
158      */

159     private void dispatchPathname(HttpServletRequest req, HttpServletResponse res, boolean headOnly, String JavaDoc path, String JavaDoc pathname) throws IOException {
160
161         String JavaDoc filename = pathname.replace('/', File.separatorChar);
162         if (filename.charAt(filename.length() - 1) == File.separatorChar) {
163             filename = filename.substring(0, filename.length() - 1);
164         }
165
166         filename = getServletContext().getRealPath(filename);
167
168         File file = new File(filename);
169         if (file.exists()) {
170             if (!file.isDirectory()) {
171                 serveFile(req, res, headOnly, path, filename, file);
172             } else {
173                 if (pathname.charAt(pathname.length() - 1) != '/') {
174                     redirectDirectory(req, res, path, file);
175                 } else {
176                     String JavaDoc indexFilename = filename + File.separatorChar + "index.html";
177                     File indexFile = new File(indexFilename);
178                     if (indexFile.exists()) {
179                         serveFile(req, res, headOnly, path, indexFilename, indexFile);
180                     } else {
181                         serveDirectory(req, res, headOnly, path, filename, file);
182                     }
183                 }
184             }
185         } else {
186             if (pathname.endsWith("/index.html")) {
187                 dispatchPathname(req, res, headOnly, path, pathname.substring(0, pathname.length() - 10));
188             } else if (pathname.equals("index.html")) {
189                 dispatchPathname(req, res, headOnly, path, "./");
190             } else {
191                 res.sendError(HttpServletResponse.SC_NOT_FOUND);
192             }
193         }
194     }
195
196     /**
197      * Description of the Method
198      *
199      * @param req
200      * Description of the Parameter
201      * @param res
202      * Description of the Parameter
203      * @param headOnly
204      * Description of the Parameter
205      * @param path
206      * Description of the Parameter
207      * @param filename
208      * Description of the Parameter
209      * @param file
210      * Description of the Parameter
211      * @exception IOException
212      * Description of the Exception
213      */

214     protected void serveFile(HttpServletRequest req, HttpServletResponse res, boolean headOnly, String JavaDoc path, String JavaDoc filename, File file) throws IOException {
215
216         if (!file.canRead()) {
217             res.sendError(HttpServletResponse.SC_FORBIDDEN);
218             return;
219         }
220
221         // Handle If-Modified-Since.
222
res.setStatus(HttpServletResponse.SC_OK);
223         long lastMod = file.lastModified();
224         String JavaDoc ifModSinceStr = req.getHeader("If-Modified-Since");
225         long ifModSince = -1;
226
227         if (ifModSinceStr != null) {
228             int semi = ifModSinceStr.indexOf(';');
229             if (semi != -1) {
230                 ifModSinceStr = ifModSinceStr.substring(0, semi);
231             }
232             try {
233                 ifModSince = DateFormat.getDateInstance().parse(ifModSinceStr).getTime();
234             } catch (Exception JavaDoc ignore) {
235             }
236         }
237
238         if (ifModSince != -1 && ifModSince >= lastMod) {
239             res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
240             headOnly = true;
241         }
242
243         res.setContentType(getServletContext().getMimeType(filename));
244         res.setContentLength((int) file.length());
245         res.setDateHeader("Last-Modified", lastMod);
246         OutputStream out = res.getOutputStream();
247         if (!headOnly) {
248             InputStream in = new FileInputStream(file);
249             copyStream(in, out);
250             in.close();
251         }
252         out.close();
253     }
254
255     /**
256      * Copy a file from in to out. Sub-classes can override this in order to do
257      * filtering of some sort.
258      *
259      * @param in
260      * Description of the Parameter
261      * @param out
262      * Description of the Parameter
263      * @exception IOException
264      * Description of the Exception
265      */

266     public void copyStream(InputStream in, OutputStream out) throws IOException {
267         byte buf[] = new byte[2048];
268         int cnt = 0;
269         int n;
270         try {
271             while ((n = in.read(buf)) != -1) {
272                 out.write(buf, 0, n);
273             }
274         } catch (IOException e) {
275         }
276     }
277
278     /**
279      * Description of the Method
280      *
281      * @param req
282      * Description of the Parameter
283      * @param res
284      * Description of the Parameter
285      * @param headOnly
286      * Description of the Parameter
287      * @param path
288      * Description of the Parameter
289      * @param filename
290      * Description of the Parameter
291      * @param file
292      * Description of the Parameter
293      * @exception IOException
294      * Description of the Exception
295      */

296     private void serveDirectory(HttpServletRequest req, HttpServletResponse res, boolean headOnly, String JavaDoc path, String JavaDoc filename, File file) throws IOException {
297         if (!file.canRead()) {
298             res.sendError(HttpServletResponse.SC_FORBIDDEN);
299             return;
300         }
301         res.setStatus(HttpServletResponse.SC_OK);
302         res.setContentType("text/html");
303         OutputStream out = res.getOutputStream();
304         if (!headOnly) {
305             PrintStream p = new PrintStream(new BufferedOutputStream(out));
306             p.println("<HTML><HEAD>");
307             p.println("<TITLE>Index of " + path + "</TITLE>");
308             p.println("</HEAD><BODY BGCOLOR=\"#ffffff\">");
309             p.println("<H2>Index of " + path + "</H2>");
310             p.println("<PRE>");
311             p.println("mode bytes last-changed name");
312             p.println("<HR>");
313             String JavaDoc[] names = file.list();
314
315             for (int i = 0; i < names.length; ++i) {
316                 String JavaDoc aFilename = filename + File.separatorChar + names[i];
317                 File aFile = new File(aFilename);
318                 String JavaDoc aFileType;
319                 if (aFile.isDirectory()) {
320                     aFileType = "d";
321                 } else if (aFile.isFile()) {
322                     aFileType = "-";
323                 } else {
324                     aFileType = "?";
325                 }
326                 String JavaDoc aFileRead = (aFile.canRead() ? "r" : "-");
327                 String JavaDoc aFileWrite = (aFile.canWrite() ? "w" : "-");
328                 String JavaDoc aFileExe = "-";
329                 String JavaDoc aFileSize = Long.toString(aFile.length());
330                 String JavaDoc aFileDate = new Date(aFile.lastModified()).toString();
331                 String JavaDoc aFileDirsuf = (aFile.isDirectory() ? "/" : "");
332                 String JavaDoc aFileSuf = (aFile.isDirectory() ? "/" : "");
333                 p.println(aFileType + aFileRead + aFileWrite + aFileExe + " " + aFileSize + " " + aFileDate + " " + "<A HREF=\"" + names[i] + aFileDirsuf
334                         + "\">" + names[i] + aFileSuf + "</A>");
335             }
336             p.println("</PRE>");
337             p.println("<HR>");
338             p.println("</BODY></HTML>");
339             p.flush();
340         }
341         out.close();
342     }
343
344     /**
345      * Description of the Method
346      *
347      * @param req
348      * Description of the Parameter
349      * @param res
350      * Description of the Parameter
351      * @param path
352      * Description of the Parameter
353      * @param file
354      * Description of the Parameter
355      * @exception IOException
356      * Description of the Exception
357      */

358     protected void redirectDirectory(HttpServletRequest req, HttpServletResponse res, String JavaDoc path, File file) throws IOException {
359         res.sendRedirect(path + "/");
360     }
361
362 }
363
Popular Tags