1 2 24 25 package org.enhydra.servlet.servlets; 26 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.io.OutputStream ; 30 import java.util.StringTokenizer ; 31 import java.util.zip.ZipEntry ; 32 import java.util.zip.ZipFile ; 33 34 import javax.servlet.ServletConfig ; 35 import javax.servlet.ServletContext ; 36 import javax.servlet.ServletException ; 37 import javax.servlet.ServletOutputStream ; 38 import javax.servlet.http.HttpServlet ; 39 import javax.servlet.http.HttpServletRequest ; 40 import javax.servlet.http.HttpServletResponse ; 41 42 import com.lutris.http.MimeType; 43 import com.lutris.logging.LogChannel; 44 import com.lutris.logging.Logger; 45 import com.lutris.logging.StandardLogger; 46 49 50 61 public class JarServerServlet extends HttpServlet { 62 63 66 private static final int buffer_size = 1024*1; 67 68 71 private final static String NOT_FOUND_MSG = 72 "<TITLE>Not Found</TITLE><H1>Not Found</H1> " + 73 "The requested object does not exist on this Enhydra Server. " + 74 "The link you followed is either outdated, inaccurate, " + 75 "or the server has been instructed not to let you have it."; 76 77 80 private final static String ACCESS_DENIED_MSG = 81 "<TITLE>Access Denied</TITLE><H1>Access Denied</H1> " + 82 "Access is not allowed to the requested file. "; 83 84 87 private final static String SC_MOVED_PERMANENTLY_MSG = 88 "<TITLE>Moved Permanently</TITLE><H1>Moved Permanently</H1> " + 89 "Resource has been moved"; 90 91 94 private LogChannel logChannel; 95 96 100 private StandardLogger standardLogger; 101 102 106 private boolean needToConfigureLogChannel = false; 107 108 111 private ServletContext myContext; 112 113 117 private String jarFileName = null; 118 private ZipFile jarFile = null; 119 123 private String defaultInner = null; 124 125 128 private long numServed = 0; 129 130 133 private MimeType mimetypes = new MimeType(); 134 135 140 private Path docRoot = null; 141 142 145 public JarServerServlet() { 146 super(); 147 if (Logger.getCentralLogger() == null) { 148 standardLogger = new StandardLogger(true); 149 needToConfigureLogChannel = true; 150 } 151 logChannel = Logger.getCentralLogger().getChannel("Enhydra"); 152 } 153 154 160 public void init(ServletConfig config) 161 throws ServletException { 162 super.init(config); 163 myContext = config.getServletContext(); 164 165 jarFileName = config.getInitParameter("jarFile"); 166 defaultInner = config.getInitParameter("default"); 167 168 String docRoot = myContext.getRealPath(""); 171 172 String tmp = docRoot.replace('\\', '/'); 174 if (!tmp.startsWith("/")) { 175 tmp = "/" + tmp; 176 } 177 if (!tmp.endsWith("/")) { 178 tmp = tmp + "/"; 179 } 180 181 StringBuffer sb = new StringBuffer (); 184 StringTokenizer st = new StringTokenizer (tmp, "/"); 185 sb.append("/"); 186 while (st.hasMoreTokens()) { 187 String tok = st.nextToken(); 188 if (st.countTokens() > 0) { 189 sb.append(tok); 190 sb.append("/"); 191 } else if (st.countTokens() == 0) { 192 sb.append(tok); 193 } else { 194 System.err.println("ERROR: no able to determine DocRoot"); 196 } 197 } 198 docRoot = sb.toString(); 199 try { 200 jarFile = new ZipFile (jarFileName); 201 } catch (IOException ioe) { 202 try { 203 jarFileName = docRoot+"/"+jarFileName; 204 jarFile = new ZipFile (jarFileName); 205 } catch (IOException ioex) { 206 throw new ServletException (ioe.getMessage()); 207 } 208 } 209 210 logInfo("Starting Jar Server Servlet with jarFile " + jarFileName); 218 } 219 220 229 public void doGet(HttpServletRequest req, HttpServletResponse res) 230 throws ServletException , IOException { 231 232 String pathInfo = req.getPathInfo(); 233 234 237 if (pathInfo==null || pathInfo.equals("") || pathInfo.equals("/")) { 238 pathInfo = defaultInner; 239 } 240 241 245 if (pathInfo.startsWith("/")) { 246 pathInfo = pathInfo.substring(1); 247 } 248 249 ZipEntry jarEntry = jarFile.getEntry(pathInfo); 250 if (isAuth(pathInfo)) { 251 processFileRequest(jarEntry, req, res); 252 } else { 253 res.sendError(res.SC_NOT_FOUND, NOT_FOUND_MSG); 255 logInfo("JarServerServlet: File " + pathInfo + " not Found."); 256 } 257 } 258 259 262 private void processFileRequest(ZipEntry file, HttpServletRequest req, 263 HttpServletResponse res) throws IOException { 264 265 if (file != null) { 266 if (file.isDirectory()) { 268 res.sendError(res.SC_NOT_FOUND, NOT_FOUND_MSG); 270 logInfo("JarServerServlet: File " + file + " not Found."); 271 } else { 272 sendPage(file, res); 274 } 275 } else { 276 res.sendError(res.SC_NOT_FOUND, NOT_FOUND_MSG); 278 logInfo("JarServerServlet: File " + file + " not Found."); 279 } 280 } 281 282 290 private boolean isAuth(String path) { 291 292 if (path.indexOf("..") == -1) { 293 return true; 294 } 295 return false; 296 } 297 298 302 private void sendPage(ZipEntry file, HttpServletResponse res) 303 throws IOException { 304 305 String filetype = mimetypes.getType(file.getName()); 306 res.setContentType(filetype); 307 Long len = new Long (file.getSize()); 308 res.setHeader("Content-Length", len.toString()); 309 ServletOutputStream out = res.getOutputStream(); 310 InputStream in = jarFile.getInputStream(file); 311 writeFile(out, in); 312 in.close(); 313 numServed++; 314 } 315 316 325 public void doPost (HttpServletRequest req, HttpServletResponse res) 326 throws ServletException , IOException { 327 res.sendError(res.SC_NOT_IMPLEMENTED); 328 logInfo("JarServerServlet: Access Denied."); 329 } 330 331 337 public String getServletInfo() { 338 return "A JarServerServlet, with jar file " + jarFileName; 339 } 340 341 344 public String toHtml() { 345 return "Serving files from the jar " + jarFileName + ".<BR>\n" + 346 numServed + " files served."; 347 } 348 349 358 private void writeFile(OutputStream out, InputStream in) 359 throws IOException { 360 361 byte buffer[] = new byte[buffer_size]; 362 while (true) { 363 int n = in.read(buffer); 364 if (n == -1) break; 365 out.write(buffer, 0, n); 366 } 367 } 368 369 377 private void logInfo(String msg) { 378 if (logChannel != null) { 379 logChannel.write(Logger.INFO, msg); 380 } else { 381 myContext.log(msg); 382 } 383 } 384 385 394 private void logError(String err, Exception e) { 395 if (logChannel != null) { 396 logChannel.write(Logger.ERROR, err, e); 397 } else { 398 myContext.log(e, err); 399 } 400 } 401 } 402 403 | Popular Tags |