Author: [email protected]
Date: Thu Oct  6 16:06:14 2011
New Revision: 1448

Log:
AMDATU-432 explicitly closes the connection the way Arthur suggested it, and 
refactored the codebase a bit to not open every resource twice

Modified:
   
trunk/amdatu-web/resource/src/main/java/org/amdatu/web/resource/service/ResourceServlet.java

Modified: 
trunk/amdatu-web/resource/src/main/java/org/amdatu/web/resource/service/ResourceServlet.java
==============================================================================
--- 
trunk/amdatu-web/resource/src/main/java/org/amdatu/web/resource/service/ResourceServlet.java
        (original)
+++ 
trunk/amdatu-web/resource/src/main/java/org/amdatu/web/resource/service/ResourceServlet.java
        Thu Oct  6 16:06:14 2011
@@ -15,125 +15,106 @@
  */
 package org.amdatu.web.resource.service;
 
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.ServletException;
 import java.io.IOException;
-import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URL;
 import java.net.URLConnection;
 
-public final class ResourceServlet extends HttpServlet {
-
-    public ResourceServlet() {
-    }
-
-    @Override
-    protected void doGet(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse) throws ServletException, IOException {
-        
-        String target = httpServletRequest.getRequestURI();
-        if(!httpServletRequest.getContextPath().equals("")){
-            target = target.replaceFirst(httpServletRequest.getContextPath(), 
"");
-        }
-        
-        if (target == null) {
-            target = "";
-        }
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
-        if (!target.startsWith("/")) {
-            target += "/" + target;
-        }
+public final class ResourceServlet extends HttpServlet {
+       private static final long serialVersionUID = 1L;
+       private static final int INTERNAL_BUFFER_SIZE = 4096;
 
-        URL url = getServletContext().getResource(target);
+       @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException {
+        String path = getResourcePath(request);
+        URL url = getServletContext().getResource(path);
         if (url == null) {
-            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
         }
         else {
-            handle(httpServletRequest, httpServletResponse, url, target);
-        }
-    }
-
-    private void handle(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse, URL url, String resName) throws 
IOException {
-        String contentType = getServletContext().getMimeType(resName);
-        if (contentType != null) {
-            httpServletResponse.setContentType(contentType);
-        }
-
-        long lastModified = getLastModified(url);
-        if (lastModified != 0) {
-            httpServletResponse.setDateHeader("Last-Modified", lastModified);
-        }
-
-        if (!resourceModified(lastModified, 
httpServletRequest.getDateHeader("If-Modified-Since"))) {
-            httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
-        }
-        else {
-            copyResource(url, httpServletResponse);
-        }
-    }
-
-    private long getLastModified(URL url) {
-        long lastModified = 0;
-
-        try {
-            URLConnection conn = url.openConnection();
-            lastModified = conn.getLastModified();
-        }
-        catch (Exception e) {
-            // Do nothing
-        }
-
-        if (lastModified == 0) {
-            String filepath = url.getPath();
-            if (filepath != null) {
-                File f = new File(filepath);
-                if (f.exists()) {
-                    lastModified = f.lastModified();
-                }
-            }
-        }
-
-        return lastModified;
-    }
-
-    private boolean resourceModified(long resTimestamp, long modSince) {
-        modSince /= 1000;
-        resTimestamp /= 1000;
-
-        return resTimestamp == 0 || modSince == -1 || resTimestamp > modSince;
-    }
-
-    private void copyResource(URL url, HttpServletResponse res)
-        throws IOException {
-        OutputStream os = null;
-        InputStream is = null;
-
-        try {
-            os = res.getOutputStream();
-            is = url.openStream();
-
-            int len = 0;
-            byte[] buf = new byte[1024];
-            int n;
-
-            while ((n = is.read(buf, 0, buf.length)) >= 0) {
-                os.write(buf, 0, n);
-                len += n;
-            }
-
-            res.setContentLength(len);
-        }
-        finally {
-            if (is != null) {
-                is.close();
-            }
-
-            if (os != null) {
-                os.close();
-            }
-        }
-    }
+            String contentType = getServletContext().getMimeType(path);
+                       if (contentType != null) {
+                           response.setContentType(contentType);
+                       }
+                       URLConnection conn = null;
+                       OutputStream os = null;
+                       InputStream is = null;
+                       try {
+                               conn = url.openConnection();
+                               long lastModified = conn.getLastModified();
+                               if (lastModified != 0) {
+                                   response.setDateHeader("Last-Modified", 
lastModified);
+                               }
+                               // send the whole response, unless there was an 
"if modified since" header and the
+                               // resource is indeed not modified since that 
date
+                               long ifModifiedSince = 
request.getDateHeader("If-Modified-Since");
+                               if ((lastModified == 0 || ifModifiedSince == -1 
|| lastModified > ifModifiedSince)) {
+                                       try {
+                                               is = conn.getInputStream();
+                                           os = response.getOutputStream();
+                                           copy(is, os);
+                                       }
+                                       finally {
+                                           if (is != null) {
+                                               is.close();
+                                           }
+                                           if (os != null) {
+                                               os.close();
+                                           }
+                                       }
+                               }
+                               else {
+                                   
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                               }
+                       }
+                       finally {
+                               if (conn != null && is == null) {
+                                       // AMDATU-432 if the connection is open 
(conn != null), but nothing 
+                                       // has been read (is == null), and the 
URL points to a local file,
+                                       // it stays open, so explicitly close 
it.
+                                       conn.getInputStream().close();
+                               }
+                       }
+        }
+    }
+
+       /**
+        * Returns the path to the resource based on the request. This is the
+        * path part of the request URI minus the servlet context path.
+        */
+       private String getResourcePath(HttpServletRequest request) {
+               String path = request.getRequestURI();
+        String contextPath = request.getContextPath();
+        if (path == null) {
+               path = "";
+        }
+        if (!path.startsWith("/")) {
+               path += "/" + path;
+        }
+        int contextPathLength = contextPath.length();
+               if (contextPathLength > 0) {
+            path = path.substring(contextPathLength);
+        }
+               return path;
+       }
+
+       /**
+        * Copy data from InputStream to OutputStream.
+        */
+       private void copy(InputStream is, OutputStream os) throws IOException {
+               int len = 0;
+               byte[] buf = new byte[INTERNAL_BUFFER_SIZE];
+               int n;
+
+               while ((n = is.read(buf, 0, buf.length)) >= 0) {
+                   os.write(buf, 0, n);
+                   len += n;
+               }
+       }
 }
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to