1 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 37 public class FileServlet extends HttpServlet { 38 39 45 public String getServletInfo() { 46 return "servlet similar to a standard httpd"; 47 } 48 49 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 77 String path = req.getRequestURI(); 78 String pathInfo = req.getPathInfo(); 79 80 String 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 reste = path; 87 88 CDSServlet.cofaxLog("removing alias part : " + reste); 89 90 int i = reste.lastIndexOf("/"); 91 String filename = reste.substring(i + 1); 92 reste = reste.substring(0, i); 93 94 CDSServlet.cofaxLog("got the filename : " + filename + " - rest : " + reste); 95 96 104 105 i = reste.lastIndexOf("/"); 106 String 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 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 String stripMe = req.getContextPath(); 131 int stripMeLen = stripMe.length(); 132 path = path.substring(stripMeLen); 133 134 String pathname = path.substring(1); 136 if (pathname.length() == 0) { 137 pathname = "./"; 138 } 139 dispatchPathname(req, res, headOnly, path, pathname); 140 141 } 142 143 159 private void dispatchPathname(HttpServletRequest req, HttpServletResponse res, boolean headOnly, String path, String pathname) throws IOException { 160 161 String 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 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 214 protected void serveFile(HttpServletRequest req, HttpServletResponse res, boolean headOnly, String path, String filename, File file) throws IOException { 215 216 if (!file.canRead()) { 217 res.sendError(HttpServletResponse.SC_FORBIDDEN); 218 return; 219 } 220 221 res.setStatus(HttpServletResponse.SC_OK); 223 long lastMod = file.lastModified(); 224 String 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 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 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 296 private void serveDirectory(HttpServletRequest req, HttpServletResponse res, boolean headOnly, String path, String 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 [] names = file.list(); 314 315 for (int i = 0; i < names.length; ++i) { 316 String aFilename = filename + File.separatorChar + names[i]; 317 File aFile = new File(aFilename); 318 String aFileType; 319 if (aFile.isDirectory()) { 320 aFileType = "d"; 321 } else if (aFile.isFile()) { 322 aFileType = "-"; 323 } else { 324 aFileType = "?"; 325 } 326 String aFileRead = (aFile.canRead() ? "r" : "-"); 327 String aFileWrite = (aFile.canWrite() ? "w" : "-"); 328 String aFileExe = "-"; 329 String aFileSize = Long.toString(aFile.length()); 330 String aFileDate = new Date(aFile.lastModified()).toString(); 331 String aFileDirsuf = (aFile.isDirectory() ? "/" : ""); 332 String 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 358 protected void redirectDirectory(HttpServletRequest req, HttpServletResponse res, String path, File file) throws IOException { 359 res.sendRedirect(path + "/"); 360 } 361 362 } 363 | Popular Tags |