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